Skip to content

Commit

Permalink
feat(lib): allow chaining of TerraformIterator created resources
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielMSchmidt committed Nov 20, 2023
1 parent 47c8ec5 commit 5792382
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 1 deletion.
37 changes: 36 additions & 1 deletion examples/typescript/documentation/iterators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ import { Team } from "@cdktf/provider-github/lib/team";
import { DataGithubOrganization } from "@cdktf/provider-github/lib/data-github-organization";
import { TeamMembers } from "@cdktf/provider-github/lib/team-members";
// DOCS_BLOCK_START:iterators,iterators-complex-types
import { TerraformIterator, TerraformStack, TerraformVariable } from "cdktf";
import {
TerraformAsset,
TerraformIterator,
TerraformStack,
TerraformVariable,
} from "cdktf";
import { Construct } from "constructs";
import { AwsProvider } from "@cdktf/provider-aws/lib/aws-provider";
import { S3Bucket } from "@cdktf/provider-aws/lib/s3-bucket";
import { S3BucketObject } from "@cdktf/provider-aws/lib/s3-bucket-object";

export class IteratorsStack extends TerraformStack {
constructor(scope: Construct, id: string) {
Expand Down Expand Up @@ -78,6 +84,35 @@ export class IteratorsStack extends TerraformStack {
});
// DOCS_BLOCK_END:iterators-complex-types

// TODO: write documentation for the following
const chainedIterators = TerraformIterator.fromMap({
website: {
name: "website-static-files",
tags: { app: "website" },
},
images: {
name: "images",
tags: { app: "image-converter" },
},
});

const s3Buckets = new S3Bucket(this, "complex-iterator-buckets", {
forEach: chainedIterators,
bucket: chainedIterators.getString("name"),
tags: chainedIterators.getStringMap("tags"),
});

const s3BucketsIterator = TerraformIterator.fromResources(s3Buckets);
const helpFile = new TerraformAsset(this, "help", {
path: "./help",
});
new S3BucketObject(this, "object", {
forEach: s3BucketsIterator,
bucket: s3BucketsIterator.getString("id"),
key: "help",
source: helpFile.path,
});

// DOCS_BLOCK_START:iterators,iterators-complex-types
}
}
Expand Down
64 changes: 64 additions & 0 deletions packages/cdktf/lib/terraform-iterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from "./complex-computed-list";
import { TerraformDynamicExpression } from "./terraform-dynamic-expression";
import { Fn } from "./terraform-functions";
import { ITerraformResource } from "./terraform-resource";
import {
FOR_EXPRESSION_KEY,
FOR_EXPRESSION_VALUE,
Expand Down Expand Up @@ -80,6 +81,26 @@ export abstract class TerraformIterator implements ITerraformIterator {
return new MapTerraformIterator(map);
}

/**
* Creates a new iterator from a resource that
* has been created with the `for_each` argument.
*/
public static fromResources(
resource: ITerraformResource
): ResourceTerraformIterator {
return new ResourceTerraformIterator(resource);
}

/**
* Creates a new iterator from a data source that
* has been created with the `for_each` argument.
*/
public static fromDataSources(
resource: ITerraformResource
): ResourceTerraformIterator {
return new ResourceTerraformIterator(resource);
}

/**
* @param attribute name of the property to retrieve
* @returns the given attribute of the current item iterated over as a string
Expand Down Expand Up @@ -284,3 +305,46 @@ export class MapTerraformIterator extends TerraformIterator {
return this._getValue();
}
}

// eslint-disable-next-line jsdoc/require-jsdoc
export class ResourceTerraformIterator extends TerraformIterator {
constructor(private readonly element: ITerraformResource) {
super();

if (element.count) {
throw new Error(
"Cannot create iterator from resource with count argument. Please use the same TerraformCount used in the resource passed here instead."
);
}

if (!element.forEach) {
throw new Error(
"Cannot create iterator from resource without for_each argument"
);
}
}

/**
* Returns the currenty entry in the list or set that is being iterated over.
* For lists this is the same as `iterator.value`. If you need the index,
* use count using the escape hatch:
* https://developer.hashicorp.com/terraform/cdktf/concepts/resources#escape-hatch
*/
public get key(): any {
return this._getKey();
}

/**
* Returns the value of the current item iterated over.
*/
public get value(): any {
return this._getValue();
}

/**
* @internal used by TerraformResource to set the for_each expression
*/
public _getForEachExpression(): any {
return this.element.fqn; // no wrapping necessary for resources
}
}

0 comments on commit 5792382

Please sign in to comment.