For Loops
Terraform provides for-loops and for-each loops. These can be used to loop over variables, transform those, and output in different formats.
For example,
[for s in ["this is a ", "list"] : upper(s)] : this loop over the list and make all strings uppercase.
We can loop over a list or maps
We can even perform calculations or manipulations on values
And it's possible to output them as a list or map
For loops
In order to further explore this, let's first create a file with the name vars.tf
,
variable "list1" {
type = list(string)
default = [1, 10, 9, 101, 3]
}
variable "list2" {
type = list(string)
default = ["apple", "pear", "banana", "mango"]
}
variable "map1" {
type = map(number)
default = {
"apple" = 5
"pear" = 3
"banana" = 10
"mango" = 0
}
}
Let's start the Terraform console and experiment with this file,
$ terraform console
> [for s in ["a", "b", "c"]: s]
[
"a",
"b",
"c",
]
> [for s in ["a", "b", "c"]: upper(s)]
[
"A",
"B",
"C",
]
> [for s in var.list1: s ]
[
"1",
"10",
"9",
"101",
"3",
]
> [for s in var.list1: s + 1]
[
2,
11,
10,
102,
4,
]
> [for s in var.list2: upper(s)]
[
"APPLE",
"PEAR",
"BANANA",
"MANGO",
]
> [for k, v in var.map1: k]
[
"apple",
"banana",
"mango",
"pear",
]
> [for k, v in var.map1: v]
[
5,
10,
0,
3,
]
> {for k, v in var.map1: k => v}
{
"apple" = 5
"banana" = 10
"mango" = 0
"pear" = 3
}
> {for k, v in var.map1: v => k}
{
"0" = "mango"
"10" = "banana"
"3" = "pear"
"5" = "apple"
}
>
To make things more interesting let's create a file with the name provider.tf
,
provider "aws" {
region = var.AWS_REGION
}
Then replace the content of the vars.tf
file,
variable "AWS_REGION" {
type = string
default = "eu-west-1"
}
variable "project_tags" {
type = map(string)
default = {
Component = "Frontend"
Environment = "Production"
}
}
Finally a file with the name ebs.tf
,
resource "aws_ebs_volume" "example" {
availability_zone = "eu-west-1a"
size = 8
tags = {for k, v in merge({ Name = "Myvolume" }, var.project_tags): k => lower(v)}
}
Init the modules,
$ terraform init
Let's examine the output,
$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
+ create
Terraform will perform the following actions:
# aws_ebs_volume.example will be created
+ resource "aws_ebs_volume" "example" {
+ arn = (known after apply)
+ availability_zone = "eu-west-1a"
+ encrypted = (known after apply)
+ id = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ size = 8
+ snapshot_id = (known after apply)
+ tags = {
+ "Component" = "frontend"
+ "Environment" = "production"
+ "Name" = "myvolume"
}
+ tags_all = {
+ "Component" = "frontend"
+ "Environment" = "production"
+ "Name" = "myvolume"
}
+ throughput = (known after apply)
+ type = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run
"terraform apply" now.
For-Each loops
Let's start this by creating a file with the name provider.tf
,
provider "aws" {
region = var.AWS_REGION
}
Then let's create a file with the name vars.tf
,
variable "AWS_REGION" {
type = string
default = "eu-west-1"
}
variable "ports" {
type = map(list(string))
default = {
"22" = [ "127.0.0.1/32", "192.168.0.0/24" ]
"443" = [ "0.0.0.0/0" ]
}
}
Finally a file with the name securitygroup.tf
,
resource "aws_security_group" "example" {
name = "example" # can use expressions here
dynamic "ingress" {
for_each = var.ports
content {
from_port = ingress.key
to_port = ingress.key
cidr_blocks = ingress.value
protocol = "tcp"
}
}
}
Init the modules,
$ terraform init
Let's examine the output,
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
+ create
Terraform will perform the following actions:
# aws_security_group.example will be created
+ resource "aws_security_group" "example" {
+ arn = (known after apply)
+ description = "Managed by Terraform"
+ egress = (known after apply)
+ id = (known after apply)
+ ingress = [
+ {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = ""
+ from_port = 443
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 443
},
+ {
+ cidr_blocks = [
+ "127.0.0.1/32",
+ "192.168.0.0/24",
]
+ description = ""
+ from_port = 22
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 22
},
]
+ name = "example"
+ name_prefix = (known after apply)
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags_all = (known after apply)
+ vpc_id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run
"terraform apply" now.
Last updated
Was this helpful?