For / If Expressions
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 attributesawscc.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 } }}