This post is linked to from the AWS: Deep Dive Project
Workflow
- Commit code to AWS CodeCommit
- CloudWatch rule triggers CodePipeline
- CodePipeline uses CodeBuild to build the Docker image
- CodePipeline pushes the image to ECR
Deploy Code to CodeCommit
- Open CodeCommit.
- Create a repository
- Go to your IAM page and edit your user.
- Look for "HTTPS Git credentials for AWS CodeCommit"
- click Generate Credentials
- Save your credentials.
- Grab the HTTPS URL for your repository and
git clone
it. Use your new
credentials.
- Commit your code (including a Dockerfile) to the CodeCommit repository.
Write buildspec.yml
AWS CodeBuild will look for a buildspec.yml
file to dictate its actions.
This is where we define how the image will be built. Put it in your CodeCommit
project's root directory.
Here's mine. This will build a docker image and tag it with a timestamp, then
push it to ECR as the timestamp and latest. The variables are defined inside
the build as Environment Variables.
# buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
docker: 18
pre_build:
commands:
- echo Logging in to Amazon ECR...
- $(aws ecr get-login --no-include-email --region ca-central-1)
- IMAGE_TAG=$(date +%Y.%m.%d.%I.%M)
build:
commands:
- echo Build started on `date`
- echo "Building the 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
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:latest
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:latest
Define the Pipeline
Cloud Build Role
Bad Practice Alert: These steps don't apply the principal of least
privilege. You should lock down your role to be allowed to do only the minimum
that it needs to do.
- In the IAM page, create a new role.
- It will be used by CodeBuild.
- Assing the following policies (again, more than it needs)
- CloudWatchLogsFullAccess
- AWSCodeBuildAdminAccess
- AmazonS3FullAccess
- AmazonEC2ContainerRegistryFullAccess
- AWSCodeCommitFullAccess
- Name: Assign a name, such as
CloudBuild-Admin
Define CloudBuild project
- Navigate to the CloudBuild Console
- Create build project
- No build badge
- Source provider: CodeCommit
- Choose your repository
- Choose your branch
- Managed Image
- Operating System: Ubuntu
- Runtime: Standard
- Image: aws/codebuild/standard:3.0
- Image version: latest
- Environment type: Linux
- Privileged: true
- Service Role: Existing service role. Use the one you just made.
- Allow CodeBuild to modify this role: False (we gave it admin)
- Additional Configuration - Environment variables (click Add to get more)
- IMAGE_REPO_NAME: (your image name)
- AWS_ACCOUNT_ID: (your numeric AWS account iD)
- AWS_DEFAULT_REGION: ca-central-1
- Buildspec: Use a buildspec file
- Artifacts: No artifacts
- Logs: Give a group and stream name for CloudWatch
- Create Build Project
Now test the build by clicking "Start build". It should create your image.
You'll need to disable artifacts.
Once the build works and your image is pushed successfully to ECR, you can move
on to setting up a pipeline so this happens automatically.
Create Pipeline Role
Bad Practice Alert: These steps don't apply the principal of least
privilege. You should lock down your role to be allowed to do only the minimum
that it needs to do.
- In the IAM page, create a new role.
- It will be used by CodeBuild.
- Assing the following policies (again, more than it needs)
- CloudWatchLogsFullAccess
- AWSCodeBuildAdminAccess
- AmazonS3FullAccess
- AmazonEC2ContainerRegistryFullAccess
- AWSCodeCommitFullAccess
- Name: Assign a name, such as
CloudBuild-Admin
Define the pipeline
- Open the CodePipeline console
- Click Create Pipeline
- Name the pipeline
- Service Role: New service role
- Role Name: Pick a name
- Allow AWS CodePipeline to create a role
- Next
- Source Provider: AWS CodeCommit
- Repository Name: Select the repository name
- Branch name: master
- Change detection: Amazon CloudWatch Events
- Next
- Build Provider: AWS CodeBuild
- Region: Canada (Central)
- Project Name: Create Project
- Project Name: Choose a name
- Description: Add a description
- Environment image: Managed Image
- Operating System: Ubuntu
- Runtimes: Standard
- Image: aws/codebuild/standard:3.0
- Image version: Always use the latest
- Environment type: Linux
- Privileged: True
- Service Role: New service role
- Role Name: default name is fine
- Advanced Configuration - Environment variables (click Add to get more)
- IMAGE_REPO_NAME: (your image name)
- AWS_ACCOUNT_ID: (your numeric AWS account iD)
- AWS_DEFAULT_REGION: ca-central-1
- Build specifications: Use a buildspec file
- Buildspec name: Leave it blank so it uses buildspec.yml
- CloudWatch logs: True
- Group name: pick a name
- Stream name: pick a name
- S3 logs: false
- Continue to CodePipeline
- Next
- Skip deploy stage, pushing to ECR is enough
- Create pipeline
This will re-run the build that you tested before. It should pass again.