Skip to content

Commit

Permalink
Merge pull request #2386 from hashicorp/b-template-variable-change-fa…
Browse files Browse the repository at this point in the history
…ilure

provider/template: don't error when rendering fails in Exists
  • Loading branch information
phinze committed Jun 17, 2015
2 parents e1c7990 + 385b17d commit 5e86e70
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 11 deletions.
15 changes: 13 additions & 2 deletions builtin/providers/template/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/hex"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"

Expand Down Expand Up @@ -75,7 +76,13 @@ func Delete(d *schema.ResourceData, meta interface{}) error {
func Exists(d *schema.ResourceData, meta interface{}) (bool, error) {
rendered, err := render(d)
if err != nil {
return false, err
if _, ok := err.(templateRenderError); ok {
log.Printf("[DEBUG] Got error while rendering in Exists: %s", err)
log.Printf("[DEBUG] Returning false so the template re-renders using latest variables from config.")
return false, nil
} else {
return false, err
}
}
return hash(rendered) == d.Id(), nil
}
Expand All @@ -87,6 +94,8 @@ func Read(d *schema.ResourceData, meta interface{}) error {
return nil
}

type templateRenderError error

var readfile func(string) ([]byte, error) = ioutil.ReadFile // testing hook

func render(d *schema.ResourceData) (string, error) {
Expand All @@ -105,7 +114,9 @@ func render(d *schema.ResourceData) (string, error) {

rendered, err := execute(string(buf), vars)
if err != nil {
return "", fmt.Errorf("failed to render %v: %v", filename, err)
return "", templateRenderError(
fmt.Errorf("failed to render %v: %v", filename, err),
)
}

return rendered, nil
Expand Down
62 changes: 53 additions & 9 deletions builtin/providers/template/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,7 @@ func TestTemplateRendering(t *testing.T) {
Providers: testProviders,
Steps: []r.TestStep{
r.TestStep{
Config: `
resource "template_file" "t0" {
filename = "mock"
vars = ` + tt.vars + `
}
output "rendered" {
value = "${template_file.t0.rendered}"
}
`,
Config: testTemplateConfig(tt.vars),
Check: func(s *terraform.State) error {
got := s.RootModule().Outputs["rendered"]
if tt.want != got {
Expand All @@ -55,3 +47,55 @@ output "rendered" {
})
}
}

// https://github.com/hashicorp/terraform/issues/2344
func TestTemplateVariableChange(t *testing.T) {
steps := []struct {
vars string
template string
want string
}{
{`{a="foo"}`, `${a}`, `foo`},
{`{b="bar"}`, `${b}`, `bar`},
}

var testSteps []r.TestStep
for i, step := range steps {
testSteps = append(testSteps, r.TestStep{
PreConfig: func(template string) func() {
return func() {
readfile = func(string) ([]byte, error) {
return []byte(template), nil
}
}
}(step.template),
Config: testTemplateConfig(step.vars),
Check: func(i int, want string) r.TestCheckFunc {
return func(s *terraform.State) error {
got := s.RootModule().Outputs["rendered"]
if want != got {
return fmt.Errorf("[%d] got:\n%q\nwant:\n%q\n", i, got, want)
}
return nil
}
}(i, step.want),
})
}

r.Test(t, r.TestCase{
Providers: testProviders,
Steps: testSteps,
})
}

func testTemplateConfig(vars string) string {
return `
resource "template_file" "t0" {
filename = "mock"
vars = ` + vars + `
}
output "rendered" {
value = "${template_file.t0.rendered}"
}
`
}
8 changes: 8 additions & 0 deletions helper/resource/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ type TestCase struct {
// potentially complex update logic. In general, simply create/destroy
// tests will only need one step.
type TestStep struct {
// PreConfig is called before the Config is applied to perform any per-step
// setup that needs to happen
PreConfig func()

// Config a string of the configuration to give to Terraform.
Config string

Expand Down Expand Up @@ -160,6 +164,10 @@ func testStep(
opts terraform.ContextOpts,
state *terraform.State,
step TestStep) (*terraform.State, error) {
if step.PreConfig != nil {
step.PreConfig()
}

cfgPath, err := ioutil.TempDir("", "tf-test")
if err != nil {
return state, fmt.Errorf(
Expand Down

0 comments on commit 5e86e70

Please sign in to comment.