For / If Expressions
Learn how to use for loops and if/else expressions in Carina to create multiple resources, iterate over lists and maps, and conditionally include resources.
Carina supports for and if expressions to dynamically generate resources. This guide shows you how to iterate over collections and conditionally create resources.
For expressions
A for expression creates multiple resources by iterating over a list or map.
Iterating over a list
The simplest form iterates over a list of values:
provider awscc {
region = awscc.Region.ap_northeast_1
}
let vpcs = for env in ['dev', 'stg'] {
awscc.ec2.Vpc {
cidr_block = '10.0.0.0/16'
tags = {
Name = "vpc-${env}"
Environment = env
}
}
}
This creates two VPCs, one for each environment.
Indexed iteration
Use the (index, value) form to access the iteration index:
let vpcs = for (i, env) in ['dev', 'stg'] {
awscc.ec2.Vpc {
cidr_block = cidr_subnet('10.0.0.0/8', 8, i)
tags = {
Name = "vpc-${env}"
Environment = env
}
}
}
The index i starts at 0. Here it is used with cidr_subnet to assign different CIDR blocks to each VPC.
Iterating over a map
Use key, value binding to iterate over map entries:
let cidrs = {
dev = '10.0.0.0/16'
stg = '10.1.0.0/16'
}
let vpcs = for name, cidr in cidrs {
awscc.ec2.Vpc {
cidr_block = cidr
tags = {
Name = "vpc-${name}"
Environment = name
}
}
}
Accessing for expression results
The result of a for expression is a list. You can access individual elements with index syntax:
let vpcs = for env in ['dev', 'stg'] {
awscc.ec2.Vpc {
cidr_block = '10.0.0.0/16'
tags = {
Name = "vpc-${env}"
}
}
}
# Reference the first VPC's attributes
awscc.ec2.Subnet {
vpc_id = vpcs[0].vpc_id
cidr_block = '10.0.1.0/24'
availability_zone = 'ap-northeast-1a'
tags = {
Name = 'dev-subnet'
}
}
Local variables in for body
You can define local let bindings inside a for body:
let vpc = awscc.ec2.Vpc {
cidr_block = '10.0.0.0/16'
}
let subnets = for (i, az) in ['ap-northeast-1a', 'ap-northeast-1c'] {
let cidr = cidr_subnet('10.0.0.0/16', 8, i)
awscc.ec2.Subnet {
vpc_id = vpc.vpc_id
cidr_block = cidr
availability_zone = az
tags = {
Name = "subnet-${az}"
}
}
}
For with modules
You can call modules inside for expressions to create multiple instances of a module. See the Using Modules guide for a full example.
If expressions
An if expression conditionally creates a resource or selects a value.
Conditional resources
Create a resource only when a condition is true:
let enabled = true
let vpc = if enabled {
awscc.ec2.Vpc {
cidr_block = '10.0.0.0/16'
tags = {
Name = 'conditional-vpc'
}
}
}
When enabled is false, no VPC is created and the let binding is empty.
Conditional values with if/else
Use if/else as a value expression to choose between two values:
let is_production = true
awscc.ec2.Vpc {
cidr_block = if is_production { '10.0.0.0/16' } else { '172.16.0.0/16' }
tags = {
Name = if is_production { 'prod-vpc' } else { 'dev-vpc' }
}
}
This creates a single VPC but uses different CIDR blocks and names depending on the condition.
Combining for and if
You can use if expressions inside for bodies and vice versa:
let environments = {
dev = '10.0.0.0/16'
stg = '10.1.0.0/16'
prd = '10.2.0.0/16'
}
let vpcs = for name, cidr in environments {
awscc.ec2.Vpc {
cidr_block = cidr
enable_dns_hostnames = if name == 'prd' { true } else { false }
tags = {
Name = "vpc-${name}"
Environment = name
}
}
}