Now that we’ve set up the GitHub connection and deployed our CloudFormation template, let’s understand how our CI/CD pipeline is configured to integrate Docker Build Cloud, Docker Scout, and Amazon ECS deployment.
Our CloudFormation template creates a complete CI/CD pipeline with these key components:
Let’s examine the key components in our CloudFormation template that power our pipeline:
The template includes a CodeBuild project specifically configured to use Docker Build Cloud:
# CodeBuild Project for Docker Build
DockerBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: docker-build-cloud-project
Description: "Build Docker image using Docker Build Cloud and push to Docker Hub"
ServiceRole: !GetAtt CodeBuildServiceRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
Type: ARM_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/amazonlinux2-aarch64-standard:2.0
PrivilegedMode: true
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.2
env:
secrets-manager:
DOCKER_USERNAME: "dockerhub-credentials:DOCKER_USERNAME"
DOCKER_TOKEN: "dockerhub-credentials:DOCKER_TOKEN"
phases:
pre_build:
commands:
- echo Logging in to Docker Hub...
- echo $DOCKER_TOKEN | docker login -u $DOCKER_USERNAME --password-stdin
- echo Setting up Docker Buildx...
- docker version
- mkdir -p ~/.docker/cli-plugins/
- curl -SL https://github.com/docker/buildx/releases/download/v0.10.4/buildx-v0.10.4.linux-arm64 -o ~/.docker/cli-plugins/docker-buildx
- chmod +x ~/.docker/cli-plugins/docker-buildx
- docker buildx version
- docker buildx create --name mybuilder --driver docker-container
- docker buildx use mybuilder
- docker buildx inspect --bootstrap
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Building Docker image using BuildKit...
- docker buildx build --platform linux/arm64 -t $DOCKER_USERNAME/rent-a-room:latest -t $DOCKER_USERNAME/rent-a-room:$IMAGE_TAG --push .
post_build:
commands:
- echo Docker image pushed to Docker Hub
- echo Writing image definitions file...
- echo '[{"name":"rent-a-room","imageUri":"'$DOCKER_USERNAME/rent-a-room:$IMAGE_TAG'"}]' > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
Element | Description | Benefit |
---|---|---|
ARM_CONTAINER | Uses ARM-based build environment | Optimized for building ARM64 images |
PrivilegedMode: true | Enables Docker-in-Docker capabilities | Required for Docker Buildx |
docker buildx | Sets up Docker’s multi-architecture build tool | Enables advanced build features |
–platform linux/arm64 | Specifies target architecture | Ensures compatibility with ARM-based ECS instances |
–push | Pushes directly to registry | Streamlines the build and push process |
While our current pipeline is configured specifically for ARM64 to match our ECS task definition, Docker Build Cloud supports multi-architecture builds. With a simple modification, you could build for multiple architectures simultaneously:
# Example of multi-architecture build command
docker buildx build --platform linux/amd64,linux/arm64 -t $DOCKER_USERNAME/rent-a-room:latest --push .
This capability allows you to:
The template includes a dedicated CodeBuild project for Docker Scout security scanning:
# CodeBuild Project for Docker Scout Security Scan
DockerScoutProject:
Type: AWS::CodeBuild::Project
Properties:
Name: docker-scout-scan-project
Description: 'Scan Docker image using Docker Scout'
ServiceRole: !GetAtt CodeBuildServiceRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
Type: ARM_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/amazonlinux2-aarch64-standard:2.0
PrivilegedMode: true
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.2
env:
secrets-manager:
DOCKER_USERNAME: "dockerhub-credentials:DOCKER_USERNAME"
DOCKER_TOKEN: "dockerhub-credentials:DOCKER_TOKEN"
phases:
pre_build:
commands:
- echo Logging in to Docker Hub...
- echo $DOCKER_TOKEN | docker login -u $DOCKER_USERNAME --password-stdin
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Running Docker Scout security scan...
- docker pull $DOCKER_USERNAME/rent-a-room:$IMAGE_TAG
# Run Docker Scout with security gates
- >
docker run --rm
-e DOCKER_SCOUT_HUB_USER=$DOCKER_USERNAME
-e DOCKER_SCOUT_HUB_PASSWORD=$DOCKER_TOKEN
docker/scout-cli cves $DOCKER_USERNAME/rent-a-room:$IMAGE_TAG --exit-code --only-severity critical,high
- echo "No critical or high vulnerabilities found. Scan passed!"
- >
docker run --rm
-e DOCKER_SCOUT_HUB_USER=$DOCKER_USERNAME
-e DOCKER_SCOUT_HUB_PASSWORD=$DOCKER_TOKEN
docker/scout-cli recommendations $DOCKER_USERNAME/rent-a-room:$IMAGE_TAG
post_build:
commands:
- echo Security scan completed
- echo Generating security report...
- >
docker run --rm
-e DOCKER_SCOUT_HUB_USER=$DOCKER_USERNAME
-e DOCKER_SCOUT_HUB_PASSWORD=$DOCKER_TOKEN
docker/scout-cli cves $DOCKER_USERNAME/rent-a-room:$IMAGE_TAG --format json > security-report.json
- echo "Creating imagedefinitions.json file"
- echo '[{"name":"rent-a-room","imageUri":"'$DOCKER_USERNAME/rent-a-room:$IMAGE_TAG'"}]' > imagedefinitions.json
artifacts:
files:
- security-report.json
- imagedefinitions.json
Element | Description | Benefit |
---|---|---|
docker/scout-cli | Uses Docker Scout CLI in a container | No need to install Scout separately |
–exit-code –only-severity critical,high | Implements security gates | Fails the build if critical/high vulnerabilities are found |
recommendations | Generates improvement suggestions | Provides actionable security insights |
–format json > security-report.json | Creates structured security report | Enables automated analysis and reporting |
The CloudFormation template defines a complete pipeline that connects all these components:
# CodePipeline
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
# Source Stage - Pull from GitHub
- Name: Source
Actions:
- Name: Source
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeStarSourceConnection
Version: "1"
Configuration:
ConnectionArn: !Ref CodeStarConnectionArn
FullRepositoryId: !Sub ${GitHubOwner}/${GitHubRepo}
BranchName: !Ref GitHubBranch
OutputArtifacts:
- Name: SourceCode
# Build Stage - Build Docker image with Docker Build Cloud
- Name: Build
Actions:
- Name: BuildDockerImage
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: "1"
Configuration:
ProjectName: !Ref DockerBuildProject
InputArtifacts:
- Name: SourceCode
OutputArtifacts:
- Name: BuildOutput
# Security Scan Stage - Scan with Docker Scout
- Name: SecurityScan
Actions:
- Name: DockerScoutScan
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: "1"
Configuration:
ProjectName: !Ref DockerScoutProject
InputArtifacts:
- Name: BuildOutput
OutputArtifacts:
- Name: SecurityScanOutput
# Deploy Stage - Deploy to ECS
- Name: Deploy
Actions:
- Name: DeployToECS
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: ECS
Version: "1"
Configuration:
ClusterName: !Ref ECSClusterName
ServiceName: !Ref ECSServiceName
FileName: imagedefinitions.json
InputArtifacts:
- Name: SecurityScanOutput
Stage | Purpose | Key Components |
---|---|---|
Source | Pull code from GitHub | CodeStar Connection, GitHub repository |
Build | Build Docker image | Docker Build Cloud, Buildx, ARM64 optimization |
Security Scan | Scan for vulnerabilities | Docker Scout, Security gates, Recommendations |
Deploy | Deploy to ECS | Amazon ECS, Container deployment |
The pipeline seamlessly integrates Docker technologies:
Docker Build Cloud with Buildx:
Docker Scout:
Docker Hub:
While our current pipeline is optimized specifically for ARM64 to match our ECS task definition, Docker Build Cloud’s multi-architecture capabilities are worth highlighting:
To enable multi-architecture builds in your own projects, you would modify the build command to:
docker buildx build --platform linux/amd64,linux/arm64 -t yourusername/yourapp:latest --push .
This creates a multi-architecture manifest that automatically serves the right image architecture based on the runtime environment.
Now that you understand how the pipeline is configured, let’s complete the workshop by:
In the next section, we’ll make a personalized change to the application and watch our complete CI/CD pipeline in action!