4.3 Modern IaC: AWS CDK, SAM & Service Catalog Governance

Key Takeaways

  • The AWS Cloud Development Kit (CDK) models cloud applications using familiar programming languages, synthesizing construct trees (L1 Cfn primitives, L2 curated defaults, L3 architectural patterns) into standard CloudFormation templates.
  • CDK bootstrapping provisions essential staging resources (S3 asset bucket, ECR image repository, and IAM deployment/execution roles); cdk.context.json caches non-deterministic API lookups to guarantee reproducible CI/CD builds.
  • The CDK Aspect pattern leverages the Visitor design pattern (IAspect) to traverse all constructs recursively during synthesis, enforcing enterprise security guardrails (such as mandatory KMS encryption and required tagging) before templates are generated.
  • AWS Serverless Application Model (SAM) simplifies serverless engineering via the AWS::Serverless-2016-10-31 transform macro, built-in scoped policy templates, and local Docker-based emulation using sam local.
  • AWS Service Catalog provides self-service governance by bundling CloudFormation templates into versioned products within portfolios, using Launch Constraints (IAM service roles) to enable end users to provision resources without direct IAM infrastructure privileges.
Last updated: September 2026

Evolution of Modern Infrastructure as Code

While declarative YAML and JSON templates form the raw deployment mechanism of AWS CloudFormation, managing thousands of lines of boilerplate across microservices becomes cumbersome. Modern DevOps engineering incorporates higher-level abstractions that introduce object-oriented composition, unit testability, and standardized compliance guardrails.

For the AWS Certified DevOps Engineer - Professional (DOP-C02) exam, you must demonstrate mastery across three pillars of modern IaC:

  1. AWS Cloud Development Kit (CDK): An open-source software development framework to define cloud infrastructure using expressive programming languages (TypeScript, Python, Java, C#, Go) that compiles into native CloudFormation.
  2. AWS Serverless Application Model (SAM): A specialized framework and CLI optimized for serverless applications, offering macro transforms, policy templates, and local containerized testing.
  3. AWS Service Catalog: An enterprise governance service enabling organizations to create and curate pre-approved catalogs of CloudFormation templates, providing self-service provisioning to developers under strict least-privilege launch constraints.

AWS Cloud Development Kit (CDK): Architecture, Constructs & Lifecycle

The AWS CDK organizes cloud applications into an object-oriented construct hierarchy:

+-------------------------------------------------------------------------+
|                                 CDK App                                 |
|  - Root container representing the entire multi-stack application       |
|                                                                         |
|  +-----------------------+     +-------------------------------------+  |
|  |      Stack A          |     |              Stack B                |  |
|  | (Stateful / Database) |     |       (Stateless / Microservice)    |  |
|  |                       |     |                                     |  |
|  |  [L2: s3.Bucket]      |     |  [L3: ApplicationLoadBalanced...   |  |
|  |  [L2: rds.Database]   |     |       FargateService]               |  |
|  |                       |     |       ├── [L2: ecs.FargateTaskDef]  |  |
|  |  [L1: CfnParameter]   |     |       └── [L2: ec2.SecurityGroup]   |  |
|  +-----------+-----------+     +------------------+------------------+  |
|              |                                    |                     |
+--------------|------------------------------------|---------------------+
               v                                    v
      [cdk synth: App.synth()]             [cdk synth: App.synth()]
               │                                    │
               ▼                                    ▼
    [CloudFormation Template A]          [CloudFormation Template B]
    Stored in cdk.out/                   Stored in cdk.out/

The Three Construct Levels

Constructs are the basic building blocks of CDK applications. They are classified into three levels of abstraction:

  • Level 1 (L1 / Cfn* Primitives): Represent direct, 1-to-1 mappings to raw CloudFormation resource specifications (e.g., CfnBucket, CfnVPC, CfnInstance). They are auto-generated from the CloudFormation resource schema. Every property must be explicitly configured; they offer zero defaults or helper methods.
  • Level 2 (L2 / Curated AWS Constructs): Handcrafted, intent-based constructs developed by AWS (e.g., s3.Bucket, ec2.Vpc, iam.Role). L2 constructs incorporate security best practices by default (such as enabling S3 server-side encryption and blocking public access), automatically generate supporting boilerplate (such as subnets and route tables in a VPC), and provide ergonomic helper methods (e.g., myBucket.grantRead(myLambdaRole)).
  • Level 3 (L3 / Solution Patterns): Highly opinionated, multi-resource patterns that combine multiple AWS services into complete architectural solutions (e.g., aws-ecs-patterns.ApplicationLoadBalancedFargateService or aws-apigateway.LambdaRestApi).

The CDK Application Lifecycle

  1. Construction: The developer code executes, instantiating the construct tree in memory (creating instances of App, Stack, and child constructs).
  2. Preparation: Constructs that implement the prepare lifecycle or Aspects traverse the tree to perform final property mutations and validations.
  3. Validation: Constructs validate their internal configurations, throwing compilation or runtime errors if required parameters are missing or invalid.
  4. Synthesis (cdk synth): The CDK synthesizes the construct tree into declarative AWS CloudFormation templates, asset manifests, and metadata files written to the local cdk.out directory.
  5. Deployment (cdk deploy): The CDK CLI uploads synthesized assets to S3 and ECR, calls CloudFormation APIs to create change sets, and monitors stack execution.

Assets Management

CDK assets represent local artifacts referenced by constructs—such as a local directory of Python code for an AWS Lambda function, a zip file, or a local Dockerfile for an Amazon ECS task. During synthesis, the CDK hashes the asset directory contents to generate a unique fingerprint. If the contents change, a new asset bundle is created, uploaded to the CDK bootstrap S3 bucket or ECR repository, and referenced dynamically in the generated CloudFormation template.

Bootstrapping: The Modern Bootstrap Stack

Before a CDK application can be deployed into an AWS environment (a specific account and region combination), the environment must be bootstrapped via cdk bootstrap:

  • Provisions Shared Primitives: Deploys a CloudFormation stack named CDKToolkit containing:
    • An Amazon S3 bucket for file assets (Lambda code, nested templates).
    • An Amazon ECR repository for Docker container image assets.
    • IAM Roles with granular trust relationships: File Publishing Role, Image Publishing Role, Deployment Action Role, Lookup Role, and the CloudFormation Execution Role (cdk-*-cfn-exec-role).
    • An AWS Systems Manager Parameter Store parameter (/cdk-bootstrap/.../version) tracking bootstrap schema versions.
  • Modern vs. Legacy Bootstrapping: Modern bootstrapping supports strict least-privilege customization using the --cloudformation-execution-policies flag, replacing broad administrative assumptions with corporate-approved IAM policy ARNs.

Context & Deterministic Pipelines (cdk.context.json)

In continuous integration and deployment pipelines, infrastructure synthesis must be 100% deterministic. If a construct queries live AWS APIs (such as looking up an existing VPC via Vpc.fromLookup() or querying the latest Amazon Linux AMI via MachineImage.latestAmazonLinux()), running cdk synth without live AWS credentials or during network partitioning will fail.

  • How Context Caching Works: When a lookup method is first invoked, CDK queries the AWS account and caches the response locally in cdk.context.json.
  • Pipeline Requirement: The cdk.context.json file must be committed to version control. In the CI/CD pipeline, cdk synth uses the cached values without making outbound AWS API calls, guaranteeing reproducible synthesis across test, staging, and production environments.

Enterprise Policy Enforcement with CDK Aspects

An Aspect is an implementation of the Visitor design pattern within the CDK. Aspects allow security, compliance, and DevOps teams to apply transformations or validation checks across all constructs in an entire construct tree during the synthesis lifecycle.

How Aspects Work Under the Hood

An Aspect is a class implementing the IAspect interface, which defines a single visit(node: IConstruct) method. When an Aspect is applied to an App or Stack via Aspects.of(scope).add(myAspect), the CDK engine recursively visits every construct node in the tree prior to template synthesis.

import { IAspect, Annotations } from 'aws-cdk-lib';
import { CfnBucket } from 'aws-cdk-lib/aws-s3';
import { IConstruct } from 'constructs';

// Enterprise Compliance Aspect: Enforce KMS Encryption on all S3 Buckets
export class EnforceKmsBucketEncryption implements IAspect {
  public visit(node: IConstruct): void {
    if (node instanceof CfnBucket) {
      const encryption = node.bucketEncryption as CfnBucket.BucketEncryptionProperty;
      if (!encryption || !encryption.serverSideEncryptionConfiguration) {
        Annotations.of(node).addError(
          'Security Violation: All S3 buckets must define ServerSideEncryptionConfiguration with KMS.'
        );
      }
    }
  }
}

// Applied globally to the entire CDK App
const app = new App();
Aspects.of(app).add(new EnforceKmsBucketEncryption());

Production Use Cases for Aspects on DOP-C02

  • Mandatory Corporate Tagging: Automatically injecting required enterprise tags (Environment, CostCenter, ComplianceScope, Owner) across every taggable construct using the built-in cdk.Tags.of(app).add('CostCenter', 'Finance') Aspect.
  • Security Group Ingress Auditing: Inspecting all CfnSecurityGroup instances and failing synthesis (addError) if any rule specifies an inbound CIDR of 0.0.0.0/0 on port 22 or 3389.
  • Stateful Resource Deletion Policies: Enforcing that all production databases and storage volumes have their applyRemovalPolicy set to RemovalPolicy.RETAIN.

AWS Serverless Application Model (SAM)

AWS SAM is an open-source framework purpose-built for developing, testing, and deploying serverless applications. SAM extends CloudFormation using a native Transform Macro.

The Transform Header & Serverless Primitives

Every SAM template begins with the transform declaration:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Enterprise Serverless Order Processing Service

Resources:
  OrderProcessingFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: app.lambda_handler
      Runtime: python3.11
      MemorySize: 512
      Timeout: 15
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref OrdersTable
      Events:
        OrderApi:
          Type: Api
          Properties:
            Path: /orders
            Method: post

  OrdersTable:
    Type: AWS::Serverless::SimpleTable
    Properties:
      PrimaryKey:
        Name: order_id
        Type: String

When deployed, CloudFormation invokes the SAM macro, which expands the concise SAM syntax into full underlying CloudFormation resources: AWS::Serverless::Function expands into an AWS::Lambda::Function, an AWS::IAM::Role, and an AWS::Lambda::Permission, while the Api event source expands into an AWS::ApiGateway::RestApi, Deployment, Stage, and Method.

SAM Policy Templates

Instead of authoring complex IAM policy documents with raw JSON statements, SAM provides a large library of Policy Templates that grant scoped, least-privilege permissions:

  • S3ReadPolicy: { BucketName: !Ref MyBucket }
  • DynamoDBCrudPolicy: { TableName: !Ref MyTable }
  • SQSPollerPolicy: { QueueName: !GetAtt MyQueue.QueueName }
  • VPCAccessPolicy: {}

Local Testing and Emulation with the SAM CLI

A major advantage of AWS SAM tested on the DOP-C02 exam is local simulation using the local Docker engine:

  • sam build: Resolves language dependencies, compiles code, and stages deployment artifacts in .aws-sam/build.
  • sam local invoke: Executes a Lambda function locally inside a Docker container mimicking the AWS Lambda execution environment, passing a synthetic event payload (e.g., sam local invoke FunctionName -e event.json).
  • sam local start-api: Spawns a local HTTP server emulating Amazon API Gateway on localhost:3000, routing incoming HTTP requests to locally executing Lambda containers.
  • sam local generate-event: Generates mock event JSON payloads for dozens of AWS services (S3, SQS, Kinesis, SNS, API Gateway).

AWS Service Catalog: Portfolios, Products & Launch Constraints

Enterprise organizations struggle with two competing demands: developers require self-service velocity to spin up infrastructure without waiting for operations tickets, while security teams mandate strict guardrails preventing misconfigurations and credential sprawl.

AWS Service Catalog solves this dilemma by enabling administrators to manage catalogs of approved, compliant IT services provisioned via CloudFormation.

+-------------------------------------------------------------------------+
|                     Central IT / Security Team                          |
|  - Creates compliant CloudFormation templates (Approved EMR, RDS, EC2)   |
|  - Packages templates into Service Catalog Products and Portfolios      |
|  - Associates Launch Role Constraint (IAM Role with resource privileges)|
+------------------------------------+------------------------------------+
                                     |
                                     v Shares Portfolio via AWS Organizations / RAM
+-------------------------------------------------------------------------+
|                    Member / Developer Account                           |
|                                                                         |
|  +---------------------+                                                |
|  | End User Developer  |                                                |
|  | IAM: ReadOnlyAccess |                                                |
|  +----------+----------+                                                |
|             | 1. Discovers Product in Service Catalog                   |
|             | 2. Calls servicecatalog:ProvisionProduct                  |
|             v                                                           |
|  +-------------------------------------------------------------------+  |
|  | AWS Service Catalog Engine                                        |  |
|  | - Assumes configured Launch Constraint IAM Role                   |  |
|  | - Enforces Template Constraint Rules (e.g., t3.medium only)       |  |
|  +----------------------------------+--------------------------------+  |
|                                     |                                   |
|                                     v 3. Provisions Stack using Launch Role
|  +-------------------------------------------------------------------+  |
|  | Deployed CloudFormation Stack (Physical Resources)                |  |
|  +-------------------------------------------------------------------+  |
+-------------------------------------------------------------------------+

Core Service Catalog Entities

  1. Product: A blueprint representing an IT service, packaged from an AWS CloudFormation template (or Terraform configuration). Products support semantic versioning through product versions (artifacts).
  2. Portfolio: A logical collection of products. Administrators configure user access to portfolios by associating IAM roles, IAM groups, or IAM Identity Center principals.
  3. Launch Constraint (The Critical DOP-C02 Pattern):
    • The Governance Problem: If developers need to provision Amazon SageMaker notebooks or Amazon RDS databases, granting them direct IAM permissions (sagemaker:*, rds:*, iam:PassRole) exposes the account to unauthorized modifications or privilege escalation.
    • The Launch Constraint Solution: An administrator defines a Launch Role (an IAM service role) attached to the product or portfolio. When an end user provisions the product, AWS Service Catalog assumes the Launch Role to deploy the underlying CloudFormation stack.
    • Least Privilege Achieved: The end user needs only permissions to access the Service Catalog portfolio (servicecatalog:*). They possess zero direct permissions to create S3 buckets, launch EC2 instances, or provision databases!
  4. Template Constraints & Rules: Enforce parameter restrictions at launch time. For example, a template constraint can restrict the InstanceType parameter to an approved list (t3.small, t3.medium) or mandate specific corporate VPC subnets based on environment tags.

Multi-Account Portfolio Distribution

Portfolios can be shared across an entire enterprise using AWS Organizations integration or AWS Resource Access Manager (RAM):

  • The master catalog account shares the portfolio with an entire Organization, an OU, or specific member accounts.
  • In recipient accounts, administrators accept the portfolio and associate local IAM roles or Identity Center groups to enable developer self-service.

Comparison: Modern IaC Paradigms

FeatureAWS CDKAWS SAMAWS Service Catalog
Language / SyntaxTypeScript, Python, Java, C#, GoYAML / JSON (with SAM macro)CloudFormation / Terraform templates
Primary Use CaseFull-stack cloud applications & infrastructureServerless microservices (Lambda, API GW, DynamoDB)Enterprise self-service provisioning & governance
Abstraction LevelHigh (L2/L3 constructs, programmatic logic)Medium (Serverless transform abstractions)Low/Medium (Pre-packaged template governance)
Local EmulationUnit testing via assertions frameworkDocker-based local API/Lambda emulation (sam local)None (Delegates to AWS provisioning)
Access ControlDeveloper IAM credentials deploy stacksDeveloper IAM credentials deploy stacksLaunch Constraints (Users need no direct infra IAM)

Current Status of AWS OpsWorks

The DOP-C02 blueprint names configuration-management services and strategies, and older exam material can mention AWS OpsWorks as the managed Chef/Puppet or stack-oriented choice. That is now historical context: AWS lists OpsWorks, OpsWorks Stacks, OpsWorks for Chef Automate, and OpsWorks for Puppet Enterprise as fully shut down in 2024 and unavailable to new and existing customers.

For a current design, choose the replacement by responsibility:

  • AWS Systems Manager State Manager, Run Command, Patch Manager, and Distributor apply desired state, commands, patches, and packages to managed nodes.
  • AWS AppConfig deploys validated runtime application configuration with monitors and rollback.
  • CloudFormation or CDK plus EC2 Auto Scaling replaces the infrastructure and lifecycle portions of an older OpsWorks Stacks design.
  • If an organization still requires Chef or Puppet semantics, operate a supported vendor/SaaS or self-managed implementation rather than proposing the retired OpsWorks service.

On a current scenario, an answer that provisions a new OpsWorks stack or managed Chef/Puppet server is invalid even if the configuration-management concept sounds familiar. Separate the tested concept—declarative, repeatable desired state—from the retired product name.

Loading diagram...
Modern IaC Synthesis and Service Catalog Governance Workflow
Test Your Knowledge

A lead DevOps engineer is tasked with enforcing corporate compliance across all infrastructure developed using the AWS CDK. The requirement mandates that every Amazon S3 bucket created across 15 engineering teams must have AWS KMS Customer Managed Key (CMK) server-side encryption enabled. If a developer attempts to synthesize a stack containing an unencrypted bucket or an S3-managed key (SSE-S3), the synthesis must fail with an informative error before CloudFormation templates are generated. How can this be implemented centrally?

A
B
C
D
Test Your Knowledge

A financial enterprise requires data scientists to provision standardized, pre-approved Amazon EMR clusters and S3 analytics buckets. Corporate security mandates that data scientists must not possess direct IAM permissions to create, update, or terminate EMR clusters, S3 buckets, or IAM roles in the AWS account. How can the DevOps engineer configure AWS Service Catalog to enable self-service provisioning while strictly adhering to the principle of least privilege?

A
B
C
D
Test Your Knowledge

A DevOps team manages an AWS CDK application deployed through an isolated CI/CD pipeline running in AWS CodeBuild. The CDK application utilizes Vpc.fromLookup() to retrieve configuration details for an existing production VPC. When the pipeline runs cdk synth inside an isolated build container that intentionally lacks network access to the target AWS account's EC2 describe APIs, the synthesis fails with an error stating that account lookups cannot be performed without valid credentials. How should the DevOps engineer resolve this issue while maintaining an isolated build environment?

A
B
C
D