provider/template: convert resources to data sources
The template resources don't actually need to retain any state, so they are good candidates to be data sources. This includes a few tweaks to the acceptance tests -- now configured to run as unit tests -- since it seems that they have been slightly broken for a while now. In particular, the "update" cases are no longer tested because updating is not a meaningful operation for a data source.
This commit is contained in:
parent
46e3cacee3
commit
861ac536dd
|
@ -15,13 +15,9 @@ import (
|
|||
"github.com/sthulb/mime/multipart"
|
||||
)
|
||||
|
||||
func resourceCloudinitConfig() *schema.Resource {
|
||||
func dataSourceCloudinitConfig() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceCloudinitConfigCreate,
|
||||
Delete: resourceCloudinitConfigDelete,
|
||||
Update: resourceCloudinitConfigCreate,
|
||||
Exists: resourceCloudinitConfigExists,
|
||||
Read: resourceCloudinitConfigRead,
|
||||
Read: dataSourceCloudinitConfigRead,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"part": &schema.Schema{
|
||||
|
@ -52,13 +48,11 @@ func resourceCloudinitConfig() *schema.Resource {
|
|||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"base64_encode": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"rendered": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
|
@ -69,7 +63,7 @@ func resourceCloudinitConfig() *schema.Resource {
|
|||
}
|
||||
}
|
||||
|
||||
func resourceCloudinitConfigCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
func dataSourceCloudinitConfigRead(d *schema.ResourceData, meta interface{}) error {
|
||||
rendered, err := renderCloudinitConfig(d)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -80,24 +74,6 @@ func resourceCloudinitConfigCreate(d *schema.ResourceData, meta interface{}) err
|
|||
return nil
|
||||
}
|
||||
|
||||
func resourceCloudinitConfigDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCloudinitConfigExists(d *schema.ResourceData, meta interface{}) (bool, error) {
|
||||
rendered, err := renderCloudinitConfig(d)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return strconv.Itoa(hashcode.String(rendered)) == d.Id(), nil
|
||||
}
|
||||
|
||||
func resourceCloudinitConfigRead(d *schema.ResourceData, meta interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func renderCloudinitConfig(d *schema.ResourceData) (string, error) {
|
||||
gzipOutput := d.Get("gzip").(bool)
|
||||
base64Output := d.Get("base64_encode").(bool)
|
|
@ -0,0 +1,80 @@
|
|||
package template
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
r "github.com/hashicorp/terraform/helper/resource"
|
||||
)
|
||||
|
||||
func TestRender(t *testing.T) {
|
||||
testCases := []struct {
|
||||
ResourceBlock string
|
||||
Expected string
|
||||
}{
|
||||
{
|
||||
`data "template_cloudinit_config" "foo" {
|
||||
gzip = false
|
||||
base64_encode = false
|
||||
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
}
|
||||
}`,
|
||||
"Content-Type: multipart/mixed; boundary=\"MIMEBOUNDARY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDARY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDARY--\r\n",
|
||||
},
|
||||
{
|
||||
`data "template_cloudinit_config" "foo" {
|
||||
gzip = false
|
||||
base64_encode = false
|
||||
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
filename = "foobar.sh"
|
||||
}
|
||||
}`,
|
||||
"Content-Type: multipart/mixed; boundary=\"MIMEBOUNDARY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDARY\r\nContent-Disposition: attachment; filename=\"foobar.sh\"\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDARY--\r\n",
|
||||
},
|
||||
{
|
||||
`data "template_cloudinit_config" "foo" {
|
||||
gzip = false
|
||||
base64_encode = false
|
||||
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
}
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "ffbaz"
|
||||
}
|
||||
}`,
|
||||
"Content-Type: multipart/mixed; boundary=\"MIMEBOUNDARY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDARY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDARY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nffbaz\r\n--MIMEBOUNDARY--\r\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
r.UnitTest(t, r.TestCase{
|
||||
Providers: testProviders,
|
||||
Steps: []r.TestStep{
|
||||
r.TestStep{
|
||||
Config: tt.ResourceBlock,
|
||||
Check: r.ComposeTestCheckFunc(
|
||||
r.TestCheckResourceAttr("data.template_cloudinit_config.foo", "rendered", tt.Expected),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var testCloudInitConfig_basic = `
|
||||
data "template_cloudinit_config" "config" {
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
}
|
||||
}`
|
||||
|
||||
var testCloudInitConfig_basic_expected = `Content-Type: multipart/mixed; boundary=\"MIMEBOUNDARY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDARY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDARY--\r\n`
|
|
@ -4,7 +4,6 @@ import (
|
|||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
|
@ -15,19 +14,15 @@ import (
|
|||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceFile() *schema.Resource {
|
||||
func dataSourceFile() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceFileCreate,
|
||||
Delete: resourceFileDelete,
|
||||
Exists: resourceFileExists,
|
||||
Read: resourceFileRead,
|
||||
Read: dataSourceFileRead,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"template": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Contents of the template",
|
||||
ForceNew: true,
|
||||
ConflictsWith: []string{"filename"},
|
||||
ValidateFunc: validateTemplateAttribute,
|
||||
},
|
||||
|
@ -35,7 +30,6 @@ func resourceFile() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
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) == "" {
|
||||
|
@ -59,7 +53,6 @@ func resourceFile() *schema.Resource {
|
|||
Optional: true,
|
||||
Default: make(map[string]interface{}),
|
||||
Description: "variables to substitute",
|
||||
ForceNew: true,
|
||||
},
|
||||
"rendered": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
|
@ -70,7 +63,7 @@ func resourceFile() *schema.Resource {
|
|||
}
|
||||
}
|
||||
|
||||
func resourceFileCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
func dataSourceFileRead(d *schema.ResourceData, meta interface{}) error {
|
||||
rendered, err := renderFile(d)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -80,32 +73,6 @@ func resourceFileCreate(d *schema.ResourceData, meta interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func resourceFileDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceFileExists(d *schema.ResourceData, meta interface{}) (bool, error) {
|
||||
rendered, err := renderFile(d)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
func resourceFileRead(d *schema.ResourceData, meta interface{}) error {
|
||||
// Logic is handled in Exists, which only returns true if the rendered
|
||||
// contents haven't changed. That means if we get here there's nothing to
|
||||
// do.
|
||||
return nil
|
||||
}
|
||||
|
||||
type templateRenderError error
|
||||
|
||||
func renderFile(d *schema.ResourceData) (string, error) {
|
|
@ -23,13 +23,13 @@ func TestTemplateRendering(t *testing.T) {
|
|||
want string
|
||||
}{
|
||||
{`{}`, `ABC`, `ABC`},
|
||||
{`{a="foo"}`, `${a}`, `foo`},
|
||||
{`{a="hello"}`, `${replace(a, "ello", "i")}`, `hi`},
|
||||
{`{a="foo"}`, `$${a}`, `foo`},
|
||||
{`{a="hello"}`, `$${replace(a, "ello", "i")}`, `hi`},
|
||||
{`{}`, `${1+2+3}`, `6`},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
r.Test(t, r.TestCase{
|
||||
r.UnitTest(t, r.TestCase{
|
||||
Providers: testProviders,
|
||||
Steps: []r.TestStep{
|
||||
r.TestStep{
|
||||
|
@ -47,39 +47,6 @@ func TestTemplateRendering(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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{
|
||||
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"]
|
||||
if want != got.Value {
|
||||
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 TestValidateTemplateAttribute(t *testing.T) {
|
||||
file, err := ioutil.TempFile("", "testtemplate")
|
||||
if err != nil {
|
||||
|
@ -129,11 +96,11 @@ func TestTemplateSharedMemoryRace(t *testing.T) {
|
|||
|
||||
func testTemplateConfig(template, vars string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "template_file" "t0" {
|
||||
data "template_file" "t0" {
|
||||
template = "%s"
|
||||
vars = %s
|
||||
}
|
||||
output "rendered" {
|
||||
value = "${template_file.t0.rendered}"
|
||||
value = "${data.template_file.t0.rendered}"
|
||||
}`, template, vars)
|
||||
}
|
|
@ -7,9 +7,19 @@ import (
|
|||
|
||||
func Provider() terraform.ResourceProvider {
|
||||
return &schema.Provider{
|
||||
DataSourcesMap: map[string]*schema.Resource{
|
||||
"template_file": dataSourceFile(),
|
||||
"template_cloudinit_config": dataSourceCloudinitConfig(),
|
||||
},
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"template_file": resourceFile(),
|
||||
"template_cloudinit_config": resourceCloudinitConfig(),
|
||||
"template_file": schema.DataSourceResourceShim(
|
||||
"template_file",
|
||||
dataSourceFile(),
|
||||
),
|
||||
"template_cloudinit_config": schema.DataSourceResourceShim(
|
||||
"template_cloudinit_config",
|
||||
dataSourceCloudinitConfig(),
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
package template
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
r "github.com/hashicorp/terraform/helper/resource"
|
||||
)
|
||||
|
||||
func TestRender(t *testing.T) {
|
||||
testCases := []struct {
|
||||
ResourceBlock string
|
||||
Expected string
|
||||
}{
|
||||
{
|
||||
`resource "template_cloudinit_config" "foo" {
|
||||
gzip = false
|
||||
base64_encode = false
|
||||
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
}
|
||||
}`,
|
||||
"Content-Type: multipart/mixed; boundary=\"MIMEBOUNDRY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDRY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDRY--\r\n",
|
||||
},
|
||||
{
|
||||
`resource "template_cloudinit_config" "foo" {
|
||||
gzip = false
|
||||
base64_encode = false
|
||||
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
filename = "foobar.sh"
|
||||
}
|
||||
}`,
|
||||
"Content-Type: multipart/mixed; boundary=\"MIMEBOUNDRY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDRY\r\nContent-Disposition: attachment; filename=\"foobar.sh\"\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDRY--\r\n",
|
||||
},
|
||||
{
|
||||
`resource "template_cloudinit_config" "foo" {
|
||||
gzip = false
|
||||
base64_encode = false
|
||||
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
}
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "ffbaz"
|
||||
}
|
||||
}`,
|
||||
"Content-Type: multipart/mixed; boundary=\"MIMEBOUNDRY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDRY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDRY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nffbaz\r\n--MIMEBOUNDRY--\r\n",
|
||||
},
|
||||
{
|
||||
`resource "template_cloudinit_config" "foo" {
|
||||
gzip = true
|
||||
base64_encode = false
|
||||
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
filename = "ah"
|
||||
}
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "ffbaz"
|
||||
}
|
||||
}`,
|
||||
"\x1f\x8b\b\x00\x00\tn\x88\x00\xff\xac\xce\xc1J\x031\x10\xc6\xf1{`\xdf!\xe4>VO\u0096^\xb4=xX\x05\xa9\x82\xc7\xd9݉;\x90LB2\x85\xadOo-\x88\x8b\xe2\xadDŽ\x1f\xf3\xfd\xef\x93(\x89\xc2\xfe\x98\xa9\xb5\xf1\x10\x943\x16]E\x9ei\\\xdb>\x1dd\xc4rܸ\xee\xa1\xdb\xdd=\xbd<n\x9fߜ\xf9z\xc0+\x95\xcaIZ{su\xdd\x18\x80\x85h\xcc\xf7\xdd-ל*\xeb\x19\xa2*\x0eS<\xfd\xaf\xad\xe7@\x82\x916\x0e'\xf7\xe3\xf7\x05\xa5z*\xb0\x93!\x8d,ﭽ\xedY\x17\xe0\x1c\xaa4\xebj\x86:Q\bu(\x9cO\xa2\xe3H\xbf\xa2\x1a\xd3\xe3ǿm\x97\xde\xf2\xfe\xef\x1a@c>\x03\x00\x00\xff\xffmB\x8c\xeed\x01\x00\x00",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
r.Test(t, r.TestCase{
|
||||
Providers: testProviders,
|
||||
Steps: []r.TestStep{
|
||||
r.TestStep{
|
||||
Config: tt.ResourceBlock,
|
||||
Check: r.ComposeTestCheckFunc(
|
||||
r.TestCheckResourceAttr("template_cloudinit_config.foo", "rendered", tt.Expected),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloudConfig_update(t *testing.T) {
|
||||
r.Test(t, r.TestCase{
|
||||
Providers: testProviders,
|
||||
Steps: []r.TestStep{
|
||||
r.TestStep{
|
||||
Config: testCloudInitConfig_basic,
|
||||
Check: r.ComposeTestCheckFunc(
|
||||
r.TestCheckResourceAttr("template_cloudinit_config.config", "rendered", testCloudInitConfig_basic_expected),
|
||||
),
|
||||
},
|
||||
|
||||
r.TestStep{
|
||||
Config: testCloudInitConfig_update,
|
||||
Check: r.ComposeTestCheckFunc(
|
||||
r.TestCheckResourceAttr("template_cloudinit_config.config", "rendered", testCloudInitConfig_update_expected),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
var testCloudInitConfig_basic = `
|
||||
resource "template_cloudinit_config" "config" {
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
}
|
||||
}`
|
||||
|
||||
var testCloudInitConfig_basic_expected = `Content-Type: multipart/mixed; boundary=\"MIMEBOUNDRY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDRY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDRY--\r\n`
|
||||
|
||||
var testCloudInitConfig_update = `
|
||||
resource "template_cloudinit_config" "config" {
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "baz"
|
||||
}
|
||||
|
||||
part {
|
||||
content_type = "text/x-shellscript"
|
||||
content = "ffbaz"
|
||||
}
|
||||
}`
|
||||
|
||||
var testCloudInitConfig_update_expected = `Content-Type: multipart/mixed; boundary=\"MIMEBOUNDARY\"\nMIME-Version: 1.0\r\n--MIMEBOUNDARY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nbaz\r\n--MIMEBOUNDARY\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/x-shellscript\r\nMime-Version: 1.0\r\n\r\nffbaz\r\n--MIMEBOUNDARY--\r\n`
|
|
@ -17,7 +17,7 @@ func TestState_basic(t *testing.T) {
|
|||
Config: testAccState_basic,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckStateValue(
|
||||
"terraform_remote_state.foo", "foo", "bar"),
|
||||
"data.terraform_remote_state.foo", "foo", "bar"),
|
||||
),
|
||||
},
|
||||
},
|
||||
|
@ -64,7 +64,7 @@ func testAccCheckStateValue(id, name, value string) resource.TestCheckFunc {
|
|||
}
|
||||
|
||||
const testAccState_basic = `
|
||||
resource "terraform_remote_state" "foo" {
|
||||
data "terraform_remote_state" "foo" {
|
||||
backend = "_local"
|
||||
|
||||
config {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
layout: "template"
|
||||
page_title: "Template: cloudinit_multipart"
|
||||
sidebar_current: "docs-template-resource-cloudinit-config"
|
||||
sidebar_current: "docs-template-datasource-cloudinit-config"
|
||||
description: |-
|
||||
Renders a multi-part cloud-init config from source files.
|
||||
---
|
||||
|
@ -14,7 +14,7 @@ Renders a multi-part cloud-init config from source files.
|
|||
|
||||
```
|
||||
# Render a part using a `template_file`
|
||||
resource "template_file" "script" {
|
||||
data "template_file" "script" {
|
||||
template = "${file("${path.module}/init.tpl")}"
|
||||
|
||||
vars {
|
||||
|
@ -24,7 +24,7 @@ resource "template_file" "script" {
|
|||
|
||||
# Render a multi-part cloudinit config making use of the part
|
||||
# above, and other source files
|
||||
resource "template_cloudinit_config" "config" {
|
||||
data "template_cloudinit_config" "config" {
|
||||
gzip = true
|
||||
base64_encode = true
|
||||
|
||||
|
@ -32,7 +32,7 @@ resource "template_cloudinit_config" "config" {
|
|||
part {
|
||||
filename = "init.cfg"
|
||||
content_type = "text/part-handler"
|
||||
content = "${template_file.script.rendered}"
|
||||
content = "${data.template_file.script.rendered}"
|
||||
}
|
||||
|
||||
part {
|
||||
|
@ -50,7 +50,7 @@ resource "template_cloudinit_config" "config" {
|
|||
resource "aws_instance" "web" {
|
||||
ami = "ami-d05e75b8"
|
||||
instance_type = "t2.micro"
|
||||
user_data = "${template_cloudinit_config.config.rendered}"
|
||||
user_data = "${data.template_cloudinit_config.config.rendered}"
|
||||
}
|
||||
```
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
layout: "template"
|
||||
page_title: "Template: template_file"
|
||||
sidebar_current: "docs-template-resource-file"
|
||||
sidebar_current: "docs-template-datasource-file"
|
||||
description: |-
|
||||
Renders a template from a file.
|
||||
---
|
||||
|
@ -13,7 +13,7 @@ Renders a template from a file.
|
|||
## Example Usage
|
||||
|
||||
```
|
||||
resource "template_file" "init" {
|
||||
data "template_file" "init" {
|
||||
template = "${file("${path.module}/init.tpl")}"
|
||||
|
||||
vars {
|
|
@ -8,23 +8,16 @@ description: |-
|
|||
|
||||
# Template Provider
|
||||
|
||||
The template provider exposes resources to use templates to generate
|
||||
The template provider exposes data sources to use templates to generate
|
||||
strings for other Terraform resources or outputs.
|
||||
|
||||
The template provider is what we call a _logical provider_. This has no
|
||||
impact on how it behaves, but conceptually it is important to understand.
|
||||
The template provider doesn't manage any _physical_ resources; it isn't
|
||||
creating servers, writing files, etc. It is used to generate attributes that
|
||||
can be used for interpolation for other resources. Examples will explain
|
||||
this best.
|
||||
|
||||
Use the navigation to the left to read about the available resources.
|
||||
Use the navigation to the left to read about the available data sources.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
# Template for initial configuration bash script
|
||||
resource "template_file" "init" {
|
||||
data "template_file" "init" {
|
||||
template = "${file("init.tpl")}"
|
||||
|
||||
vars {
|
||||
|
@ -36,6 +29,6 @@ resource "template_file" "init" {
|
|||
resource "aws_instance" "web" {
|
||||
# ...
|
||||
|
||||
user_data = "${template_file.init.rendered}"
|
||||
user_data = "${data.template_file.init.rendered}"
|
||||
}
|
||||
```
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
<a href="/docs/providers/template/index.html">Template Provider</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current(/^docs-template-resource/) %>>
|
||||
<a href="#">Resources</a>
|
||||
<li<%= sidebar_current(/^docs-template-datasource/) %>>
|
||||
<a href="#">Data Sources</a>
|
||||
<ul class="nav nav-visible">
|
||||
<li<%= sidebar_current("docs-template-resource-file") %>>
|
||||
<a href="/docs/providers/template/r/file.html">template_file</a>
|
||||
<li<%= sidebar_current("docs-template-datasource-file") %>>
|
||||
<a href="/docs/providers/template/d/file.html">template_file</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-template-resource-cloudinit-config") %>>
|
||||
<a href="/docs/providers/template/r/cloudinit_config.html">template_cloudinit_config</a>
|
||||
<li<%= sidebar_current("docs-template-datasource-cloudinit-config") %>>
|
||||
<a href="/docs/providers/template/d/cloudinit_config.html">template_cloudinit_config</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue