terraform/tools/terraform-bundle/config.go

63 lines
1.2 KiB
Go
Raw Normal View History

terraform-bundle tool for bundling Terraform with providers Normally "terraform init" will download and install the plugins necessary to work with a particular configuration, but sometimes Terraform is deployed in a network that, for one reason or another, cannot access the official plugin repository for automatic download. terraform-bundle provides an alternative method, allowing the auto-download process to be run out-of-band on a separate machine that _does_ have access to the repository. The result is a zip file that can be extracted onto the target system to install both the desired Terraform version and a selection of providers, thus avoiding the need for on-the-fly plugin installation. This is provided as a separate tool from Terraform because it is not something that most users will need. In the rare case where this is needed, we will for the moment assume that users are able to build this tool themselves. We may later release it in a pre-built form, if it proves to be generally useful. It uses the same API from the plugin/discovery package is is used by the auto-install behavior in "terraform init", so plugin versions are resolved in the same way. However, it's expected that several different Terraform configurations will run from the same bundle, so this tool allows the bundle to include potentially many versions of the same provider and thus allows each Terraform configuration to select from the available versions in the bundle, avoiding the need to upgrade all configurations to new provider versions in lockstep.
2017-07-05 18:44:50 +02:00
package main
import (
"fmt"
"io/ioutil"
"github.com/hashicorp/hcl"
"github.com/hashicorp/terraform/plugin/discovery"
)
type Config struct {
Terraform TerraformConfig `hcl:"terraform"`
Providers map[string][]discovery.ConstraintStr `hcl:"providers"`
}
type TerraformConfig struct {
Version discovery.VersionStr `hcl:"version"`
}
func LoadConfig(src []byte, filename string) (*Config, error) {
config := &Config{}
err := hcl.Decode(config, string(src))
if err != nil {
return config, err
}
err = config.validate()
return config, err
}
func LoadConfigFile(filename string) (*Config, error) {
src, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return LoadConfig(src, filename)
}
func (c *Config) validate() error {
if c.Terraform.Version == "" {
return fmt.Errorf("terraform.version is required")
}
if _, err := c.Terraform.Version.Parse(); err != nil {
return fmt.Errorf("terraform.version: %s", err)
}
if c.Providers == nil {
c.Providers = map[string][]discovery.ConstraintStr{}
}
for k, cs := range c.Providers {
for _, c := range cs {
if _, err := c.Parse(); err != nil {
return fmt.Errorf("providers.%s: %s", k, err)
}
}
}
return nil
}