codebuild-notifier
Reports status of AWS CodeBuild CI jobs to Slack.
Infrastructure Requirements
Slack App or Bot in your workspace
Notifications will be sent as Slack Direct Messages to users from the default Slack bot in your workspace (e.g. @slackbot)
- Go to https://api.slack.com/apps
- Create a New App, e.g. App Name: CodeBuild Notifier
- Under Add features and functionality select "Permissions" and grant these scopes:
- chat:write:bot
- users:read
- users:read.email
- Click Install App To Workspace and store the OAuth token generated in a new secret in AWS Secrets Manager (see below)
Optional Add a Bot User to your app - instead of the default Slack bot, messages will come from a user with a name you choose, e.g. CodeBuildBot
- Under Features / Bot Users, click Add a Bot User
- Select a name and display name; the always show as online option does not matter
- After adding the Bot User, re-install the app to your workspace
- A new OAuth token will be generated specific to the Bot User. Store this in AWS Secrets Manager instead of the App token.
DynamoDB table for build history
- expected to be named 'codebuild-history', but can be configured
- the following definition:
AttributeDefinitions [
{ AttributeName: 'commit_hash', AttributeType: 'S' },
{ AttributeName: 'source_id', AttributeType: 'S' },
{ AttributeName: 'version_key', AttributeType: 'S' }
]
GlobalSecondaryIndexes [
{
IndexName: 'commit_hash_index',
KeySchema: [
{ AttributeName: 'commit_hash', KeyType: 'HASH' },
{ AttributeName: 'version_key', KeyType: 'RANGE' }
],
Projection: { ProjectionType: 'ALL' }
}
]
KeySchema [
{ AttributeName: 'source_id', KeyType: 'HASH' },
{ AttributeName: 'version_key', KeyType: 'RANGE' }
]
Secret in AWS Secrets Manager
- expected to be named 'slack/codebuild', but can be configured
- contents should be:
json { "token": "xoxo-your-slack-app-token" }
Optional DynamoDB table for Slack aliases
Slack message recipients are located by extracting the email address of the author/commiter of the git commit triggering the build, then searching for users with that email address within the Slack workspace.
Users might sign commits with a different email address than they used to register with Slack. Even if their git config has a matching address, merges and commits made via the github web interface may use the primary email address for the user's github account, or [email protected].
To ensure delivery in these cases, a second DynamoDb table can be created and configured to do a second lookup if the original lookup fails.
- suggested table name: 'codebuild-slack-aliases', but can be configured
- by default, the table name is unspecified, meaning no second lookup will be performed
- the email address for which the original lookup fails (the commit
signature address) should be stored in index field
alternate_email
- the user's Slack email address should be stored in a string field
named
workspace_email
- multiple items can be created with different values for
alternate_email
pointing to the sameworkspace_email
value - the table should have the following definition:
ruby AttributeDefinitions [ { AttributeName: 'alternate_email', AttributeType: 'S' } ] KeySchema [ { AttributeName: 'alternate_email', KeyType: 'HASH' } ]
IAM Service Role for CodeBuild projects
You will likely already have a service role granting CloudWatch access, to which you will want to add the following, substituing your region, account id, and if different, dynamo table name and secrets-manager secret name:
{
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:UpdateItem"
],
"Effect": "Allow",
"Resource": [
"arn:aws:dynamodb:<your-region>:<your-account-id>:table/codebuild-history",
"arn:aws:dynamodb:<your-region>:<your-account-id>:table/codbuild-history/*",
// if optional slack alias table is configured
"arn:aws:dynamodb:<your-region>:<your-account-id>:table/codebuild-slack-aliases",
"arn:aws:dynamodb:<your-region>:<your-account-id>:table/codbuild-slack-aliases/*"
]
},
{
"Action": "secretsmanager:GetSecretValue",
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:<your-region>:<your-account-id>:secret:slack/codebuild*"
]
}
Configuration
Installation
Pre-requisites
The base docker image used for your CodeBuild project must include ruby, or you must install it using the project's buildspec.yml file. Any ruby from 2.3.x to 2.5.x will work.
Using buildspec
Add to the install:
phase of your buildspec.yml
phases:
install:
commands:
- gem install codebuild-notifier
Using custom Docker image
Add to your Dockerfile
RUN gem install codebuild-notifier
Usage
Add to the post_build:
phase of your buildspec.yml file
phases:
post_build:
commands:
- update-build-status
Configuration
ENV vars
ENV vars can either be set in Dockerfile e.g.
ENV CBN_SLACK_ADMIN_USERNAMES scooby,shaggy
Or in buildspec.yml
env:
variables:
CBN_SLACK_ADMIN_USERNAMES: 'fred,velma'
command-line
In buildspec.yml
phases:
post_build:
commands:
- update-build-status --slack-admin-usernames="fred,velma"
Options
ENV var | command-line | Default value | Notes |
---|---|---|---|
CBN_ADDITIONAL_CHANNEL |
|
not set | If whitelist branches are set, status notifications for these branches can be sent to this channel, as well as direct messages to the author/committer of the commit triggering the build. |
CBN_AWS_REGION |
|
value of AWS_REGION env var in CodeBuild container | If for some reason the dynamo table and secrets-manager live in a different region than where CodeBuild is executing, you can specify that region. |
CBN_DEFAULT_NOTIFY_STRATEGY |
|
fail_or_status_change | Determines when notifications will be sent. 'status_change' sends notifications for the first build in a PR or whitelisted branch, thereafter if a build in that PR/branch has a different status to the previous build. 'every_build' sends a notification regardless of status. 'fail_or_status_change', the default value, will send if the status changes, but will also send notifications of every failure, regardless of previous status. |
CBN_DYNAMO_TABLE |
|
codebuild-history | This table must be created and permissions granted to it as described in Infrastructure Requirements |
CBN_OVERRIDE_NOTIFY_STRATEGY |
|
not set | Allows overriding default notify strategy. Specify a branch and strategy for that branch, with a colon separator. Valid strategies are: status_change, every_build, fail_or_status_change Specify multiple branch strategies delimited by comma. e.g. 'master:every_build,jira-15650:status_change' |
CBN_SLACK_ADMIN_USERNAMES |
|
not set |
If no Slack user can be found in your workspace with the email
address of the author or committer of a commit, a message will be
sent to the Slack usernames specified. Separate multiple values with commas, with no spaces. e.g. fred,velma |
CBN_SLACK_ALIAS_TABLE |
|
not set | If no Slack user can be found in your workspace with the email address of the author or committer of a commit, this table will be queried to find the Slack workspace email matching the failed address. |
CBN_SLACK_SECRET_NAME |
|
slack/codebuild | The name of a secret in AWS Secrets Manager with the app or bot auth token. |
CBN_WHITELIST_BRANCHES |
|
master |
Normally statuses will be stored and notifications sent only for builds
triggered by commits to branches with open Pull Requests. However, it
can be useful to get notifications for all commits to certain branches,
regardless of Pull Request status. Separate multiple values with commas, without spaces. e.g. 'master,nightly,jira-50012' |