Terraform
Iterators
Iterators let you loop over a collection of values. You can use them to create multiple resources of the same type based on dynamic data that is only known at runtime.
When to Use Iterators
Use iterators when you need to reference dynamic data that is not known until after Terraform applies a configuration. For example, instance IDs that cloud providers assign on creation.
When data is static or you know the values before synthesizing your code, we recommend using loops in your preferred programming language.
Define Iterators
Import the TerraformIterator
class and call the .fromList()
or .fromMap()
static method. Then use the forEach
property to pass the iterator to a resource, data source, or module. This lets you use the iterator in attributes.
The following example uses an iterator to create a unique name for each new S3 bucket.
import { S3Bucket } from "@cdktf/provider-aws/lib/s3-bucket";
import { TerraformIterator, TerraformVariable } from "cdktf";
const list = new TerraformVariable(this, "list", {
type: "list(string)",
});
const iterator = TerraformIterator.fromList(list.listValue);
const s3Bucket = new S3Bucket(this, "bucket", {
forEach: iterator,
name: iterator.value,
});
You cannot access the index of items when iterating over lists. This is because CDKTF implicitly converts lists to sets when iterating over them, but Terraform requires sets for iteration. This behavior prevents Terraform from accidentally deleting and recreating resources when their indices change. If you need an index, use an escape hatch with the count.index
property.
Using Iterators on Complex Types
The iterator also exposes methods to access nested attributes. The following example uses the getString
and getStringMap
methods to access the name
and tags
attributes of each list item.
const iterator = TerraformIterator.fromList([
{
name: "website-static-files",
tags: { app: "website" },
},
{
name: "images",
tags: { app: "image-converter" },
},
] as any);
const s3Bucket = new S3Bucket(this, "bucket", {
forEach: iterator,
name: iterator.getString("name"),
tags: iterator.getStringMap("tags"),
});
Using Iterators for List Attributes
You can also use iterators to create a list of objects based on each item in a list and assign the result as a value to a property of a resource. This is equivalent to using Array.map
in TypeScript and using dynamic blocks in a Terraform HCL configuration.
Use iterators for list attributes if the length of the list is not known before deploying. Otherwise, use native functions that are available in your language (e.g., Array.map
in TypeScript).
The following examples use an iterator to create a team containing each member of an organization.
const orgName = "my-org";
new GithubProvider(this, "github", {
organization: orgName,
});
const team = new Team(this, "core-team", {
name: "core",
});
const orgMembers = new DataGithubOrganization(this, "org", {
name: orgName,
});
const orgMemberIterator = TerraformIterator.fromList(orgMembers.members);
new TeamMembers(this, "members", {
teamId: team.id,
members: orgMemberIterator.dynamic({
username: orgMemberIterator.value,
role: "maintainer",
}),
});