or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations-aspects.mdbackend-configuration.mdcore-infrastructure.mdindex.mditerators-dynamic.mdproviders-modules.mdprovisioners.mdresources-data-sources.mdterraform-functions.mdtesting.mdtokens-expressions.mdvariables-outputs.md

iterators-dynamic.mddocs/

0

# Iterators and Dynamic Blocks

1

2

Iterator support for for_each constructs and dynamic block generation, enabling scalable and flexible infrastructure patterns.

3

4

## Capabilities

5

6

### TerraformIterator Class

7

8

Abstract base class providing iterator functionality for creating multiple similar resources or dynamic configuration blocks.

9

10

```typescript { .api }

11

/**

12

* Base iterator class for for_each and dynamic block constructs

13

*/

14

abstract class TerraformIterator {

15

/**

16

* Create an iterator from a list

17

* @param list - Array to iterate over

18

* @returns List iterator instance

19

*/

20

static fromList(list: any[]): ListTerraformIterator;

21

22

/**

23

* Create an iterator from a complex list with map conversion

24

* @param list - Complex list to iterate over

25

* @param mapKeyAttributeName - Attribute to use as map key

26

* @returns Dynamic list iterator instance

27

*/

28

static fromComplexList(

29

list: any[],

30

mapKeyAttributeName: string

31

): DynamicListTerraformIterator;

32

33

/**

34

* Create an iterator from a map/object

35

* @param map - Map to iterate over

36

* @returns Map iterator instance

37

*/

38

static fromMap(map: {[key: string]: any}): MapTerraformIterator;

39

40

/**

41

* Create an iterator from resources with for_each

42

* @param resource - Resource with for_each

43

* @returns Resource iterator instance

44

*/

45

static fromResources(resource: ITerraformResource): ResourceTerraformIterator;

46

47

/**

48

* Create an iterator from data sources with for_each

49

* @param resource - Data source with for_each

50

* @returns Resource iterator instance

51

*/

52

static fromDataSources(resource: ITerraformResource): ResourceTerraformIterator;

53

54

/**

55

* Get string attribute from current iteration

56

* @param attribute - Attribute name

57

* @returns String value

58

*/

59

getString(attribute: string): string;

60

61

/**

62

* Get number attribute from current iteration

63

* @param attribute - Attribute name

64

* @returns Number value

65

*/

66

getNumber(attribute: string): number;

67

68

/**

69

* Get boolean attribute from current iteration

70

* @param attribute - Attribute name

71

* @returns Boolean value

72

*/

73

getBoolean(attribute: string): IResolvable;

74

75

/**

76

* Get any attribute from current iteration

77

* @param attribute - Attribute name

78

* @returns Any value

79

*/

80

getAny(attribute: string): IResolvable;

81

82

/**

83

* Get list attribute from current iteration

84

* @param attribute - Attribute name

85

* @returns String array

86

*/

87

getList(attribute: string): string[];

88

89

/**

90

* Get number list attribute from current iteration

91

* @param attribute - Attribute name

92

* @returns Number array

93

*/

94

getNumberList(attribute: string): number[];

95

96

/**

97

* Get map attribute from current iteration

98

* @param attribute - Attribute name

99

* @returns Map of any values

100

*/

101

getMap(attribute: string): {[key: string]: any};

102

103

/**

104

* Get string map attribute from current iteration

105

* @param attribute - Attribute name

106

* @returns Map of string values

107

*/

108

getStringMap(attribute: string): {[key: string]: string};

109

110

/**

111

* Get number map attribute from current iteration

112

* @param attribute - Attribute name

113

* @returns Map of number values

114

*/

115

getNumberMap(attribute: string): {[key: string]: number};

116

117

/**

118

* Get boolean map attribute from current iteration

119

* @param attribute - Attribute name

120

* @returns Map of boolean values

121

*/

122

getBooleanMap(attribute: string): {[key: string]: boolean};

123

124

/**

125

* Get any map attribute from current iteration

126

* @param attribute - Attribute name

127

* @returns Map of any values

128

*/

129

getAnyMap(attribute: string): {[key: string]: any};

130

131

/**

132

* Create dynamic block content

133

* @param attributes - Attributes for the dynamic block

134

* @returns Dynamic block content

135

*/

136

dynamic(attributes: {[key: string]: any}): IResolvable;

137

138

/**

139

* Get keys from the iterator

140

* @returns Iterator keys

141

*/

142

keys(): IResolvable;

143

144

/**

145

* Get values from the iterator

146

* @returns Iterator values

147

*/

148

values(): IResolvable;

149

150

/**

151

* Pluck a specific property from each item

152

* @param property - Property name to extract

153

* @returns List of property values

154

*/

155

pluckProperty(property: string): IResolvable;

156

157

/**

158

* Create a for expression over the iterator for lists

159

* @param expression - Expression to evaluate for each item

160

* @returns For expression result

161

*/

162

forExpressionForList(expression: string | IResolvable): IResolvable;

163

164

/**

165

* Create a for expression over the iterator for maps

166

* @param keyExpression - Expression for map keys

167

* @param valueExpression - Expression for map values

168

* @returns For expression result

169

*/

170

forExpressionForMap(

171

keyExpression: string | IResolvable,

172

valueExpression: string | IResolvable

173

): IResolvable;

174

}

175

```

176

177

### Iterator Implementations

178

179

#### ListTerraformIterator

180

181

Iterator for arrays and lists.

182

183

```typescript { .api }

184

/**

185

* Iterator for lists and arrays

186

*/

187

class ListTerraformIterator extends TerraformIterator {

188

constructor(list: any[]);

189

190

readonly list: any[];

191

}

192

```

193

194

**Usage Examples:**

195

196

```typescript

197

import { TerraformIterator, AwsInstance } from "cdktf";

198

199

// Create instances for multiple environments

200

const environments = ["dev", "staging", "prod"];

201

const envIterator = TerraformIterator.fromList(environments);

202

203

new AwsInstance(this, "web-servers", {

204

forEach: envIterator,

205

ami: "ami-12345678",

206

instanceType: "t2.micro",

207

tags: {

208

Environment: envIterator.getString("each.value"),

209

Name: `web-${envIterator.getString("each.value")}`

210

}

211

});

212

213

// Using with complex objects

214

const serverConfigs = [

215

{ name: "web", type: "t2.micro", count: 2 },

216

{ name: "db", type: "t3.large", count: 1 },

217

{ name: "cache", type: "t3.medium", count: 1 }

218

];

219

220

const configIterator = TerraformIterator.fromList(serverConfigs);

221

222

new AwsInstance(this, "servers", {

223

forEach: configIterator,

224

ami: "ami-12345678",

225

instanceType: configIterator.getString("each.value.type"),

226

tags: {

227

Name: configIterator.getString("each.value.name"),

228

Type: configIterator.getString("each.value.name")

229

}

230

});

231

```

232

233

#### MapTerraformIterator

234

235

Iterator for maps and objects.

236

237

```typescript { .api }

238

/**

239

* Iterator for maps and objects

240

*/

241

class MapTerraformIterator extends TerraformIterator {

242

constructor(map: {[key: string]: any});

243

244

readonly map: {[key: string]: any};

245

}

246

```

247

248

**Usage Examples:**

249

250

```typescript

251

import { TerraformIterator, AwsS3Bucket } from "cdktf";

252

253

// Create buckets for different purposes

254

const buckets = {

255

"logs": { versioning: true, encryption: true },

256

"assets": { versioning: false, encryption: false },

257

"backups": { versioning: true, encryption: true }

258

};

259

260

const bucketIterator = TerraformIterator.fromMap(buckets);

261

262

new AwsS3Bucket(this, "buckets", {

263

forEach: bucketIterator,

264

bucket: `my-app-${bucketIterator.getString("each.key")}`,

265

versioning: [{

266

enabled: bucketIterator.getBoolean("each.value.versioning")

267

}],

268

serverSideEncryptionConfiguration: bucketIterator.getBoolean("each.value.encryption") ? [

269

{

270

rule: [{

271

applyServerSideEncryptionByDefault: [{

272

sseAlgorithm: "AES256"

273

}]

274

}]

275

}

276

] : []

277

});

278

```

279

280

#### ResourceTerraformIterator

281

282

Iterator for resources created with for_each.

283

284

```typescript { .api }

285

/**

286

* Iterator for resources with for_each

287

*/

288

class ResourceTerraformIterator extends TerraformIterator {

289

constructor(resource: ITerraformResource);

290

291

readonly resource: ITerraformResource;

292

}

293

```

294

295

### Dynamic Blocks

296

297

Dynamic blocks allow you to generate multiple nested blocks based on iteration.

298

299

**Usage Examples:**

300

301

```typescript

302

import { TerraformIterator } from "cdktf";

303

304

// Dynamic security group rules

305

const ingressRules = [

306

{ from_port: 80, to_port: 80, protocol: "tcp", cidr_blocks: ["0.0.0.0/0"] },

307

{ from_port: 443, to_port: 443, protocol: "tcp", cidr_blocks: ["0.0.0.0/0"] },

308

{ from_port: 22, to_port: 22, protocol: "tcp", cidr_blocks: ["10.0.0.0/8"] }

309

];

310

311

const ruleIterator = TerraformIterator.fromList(ingressRules);

312

313

new AwsSecurityGroup(this, "web-sg", {

314

namePrefix: "web-",

315

vpcId: vpc.id,

316

317

// Dynamic ingress blocks

318

dynamic: {

319

ingress: ruleIterator.dynamic({

320

fromPort: ruleIterator.getNumber("each.value.from_port"),

321

toPort: ruleIterator.getNumber("each.value.to_port"),

322

protocol: ruleIterator.getString("each.value.protocol"),

323

cidrBlocks: ruleIterator.getList("each.value.cidr_blocks")

324

})

325

}

326

});

327

328

// Dynamic tags based on map

329

const tags = {

330

Environment: "production",

331

Team: "platform",

332

Project: "web-app"

333

};

334

335

const tagIterator = TerraformIterator.fromMap(tags);

336

337

new AwsInstance(this, "web", {

338

ami: "ami-12345678",

339

instanceType: "t2.micro",

340

341

// Dynamic tags

342

dynamic: {

343

tag: tagIterator.dynamic({

344

key: tagIterator.getString("each.key"),

345

value: tagIterator.getString("each.value"),

346

propagateAtLaunch: true

347

})

348

}

349

});

350

```

351

352

### Advanced Iterator Patterns

353

354

#### Transforming Data with For Expressions

355

356

```typescript

357

import { TerraformIterator, Fn } from "cdktf";

358

359

const users = [

360

{ name: "alice", role: "admin", active: true },

361

{ name: "bob", role: "user", active: true },

362

{ name: "charlie", role: "user", active: false }

363

];

364

365

const userIterator = TerraformIterator.fromList(users);

366

367

// Get list of active user names

368

const activeUsers = userIterator.forExpressionForList(

369

Fn.conditional(

370

userIterator.getBoolean("each.value.active"),

371

userIterator.getString("each.value.name"),

372

null

373

)

374

);

375

376

// Create map of user roles

377

const userRoleMap = userIterator.forExpressionForMap(

378

userIterator.getString("each.value.name"),

379

userIterator.getString("each.value.role")

380

);

381

382

// Use in outputs

383

new TerraformOutput(this, "active_users", {

384

value: activeUsers,

385

description: "List of active users"

386

});

387

388

new TerraformOutput(this, "user_roles", {

389

value: userRoleMap,

390

description: "Map of users to their roles"

391

});

392

```

393

394

#### Nested Iterations

395

396

```typescript

397

import { TerraformIterator } from "cdktf";

398

399

// Create subnets for multiple AZs and tiers

400

const azs = ["us-east-1a", "us-east-1b", "us-east-1c"];

401

const tiers = ["public", "private"];

402

403

const azIterator = TerraformIterator.fromList(azs);

404

const tierIterator = TerraformIterator.fromList(tiers);

405

406

// Flatten to create all combinations

407

const subnetConfigs = azIterator.forExpressionForList(

408

tierIterator.forExpressionForList({

409

az: azIterator.getString("each.value"),

410

tier: tierIterator.getString("each.value"),

411

cidr: `10.0.${azIterator.getNumber("each.key")}.${tierIterator.getNumber("each.key") * 16}/20`

412

})

413

);

414

415

const subnetIterator = TerraformIterator.fromList(subnetConfigs);

416

417

new AwsSubnet(this, "subnets", {

418

forEach: subnetIterator,

419

vpcId: vpc.id,

420

availabilityZone: subnetIterator.getString("each.value.az"),

421

cidrBlock: subnetIterator.getString("each.value.cidr"),

422

mapPublicIpOnLaunch: subnetIterator.getString("each.value.tier") === "public",

423

tags: {

424

Name: `${subnetIterator.getString("each.value.tier")}-${subnetIterator.getString("each.value.az")}`,

425

Tier: subnetIterator.getString("each.value.tier"),

426

AZ: subnetIterator.getString("each.value.az")

427

}

428

});

429

```

430

431

## Type Definitions

432

433

```typescript { .api }

434

/**

435

* Interface for resources that can be iterated over

436

*/

437

interface ITerraformResource extends ITerraformDependable, ITerraformAddressable {

438

readonly terraformResourceType: string;

439

readonly fqn: string;

440

}

441

442

/**

443

* Dynamic block configuration

444

*/

445

interface DynamicBlockConfig {

446

/**

447

* Iterator to use for the dynamic block

448

*/

449

readonly forEach: ITerraformIterator;

450

451

/**

452

* Content to generate for each iteration

453

*/

454

readonly content: {[key: string]: any};

455

456

/**

457

* Iterator variable name (defaults to each)

458

*/

459

readonly iterator?: string;

460

}

461

```