Skip to content

Commit

Permalink
Merge pull request #3909 from hashicorp/phinze/template-file-contents
Browse files Browse the repository at this point in the history
template_file: source contents instead of path
  • Loading branch information
phinze committed Nov 16, 2015
2 parents 0cdc81f + 928f534 commit 993ec0a
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 39 deletions.
29 changes: 19 additions & 10 deletions builtin/providers/template/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"

"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/lang"
"github.com/hashicorp/terraform/config/lang/ast"
"github.com/hashicorp/terraform/helper/pathorcontents"
"github.com/hashicorp/terraform/helper/schema"
"github.com/mitchellh/go-homedir"
)

func resource() *schema.Resource {
Expand All @@ -24,13 +23,23 @@ func resource() *schema.Resource {
Read: Read,

Schema: map[string]*schema.Schema{
"template": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "Contents of the template",
ForceNew: true,
ConflictsWith: []string{"filename"},
},
"filename": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
Description: "file to read template from",
ForceNew: true,
// Make a "best effort" attempt to relativize the file path.
StateFunc: func(v interface{}) string {
if v == nil || v.(string) == "" {
return ""
}
pwd, err := os.Getwd()
if err != nil {
return v.(string)
Expand All @@ -41,6 +50,8 @@ func resource() *schema.Resource {
}
return rel
},
Deprecated: "Use the 'template' attribute instead.",
ConflictsWith: []string{"template"},
},
"vars": &schema.Schema{
Type: schema.TypeMap,
Expand Down Expand Up @@ -96,23 +107,21 @@ func Read(d *schema.ResourceData, meta interface{}) error {

type templateRenderError error

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

func render(d *schema.ResourceData) (string, error) {
template := d.Get("template").(string)
filename := d.Get("filename").(string)
vars := d.Get("vars").(map[string]interface{})

path, err := homedir.Expand(filename)
if err != nil {
return "", err
if template == "" && filename != "" {
template = filename
}

buf, err := readfile(path)
contents, _, err := pathorcontents.Read(template)
if err != nil {
return "", err
}

rendered, err := execute(string(buf), vars)
rendered, err := execute(contents, vars)
if err != nil {
return "", templateRenderError(
fmt.Errorf("failed to render %v: %v", filename, err),
Expand Down
35 changes: 11 additions & 24 deletions builtin/providers/template/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,10 @@ func TestTemplateRendering(t *testing.T) {

for _, tt := range cases {
r.Test(t, r.TestCase{
PreCheck: func() {
readfile = func(string) ([]byte, error) {
return []byte(tt.template), nil
}
},
Providers: testProviders,
Steps: []r.TestStep{
r.TestStep{
Config: testTemplateConfig(tt.vars),
Config: testTemplateConfig(tt.template, tt.vars),
Check: func(s *terraform.State) error {
got := s.RootModule().Outputs["rendered"]
if tt.want != got {
Expand Down Expand Up @@ -62,14 +57,7 @@ func TestTemplateVariableChange(t *testing.T) {
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),
Config: testTemplateConfig(step.template, step.vars),
Check: func(i int, want string) r.TestCheckFunc {
return func(s *terraform.State) error {
got := s.RootModule().Outputs["rendered"]
Expand All @@ -88,14 +76,13 @@ func TestTemplateVariableChange(t *testing.T) {
})
}

func testTemplateConfig(vars string) string {
return `
resource "template_file" "t0" {
filename = "mock"
vars = ` + vars + `
}
output "rendered" {
value = "${template_file.t0.rendered}"
}
`
func testTemplateConfig(template, vars string) string {
return fmt.Sprintf(`
resource "template_file" "t0" {
template = "%s"
vars = %s
}
output "rendered" {
value = "${template_file.t0.rendered}"
}`, template, vars)
}
21 changes: 21 additions & 0 deletions config/interpolate.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ type SelfVariable struct {
key string
}

// SimpleVariable is an unprefixed variable, which can show up when users have
// strings they are passing down to resources that use interpolation
// internally. The template_file resource is an example of this.
type SimpleVariable struct {
Key string
}

// A UserVariable is a variable that is referencing a user variable
// that is inputted from outside the configuration. This looks like
// "${var.foo}"
Expand All @@ -97,6 +104,8 @@ func NewInterpolatedVariable(v string) (InterpolatedVariable, error) {
return NewUserVariable(v)
} else if strings.HasPrefix(v, "module.") {
return NewModuleVariable(v)
} else if !strings.ContainsRune(v, '.') {
return NewSimpleVariable(v)
} else {
return NewResourceVariable(v)
}
Expand Down Expand Up @@ -227,6 +236,18 @@ func (v *SelfVariable) GoString() string {
return fmt.Sprintf("*%#v", *v)
}

func NewSimpleVariable(key string) (*SimpleVariable, error) {
return &SimpleVariable{key}, nil
}

func (v *SimpleVariable) FullKey() string {
return v.Key
}

func (v *SimpleVariable) GoString() string {
return fmt.Sprintf("*%#v", *v)
}

func NewUserVariable(key string) (*UserVariable, error) {
name := key[len("var."):]
elem := ""
Expand Down
15 changes: 15 additions & 0 deletions terraform/interpolate.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ func (i *Interpolater) Values(
err = i.valueResourceVar(scope, n, v, result)
case *config.SelfVariable:
err = i.valueSelfVar(scope, n, v, result)
case *config.SimpleVariable:
err = i.valueSimpleVar(scope, n, v, result)
case *config.UserVariable:
err = i.valueUserVar(scope, n, v, result)
default:
Expand Down Expand Up @@ -249,6 +251,19 @@ func (i *Interpolater) valueSelfVar(
return i.valueResourceVar(scope, n, rv, result)
}

func (i *Interpolater) valueSimpleVar(
scope *InterpolationScope,
n string,
v *config.SimpleVariable,
result map[string]ast.Variable) error {
// SimpleVars are never handled by Terraform's interpolator
result[n] = ast.Variable{
Value: config.UnknownVariableValue,
Type: ast.TypeString,
}
return nil
}

func (i *Interpolater) valueUserVar(
scope *InterpolationScope,
n string,
Expand Down
17 changes: 12 additions & 5 deletions website/source/docs/providers/template/r/file.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Renders a template from a file.

```
resource "template_file" "init" {
filename = "${path.module}/init.tpl"
template = "${file(${path.module}/init.tpl)}"
vars {
consul_address = "${aws_instance.consul.private_ip}"
Expand All @@ -27,17 +27,24 @@ resource "template_file" "init" {

The following arguments are supported:

* `filename` - (Required) The filename for the template. Use [path
variables](/docs/configuration/interpolation.html#path-variables) to make
this path relative to different path roots.
* `template` - (Required) The contents of the template. These can be loaded
from a file on disk using the [`file()` interpolation
function](/docs/configuration/interpolation.html#file_path_).

* `vars` - (Optional) Variables for interpolation within the template.

The following arguments are maintained for backwards compatibility and may be
removed in a future version:

* `filename` - __Deprecated, please use `template` instead_. The filename for
the template. Use [path variables](/docs/configuration/interpolation.html#path-variables) to make
this path relative to different path roots.

## Attributes Reference

The following attributes are exported:

* `filename` - See Argument Reference above.
* `template` - See Argument Reference above.
* `vars` - See Argument Reference above.
* `rendered` - The final rendered template.

Expand Down

0 comments on commit 993ec0a

Please sign in to comment.