Terraform 0.12 was recently released and you can check out the details more in-dept at terraform blogs. The focus of this blog post will be the new features released and how to use them. You can find the code used in this Github repo. Below is the content of the ec2 main.tf.
module "test_ec2" {
source = "./ec2_module"
//I am passing the subnet object instead of the id
subnet = aws_subnet.private.0
instance_tags = [
{
Key = "Name"
Value = "Test"
},
{
Key = "Environment"
Value = "prd"
}
]
}
Here is the content of the ec2 module;
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
subnet_id = var.subnet.id
user_data = templatefile("${path.module}/userdata.tpl", { instance_tags = var.instance_tags })
tags = {
for tag in var.instance_tags:
tag.Key => tag.Value
}
}
variable "instance_type" {
default = "t2.micro"
}
variable "instance_tags" {
type = list
}
variable "subnet" {
type = object({
id = string
})
}
For expression
From my perspective, this is one of the best feature of 0.12 which allows you to iterate over a list or map and you can do whatever you want with each item. From above, you can see that we generated the instance tags property from the user passed in list of maps.
tags = {
for tag in var.instance_tags:
tag.Key => tag.Value
}
First class expression
You can see from above that we did not have to interpolate over the variables or object values instead they were used directly as first class variable. This will save some ink and allows for more complex operational usage with terraform.
...
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
subnet_id = var.subnet.id
...
Rich Value Type
My impression of this feature so far is that we can have user-defined type and existing type are supported as first class type without quote. We defined a type that expects map with id attribute and if passing a non-matching object, it will be rejected which is pretty cool.
variable "instance_tags" {
type = list
}
variable "subnet" {
type = object({
id = string
})
}
New Type Interpolation
New terraform now gives you the capability to loop in your user data. For our example, here is the userdata;
#!/bin/bash
%{ for tag in instance_tags~}
cat ${tag.Key}=${tag.Value}
%{ endfor ~}
We were able to use forloop to go over the tags and use it in instance user data which is lovely without having to through hacks.
One other feature that was not discussed here is the dynamic block which you can checkout on terraform blog page.
Top comments (0)