ECS Deployment Pipeline Module
This Terraform module creates a complete CI/CD pipeline for deploying containerized applications to Amazon ECS using AWS CodePipeline, CodeBuild, and CodeDeploy with Blue/Green deployment strategy.
Features
- Source: GitHub integration via CodeStar Connection
- Build: CodeBuild for Docker image building and pushing to ECR
- Deploy: CodeDeploy with Blue/Green deployment for ECS
- Automated: Triggered on code push to specified branch
- Secure: IAM roles with least privilege access
- Artifact Storage: S3 bucket for pipeline artifacts (create new or use existing)
Architecture
Usage
module "ecs_deployment_pipeline" {
source = "s3::https://apro-terraform-modules.s3.eu-west-1.amazonaws.com/v2.54.0/ecs_deployment_pipeline.zip"
# Pipeline Configuration
pipeline_name = "fiskeldi-dev-pipeline"
environment = "development"
# GitHub Configuration
codestar_connection_arn = "arn:aws:codeconnections:eu-west-1:123456789012:connection/xxxxx"
repository_id = "MastUT/Fiskeldi"
branch_name = "development"
# Build Configuration
buildspec_path = "buildspec-dev.yml"
ecr_repository_name = "fiskeldi-dev"
image_tag = "latest"
codebuild_environment_variables = [
{
name = "Docker_Login"
type = "SECRETS_MANAGER"
value = "Production/Heilsa/DockerLogin"
}
]
# ECS Configuration
ecs_cluster_name = "dev-fiskeldi-cluster"
ecs_service_name = "dev-fiskeldi-service"
# CodeDeploy Configuration
taskdef_template_path = "taskdef-dev.json"
appspec_template_path = "appspec-dev.yml"
image_container_name = "IMAGE1_NAME"
# Load Balancer Configuration
listener_arn = "arn:aws:elasticloadbalancing:..."
target_group_blue_name = "dev-fiskeldi-tg1"
target_group_green_name = "dev-fiskeldi-tg2"
# S3 Artifact Bucket (optional - creates new if not specified)
create_artifact_bucket = false
artifact_bucket_name = "existing-artifact-bucket"
tags = {
Project = "Fiskeldi"
Team = "DevOps"
}
}
Requirements
| Name | Version |
|---|---|
| terraform | >= 1.0 |
| aws | >= 5.0 |
Providers
| Name | Version |
|---|---|
| aws | >= 5.0 |
Resources Created
- CodePipeline: Main pipeline with Source, Build, and Deploy stages
- CodeBuild Project: For building Docker images
- CodeDeploy Application: ECS deployment application
- CodeDeploy Deployment Group: Blue/Green deployment configuration
- S3 Bucket: For artifacts (optional)
- IAM Roles: For CodePipeline, CodeBuild, and CodeDeploy with least privilege
Inputs
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| pipeline_name | Name of the CodePipeline | string |
n/a | yes |
| environment | Environment name | string |
n/a | yes |
| codestar_connection_arn | CodeStar connection ARN for GitHub | string |
n/a | yes |
| repository_id | GitHub repository (owner/repo) | string |
n/a | yes |
| branch_name | Branch to monitor | string |
n/a | yes |
| ecr_repository_name | ECR repository name | string |
n/a | yes |
| ecs_cluster_name | ECS cluster name | string |
n/a | yes |
| ecs_service_name | ECS service name | string |
n/a | yes |
| listener_arn | ALB listener ARN | string |
n/a | yes |
| target_group_blue_name | Blue target group name | string |
n/a | yes |
| target_group_green_name | Green target group name | string |
n/a | yes |
| buildspec_path | Path to buildspec file | string |
"buildspec.yml" |
no |
| image_tag | Docker image tag | string |
"latest" |
no |
| taskdef_template_path | Path to task definition template | string |
"taskdef.json" |
no |
| appspec_template_path | Path to AppSpec template | string |
"appspec.yml" |
no |
| create_artifact_bucket | Create new S3 bucket | bool |
true |
no |
| artifact_bucket_name | Existing S3 bucket name | string |
null |
no |
Outputs
| Name | Description |
|---|---|
| pipeline_name | Name of the CodePipeline |
| pipeline_arn | ARN of the CodePipeline |
| codebuild_project_name | Name of the CodeBuild project |
| codedeploy_app_name | Name of the CodeDeploy application |
| artifact_bucket_name | Name of the S3 artifacts bucket |
Blue/Green Deployment
The module uses CodeDeploy's Blue/Green deployment strategy:
- Blue (Current): Original task set with existing traffic
- Green (New): New task set with updated container image
- Traffic Shift: Automatically shifts traffic from Blue to Green
- Rollback: Automatic rollback on deployment failure
- Termination: Terminates Blue task set after successful deployment (configurable wait time)
Repository Requirements
Your repository should contain:
buildspec.ymlor custom buildspec filetaskdef.json- ECS task definition templateappspec.yml- CodeDeploy AppSpec file
Example buildspec.yml
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
build:
commands:
- echo Building Docker image...
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Pushing Docker image...
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
- printf '[{"name":"IMAGE1_NAME","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imageDetail.json
artifacts:
files:
- imageDetail.json
- taskdef.json
- appspec.yml
License
This module is maintained by APRÓ.
Inputs
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| additional_codebuild_s3_bucket_arns | List of additional S3 bucket ARNs that CodeBuild can read from and write to (e.g., for build caches or dependencies) | list(string) |
[] |
no |
| additional_codedeploy_s3_bucket_arns | List of additional S3 bucket ARNs that CodeDeploy can read from (e.g., for deployment artifacts from other sources) | list(string) |
[] |
no |
| appspec_template_path | Path to AppSpec template in repository | string |
"appspec.yml" |
no |
| artifact_bucket_name | Name of existing S3 bucket for artifacts. Required when create_artifact_bucket is false. | string |
null |
no |
| auto_rollback_enabled | Enable automatic rollback on deployment failure | bool |
true |
no |
| blue_green_termination_wait_time | Wait time in minutes before terminating blue instances | number |
5 |
no |
| branch_name | Branch to monitor for changes | string |
n/a | yes |
| buildspec_path | Path to buildspec file in repository | string |
"buildspec.yml" |
no |
| codebuild_compute_type | CodeBuild compute type. Options: BUILD_GENERAL1_SMALL, BUILD_GENERAL1_MEDIUM, BUILD_GENERAL1_LARGE, BUILD_GENERAL1_2XLARGE, BUILD_LAMBDA_1GB, BUILD_LAMBDA_2GB, BUILD_LAMBDA_4GB, BUILD_LAMBDA_8GB, BUILD_LAMBDA_10GB | string |
"BUILD_GENERAL1_MEDIUM" |
no |
| codebuild_environment_variables | Additional environment variables for CodeBuild | list(object({ |
[] |
no |
| codebuild_image | CodeBuild Docker image. Must be a valid AWS CodeBuild managed image (e.g., aws/codebuild/standard:5.0) or custom image URI | string |
"aws/codebuild/standard:5.0" |
no |
| codebuild_secret_arns | List of Secrets Manager secret ARNs that CodeBuild can access during builds | list(string) |
[] |
no |
| codestar_connection_arn | CodeStar connection ARN for GitHub repository | string |
n/a | yes |
| create_artifact_bucket | Whether to create a new artifact bucket. If false, artifact_bucket_name must be provided. | bool |
true |
no |
| deployment_config_name | CodeDeploy deployment configuration name | string |
"CodeDeployDefault.ECSAllAtOnce" |
no |
| deployment_hook_lambda_arns | List of Lambda function ARNs that can be invoked as CodeDeploy lifecycle hooks | list(string) |
[] |
no |
| detect_changes | Whether to automatically trigger the pipeline on source changes. Set to false for manual-trigger-only pipelines. | bool |
true |
no |
| ecr_repository_arns | List of ECR repository ARNs that CodeBuild can push/pull images to/from. If empty, defaults to the primary ecr_repository_name in the current account/region. | list(string) |
[] |
no |
| ecr_repository_name | Primary ECR repository name for Docker images (used in CodeBuild environment variables) | string |
n/a | yes |
| ecs_cluster_name | ECS cluster name for deployment | string |
n/a | yes |
| ecs_service_name | ECS service name for deployment | string |
n/a | yes |
| ecs_task_role_arns | List of ECS task role ARNs that CodeDeploy can pass to ECS tasks. Include both task execution role and task role ARNs. | list(string) |
n/a | yes |
| environment | Environment name (e.g., dev, staging, prod) | string |
n/a | yes |
| execution_mode | Pipeline execution mode (QUEUED, SUPERSEDED, PARALLEL) | string |
"SUPERSEDED" |
no |
| image_container_name | Container name placeholder in task definition | string |
"IMAGE1_NAME" |
no |
| image_tag | Docker image tag | string |
"latest" |
no |
| listener_arn | ALB/NLB listener ARN for blue/green deployment | string |
n/a | yes |
| listener_rule_arn_pattern | ARN pattern for listener rules that CodeDeploy can modify. Use '' for all rules in account, or specify a pattern like 'app/my-alb/' for specific ALB. The full ARN is constructed as: arn:aws:elasticloadbalancing:{region}:{account}:listener-rule/{pattern} | string |
"*" |
no |
| permissions_boundary_arn | ARN of the IAM permissions boundary to apply to all roles created by this module | string |
null |
no |
| pipeline_name | Name of the CodePipeline and related resources | string |
n/a | yes |
| pipeline_type | Pipeline type. V2 (default) supports pipeline variables and triggers. V1 is legacy. | string |
"V2" |
no |
| pipeline_variables | Pipeline-level variables for CodePipeline V2. Referenced in actions using #{variables. |
list(object({ |
[] |
no |
| repository_id | GitHub repository in format owner/repo-name | string |
n/a | yes |
| sns_notification_topic_arns | List of SNS topic ARNs for deployment notifications | list(string) |
[] |
no |
| tags | Additional tags to apply to all resources | map(string) |
{} |
no |
| target_group_blue_name | Blue target group name for blue/green deployment | string |
n/a | yes |
| target_group_green_name | Green target group name for blue/green deployment | string |
n/a | yes |
| taskdef_template_path | Path to task definition template in repository | string |
"taskdef.json" |
no |
Outputs
| Name | Description |
|---|---|
| artifact_bucket_arn | ARN of the S3 bucket for artifacts |
| artifact_bucket_name | Name of the S3 bucket for artifacts |
| codebuild_project_arn | ARN of the CodeBuild project |
| codebuild_project_name | Name of the CodeBuild project |
| codebuild_role_arn | ARN of the CodeBuild IAM role |
| codedeploy_app_arn | ARN of the CodeDeploy application |
| codedeploy_app_name | Name of the CodeDeploy application |
| codedeploy_deployment_group_arn | ARN of the CodeDeploy deployment group |
| codedeploy_deployment_group_name | Name of the CodeDeploy deployment group |
| codedeploy_role_arn | ARN of the CodeDeploy IAM role |
| codepipeline_role_arn | ARN of the CodePipeline IAM role |
| pipeline_arn | ARN of the CodePipeline |
| pipeline_id | ID of the CodePipeline |
| pipeline_name | Name of the CodePipeline |