AWS DevOps & Developer Productivity Blog
Streamlining Cloud Compliance at GoDaddy Using CDK Aspects
This is a guest post written by Jasdeep Singh Bhalla from GoDaddy.
AWS Cloud Development Kit (CDK) Aspects are a powerful mechanism that allows you to apply organization-wide policies, like security rules, tagging standards, and compliance requirements across your entire infrastructure as code. By implementing the Visitor pattern, Aspects can inspect and modify every construct in your CDK application before it’s synthesized into AWS CloudFormation templates, enabling you to enforce organizational standards automatically at build time.
At GoDaddy, we’ve used CDK Aspects to transform how we enforce compliance across our massive AWS footprint. Our Cloud Governance team is responsible for ensuring every AWS resource deployed across thousands of accounts adheres to strict security, compliance, and operational standards.
We have a simple goal:
Make it easy for developers to do the right thing without slowing them down.
Traditionally, we relied on documentation, Slack threads, and peer reviews to flag misconfigurations. But as our cloud footprint grew, this approach quickly hit its limits. It simply didn’t scale.
We needed something proactive.
From reactive to proactive: CloudFormation Hooks
Our first major leap forward came through CloudFormation Hooks. These allow us to validate every resource in a CloudFormation template against our compliance rules at deployment time. If a resource passes, it gets deployed. If not, the deployment is blocked, and we provide developers with clear, actionable error messages to help them fix the template.
This worked well, but it wasn’t perfect. Developers would often only discover issues after writing their entire templates using manual values to make the template compliant, and attempting deployment. This was a time-consuming process, and it was not a good developer experience.
We needed an automated way to make CloudFormation templates compliant with our compliance rules without manual effort.
This is where CDK Aspects come in.
CDK Aspects: compliance while you code
CDK Aspects are our answer to proactive, early-stage compliance enforcement — catching and resolving issues at the code level, before deployment.
In AWS CDK, an Aspect is a lightweight Visitor that can inspect and act on every construct in your infrastructure code before it’s synthesized into a CloudFormation template. This means you can apply organization-wide rules as developers write CDK code, not after.
Think of it as linting for your infrastructure.
Want to ensure all Amazon Simple Storage Service (Amazon S3) buckets have encryption enabled? Require specific tags on resources? Block public access on security groups? With CDK Aspects, all of that becomes not only possible, but automatic.
Under the hood: how CDK Aspects work
CDK Aspects are a powerful mechanism for inspecting and modifying your infrastructure as code. At their core, they use the Visitor Pattern, which allows you to traverse a tree of objects (constructs) and perform operations on each node without modifying the constructs themselves directly.
Interface IAspect
An Aspect is a class that implements the IAspect interface:
interface IAspect {
visit(node: IConstruct): void;
}
The single visit() method is called for every construct in the scope where the Aspect is applied. Inside visit(), you can inspect, modify, or enforce rules on the construct.
Adding Aspects
To attach an Aspect to a construct (or a tree of constructs), use the following method:
Aspects.of(myConstruct).add(new SomeAspect());
This adds the Aspect to the construct’s internal list.
When cdk deploy is run, a CDK app goes through several phases:
Figure 1: CDK app lifecycle from source code to deployment
- Construction – Constructs are instantiated.
- Preparation – Final modifications and Aspects are applied.
- Validation – Checks for invalid configurations.
- Synthesis – CloudFormation templates are generated.
- Deployment – Resources are provisioned in AWS.
Aspects are executed during the Preparation phase, which happens automatically. This ensures all rules, validations, or mutations are applied before synthesis, so your generated CloudFormation templates are compliant and valid before deployment.
During the Preparation phase of the CDK lifecycle, CDK traverses the construct tree and calls visit() on each node in top-down order (parent → children). Inside visit(), you can inspect, modify, or enforce rules on the construct.
visit(node: IConstruct) {
if (node instanceof s3.Bucket) {
node.encryption = s3.BucketEncryption.KMS; // Mutates the resource
}
}
Example: CDK Aspects to automatically add S3 Encryption to all S3 buckets in a stack by mutating the resource.
class EnforceBucketEncryption implements IAspect {
visit(node: IConstruct) {
if (node instanceof s3.Bucket) {
node.encryption = s3.BucketEncryption.KMS; // Mutates the resource
}
}
}
This aspect can be registered on the stack by calling the following method:
Aspects.of(this).add(new EnforceBucketEncryption());
The template generated by CDK will look something like this:
Resources:
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
From the example above, you can see that the BucketEncryption property is added to the MyBucket resource by the Aspect.
During the prepare phase, CDK traverses the construct tree from top to bottom – starting at the App, then each Stack, and down to resources like S3 buckets. At each node, Aspects are applied by invoking aspect.visit(node), allowing inspection and modification of resources. By the time CDK reaches the synth step, the CloudFormation template already includes these Aspect-driven changes, ensuring compliance and best practices are consistently enforced before deployment.
Types of CDK Aspects
AWS CDK distinguishes between two types of Aspects based on how they interact with your infrastructure: those that modify resources (mutating) and those that only inspect them (read-only).
Mutating Aspects
Mutating Aspects modify resources automatically (like adding encryption or logging). These change the properties of resources as they traverse your constructs. They are ideal for enforcing compliance and best practices like:
- Enforcing AWS Key Management Service (AWS KMS) encryption on S3 buckets
- Setting default timeouts on AWS Lambda functions
- Changing RemovalPolicy in test stacks
Mutating Aspects are powerful, but overusing them can introduce unintended changes, because they modify resources without explicit developer action.Always make sure you are aware of the changes, and avoid applying them to production resources without caution. Use logging or annotations to help you understand and debug the changes.
For example, the following aspect sets the default timeout on all Lambda functions to 300 seconds:
class SetDefaultTimeouts implements IAspect {
visit(node: IConstruct) {
if (node instanceof lambda.Function) {
node.timeout = 300; // mutates the resource
}
}
}
Read-only Aspects
Read-only Aspects only inspect resources and report findings without modifying them. They’re ideal for compliance checks, tagging audits, and policy validation.
class RequireTags implements IAspect {
visit(node: IConstruct) {
const tags = Tags.of(node);
if (!tags.hasTag("project_budget_number")) {
Annotations.of(node).addWarning(
"Missing required tag: project_budget_number",
);
}
}
}
At GoDaddy, we use mutating Aspects to enforce compliance automatically, reducing manual work and ensuring stacks are compliant with our standards by default. We add read-only Aspects for stricter audits where mutation isn’t appropriate.
Common use cases for CDK Aspects
When building cloud infrastructure at scale, enforcing consistency across stacks can be an ongoing challenge. AWS CDK Aspects let you automatically enforce security, compliance, and operational standards across your entire infrastructure.
Below are some of the most impactful use cases where Aspects can save you time, reduce risk, and improve governance.
- Security & compliance: Security and compliance go hand in hand, and Aspects are a powerful way to enforce both before resources ever reach AWS. With Aspects, you can:
- Enforce encryption on S3 buckets, Amazon Relational Database Service (Amazon RDS) databases, and Amazon Elastic Block Store (Amazon EBS) volumes
- Require versioning on S3 buckets
- Flag wildcard * permissions in Identity and Access Management (IAM) policies
- Validate that required tags (like cost allocation tags) are present
- IAM policies: Aspects make it trivial and consistent across all stacks to apply the same permissions boundary to every IAM role.
- Tagging enforcement: Tags are the backbone of cost allocation, compliance, and automation. Yet, they’re easy to forget. With Aspects, you can enforce required tags across every resource.
- Operational best practices: Use Aspects to enforce sensible defaults and operational hygiene:
- Set Lambda function timeouts and memory sizes
- Ensure logging is enabled for S3, Amazon API Gateway(API Gateway), and AWS CloudTrail (CloudTrail)
- Testing made easier: You can use Aspects to override the default RemovalPolicy for test stacks to DESTROY, ensuring everything is cleaned up automatically.
- Working around 3rd-party constructs: Sometimes external constructs create resources you can’t fully configure, like an S3 bucket without encryption or logging options. Instead of waiting on maintainers or forking the library, you can apply an Aspect to modify those resources directly.
- Network policies: Networking issues often lead to security incidents. With Aspects, you can:
- Validate resources are deployed in approved Amazon Virtual Private Cloud (Amazon VPC) or subnets
- Prevent accidental public IP assignments
- Cost control: Budgets matter. Aspects can help by:
- Flagging high-cost instance types before deployment
- Limiting use of expensive storage classes
- Warning when provisioned throughput exceeds thresholds
You can combine these use cases into reusable, testable policies that run consistently across all CDK stacks.
CDK Aspects in action at GoDaddy
At GoDaddy, we define CDK Aspects and distribute them through a wrapper Stack that development teams use when building infrastructure with CDK. Every template a team creates is automatically made compliant with GoDaddy’s cloud compliance rules, without requiring manual updates or fixes.
As an example, some of the Aspects are:
- S3BucketAspect – Enforces encryption, logging, and public access block on S3 buckets.
- IAMRoleAspect – Flags wildcard permissions and enforces naming conventions.
- LambdaFunctionAspect – Validates timeouts, memory limits, and Amazon VPC configurations.
These Aspects enforce security, operational, and tagging standards at the code level. When you use the wrapper stack, the relevant Aspects are applied automatically, injecting the necessary properties into the CloudFormation template before deployment. This is intended to support compliance without slowing down development.
Each of these aspects implements the IAspect interface and is applied to stacks directly:
Aspects.of(myStack).add(new S3BucketAspect());
Aspects.of(myStack).add(new IAMRoleAspect());
Aspects.of(myStack).add(new LambdaFunctionAspect());
This approach means that when a developer defines a new resource, like an S3 bucket or IAM role, all relevant compliance rules are automatically applied:
const bucket = new s3.Bucket(myStack, "MyBucket", {
// developer doesn't need to manually configure encryption or logging
});
During the CDK preparation phase, the aspect injects the required properties into the CloudFormation template, which is done before the template is synthesized and deployed. This ensures that the resources are deployed with the required properties at GoDaddy’s standards.
# s3-bucket.yaml - generated by `cdk synth`
Resources:
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
LoggingConfiguration:
DestinationBucketName: logging-bucket
LogFilePrefix: logs/
Consider a team that deploys hundreds of S3 buckets per month, where each bucket requires encryption, logging, versioning, and public access block. With CDK Aspects, you don’t have to manually update the CloudFormation template to add the required properties.
This saves a lot of engineering effort and time, and ensures that the resources are deployed with the required properties that meet GoDaddy’s standards.
Conclusion
At GoDaddy, CDK Aspects have significantly transformed our approach to cloud infrastructure compliance.
Because Aspects run during the CDK preparation phase, before synthesis and deployment, they inject required properties like encryption, logging, and access controls into CloudFormation templates automatically. Developers write their CDK code as usual, and compliance happens behind the scenes. This eliminates the manual effort of configuring each resource to meet security and compliance standards.
This proactive approach has also improved developer productivity. Instead of discovering compliance failures after attempting deployment (as was the case with CloudFormation Hooks alone), developers now get compliant templates on the first synthesis. Fewer failed deployments mean faster iteration cycles and less time spent debugging configuration issues.
Policy enforcement is consistent because every team uses the same wrapper Stack with the same Aspects applied. Whether a team deploys an S3 bucket, an IAM role, or a Lambda function, the same tagging, encryption, network isolation, and cost control rules are applied uniformly.
Finally, this model scales. Adding a new compliance rule means updating a single Aspect in the shared library, and every stack that uses the wrapper inherits the change automatically. This lets our Cloud Governance team enforce standards across thousands of accounts with minimal operational overhead.
If you’re working with AWS CDK at scale, adopting CDK Aspects isn’t just a nice-to-have, it’s essential. Your future self and your security team will thank you.
To get started, pick one compliance rule, like S3 encryption, and implement it as a mutating Aspect. Once you see how it works, expand to cover tagging and IAM policies. From there, package your Aspects into a shared library that teams across your organization can adopt.
References
- AWS CDK – Basics of AWS Cloud Development Kit
- AWS CDK Constructs – Learn to build your own Constructs
- AWS CDK Aspects – How to use AWS CDK Aspects
- Visitor Design Pattern – More about Visitor Design Pattern
The content and opinions in this blog are those of the third-party author and AWS is not responsible for the content or accuracy of this blog.