AWS DevOps Masterclass: Orchestrating Continuous Delivery with AWS CodePipeline
A comprehensive, enterprise-grade guide to designing, building, securing, and scaling automated continuous delivery pipelines on AWS.
Table of Contents
- 1. Introduction to Enterprise Continuous Delivery
- 2. What You Will Learn
- 3. Prerequisites
- 4. AWS CodePipeline Architecture & Core Concepts
- 5. Architectural Blueprints & Workflows
- 6. Action Types & Execution Models
- 7. Advanced Enterprise Patterns: Multi-Account & Cross-Region
- 8. Production-Grade IaC: Complete Terraform Implementation
- 9. Production-Grade IaC: Complete CloudFormation Template
- 10. Blue/Green, Canary, and GitOps Integrations
- 11. Security, Compliance, and Governance
- 12. Observability, Metrics, and Event-Driven Automation
- 13. Troubleshooting & Common Failure Modes
- 14. Real-World Enterprise Case Study
- 15. Advanced Interview Questions & Answers
- 16. Frequently Asked Questions (FAQs)
- 17. Summary & Next Steps
1. Introduction to Enterprise Continuous Delivery
Continuous Delivery (CD) is the backbone of modern software engineering. It represents the capability to deploy software updates of all typesâincluding features, configuration changes, bug fixes, and experimentsâinto production or into the hands of users safely, quickly, and sustainably. In an enterprise environment, continuous delivery cannot be a simple script that copies files to a server. It must be a highly resilient, secure, audited, and observable process.
On AWS, the primary tool for orchestrating this process is AWS CodePipeline. AWS CodePipeline is a fully managed continuous delivery service that helps you automate your release pipelines for fast and reliable application and infrastructure updates. It models, visualizes, and automates the steps required to release your software.
Featured Snippet Definition:
AWS CodePipeline is a fully managed, continuous delivery service that automates the release pipelines for application and infrastructure updates. It operates as a workflow engine that coordinates the flow of software changes through various phasesâsuch as Source, Build, Test, and Deployâintegrating with AWS services (like CodeCommit, CodeBuild, CodeDeploy, ECS, EKS, and CloudFormation) as well as third-party tools (like GitHub, Jenkins, and Snyk) to deliver software fast, securely, and with high predictability.
Unlike traditional self-hosted CI/CD servers, AWS CodePipeline is serverless. This means you do not need to provision, configure, patch, or scale any underlying infrastructure to manage your release workflows. It scales dynamically with your deployment frequency, provides native integrations with AWS Identity and Access Management (IAM), and natively encrypts artifacts at rest using AWS Key Management Service (KMS).
In this guide, we will move beyond basic "Hello World" pipelines. We will explore how to architect production-grade pipelines that span multiple AWS accounts, cross physical AWS regions, implement zero-downtime deployment strategies, and enforce strict enterprise compliance rules.
2. What You Will Learn
By the end of this comprehensive guide, you will be able to:
- Architect multi-account, cross-region continuous delivery pipelines using AWS CodePipeline.
- Implement infrastructure as code (IaC) definitions for pipelines using both Terraform and AWS CloudFormation.
- Understand and configure complex IAM permission models, cross-account assume-roles, and KMS key policies for secure artifact sharing.
- Design advanced deployment strategies including Blue/Green, Canary, and rolling updates across ECS, EKS, Lambda, and EC2.
- Implement real-time monitoring, alerting, and event-driven automation for your pipeline lifecycle events.
- Diagnose and remediate complex pipeline failures, including artifact decryption errors, IAM role mismatches, and deployment timeouts.
3. Prerequisites
To get the most out of this masterclass lesson, you should possess the following foundational knowledge:
- AWS Core Services: Familiarity with IAM, S3, KMS, CloudWatch, and EventBridge.
- CI/CD Concepts: Understanding of version control (Git), continuous integration (compiling, linting, testing), and continuous deployment.
- Infrastructure as Code (IaC): Basic knowledge of Terraform syntax or AWS CloudFormation template structures.
- Containerization: Understanding of Docker, Amazon ECS, or Amazon EKS is highly beneficial for the deployment sections of this guide.
If you need a refresher on basic AWS DevOps concepts, we highly recommend reading our previous lesson on Introduction to AWS CodePipeline before continuing.
4. AWS CodePipeline Architecture & Core Concepts
To build reliable pipelines, you must master the building blocks of AWS CodePipeline. The service operates on a structured hierarchical model consisting of Pipelines, Stages, Actions, Transitions, Artifacts, and Variables.
Pipelines
A pipeline is a workflow construct that describes how software changes go through a release process. It is uniquely named within an AWS account and region, and it is associated with a service role that gives CodePipeline permission to orchestrate the resources involved in the workflow.
Stages
A pipeline is divided into logical segments called stages. Examples of stages include Source, Build, Staging-Deploy, Manual-Approval, and Production-Deploy. Every stage must contain at least one action, and all actions within a stage must complete successfully before the pipeline execution can progress to the next stage.
Actions
An action is a highly specific task performed on your application code or infrastructure in a given stage. Actions can run sequentially or in parallel. You configure execution order using the RunOrder parameter. For example, you can run three unit test suites in parallel by assigning them all a RunOrder of 1, and then run an integration test suite only after they succeed by assigning it a RunOrder of 2.
Transitions
Stages are connected by transitions, represented visually as arrows between stages. Transitions can be enabled or disabled. Disabling a transition prevents executions from progressing past that point. This is an excellent operational tool when you need to freeze deployments to an environment (e.g., during a major database migration or holiday code freeze) without stopping the source-control integration and build stages.
Artifacts
CodePipeline passes data between stages using artifacts. An artifact can be a ZIP file containing source code, compiled binaries, deployment manifests, or environment configurations.
Every pipeline must be configured with an Artifact Store, which is an Amazon S3 bucket. CodePipeline automatically uploads, downloads, and manages the versioning of these artifacts in the background.
When an action runs, it specifies one or more InputArtifacts and produces one or more OutputArtifacts. CodePipeline handles the retrieval of the input artifact from the S3 bucket and presents it to the action provider, and then captures the output artifact and writes it back to S3.
Variables
CodePipeline supports dynamic variables. Actions can emit variables during execution (such as the Git commit hash, build ID, or output variables from a CloudFormation stack deployment). Subsequent stages and actions can reference these variables using the syntax #{namespace.variable_name}, enabling dynamic configuration changes during execution.
Execution Modes
CodePipeline supports different execution modes that dictate how concurrent changes are handled:
- SUPERSEDED (Default): If a new execution starts while an older execution is still running in an earlier stage, the newer execution will "catch up" and supersede the older one at the transition point. The older execution is stopped. This ensures that you are always deploying the latest code and saves compute resources.
- QUEUED: Executions are processed sequentially in the order they are triggered. This is critical for deployments that modify persistent state (like database schemas) where concurrent or skipped executions could cause data corruption.
- PARALLEL: Allows multiple executions to run concurrently through the pipeline stages. This is useful for high-throughput testing pipelines but requires careful isolation of target environments to prevent resource conflicts.
5. Architectural Blueprints & Workflows
To visualize how these components interact in an enterprise environment, let us look at two architecture diagrams. The first diagram shows an event-driven, single-region pipeline. The second diagram shows a highly secure, multi-account deployment pipeline spanning three AWS accounts (Tooling, Staging, and Production).
Workflow 1: Event-Driven Single-Region Pipeline
+-------------------------------------------------------------------------------------------------------------------------+
| AWS Region (us-east-1) |
| |
| +------------------+ +--------------------+ +----------------------+ +-------------------------------+ |
| | GitHub Repo | | EventBridge Rule | | AWS CodePipeline | | S3 Artifact Store | |
| | (CodeStar Conn) | ---> | (Trigger on Push) | ---> | (Orchestration Flow) | <==> | (Encrypted with KMS CMK Key) | |
| +------------------+ +--------------------+ +----------------------+ +-------------------------------+ |
| | |
| | (Coordinates Stages) |
| v |
| +----------------------------+ |
| | Stage 1: Source | |
| | - Pull from GitHub | |
| +----------------------------+ |
| | |
| v |
| +----------------------------+ |
| | Stage 2: Build & Test | |
| | - AWS CodeBuild (Unit Tests) |
| +----------------------------+ |
| | |
| v |
| +----------------------------+ |
| | Stage 3: Manual Approval | |
| | - SNS Notification to SecOps |
| +----------------------------+ |
| | |
| v |
| +----------------------------+ |
| | Stage 4: Deploy | |
| | - ECS / Lambda Deployment | |
| +----------------------------+ |
+-------------------------------------------------------------------------------------------------------------------------+
Workflow 2: Multi-Account Pipeline Architecture
This diagram illustrates an enterprise pattern where the pipeline resides in a central Tooling/Shared Services Account and deploys applications safely to isolated Staging and Production accounts using IAM role assumption and cross-account KMS decryption key permissions.
+-------------------------------------------------------------------------------------------------------------------------+
| AWS ORGANIZATIONS STRUCTURE |
| |
| +-------------------------------------------------------------------------------------------------------------------+ |
| | [TOOLING ACCOUNT] (111111111111) | |
| | | |
| | +--------------------+ +--------------------------+ | |
| | | AWS CodePipeline | ---> | S3 Artifact Store | | |
| | | (Pipeline Role) | | (KMS CMK Encrypted) | | |
| | +--------------------+ +--------------------------+ | |
| | | | | |
| | | (Assume Cross-Account Role) | (Grants Read Access via Bucket & Key Policies) | |
| +-----------|-------------------------------|-----------------------------------------------------------------------+ |
| | | |
| | | |
| v v |
| +-------------------------------------------------------+ +-------------------------------------------------------+ |
| | [STAGING ACCOUNT] (222222222222) | | [PRODUCTION ACCOUNT] (333333333333) | |
| | | | | |
| | +----------------------------+ | | +----------------------------+ | |
| | | Deployment IAM Role | | | | Deployment IAM Role | | |
| | | (Trusts Tooling Account) | | | | (Trusts Tooling Account) | | |
| | +----------------------------+ | | +----------------------------+ | |
| | | | | | | |
| | v | | v | |
| | +----------------------------+ | | +----------------------------+ | |
| | | Target Resources | | | | Target Resources | | |
| | | (ECS, Lambda, S3) | | | | (ECS, Lambda, S3) | | |
| | +----------------------------+ | | +----------------------------+ | |
| +-------------------------------------------------------+ +-------------------------------------------------------+ |
+-------------------------------------------------------------------------------------------------------------------------+
6. Action Types & Execution Models
AWS CodePipeline classifies workflow actions into six distinct categories. Understanding the configuration properties and best practices for each category is essential for designing high-performance pipelines.
| Action Category | Common Providers | Key Input Parameters | Typical Output Artifacts | Enterprise Best Practice |
|---|---|---|---|---|
| Source | GitHub (via CodeStar), S3, CodeCommit, ECR | RepositoryName, BranchName, ConnectionArn | SourceArtifact | Use CodeStar Source Connections instead of legacy GitHub OAuth webhooks. Turn on EventBridge-based triggering. |
| Build | AWS CodeBuild, Jenkins | ProjectName, EnvironmentVariables | BuildArtifact | Run security scans (Snyk, SonarQube) inside your CodeBuild step. Keep build timeouts short. |
| Test | AWS CodeBuild, AWS Device Farm | ProjectName, TestType | TestReports | Run multiple test suites in parallel using the same RunOrder to speed up feedback loops. |
| Deploy | AWS CodeDeploy, CloudFormation, ECS, S3 | StackName, ClusterName, ServiceName | None (or DeployResult) | Use CloudFormation change sets to preview infrastructure changes before executing them. |
| Approval | Manual (SNS integration) | NotificationArn, ExternalEntityLink | None | Set up custom IAM permissions to restrict approval actions to authorized operations personnel. |
| Invoke | AWS Lambda, Step Functions | FunctionName, UserParameters | FunctionResult | Use Step Functions to orchestrate complex database migrations and rollbacks during deployment. |
Deep Dive on CodeStar Connections (GitHub v2 Integration)
Historically, connecting AWS CodePipeline to GitHub required generating personal access tokens (PATs) and storing them as plain-text secrets or using S3-based polling. This approach had serious security and scalability drawbacks. The modern, secure approach is AWS CodeStar Source Connections. CodeStar Connections use OAuth app permissions managed directly inside your GitHub Organization settings. This ensures:
- No long-lived GitHub tokens are stored in AWS.
- Finer-grained access control can be applied at the GitHub organization level.
- Automatic, event-driven webhooks are configured under the hood without manual API setup.
Dynamic Pipeline Variables
Variables allow you to build dynamic, parameter-driven workflows. For example, when using a GitHub source action, CodePipeline automatically generates variables like CommitId, BranchName, and AuthorDate.
You can reference these variables in downstream actions. For example, you can pass the Git commit ID as an environment variable to CodeBuild to tag your Docker images:
# Example snippet of referencing a variable in a downstream action
EnvironmentVariables: !Sub |
[
{"Name": "GIT_COMMIT_HASH", "Type": "PLAINTEXT", "Value": "#{SourceVariables.CommitId}"}
]
7. Advanced Enterprise Patterns: Multi-Account & Cross-Region
In a production-ready enterprise AWS setup, resource isolation is paramount. Deploying dev, staging, and production environments inside a single AWS account is an anti-pattern. If a developer accidentally runs a destructive command or misconfigures an IAM policy, it could compromise or take down production systems. The industry standard is to use AWS Organizations to separate workloads into distinct accounts.
To orchestrate deployments across these boundaries, CodePipeline must be configured for multi-account access. This design relies on three security pillars: Cross-Account IAM Roles, Cross-Account KMS Cryptographic Keys, and Cross-Account S3 Bucket Policies.
1. Cross-Account IAM Roles
The pipeline runs in the Tooling Account (e.g., 111111111111). When it reaches a deployment stage targeting the Production Account (e.g., 333333333333), CodePipeline does not call production APIs directly using its own pipeline role. Instead, it assumes a pre-existing deployment role in the Production Account.
This deployment role must have a trust policy that allows the Tooling Account's CodePipeline service role to assume it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/tooling-codepipeline-service-role"
},
"Action": "sts:AssumeRole"
}
]
}
2. Cross-Account KMS Cryptographic Keys
By default, S3 buckets use SSE-S3 encryption or the default AWS-managed KMS key (aws/s3). However, AWS-managed keys cannot be shared across AWS accounts.
To allow the Production Account to read artifacts from the Tooling Account's S3 bucket, you must encrypt the S3 bucket using a Customer Managed Key (CMK) in the Tooling Account, and configure a key policy that grants decryption rights to the Production deployment role.
Here is the KMS Key Policy template that must be applied to the CMK in the Tooling Account:
{
"Version": "2012-10-17",
"Id": "cross-account-kms-key-policy",
"Statement": [
{
"Sid": "AllowLocalAdministration",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AllowCrossAccountAccessToTargetRoles",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::222222222222:role/staging-deployment-role",
"arn:aws:iam::333333333333:role/production-deployment-role"
]
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": "*"
}
]
}
3. Cross-Account S3 Bucket Policies
The S3 bucket in the Tooling Account must also grant explicit read/write access to the cross-account deployment roles. Without this, even with valid KMS permissions, S3 will block access.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountReadWriteAccess",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::222222222222:role/staging-deployment-role",
"arn:aws:iam::333333333333:role/production-deployment-role"
]
},
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:PutObject",
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::tooling-codepipeline-artifacts-bucket",
"arn:aws:s3:::tooling-codepipeline-artifacts-bucket/*"
]
}
]
}
8. Production-Grade IaC: Complete Terraform Implementation
In this section, we present a complete, production-grade Terraform configuration file. This file provisions an AWS CodePipeline with three stages: Source (GitHub via CodeStar Connection), Build (AWS CodeBuild), and Deploy (ECS). It includes a dedicated S3 bucket, custom KMS key, and secure IAM service roles with strict least-privilege permissions.
# Configure the AWS Provider
provider "aws" {
region = "us-east-1"
}
# Local variables for resource naming
locals {
project_name = "enterprise-app"
environment = "production"
}
# KMS Key for encrypting S3 Artifacts
resource "aws_kms_key" "pipeline_key" {
description = "KMS Key for CodePipeline S3 Artifacts Encryption"
deletion_window_in_days = 30
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow CodePipeline and CodeBuild Access"
Effect = "Allow"
Principal = {
AWS = [
aws_iam_role.pipeline_role.arn,
aws_iam_role.build_role.arn
]
}
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
Resource = "*"
}
]
})
tags = {
Name = "${local.project_name}-pipeline-key"
Environment = local.environment
}
}
# Fetch metadata about the current AWS account
data "aws_caller_identity" "current" {}
# S3 Bucket for Pipeline Artifacts
resource "aws_s3_bucket" "artifacts_bucket" {
bucket = "${local.project_name}-artifacts-bucket-${data.aws_caller_identity.current.account_id}"
force_destroy = true
tags = {
Name = "${local.project_name}-artifacts-bucket"
Environment = local.environment
}
}
# Block all public access to the S3 bucket
resource "aws_s3_bucket_public_access_block" "artifacts_bucket_block" {
bucket = aws_s3_bucket.artifacts_bucket.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# Enable versioning on the S3 bucket
resource "aws_s3_bucket_versioning" "artifacts_bucket_versioning" {
bucket = aws_s3_bucket.artifacts_bucket.id
versioning_configuration {
status = "Enabled"
}
}
# Enable server-side encryption with the custom KMS key
resource "aws_s3_bucket_server_side_encryption_configuration" "artifacts_bucket_encryption" {
bucket = aws_s3_bucket.artifacts_bucket.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.pipeline_key.arn
sse_algorithm = "aws:kms"
}
}
}
# IAM Role for CodePipeline Service
resource "aws_iam_role" "pipeline_role" {
name = "${local.project_name}-pipeline-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "codepipeline.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}
# IAM Policy for CodePipeline Service Role
resource "aws_iam_role_policy" "pipeline_policy" {
name = "${local.project_name}-pipeline-policy"
role = aws_iam_role.pipeline_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketLocation",
"s3:PutObject",
"s3:ListBucket"
]
Resource = [
aws_s3_bucket.artifacts_bucket.arn,
"${aws_s3_bucket.artifacts_bucket.arn}/*"
]
},
{
Effect = "Allow"
Action = [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild"
]
Resource = [aws_codebuild_project.app_build.arn]
},
{
Effect = "Allow"
Action = [
"codestar-connections:UseConnection"
]
Resource = [var.codestar_connection_arn]
},
{
Effect = "Allow"
Action = [
"kms:Decrypt",
"kms:Encrypt",
"kms:GenerateDataKey"
]
Resource = [aws_kms_key.pipeline_key.arn]
}
]
})
}
# IAM Role for CodeBuild Service
resource "aws_iam_role" "build_role" {
name = "${local.project_name}-build-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "codebuild.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}
# IAM Policy for CodeBuild Service Role
resource "aws_iam_role_policy" "build_policy" {
name = "${local.project_name}-build-policy"
role = aws_iam_role.build_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "arn:aws:logs:*:*:*"
},
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:PutObject"
]
Resource = [
"${aws_s3_bucket.artifacts_bucket.arn}/*"
]
},
{
Effect = "Allow"
Action = [
"kms:Decrypt",
"kms:Encrypt",
"kms:GenerateDataKey"
]
Resource = [aws_kms_key.pipeline_key.arn]
}
]
})
}
# CodeBuild Project Definition
resource "aws_codebuild_project" "app_build" {
name = "${local.project_name}-build"
description = "Build project for compiling code and running tests"
service_role = aws_iam_role.build_role.arn
build_timeout = "15"
artifacts {
type = "CODEPIPELINE"
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "aws/codebuild/standard:6.0"
type = "LINUX_CONTAINER"
image_pull_credentials_type = "CODEBUILD"
environment_variable {
name = "ENV"
value = "production"
}
}
source {
type = "CODEPIPELINE"
buildspec = "buildspec.yml"
}
logs_config {
cloudwatch_logs {
group_name = "/aws/codebuild/${local.project_name}-build"
status = "ENABLED"
}
}
}
# CodePipeline Definition
resource "aws_codepipeline" "app_pipeline" {
name = "${local.project_name}-pipeline"
role_arn = aws_iam_role.pipeline_role.arn
artifact_store {
location = aws_s3_bucket.artifacts_bucket.bucket
type = "S3"
encryption_key {
id = aws_kms_key.pipeline_key.arn
type = "KMS"
}
}
stage {
name = "Source"
action {
name = "SourceAction"
category = "Source"
owner = "AWS"
provider = "CodeStarSourceConnection"
version = "1"
output_artifacts = ["SourceOutput"]
configuration = {
ConnectionArn = var.codestar_connection_arn
FullRepositoryId = var.repository_id
BranchName = "main"
}
}
}
stage {
name = "Build"
action {
name = "BuildAction"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
version = "1"
input_artifacts = ["SourceOutput"]
output_artifacts = ["BuildOutput"]
configuration = {
ProjectName = aws_codebuild_project.app_build.name
}
}
}
}
# Input variables definition
variable "codestar_connection_arn" {
type = string
description = "The ARN of the AWS CodeStar Connection to GitHub"
}
variable "repository_id" {
type = string
description = "The GitHub repository ID in the format: Organization/Repository-Name"
}
9. Production-Grade IaC: Complete CloudFormation Template
For organizations that standardize on native AWS CloudFormation, here is the equivalent production-ready YAML template. It implements best practices, including explicit parameterization, KMS encryption, and a multi-stage pipeline definition.
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Production-grade AWS CodePipeline with KMS encryption and secure IAM roles.'
Parameters:
ProjectName:
Type: String
Default: 'enterprise-app'
Description: 'Project name used for resource naming prefix'
CodeStarConnectionArn:
Type: String
Description: 'ARN of the CodeStar Connection for GitHub integration'
GitHubRepo:
Type: String
Description: 'Format: OrgName/RepoName'
BranchName:
Type: String
Default: 'main'
Description: 'Branch to monitor for code changes'
Resources:
# KMS Customer Managed Key (CMK)
PipelineKmsKey:
Type: AWS::KMS::Key
Properties:
Description: !Sub 'KMS Key for ${ProjectName} Artifacts'
EnableKeyRotation: true
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: AdminPermissions
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'kms:*'
Resource: '*'
- Sid: CodePipelineAccess
Effect: Allow
Principal:
AWS:
- !GetAtt PipelineServiceRole.Arn
- !GetAtt CodeBuildServiceRole.Arn
Action:
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
- kms:DescribeKey
Resource: '*'
# S3 Artifact Store
PipelineS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub '${ProjectName}-artifacts-${AWS::AccountId}'
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: 'aws:kms'
KMSMasterKeyId: !Ref PipelineKmsKey
BucketKeyEnabled: true
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
# IAM Service Role for CodePipeline
PipelineServiceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${ProjectName}-pipeline-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: 'codepipeline.amazonaws.com'
Action: 'sts:AssumeRole'
Policies:
- PolicyName: PipelineExecutionPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketLocation
- s3:PutObject
- s3:ListBucket
Resource:
- !GetAtt PipelineS3Bucket.Arn
- !Sub '${PipelineS3Bucket.Arn}/*'
- Effect: Allow
Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
Resource: !GetAtt CodeBuildProject.Arn
- Effect: Allow
Action:
- codestar-connections:UseConnection
Resource: !Ref CodeStarConnectionArn
- Effect: Allow
Action:
- kms:Decrypt
- kms:Encrypt
- kms:GenerateDataKey
Resource: !GetAtt PipelineKmsKey.Arn
# IAM Service Role for CodeBuild
CodeBuildServiceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${ProjectName}-codebuild-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: 'codebuild.amazonaws.com'
Action: 'sts:AssumeRole'
Policies:
- PolicyName: CodeBuildExecutionPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: 'arn:aws:logs:*:*:*'
- Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
- s3:PutObject
Resource: !Sub '${PipelineS3Bucket.Arn}/*'
- Effect: Allow
Action:
- kms:Decrypt
- kms:Encrypt
- kms:GenerateDataKey
Resource: !GetAtt PipelineKmsKey.Arn
# CodeBuild Project
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Sub '${ProjectName}-```html
# CodeBuild Project
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Sub '${ProjectName}-build'
Description: 'Enterprise build project'
ServiceRole: !GetAtt CodeBuildServiceRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/standard:7.0
Type: LINUX_CONTAINER
PrivilegedMode: true
EnvironmentVariables:
- Name: ENVIRONMENT
Value: production
Source:
Type: CODEPIPELINE
BuildSpec: buildspec.yml
TimeoutInMinutes: 15
LogsConfig:
CloudWatchLogs:
Status: ENABLED
GroupName: !Sub '/aws/codebuild/${ProjectName}-build'
# CodePipeline Definition
ApplicationPipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: !Sub '${ProjectName}-pipeline'
RoleArn: !GetAtt PipelineServiceRole.Arn
ArtifactStore:
Type: S3
Location: !Ref PipelineS3Bucket
EncryptionKey:
Id: !GetAtt PipelineKmsKey.Arn
Type: KMS
Stages:
- Name: Source
Actions:
- Name: GitHubSource
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeStarSourceConnection
Version: '1'
OutputArtifacts:
- Name: SourceOutput
Configuration:
ConnectionArn: !Ref CodeStarConnectionArn
FullRepositoryId: !Ref GitHubRepo
BranchName: !Ref BranchName
DetectChanges: true
RunOrder: 1
- Name: Build
Actions:
- Name: BuildApplication
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: '1'
InputArtifacts:
- Name: SourceOutput
OutputArtifacts:
- Name: BuildOutput
Configuration:
ProjectName: !Ref CodeBuildProject
RunOrder: 1
- Name: Deploy
Actions:
- Name: DeployCloudFormation
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: CloudFormation
Version: '1'
InputArtifacts:
- Name: BuildOutput
Configuration:
ActionMode: CREATE_UPDATE
StackName: !Sub '${ProjectName}-stack'
Capabilities: CAPABILITY_NAMED_IAM
TemplatePath: BuildOutput::infrastructure/template.yaml
RunOrder: 1
Outputs:
PipelineName:
Description: CodePipeline Name
Value: !Ref ApplicationPipeline
PipelineRoleArn:
Description: Pipeline Service Role ARN
Value: !GetAtt PipelineServiceRole.Arn
ArtifactBucket:
Description: S3 Artifact Bucket
Value: !Ref PipelineS3Bucket
KmsKeyArn:
Description: Artifact Encryption Key
Value: !GetAtt PipelineKmsKey.Arn
BuildProjectName:
Description: CodeBuild Project Name
Value: !Ref CodeBuildProject
```
10. Blue/Green, Canary, and GitOps Integrations
Modern enterprises require deployment mechanisms that minimize risk and eliminate downtime. AWS CodePipeline integrates with AWS CodeDeploy, ECS, Lambda, and EKS to support advanced deployment strategies.
Blue/Green Deployments
Blue/Green deployment creates a new environment (Green) alongside the existing production environment (Blue). After validation succeeds, traffic is shifted to Green.
Users
|
v
ALB
|
+----> Blue Environment (Current)
|
+----> Green Environment (New)
|
Validation
|
Traffic Shift
Benefits
- Near-zero downtime
- Instant rollback capability
- Reduced deployment risk
- Production validation before cutover
Canary Deployments
Canary releases gradually expose a new version to a small percentage of users before full rollout.
100% Traffic
|
+----> Version 1 (90%)
|
+----> Version 2 (10%)
After Validation
100% Traffic
|
+----> Version 2 (100%)
AWS Lambda Canary Example
{
"Type": "Linear10PercentEvery1Minute"
}
GitOps Integration Pattern
Organizations running Kubernetes commonly integrate CodePipeline with GitOps tools such as ArgoCD and Flux.
GitHub
|
CodePipeline
|
Update Helm Charts
|
GitOps Repository
|
ArgoCD / Flux
|
Amazon EKS
11. Security, Compliance, and Governance
IAM Least Privilege
Every pipeline action should execute under a dedicated IAM role with narrowly scoped permissions.
KMS Encryption
- Encrypt artifact buckets
- Rotate CMKs annually
- Use customer-managed keys
- Enable CloudTrail auditing
Compliance Controls
Framework
Relevant Controls
SOC2
Change Management, Audit Trails
PCI DSS
Access Control, Encryption
HIPAA
Audit Logging, Encryption
ISO 27001
Release Governance
Security Scanning Stage
Source
|
Build
|
Security Scan
|
Approval
|
Deploy
12. Observability, Metrics, and Event-Driven Automation
CloudWatch Metrics
- PipelineExecutionSuccessCount
- PipelineExecutionFailureCount
- BuildDuration
- DeploymentDuration
EventBridge Integration
{
"source": [
"aws.codepipeline"
]
}
SNS Alerting
CodePipeline Failure
|
EventBridge
|
SNS
|
Email / Slack