Skip to content

Commit 585b5c3

Browse files
committed
Add dynamic template output
1 parent d10fd6b commit 585b5c3

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
# terraform-code-examples
22
Solving weird problems with Terraform
3+
4+
5+
* [Dynamic Templatefile Rendering](./dynamic-template-output/README.md)
6+
* Keeping `templatefile()` function calls and the files themselves DRY — avoids writing variables twice, as input and output.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.13.4

dynamic-template-output/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Dynamic Templatefile Rendering
2+
3+
The [`templatefile()`](https://www.terraform.io/docs/configuration/functions/templatefile.html) function is very useful, but using it as-written in the documentation samples encourages very repetitive coding practices. For example, you might be supplying instance user_data from a rendered script like this:
4+
5+
```hcl
6+
resource "aws_instance" "my_server" {
7+
user_data = templatefile("${path.module}/files/user-data.sh.tmpl",
8+
{
9+
VAR_1 = "my first variable"
10+
VAR_2 = "my second variable"
11+
}
12+
)
13+
}
14+
```
15+
16+
Then, over in the actual template, you have to re-write all of the inputs you supplied to the `templatefile()` function like this:
17+
18+
```shell
19+
#!/bin/bash
20+
21+
echo ${VAR_1}
22+
echo ${VAR_2}
23+
```
24+
25+
## DRYing Templates Out
26+
27+
Instead, you can use a [string template directive](https://www.terraform.io/docs/configuration/expressions.html#string-templates) in the template file, combined with a map input to the `templatefile()` function to DRY this out.
28+
29+
To see this in action, review [main.tf](./main.tf), and see how it passes the `ENV_VARS = {}` map into the function. The `for` directive inside of [user-data.sh.tmpl](./user-data.sh.tmpl) unwraps that map, renders each line into an `export`, and the resulting script sets all of variables in the shell.
30+
31+
### Discussion
32+
33+
Relates back to [this reddit thread](https://www.reddit.com/r/Terraform/comments/jy05en/terraform_variables_in_bash_scripting/gd0dfhv/)

dynamic-template-output/main.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "rendered" {
2+
value = templatefile("${path.module}/user-data.sh.tmpl",
3+
{
4+
ENV_VARS = {
5+
var1 = "test1"
6+
var2 = "test2"
7+
}
8+
})
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
%{ for k, v in ENV_VARS ~}
4+
export ${k}="${v}"
5+
%{ endfor ~}
6+
7+
# Do stuff
8+
echo "The rendered version of this template will declare all of the keys in ENV_VARS as variables."

0 commit comments

Comments
 (0)