7 "github.com/hashicorp/go-version"
8 "github.com/mitchellh/hashstructure"
11 // Terraform is the Terraform meta-configuration that can be present
12 // in configuration files for configuring Terraform itself.
13 type Terraform struct {
14 RequiredVersion string `hcl:"required_version"` // Required Terraform version (constraint)
15 Backend *Backend // See Backend struct docs
18 // Validate performs the validation for just the Terraform configuration.
19 func (t *Terraform) Validate() []error {
22 if raw := t.RequiredVersion; raw != "" {
23 // Check that the value has no interpolations
24 rc, err := NewRawConfig(map[string]interface{}{
28 errs = append(errs, fmt.Errorf(
29 "terraform.required_version: %s", err))
30 } else if len(rc.Interpolations) > 0 {
31 errs = append(errs, fmt.Errorf(
32 "terraform.required_version: cannot contain interpolations"))
35 _, err := version.NewConstraint(raw)
37 errs = append(errs, fmt.Errorf(
38 "terraform.required_version: invalid syntax: %s", err))
44 errs = append(errs, t.Backend.Validate()...)
51 // Any conflicting fields are overwritten by t2.
52 func (t *Terraform) Merge(t2 *Terraform) {
53 if t2.RequiredVersion != "" {
54 t.RequiredVersion = t2.RequiredVersion
57 if t2.Backend != nil {
58 t.Backend = t2.Backend
62 // Backend is the configuration for the "backend" to use with Terraform.
63 // A backend is responsible for all major behavior of Terraform's core.
64 // The abstraction layer above the core (the "backend") allows for behavior
65 // such as remote operation.
70 // Hash is a unique hash code representing the original configuration
71 // of the backend. This won't be recomputed unless Rehash is called.
75 // Rehash returns a unique content hash for this backend's configuration
77 func (b *Backend) Rehash() uint64 {
78 // If we have no backend, the value is zero
83 // Use hashstructure to hash only our type with the config.
84 code, err := hashstructure.Hash(map[string]interface{}{
86 "config": b.RawConfig.Raw,
89 // This should never happen since we have just some basic primitives
90 // so panic if there is an error.
98 func (b *Backend) Validate() []error {
99 if len(b.RawConfig.Interpolations) > 0 {
100 return []error{fmt.Errorf(strings.TrimSpace(errBackendInterpolations))}
106 const errBackendInterpolations = `
107 terraform.backend: configuration cannot contain interpolations
109 The backend configuration is loaded by Terraform extremely early, before
110 the core of Terraform can be initialized. This is necessary because the backend
111 dictates the behavior of that core. The core is what handles interpolation
112 processing. Because of this, interpolations cannot be used in backend
115 If you'd like to parameterize backend configuration, we recommend using
116 partial configuration with the "-backend-config" flag to "terraform init".