Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docs): document the use of aspects and annotations #1144

Merged
merged 1 commit into from
Oct 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ Choose a language:
- Writing own [remote templates](./docs/working-with-cdk-for-terraform/remote-templates.md) for init.
- Using [assets](./docs/working-with-cdk-for-terraform/terraform-assets.md) to transfer files into the Terraform context.
- Learn how to write [tests](./docs/working-with-cdk-for-terraform/testing.md).
- Use [Aspects](./docs/working-with-cdk-for-terraform/aspects.md) to transform bigger sets of resources or build validations.

<a name="maturity"></a>

Expand Down
59 changes: 59 additions & 0 deletions docs/working-with-cdk-for-terraform/aspects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Aspects

Aspects are a way to apply an operation to all constructs in a given scope, they can be used for mutation (e.g. adding tags to cloud resources) as well as for validation (e.g. ensuring all S3 Buckets are encrypted).

## Using aspects to mutate resources

In this example we write an Aspect that adds tags to resources.

```ts
import { Aspects, IAspect } from "cdktf";

export class TagsAddingAspect implements IAspect {
constructor(private tagsToAdd: Record<string, string>) {}

// This method is called on every Construct (resources / data sources / Terraform Elements)
visit(node: IConstruct) {
if (node.hasOwnProperty("tags")) {
const currentTags = node.tags || {};
node.tags = { ...currentTags, ...this.tagsToAdd };
}
}
}

// We can call the aspect on any scope.
// A scope could be a TerraformStack, TerraformElement or an entire Application
// depending on whet you want to use your aspect for
Aspects.of(myStack).add(new TagsAddingAspect({ createdBy: "cdktf" }));
```

## Using Aspects to validate resources

In this example we write an Aspect that validates if all S3 Buckets start with an allowed prefix

```ts
import { Aspects, IAspect, Annotations } from "cdktf";
import { S3 } from "./.gen/providers/aws";

export class ValidateS3IsPrefixed implements IAspect {
constructor(private prefix: string) {}

// This method is called on every Construct (resources / data sources / Terraform Elements)
visit(node: IConstruct) {
if (node instanceof S3.S3Bucket) {
if (node.bucket && !node.bucket.startsWith(this.prefix)) {
// addInfo / addWarning / addError are possible
// these messages will be printed when running synth / plan /deploy
Annotations.of(node).addError(
`Each S3 Bucket name needs to start with ${this.prefix}`
);
}
}
}
}

// We can call the aspect on any scope.
// A scope could be a TerraformStack, TerraformElement or an entire Application
// depending on whet you want to use your aspect for
Aspects.of(myStack).add(new ValidateS3IsPrefixed("myPrefix"));
```