AWS
CodeBuild
CloudFormation
Branch Filter
Tutorial

How to set Branch Filter option in AWS CodeBuild cloudformation template?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When people ask for a branch filter in an AWS CodeBuild CloudFormation template, they usually want one build project to react only to specific Git branches. The important detail is that CodeBuild does not use a dedicated BranchFilter property in CloudFormation. For webhook-based sources, you express the rule with Triggers.FilterGroups and match full Git refs such as refs/heads/main.

How Branch Filtering Actually Works

Two CodeBuild settings are easy to confuse:

  • 'SourceVersion tells CodeBuild which revision to build when a build is started manually or by another service.'
  • 'Triggers.FilterGroups tells CodeBuild which webhook events should start a build automatically.'

If your source provider sends webhooks directly to CodeBuild, branch filtering belongs in FilterGroups. Each filter group is an AND condition, and multiple groups are OR conditions. That lets you express rules such as "build pushes to main and release/*, and also build pull requests targeting main."

The branch names are matched against full refs, not short names. That means main is usually wrong and refs/heads/main is right.

CloudFormation Example

The following template creates a GitHub-backed CodeBuild project that reacts only to pushes on main or release/*, plus pull requests aimed at main.

yaml
1Resources:
2  DocsBuild:
3    Type: AWS::CodeBuild::Project
4    Properties:
5      Name: docs-build
6      ServiceRole: arn:aws:iam::123456789012:role/codebuild-service-role
7      Artifacts:
8        Type: NO_ARTIFACTS
9      Environment:
10        ComputeType: BUILD_GENERAL1_SMALL
11        Image: aws/codebuild/standard:7.0
12        Type: LINUX_CONTAINER
13      Source:
14        Type: GITHUB
15        Location: https://github.com/example/docs.git
16        BuildSpec: buildspec.yml
17      Triggers:
18        Webhook: true
19        FilterGroups:
20          - - Type: EVENT
21              Pattern: PUSH
22            - Type: HEAD_REF
23              Pattern: ^refs/heads/(main|release/.+)$
24          - - Type: EVENT
25              Pattern: PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED
26            - Type: BASE_REF
27              Pattern: ^refs/heads/main$

A few details matter here:

  • 'Webhook: true is required. Without it, the filter groups never receive webhook events.'
  • 'HEAD_REF checks the source branch on a push or pull request.'
  • 'BASE_REF checks the destination branch for pull request events.'
  • The regex should match the entire ref. Anchors such as ^ and $ prevent accidental matches.

You can deploy a template like this with the AWS CLI:

bash
1aws cloudformation deploy \
2  --template-file codebuild.yml \
3  --stack-name docs-build \
4  --capabilities CAPABILITY_NAMED_IAM

Choosing the Right Filter Type

The filter type depends on what you are trying to control:

  • Use HEAD_REF when you care about the branch that produced the event.
  • Use BASE_REF when you care about the branch a pull request targets.
  • Use EVENT to limit the trigger to push or pull-request activity.

That combination is more precise than trying to overload SourceVersion. For example, if you set SourceVersion: refs/heads/main, CodeBuild can still receive webhook events for other branches unless the webhook filters block them.

If your build is started by CodePipeline instead of a direct webhook, branch filtering normally belongs in the pipeline source stage, not in the CodeBuild project. In that setup, CodeBuild just builds what the pipeline hands to it.

Testing the Rule

A practical way to verify your filter is to push a small change to a branch that should match and then to one that should not. If only the matching branch starts a build, your regex and event type are aligned.

For a quick regex sanity check, you can test the same pattern locally:

python
1import re
2
3pattern = re.compile(r"^refs/heads/(main|release/.+)$")
4refs = [
5    "refs/heads/main",
6    "refs/heads/release/1.2",
7    "refs/heads/feature/login",
8]
9
10for ref in refs:
11    print(ref, bool(pattern.match(ref)))

That snippet should print True, True, and False in that order.

Common Pitfalls

The most common mistake is using a short branch name such as main in a HEAD_REF filter. CodeBuild webhook filters usually see the full ref, so the safer pattern is ^refs/heads/main$.

Another common mistake is assuming SourceVersion is a trigger filter. It is not. It controls what revision is built when a build starts, but it does not decide whether a webhook starts the build.

Teams also trip over filter-group logic. Inside one group, every filter must match. Across groups, any one group can match. If you intend two separate scenarios, put them in two separate groups.

Finally, do not try to solve a CodePipeline branch problem inside CodeBuild. If CodePipeline owns the source checkout, configure the branch at the source action level and keep CodeBuild focused on the build itself.

Summary

  • In CloudFormation, branch filtering for CodeBuild webhooks is done with Triggers.FilterGroups.
  • Use full Git refs such as refs/heads/main, not short branch names.
  • 'HEAD_REF matches the source branch, and BASE_REF matches the pull-request target branch.'
  • 'SourceVersion is not a webhook filter.'
  • If CodePipeline triggers the build, branch selection usually belongs in the pipeline source stage.

Course illustration
Course illustration

All Rights Reserved.