github.com/paybyphone/terraform@v0.9.5-0.20170613192930-9706042ddd51/config/config_terraform.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/hashicorp/go-version"
     8  	"github.com/mitchellh/hashstructure"
     9  )
    10  
    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
    16  }
    17  
    18  // Validate performs the validation for just the Terraform configuration.
    19  func (t *Terraform) Validate() []error {
    20  	var errs []error
    21  
    22  	if raw := t.RequiredVersion; raw != "" {
    23  		// Check that the value has no interpolations
    24  		rc, err := NewRawConfig(map[string]interface{}{
    25  			"root": raw,
    26  		})
    27  		if err != nil {
    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"))
    33  		} else {
    34  			// Check it is valid
    35  			_, err := version.NewConstraint(raw)
    36  			if err != nil {
    37  				errs = append(errs, fmt.Errorf(
    38  					"terraform.required_version: invalid syntax: %s", err))
    39  			}
    40  		}
    41  	}
    42  
    43  	if t.Backend != nil {
    44  		errs = append(errs, t.Backend.Validate()...)
    45  	}
    46  
    47  	return errs
    48  }
    49  
    50  // Merge t with t2.
    51  // Any conflicting fields are overwritten by t2.
    52  func (t *Terraform) Merge(t2 *Terraform) {
    53  	if t2.RequiredVersion != "" {
    54  		t.RequiredVersion = t2.RequiredVersion
    55  	}
    56  
    57  	if t2.Backend != nil {
    58  		t.Backend = t2.Backend
    59  	}
    60  }
    61  
    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.
    66  type Backend struct {
    67  	Type      string
    68  	RawConfig *RawConfig
    69  
    70  	// Hash is a unique hash code representing the original configuration
    71  	// of the backend. This won't be recomputed unless Rehash is called.
    72  	Hash uint64
    73  }
    74  
    75  // Rehash returns a unique content hash for this backend's configuration
    76  // as a uint64 value.
    77  func (b *Backend) Rehash() uint64 {
    78  	// If we have no backend, the value is zero
    79  	if b == nil {
    80  		return 0
    81  	}
    82  
    83  	// Use hashstructure to hash only our type with the config.
    84  	code, err := hashstructure.Hash(map[string]interface{}{
    85  		"type":   b.Type,
    86  		"config": b.RawConfig.Raw,
    87  	}, nil)
    88  
    89  	// This should never happen since we have just some basic primitives
    90  	// so panic if there is an error.
    91  	if err != nil {
    92  		panic(err)
    93  	}
    94  
    95  	return code
    96  }
    97  
    98  func (b *Backend) Validate() []error {
    99  	if len(b.RawConfig.Interpolations) > 0 {
   100  		return []error{fmt.Errorf(strings.TrimSpace(errBackendInterpolations))}
   101  	}
   102  
   103  	return nil
   104  }
   105  
   106  const errBackendInterpolations = `
   107  terraform.backend: configuration cannot contain interpolations
   108  
   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
   113  configuration.
   114  
   115  If you'd like to parameterize backend configuration, we recommend using
   116  partial configuration with the "-backend-config" flag to "terraform init".
   117  `