6 version "github.com/hashicorp/go-version"
7 "github.com/hashicorp/hcl2/hcl"
8 "github.com/hashicorp/terraform/configs"
11 // LoadConfig reads the Terraform module in the given directory and uses it as the
12 // root module to build the static module tree that represents a configuration,
13 // assuming that all required descendent modules have already been installed.
15 // If error diagnostics are returned, the returned configuration may be either
16 // nil or incomplete. In the latter case, cautious static analysis is possible
17 // in spite of the errors.
19 // LoadConfig performs the basic syntax and uniqueness validations that are
20 // required to process the individual modules, and also detects
21 func (l *Loader) LoadConfig(rootDir string) (*configs.Config, hcl.Diagnostics) {
22 rootMod, diags := l.parser.LoadConfigDir(rootDir)
27 cfg, cDiags := configs.BuildConfig(rootMod, configs.ModuleWalkerFunc(l.moduleWalkerLoad))
28 diags = append(diags, cDiags...)
33 // moduleWalkerLoad is a configs.ModuleWalkerFunc for loading modules that
34 // are presumed to have already been installed. A different function
35 // (moduleWalkerInstall) is used for installation.
36 func (l *Loader) moduleWalkerLoad(req *configs.ModuleRequest) (*configs.Module, *version.Version, hcl.Diagnostics) {
37 // Since we're just loading here, we expect that all referenced modules
38 // will be already installed and described in our manifest. However, we
39 // do verify that the manifest and the configuration are in agreement
40 // so that we can prompt the user to run "terraform init" if not.
42 key := l.modules.manifest.ModuleKey(req.Path)
43 record, exists := l.modules.manifest[key]
46 return nil, nil, hcl.Diagnostics{
48 Severity: hcl.DiagError,
49 Summary: "Module not installed",
50 Detail: "This module is not yet installed. Run \"terraform init\" to install all modules required by this configuration.",
51 Subject: &req.CallRange,
56 var diags hcl.Diagnostics
58 // Check for inconsistencies between manifest and config
59 if req.SourceAddr != record.SourceAddr {
60 diags = append(diags, &hcl.Diagnostic{
61 Severity: hcl.DiagError,
62 Summary: "Module source has changed",
63 Detail: "The source address was changed since this module was installed. Run \"terraform init\" to install all modules required by this configuration.",
64 Subject: &req.SourceAddrRange,
67 if !req.VersionConstraint.Required.Check(record.Version) {
68 diags = append(diags, &hcl.Diagnostic{
69 Severity: hcl.DiagError,
70 Summary: "Module version requirements have changed",
72 "The version requirements have changed since this module was installed and the installed version (%s) is no longer acceptable. Run \"terraform init\" to install all modules required by this configuration.",
75 Subject: &req.SourceAddrRange,
79 mod, mDiags := l.parser.LoadConfigDir(record.Dir)
80 diags = append(diags, mDiags...)
82 // nil specifically indicates that the directory does not exist or
83 // cannot be read, so in this case we'll discard any generic diagnostics
84 // returned from LoadConfigDir and produce our own context-sensitive
86 return nil, nil, hcl.Diagnostics{
88 Severity: hcl.DiagError,
89 Summary: "Module not installed",
90 Detail: fmt.Sprintf("This module's local cache directory %s could not be read. Run \"terraform init\" to install all modules required by this configuration.", record.Dir),
91 Subject: &req.CallRange,
96 return mod, record.Version, diags