Cloud Development Kit for Terraform - programmatic infrastructure as code using familiar programming languages
Iterator support for for_each constructs and dynamic block generation, enabling scalable and flexible infrastructure patterns.
Abstract base class providing iterator functionality for creating multiple similar resources or dynamic configuration blocks.
/**
* Base iterator class for for_each and dynamic block constructs
*/
abstract class TerraformIterator {
/**
* Create an iterator from a list
* @param list - Array to iterate over
* @returns List iterator instance
*/
static fromList(list: any[]): ListTerraformIterator;
/**
* Create an iterator from a complex list with map conversion
* @param list - Complex list to iterate over
* @param mapKeyAttributeName - Attribute to use as map key
* @returns Dynamic list iterator instance
*/
static fromComplexList(
list: any[],
mapKeyAttributeName: string
): DynamicListTerraformIterator;
/**
* Create an iterator from a map/object
* @param map - Map to iterate over
* @returns Map iterator instance
*/
static fromMap(map: {[key: string]: any}): MapTerraformIterator;
/**
* Create an iterator from resources with for_each
* @param resource - Resource with for_each
* @returns Resource iterator instance
*/
static fromResources(resource: ITerraformResource): ResourceTerraformIterator;
/**
* Create an iterator from data sources with for_each
* @param resource - Data source with for_each
* @returns Resource iterator instance
*/
static fromDataSources(resource: ITerraformResource): ResourceTerraformIterator;
/**
* Get string attribute from current iteration
* @param attribute - Attribute name
* @returns String value
*/
getString(attribute: string): string;
/**
* Get number attribute from current iteration
* @param attribute - Attribute name
* @returns Number value
*/
getNumber(attribute: string): number;
/**
* Get boolean attribute from current iteration
* @param attribute - Attribute name
* @returns Boolean value
*/
getBoolean(attribute: string): IResolvable;
/**
* Get any attribute from current iteration
* @param attribute - Attribute name
* @returns Any value
*/
getAny(attribute: string): IResolvable;
/**
* Get list attribute from current iteration
* @param attribute - Attribute name
* @returns String array
*/
getList(attribute: string): string[];
/**
* Get number list attribute from current iteration
* @param attribute - Attribute name
* @returns Number array
*/
getNumberList(attribute: string): number[];
/**
* Get map attribute from current iteration
* @param attribute - Attribute name
* @returns Map of any values
*/
getMap(attribute: string): {[key: string]: any};
/**
* Get string map attribute from current iteration
* @param attribute - Attribute name
* @returns Map of string values
*/
getStringMap(attribute: string): {[key: string]: string};
/**
* Get number map attribute from current iteration
* @param attribute - Attribute name
* @returns Map of number values
*/
getNumberMap(attribute: string): {[key: string]: number};
/**
* Get boolean map attribute from current iteration
* @param attribute - Attribute name
* @returns Map of boolean values
*/
getBooleanMap(attribute: string): {[key: string]: boolean};
/**
* Get any map attribute from current iteration
* @param attribute - Attribute name
* @returns Map of any values
*/
getAnyMap(attribute: string): {[key: string]: any};
/**
* Create dynamic block content
* @param attributes - Attributes for the dynamic block
* @returns Dynamic block content
*/
dynamic(attributes: {[key: string]: any}): IResolvable;
/**
* Get keys from the iterator
* @returns Iterator keys
*/
keys(): IResolvable;
/**
* Get values from the iterator
* @returns Iterator values
*/
values(): IResolvable;
/**
* Pluck a specific property from each item
* @param property - Property name to extract
* @returns List of property values
*/
pluckProperty(property: string): IResolvable;
/**
* Create a for expression over the iterator for lists
* @param expression - Expression to evaluate for each item
* @returns For expression result
*/
forExpressionForList(expression: string | IResolvable): IResolvable;
/**
* Create a for expression over the iterator for maps
* @param keyExpression - Expression for map keys
* @param valueExpression - Expression for map values
* @returns For expression result
*/
forExpressionForMap(
keyExpression: string | IResolvable,
valueExpression: string | IResolvable
): IResolvable;
}Iterator for arrays and lists.
/**
* Iterator for lists and arrays
*/
class ListTerraformIterator extends TerraformIterator {
constructor(list: any[]);
readonly list: any[];
}Usage Examples:
import { TerraformIterator, AwsInstance } from "cdktf";
// Create instances for multiple environments
const environments = ["dev", "staging", "prod"];
const envIterator = TerraformIterator.fromList(environments);
new AwsInstance(this, "web-servers", {
forEach: envIterator,
ami: "ami-12345678",
instanceType: "t2.micro",
tags: {
Environment: envIterator.getString("each.value"),
Name: `web-${envIterator.getString("each.value")}`
}
});
// Using with complex objects
const serverConfigs = [
{ name: "web", type: "t2.micro", count: 2 },
{ name: "db", type: "t3.large", count: 1 },
{ name: "cache", type: "t3.medium", count: 1 }
];
const configIterator = TerraformIterator.fromList(serverConfigs);
new AwsInstance(this, "servers", {
forEach: configIterator,
ami: "ami-12345678",
instanceType: configIterator.getString("each.value.type"),
tags: {
Name: configIterator.getString("each.value.name"),
Type: configIterator.getString("each.value.name")
}
});Iterator for maps and objects.
/**
* Iterator for maps and objects
*/
class MapTerraformIterator extends TerraformIterator {
constructor(map: {[key: string]: any});
readonly map: {[key: string]: any};
}Usage Examples:
import { TerraformIterator, AwsS3Bucket } from "cdktf";
// Create buckets for different purposes
const buckets = {
"logs": { versioning: true, encryption: true },
"assets": { versioning: false, encryption: false },
"backups": { versioning: true, encryption: true }
};
const bucketIterator = TerraformIterator.fromMap(buckets);
new AwsS3Bucket(this, "buckets", {
forEach: bucketIterator,
bucket: `my-app-${bucketIterator.getString("each.key")}`,
versioning: [{
enabled: bucketIterator.getBoolean("each.value.versioning")
}],
serverSideEncryptionConfiguration: bucketIterator.getBoolean("each.value.encryption") ? [
{
rule: [{
applyServerSideEncryptionByDefault: [{
sseAlgorithm: "AES256"
}]
}]
}
] : []
});Iterator for resources created with for_each.
/**
* Iterator for resources with for_each
*/
class ResourceTerraformIterator extends TerraformIterator {
constructor(resource: ITerraformResource);
readonly resource: ITerraformResource;
}Dynamic blocks allow you to generate multiple nested blocks based on iteration.
Usage Examples:
import { TerraformIterator } from "cdktf";
// Dynamic security group rules
const ingressRules = [
{ from_port: 80, to_port: 80, protocol: "tcp", cidr_blocks: ["0.0.0.0/0"] },
{ from_port: 443, to_port: 443, protocol: "tcp", cidr_blocks: ["0.0.0.0/0"] },
{ from_port: 22, to_port: 22, protocol: "tcp", cidr_blocks: ["10.0.0.0/8"] }
];
const ruleIterator = TerraformIterator.fromList(ingressRules);
new AwsSecurityGroup(this, "web-sg", {
namePrefix: "web-",
vpcId: vpc.id,
// Dynamic ingress blocks
dynamic: {
ingress: ruleIterator.dynamic({
fromPort: ruleIterator.getNumber("each.value.from_port"),
toPort: ruleIterator.getNumber("each.value.to_port"),
protocol: ruleIterator.getString("each.value.protocol"),
cidrBlocks: ruleIterator.getList("each.value.cidr_blocks")
})
}
});
// Dynamic tags based on map
const tags = {
Environment: "production",
Team: "platform",
Project: "web-app"
};
const tagIterator = TerraformIterator.fromMap(tags);
new AwsInstance(this, "web", {
ami: "ami-12345678",
instanceType: "t2.micro",
// Dynamic tags
dynamic: {
tag: tagIterator.dynamic({
key: tagIterator.getString("each.key"),
value: tagIterator.getString("each.value"),
propagateAtLaunch: true
})
}
});import { TerraformIterator, Fn } from "cdktf";
const users = [
{ name: "alice", role: "admin", active: true },
{ name: "bob", role: "user", active: true },
{ name: "charlie", role: "user", active: false }
];
const userIterator = TerraformIterator.fromList(users);
// Get list of active user names
const activeUsers = userIterator.forExpressionForList(
Fn.conditional(
userIterator.getBoolean("each.value.active"),
userIterator.getString("each.value.name"),
null
)
);
// Create map of user roles
const userRoleMap = userIterator.forExpressionForMap(
userIterator.getString("each.value.name"),
userIterator.getString("each.value.role")
);
// Use in outputs
new TerraformOutput(this, "active_users", {
value: activeUsers,
description: "List of active users"
});
new TerraformOutput(this, "user_roles", {
value: userRoleMap,
description: "Map of users to their roles"
});import { TerraformIterator } from "cdktf";
// Create subnets for multiple AZs and tiers
const azs = ["us-east-1a", "us-east-1b", "us-east-1c"];
const tiers = ["public", "private"];
const azIterator = TerraformIterator.fromList(azs);
const tierIterator = TerraformIterator.fromList(tiers);
// Flatten to create all combinations
const subnetConfigs = azIterator.forExpressionForList(
tierIterator.forExpressionForList({
az: azIterator.getString("each.value"),
tier: tierIterator.getString("each.value"),
cidr: `10.0.${azIterator.getNumber("each.key")}.${tierIterator.getNumber("each.key") * 16}/20`
})
);
const subnetIterator = TerraformIterator.fromList(subnetConfigs);
new AwsSubnet(this, "subnets", {
forEach: subnetIterator,
vpcId: vpc.id,
availabilityZone: subnetIterator.getString("each.value.az"),
cidrBlock: subnetIterator.getString("each.value.cidr"),
mapPublicIpOnLaunch: subnetIterator.getString("each.value.tier") === "public",
tags: {
Name: `${subnetIterator.getString("each.value.tier")}-${subnetIterator.getString("each.value.az")}`,
Tier: subnetIterator.getString("each.value.tier"),
AZ: subnetIterator.getString("each.value.az")
}
});/**
* Interface for resources that can be iterated over
*/
interface ITerraformResource extends ITerraformDependable, ITerraformAddressable {
readonly terraformResourceType: string;
readonly fqn: string;
}
/**
* Dynamic block configuration
*/
interface DynamicBlockConfig {
/**
* Iterator to use for the dynamic block
*/
readonly forEach: ITerraformIterator;
/**
* Content to generate for each iteration
*/
readonly content: {[key: string]: any};
/**
* Iterator variable name (defaults to each)
*/
readonly iterator?: string;
}