From 3f721622b3cce1ddc2c5178c177b07cc40b393c9 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Thu, 14 Oct 2021 16:27:56 +0200 Subject: [PATCH] feat(docs): document the use of aspects and annotations --- README.md | 1 + .../working-with-cdk-for-terraform/aspects.md | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 docs/working-with-cdk-for-terraform/aspects.md diff --git a/README.md b/README.md index ce49ecc85b..b0a4817190 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/docs/working-with-cdk-for-terraform/aspects.md b/docs/working-with-cdk-for-terraform/aspects.md new file mode 100644 index 0000000000..99d23bd0a9 --- /dev/null +++ b/docs/working-with-cdk-for-terraform/aspects.md @@ -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) {} + + // 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")); +```