AWS CodeBuild allows us to include automated builds and/or tests in our projects.

CodeBuild will launch a container either chosen from a list of AWS provided containers or from a custom image stored in an AWS ECR repository. Custom triggers and source providers can be defined or the CodeBuild project can be set up as part of a CodePipeline where the source is the output from the previous step in the CodePipeline.

Setting up a CodeBuild Project

Before setting up a CodeBuild project a few things need to be understood about your project.

  1. Where is the source located?
    • CodeBuild supports the following:
      • GitHub
      • Bitbucket
      • CodeCommit
      • S3
      • CodePipeline
  2. Which build commands do you need to run and in what order?
    • CodeBuild by default will retrieve build input from your source as defined in a buildspec.yml file. (BuildSpec reference)
  3. Which runtimes and tools do you need for your build?
    • The Docker containers provided by Amazon are based around specific runtimes and all include a standard set of tools such as git and the AWS cli, for the full list of Amazon maintained images see this link: Docker Images Provided by AWS CodeBuild
    • Additional tools required for your build will either need to exist in your own custom image or be installed in the “install” phase of the build.
  4. Does your build need access to other AWS services?
    • Any permissions required by your build will need to be included in the CodeDeploy service role.
  5. Does the build need to run inside your VPC?
    • If access is required to resources that are only available inside your VPC you have the option to launch the CodeBuild inside your VPC, you will need to setup a security group and ensure that the container will be able to reach the resources required.

Once you have answered the above questions you will be ready to setup a CodeBuild project, it is recommended to create your CodeBuild project through CloudFormation as this helps make the project portable and repeatable. Below is a sample resource setup as part of a CloudFormation template:

MyCodeBuildProject:
  Type: AWS::CodeBuild::Project
  Properties:
    Name: !Sub ${AWS::StackName}-myprojecy
    ServiceRole: !GetAtt CodeBuildRole.Arn
    Artifacts:
      Type: CODEPIPELINE
    Environment:
      Type: LINUX_CONTAINER
      ComputeType: BUILD_GENERAL1_SMALL
      Image: aws/codebuild/python:3.6.5
    Source:
      Type: CODEPIPELINE
      BuildSpec: !Sub |
        version: 0.2
        phases:
          build:
            commands:
              - . ./build.config       
              - sed -i s/IAM_REPLACE/"${LambdaFunctionRoleArn}"/g samTemplate.yaml
              - rm -rf .package
              - pip3 install -r requirements.txt --target .package
              - aws cloudformation package --template-file samTemplate.yaml --s3-bucket ${ArtifactStoreLocation} --s3-prefix $stack_name --output-template-file outputSamTemplate.yaml 
              - cat outputSamTemplate.yaml
    TimeoutInMinutes: 10

This CodeBuild project uses a static build and only a single phase to package a SAM template which requires several Python packages to be installed and the Lambda function code to be zipped and uploaded to an S3 bucket. Additionally, this CodeBuild project forms part of an AWS CodePipeline which is the recommended way of using CodeBuild as it simplifies the source definition and allows you to automatically move the build artefacts on to a Deployment phase or a further build project if required.

BuildSpec

By default, CodeBuild will try to use a buildspec.yml file located in the root of the source repository to define the build process, if no buildspec is available the build will fail, it is possible to specify a different path for the buildspec file or to define a static build process as part of the CodeBuild project definition (as in the example above).

The BuildSpec file is written in YAML and supports 4 different build phases and allows you to define which files get packaged into the final artefact and where the final artefact is passed to or stored as well as several other useful settings.

The phases supported in the BuildSpec file are:

  1. install
  2. pre_build
  3. build
  4. post_build

Each phase if defined expects an array of commands to run and optionally an array of commands to run if the build step fails or succeeds.

For a full reference please see this link: BuildSpec reference