Skip to content

Commit

Permalink
Add templating for var-file names
Browse files Browse the repository at this point in the history
Signed-off-by: Reinhard Naegele <unguiculus@gmail.com>
  • Loading branch information
unguiculus committed Jan 24, 2020
1 parent 7ed6b28 commit 82fab26
Show file tree
Hide file tree
Showing 12 changed files with 44 additions and 20 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ By default, `gotf.yaml` is loaded from the current directory.
varsFiles:
# tfvars files are added to the Terraform environment via
# TF_CLI_ARGS_<command>=-var-file=<file> for commands that support them
- testmodule/test.tfvars
- testmodule/test-{{ .Params.env }}.tfvars
vars:
# Variables are added to the Terraform environment via
# TF_VAR_<var>=value for commands that support them
Expand Down Expand Up @@ -75,7 +75,7 @@ backendConfigs:
Go templating can be used in the config file as follows.
* In the first templating pass, `vars` and `envs` are processed.
* In the first templating pass, `varsFiles`, `vars`, and `envs` are processed.
All parameters specified using the `-p|--param` flag are available in the `.Params` object.
* In the second templating pass, `backendConfigs` are processed.
`vars` are available as `.Vars`, `envs` are available as `.Envs` with the results from the first templating pass.
Expand All @@ -93,7 +93,7 @@ After processing, the config file would look like this:
varsFiles:
# tfvars files are added to the Terraform environment via
# TF_CLI_ARGS_<command>=-var-file=<file> for commands that support them
- testmodule/test.tfvars
- testmodule/test-prod.tfvars
vars:
# Variables are added to the Terraform environment via
# TF_VAR_<var>=value for commands that support them
Expand Down
18 changes: 12 additions & 6 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,22 @@ func Load(configFile string, params map[string]string) (*Config, error) {
return nil, err
}

templatingInput := map[string]interface{}{
"Params": params,
}

cfgFileDir := filepath.Dir(configFile)
for i, f := range cfg.VarsFiles {
sb := strings.Builder{}
err := renderTemplate(&sb, templatingInput, f)
if err != nil {
return nil, err
}
varFile := sb.String()
if !filepath.IsAbs(f) {
varFile := filepath.Join(cfgFileDir, f)
cfg.VarsFiles[i] = varFile
varFile = filepath.Join(cfgFileDir, varFile)
}
}

templatingInput := map[string]interface{}{
"Params": params,
cfg.VarsFiles[i] = varFile
}

for key, value := range cfg.Vars {
Expand Down
22 changes: 17 additions & 5 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,25 @@ import (
)

func TestLoad(t *testing.T) {
got, err := Load("testdata/test_config.yaml", map[string]string{"param": "paramvalue"})
got, err := Load("testdata/test_config.yaml", map[string]string{
"param": "paramvalue",
"env": "prod",
})
assert.NoError(t, err)
assert.NotNil(t, got)

assert.Equal(t, got.VarsFiles, []string{"testdata/testmodule/test.tfvars"})
assert.Equal(t, got.Vars, map[string]string{"foo": "foovalue", "templatedVar": "paramvalue", "mapvar": "{\n value1 = \"testvalue\"\n value2 = true\n}"})
assert.Equal(t, got.Envs, map[string]string{"BAR": "barvalue", "TEMPLATED_ENV": "paramvalue"})
assert.Equal(t, got.VarsFiles, []string{
"testdata/testmodule/test1-prod.tfvars",
"testdata/testmodule/test2-prod.tfvars",
})
assert.Equal(t, got.Vars, map[string]string{
"foo": "foovalue",
"templatedVar": "paramvalue",
"mapvar": "{\n value1 = \"testvalue\"\n value2 = true\n}",
})
assert.Equal(t, got.Envs, map[string]string{
"BAR": "barvalue",
"TEMPLATED_ENV": "paramvalue",
})
assert.Equal(t, got.BackendConfigs, map[string]string{
"backend_key": "be_key_foovalue_barvalue",
"backend_storage_account_name": "be_storage_account_name_foovalue_barvalue",
Expand Down
3 changes: 2 additions & 1 deletion pkg/config/testdata/test_config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
varsFiles:
- testmodule/test.tfvars
- testmodule/test1-{{ .Params.env }}.tfvars
- testmodule/test2-{{ .Params.env }}.tfvars
vars:
foo: foovalue
templatedVar: "{{ .Params.param }}"
Expand Down
2 changes: 2 additions & 0 deletions pkg/config/testdata/testmodule/test.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ terraform {

variable "foo" {}

variable "bar" {}

variable "baz" {}

variable "mapvar" {
Expand Down
1 change: 1 addition & 0 deletions pkg/config/testdata/testmodule/test1-prod.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bar = "barvalue"
File renamed without changes.
2 changes: 1 addition & 1 deletion pkg/opts/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (o *MapOpts) String() string {
}

func (o *MapOpts) Type() string {
return "map"
return "key=value"
}

func NewMapOpts() *MapOpts {
Expand Down
6 changes: 3 additions & 3 deletions test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ func Test_e2e(t *testing.T) {

binary := buildBinary(tempDir)

output, err := runProcess(binary, "-d", "-c", "testdata/test_config.yaml", "init", "-no-color", "testdata/testmodule")
output, err := runProcess(binary, "-d", "-c", "testdata/test_config.yaml", "-p", "env=prod", "init", "-no-color", "testdata/testmodule")
fmt.Println(output)
assert.NoError(t, err)
assert.Contains(t, output, "Terraform has been successfully initialized!")

output, err = runProcess(binary, "-d", "-c", "testdata/test_config.yaml", "plan", "-no-color", "testdata/testmodule")
output, err = runProcess(binary, "-d", "-c", "testdata/test_config.yaml", "-p", "env=prod", "plan", "-no-color", "testdata/testmodule")
fmt.Println(output)
assert.NoError(t, err)
assert.Contains(t, output, "# null_resource.echo will be created")
assert.Contains(t, output, "Plan: 1 to add, 0 to change, 0 to destroy.")

output, err = runProcess(binary, "-d", "-c", "testdata/test_config.yaml", "apply", "-auto-approve", "-no-color", "testdata/testmodule")
output, err = runProcess(binary, "-d", "-c", "testdata/test_config.yaml", "-p", "env=prod", "apply", "-auto-approve", "-no-color", "testdata/testmodule")
fmt.Println(output)
assert.NoError(t, err)
assert.Contains(t, output, `baz = bazvalue
Expand Down
2 changes: 1 addition & 1 deletion test/testdata/test_config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
varsFiles:
- testmodule/test.tfvars
- testmodule/test-{{ .Params.env }}.tfvars
vars:
foo: 42
mapvar: |-
Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions test/testdata/testmodule/test.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ terraform {

variable "foo" {}

variable "bar" {}

variable "baz" {}

variable "mapvar" {}
Expand Down

0 comments on commit 82fab26

Please sign in to comment.