- Fully managed build service
- Alternative to other build tools such as Jenkins
- Continuous scaling (no servers to manage or provision – no build queue)
- Pay for usage: the time it takes to complete the builds
- Leverages Docker under the hood for reproducible builds
- Possibility to extend capabilities leveraging our own base Docker images
- Secure: Integration with KMS for encryption of build artifacts, IAM for build
permissions, and VPC for network security, CloudTrail for API calls logging - Source Code from GitHub / CodeCommit / CodePipeline / S3…
- Build instructions can be defined in code (
buildspec.yml
file) - Output logs to Amazon S3 & AWS CloudWatch Logs
- Metrics to monitor CodeBuild statistics
- Use CloudWatch Events to detect failed builds and trigger notifications
- Use CloudWatch Alarms to notify if you need “thresholds” for failures
- CloudWatch Events / AWS Lambda as a Glue
- SNS notifications
First build
In CodeCommit we have index.html
file with “congratulations” word. We will test whether or not the index.html
file has this word. To create a build:
CodeBuild -> Create build project -> ProjectName (MyWebAppCodeBuildMaster) -> Source provider (AWS CodeCommit) -> Repositorry (my-webpage) -> Reference type (Branch) -> Branch (master) -> Environment -> Environment image (Managed image) -> Operating system (Amazon Linux 2) -> Runtime (standard) -> Image (****-standard 1.0) -> Service Role (New service role) -> Role name (codebuild->MyWebAppCodeBuild-service-role) -> Build specifications -> Use a buildspec file -> Create build project
Because in CodeCommit we have buildspec.yml
file we don’t need to fill Buildspec section.
Now we should start a build:
Start build
->
Build will use docker container and buildspecfile.yml
from CodeCommit my-webpage repository.
We can click View entire log
to view the entire log in cloudwatch.
Buildspec.yml file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
version: 0.2 phases: install: runtime-versions: nodejs: 10 commands: - echo "installing something" pre_build: commands: - echo "we are in the pre build phase" build: commands: - echo "we are in the build block" - echo "we will run some tests" - grep -Fq "Congratulations" index.html post_build: commands: - echo "we are in the post build phase" |
This buildspec.yml check if in the index.html file is “Congratulations” word.
We can change this word in the index.html file and Commit changes:
CodeCommit -> Repositories -> my-webpage -> index.html -> Edit -> Author name -> Commit changes
and then:
Developer Tools -> CodeBuild -> Build projects -> MyWebAppCodeBuildMaster -> Start build
And the build will fail:
Docker
To use docker images we can use buildspec.yml
file from refenrences sample:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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 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 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 |
Environment variables & Parameter Store
Let’s modify our first simple buildspec.yml
file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
version: 0.2 phases: install: runtime-versions: nodejs: 10 commands: - printenv - echo "installing something" pre_build: commands: - echo "we are in the pre build phase" build: commands: - echo "we are in the build block" - echo "we will run some tests" - grep -Fq "Congratulations" index.html post_build: commands: - echo "we are in the post build phase" |
Next we must commit changes in
CodeCommit -> author name -> Email address -> Commit changes
And also we must change index.html file and put Congratulations word in:
Next we must commit changes in
CodeCommit -> author name -> Email address -> Commit changes
Then in CodeBuild we must build the project again.
After this changes all the environment variables should be printed:
We can change the environment variables directly in the buuildspec.yml file
1 2 3 4 5 6 7 8 9 10 11 |
env: shell: shell-tag variables: key: "value" key: "value" parameter-store: key: "value" key: "value" exported-variables: -variable -variable |
or directly in the console wile lounching buil project:
Build project with overrides ->
But variables changed in the buildpec.yml file and in console will be visible.
If we want to have unvisible variable we should use Parameter Store.
![](http://miro.borodziuk.eu/wp-content/uploads/CodeBuuild07.jpg)
Create Paremeter
Now in console we use:
To use parameters from Parameter Store a role codebuild-MyWebAppCodeBuild-service-role
should have attached AmazonSSMReadOnlyAccess
.
After build the project we can’t see the DB_PASSWORD variable in the log:
Artifacts and S3
Artifact is the build output. Let’s modify the buildspec file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
version: 0.2 phases: install: runtime-versions: nodejs: 10 commands: - printenv - echo "installing something" pre_build: commands: - echo "we are in the pre build phase" build: commands: - echo "we are in the build block" - echo "we will run some tests" - grep -Fq "Congratulations" index.html post_build: commands: - echo "we are in the post build phase" artifacts: files: - '**/*' name: my-webapp-artifacts |
and commit changes in CodeCommit.
First we need to create a bucket for artifacts:
If we want we can use default encryption for this bucket or encrypt the artifacts after the build proces.
Now edit the artifacts section in CodeBuild project:
Developer Tools -> CodeBuild -> Build projects -> MyWebAppCodeBuildMaster -> Edit Artifacts
As we see the CodeBuild will create a role to access to the S3 bucket.
Now we can run the build project. After building we see in the log that artifacts were succesfully upploaded to the cicd-miro-devops bucket:
S3 bucket:
CloudWatch Events & CloudWatch Logs
If we want to run build project in the sheduled way we can use CloudWatch Events:
Cloudwatch -> Events -> Rules -> Create rule
Project ARN we can take from Build details:
Configure details ->
Create rule ->
Also we can configure CloudWatch Events to react if something happen while build is runing, for example build has been failed or state changed:
Validating AWS CodeCommit Pull Requests
We can validate CodeCommit pull request by sing CloudWatch Events, CodeBuild and Lembda. There is great article abut it at AWS DevOps Blog:
References
- https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html
- https://docs.aws.amazon.com/codebuild/latest/userguide/samples.html
- https://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html
- https://aws.amazon.com/blogs/devops/validating-aws-codecommit-pull-requests-with-aws-codebuild-and-aws-lambda/
- https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html