Terraform Template - A complete guide?

In this blog post, we are gonna talk about Terraform templates we are just gonna cover the six topics for Terraform template -

  1. What is Terraform template and what's the importance of Terraform template
  2. What is the extension by which you can save your Terraform template
  3. Project structure and Terraform template location in the project?
  4. How to call a Terraform template inside your Terraform script
  5. AWS Example using Terraform Template - Set up AWS IAM users and IAM role permissions for IAM user
  6. Conclusion



1. What is Terraform template and what's the importance of Terraform template

Let's first try to answer the question "What is Terraform template"?

As you can see over here I have taken a very basic example and here I have taken a word template. So I'm just trying to explain the concept of a template first so here you can see this is a very standard template that is used for preparing the letters.

Here you will find the placeholder for -

  1. Your name
  2. Street address
  3. Date
  4. Recipient Name
  5. Title

Terraform template example with placeholder

The above template is pretty much a standard template that you can use for writing or preparing the letter, so that you don't need to create this design every time you need to write a letter you can simply reuse this template and generate hundreds of letters.

Now you might be wondering like "Do we have a very simple example to see how the Terraform template looks?"

Here is an example of Terraform template -

Terraform template with placeholder

As you can see in the above screenshot there is a Terraform template which is we are using to create a bash file so this is a typical base bash file syntax and here you will see a placeholder.

The placeholder over here is this one which is like a dollar sign with curly braces ${} and inside there is a variable console_address.

So the exact placeholder would be - ${console_address}

This is the smallest template file which I have found over here so that you can understand how the Terraform template looks like.



2. What is the extension by which you can save your Terraform template?

Terraform template extension - There are two popular extensions with which you can save the Terraform Template -

  1. .tpl
  2. .tftpl

Here is one more example of Terraform template in which we are using JSON structure template for assigning AWS IAM role permissions.

 1{
 2  "Version": "2012-10-17",
 3  "Statement": [
 4    {
 5      "Effect": "Allow",
 6      "Action": ${jsonencode(ec2_policies)},
 7    "Resource": "*"
 8    }
 9  ]
10} 

In the file, if you look carefully then you will notice a placeholder ${jsonencode(ec2_policies)} and this placeholder will be used to generate the ec2 policy name.

The above is a JSON template which we will be using inside our Terraform code and also this is the same template we will be used later in the post for setting up IAM role permissions.



3. Project structure and Terraform template location in the project?

All right so now you're familiar with the concept of a Terraform template and you have seen a couple of examples of a Terraform template file now let's see the project structure of a Terraform and where you can place your Terraform template file.

Here is the structure of my Terraform project which includes my main.tf along with template file policy.tpl -

Terraform template project structure

You can place your Terraform template in parallel to your main Terraform file but you need to specify the path where you are going to use the Terraform template.

1locals {
2  #path of template file
3  policy = templatefile("${path.module}/policy.tpl", {
4    name = "Rahul Wagh"
5  })
6}

This is a typical structure on how you are going to create your main.terraform file and how you are going to put your template file inside the Terraform project.



4. How to call a Terraform template inside your Terraform script?

Here I have prepared an example code snipped file(we will look at each example in more detail). In the file you will find templatefile() function as well as resource template_file() code.

Following code snippets are just examples of how you are going to use Terraform templates within -

  • locals
  • data source
  • resource
1resource "template_file" "policy" {
2  template = "${file("${path.module}/policy.tpl")}"
3
4  vars = {
5    name = "Rahul Wagh"
6  }
7}

Note- The Terraform template implementation has been deprecated. You must use terraform data source instead

Terraform templatefile() with locals- The template file function which is also provided by Terraform here you will notice you need to pass two things -

  1. Template file the path
  2. The variable name - String variable, List or Map

If you create Terraform locals then also you can use this template file function inside that locals -

1# main.tf
2
3locals {
4  policy = templatefile("${path.module}/policy.tpl", {
5    name = "Rahul Wagh"
6  })
7}

Here is the policy.tpl file -

1# policy.tpl
2
3Policy for ${name}

Terraform templatefile() with data source- If you create a data source or data block then also it is possible to use Terraform template.

1# main.tf
2
3data "null_data_source" "policy" {
4  inputs = {
5    policy = templatefile("${path.module}/policy.tpl", {
6      name = "Rahul Wagh"
7    })
8  }
9}
1# policy.tpl
2
3Policy for ${name}

You can run the above example using Terraform command -

1 terraform init
2 terraform plan
3 terraform apply


5. AWS Example using Terraform Template - Set up AWS IAM users and IAM role permissions for IAM user

Now you have a familiarity with the Terraform template file and how to call that template file inside your Terraform configuration, so now we will take a very real example where we will be setting an IAM user and we will be setting the policies for that particular user.

Here is my main.tf along with my template file user-policy.tftpl

 1# main.tf
 2
 3# Step 1 - Define provider "aws"      
 4provider "aws" {
 5  region = "eu-central-1"
 6  shared_credentials_files = ["/home/ubuntu/.aws/credentials"]
 7}
 8
 9# Step 2 - Define resrource as "aws_iam_user"
10resource "aws_iam_user" "test_user" {
11  name = "Test-Terraform-User"
12}
13
14# Step 3 - Define resrource as "aws_iam_access_key"
15resource "aws_iam_access_key" "access_key" {
16  user = aws_iam_user.test_user.name
17}
18
19# Step 4 - Define resrource as "aws_iam_user_policy"
20resource "aws_iam_user_policy" "instanceManageUser_assume_role" {
21  name = "InstanceManagePolicy"
22  user = "${aws_iam_user.test_user.name}"
23  
24  # Step 5 - Here we are defining terraform templatefile function with path to load the template
25  policy = templatefile("${path.module}/user-policy.tftpl", {
26  
27    #Step 6 - Here are the list of policies we will be passing
28    ec2_policies = [
29      "ec2:RunInstances",
30      "ec2:StopInstances",
31      "ec2:StartInstances",
32      "ec2:TerminateInstances",
33      "ec2:TerminateInstances",
34      "ec2:Describe*",
35      "ec2:CreateTags",
36      "ec2:RequestSpotInstances"
37    ]
38  })
39}
40
41output "secret_key" {
42  value = aws_iam_access_key.access_key.secret
43  sensitive = true
44}
45
46output "access_key" {
47  value = aws_iam_access_key.access_key.id
48}

Template file - user-policy.tftpl

 1{
 2  "Version": "2012-10-17",
 3  "Statement": [
 4    {
 5      "Effect": "Allow",
 6      
 7      #Placeholder - Here is a placeholder for inserting the policy's name inside the template.
 8      #${jsonencode()} - jsonencode for generating the policies in json format
 9      
10      "Action": ${jsonencode(ec2_policies)},
11      
12    "Resource": "*"
13    }
14  ]
15} 

5.1 Let's run the terraform init command

Alright, now we are going to run our first Terraform command which is -

1terraform init  

Here is the output after running the Terraform init command

terraform init command

5.2 Let's run the terraform plan command

After successfully running the Terraform init command, let's run the Terraform plan command -

1Terraform plan

Here is the output after running the Terraform init command

terraform init command
terraform plan command

5.3 Finally run the Terraform apply

Here is the command which you need to run at last -

1terraform apply 

Here is the output after running the Terraform apply command

terraform apply command
terraform apply create IAM user and IAM roles
terraform apply create IAM user and IAM roles

5.4 Let's verify the user and IAM roles from AWS console

Now after successfully applying the changes, let us login to AWS console and verify two things -

  1. IAM User
  2. IAM Roll permission

Go to your AWS account and log in with your AWS credentials. In the search box type IAM and in the left navigation look for User

IAM User inside AWS Console

If you will look into the use section then you will and user with the name Test-Terraform-User has been created -

IAM User inside AWS Console

let's verify the IAM User Roles also. For that you need to click on User -> Permission -> InstanceManagePolicy-

IAM User inside AWS Console

Note - Click here to read more on How to manage AWS IAM user, Roles and Policies with Terraform


6. Conclusion

As you can see in the blog post we have managed to use the Terraform template and using the template we have setup -

  1. IAM User on AWS
  2. IAM roles for the user

This blog post is a guide for those who want to understand the basics as well as a real example of how to use Terraform template. Hope this guide will help you to understand Terraform template.

Posts in this Series