github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/terraform/context_validate.go (about) 1 package terraform 2 3 import ( 4 "log" 5 6 "github.com/muratcelep/terraform/not-internal/addrs" 7 "github.com/muratcelep/terraform/not-internal/configs" 8 "github.com/muratcelep/terraform/not-internal/states" 9 "github.com/muratcelep/terraform/not-internal/tfdiags" 10 "github.com/zclconf/go-cty/cty" 11 ) 12 13 // Validate performs semantic validation of a configuration, and returns 14 // any warnings or errors. 15 // 16 // Syntax and structural checks are performed by the configuration loader, 17 // and so are not repeated here. 18 // 19 // Validate considers only the configuration and so it won't catch any 20 // errors caused by current values in the state, or other external information 21 // such as root module input variables. However, the Plan function includes 22 // all of the same checks as Validate, in addition to the other work it does 23 // to consider the previous run state and the planning options. 24 func (c *Context) Validate(config *configs.Config) tfdiags.Diagnostics { 25 defer c.acquireRun("validate")() 26 27 var diags tfdiags.Diagnostics 28 29 moreDiags := c.checkConfigDependencies(config) 30 diags = diags.Append(moreDiags) 31 // If required dependencies are not available then we'll bail early since 32 // otherwise we're likely to just see a bunch of other errors related to 33 // incompatibilities, which could be overwhelming for the user. 34 if diags.HasErrors() { 35 return diags 36 } 37 38 log.Printf("[DEBUG] Building and walking validate graph") 39 40 graph, moreDiags := ValidateGraphBuilder(&PlanGraphBuilder{ 41 Config: config, 42 Plugins: c.plugins, 43 Validate: true, 44 State: states.NewState(), 45 }).Build(addrs.RootModuleInstance) 46 diags = diags.Append(moreDiags) 47 if moreDiags.HasErrors() { 48 return diags 49 } 50 51 // Validate is to check if the given module is valid regardless of 52 // input values, current state, etc. Therefore we populate all of the 53 // input values with unknown values of the expected type, allowing us 54 // to perform a type check without assuming any particular values. 55 varValues := make(InputValues) 56 for name, variable := range config.Module.Variables { 57 ty := variable.Type 58 if ty == cty.NilType { 59 // Can't predict the type at all, so we'll just mark it as 60 // cty.DynamicVal (unknown value of cty.DynamicPseudoType). 61 ty = cty.DynamicPseudoType 62 } 63 varValues[name] = &InputValue{ 64 Value: cty.UnknownVal(ty), 65 SourceType: ValueFromUnknown, 66 } 67 } 68 69 walker, walkDiags := c.walk(graph, walkValidate, &graphWalkOpts{ 70 Config: config, 71 RootVariableValues: varValues, 72 }) 73 diags = diags.Append(walker.NonFatalDiagnostics) 74 diags = diags.Append(walkDiags) 75 if walkDiags.HasErrors() { 76 return diags 77 } 78 79 return diags 80 }