CI/CD on AWS with feature-branch builds, developer-environment deployments, and build status notifications.
Project description
Opinionated CDK CI Pipeline
CI/CD utilizing CDK Pipelines.
Features:
- pipeline deploying application from the default branch to multiple environments on multiple accounts,
- feature branch deployments to ephemeral environments,
- development environments deployments from the local CLI,
- build status notifications to repository commits,
- build failures notifications to SNS.
Currently supported source repositories are GitHub and Bitbucket.
Table of contents
Usage
To set up, you need to complete the following steps:
- Install the library in your project.
- Specify target account and region for deployed environments.
- Create
CDKApplication
with build process configuration. - Create repository access token for build status notifications.
- Bootstrap the CDK on the AWS account(s).
- Deploy the CI.
- Setup source repository mirroring to CodeCommit.
At the end, you will have CI pipeline in place, and be able to deploy your own custom environment from the CLI as well.
1. Install
For Node.js:
npm install -D opinionated-ci-pipeline
For Python:
pip install opinionated-ci-pipeline
2. Set context parameters
Add project name and environments config in the cdk.json
as context
parameters.
Each environment must have account
and region
provided.
{
"app": "...",
"context": {
"projectName": "myproject",
"environments": {
"default": {
"account": "111111111111",
"region": "us-east-1"
},
"prod": {
"account": "222222222222",
"region": "us-east-1"
}
}
}
}
The project name will be used as a prefix for the deployed CI Stack name.
Environment names should match environments provided later
in the CDKApplication
configuration.
The optional default
environment configuration is used as a fallback.
The CI pipeline itself is deployed to the ci
environment,
with a fallback to the default
environment as well.
3. Create CDKApplication
In the CDK entrypoint script referenced by the cdk.json
app
field,
replace the content with an instance of CDKApplication
:
#!/usr/bin/env node
import 'source-map-support/register';
import {ExampleStack} from '../lib/exampleStack';
import {CDKApplication} from 'opinionated-ci-pipeline';
new CDKApplication({
stacks: {
create: (scope, projectName, envName) => {
new ExampleStack(scope, 'ExampleStack', {stackName: `${projectName}-${envName}-ExampleStack`});
},
},
repository: {
host: 'github',
name: 'organization/repository',
},
packageManager: 'npm',
pipeline: [
{
environment: 'test',
post: [
'echo "do integration tests here"',
],
},
{
environment: 'prod',
},
],
});
This configures the application with one Stack
and a pipeline deploying to an environment test
,
running integration tests, and deploying to environment prod
.
The test
and prod
environments will be deployed
from the branch main
(by default).
All other branches will be deployed to separate environments.
Those feature-branch environments will be destroyed after the branch is removed.
To allow deployment of multiple environments, the Stack(s) name must include the environment name.
4. Create repository access token secret
An access to the source repository is required to send build status notifications, visible in commit status and Pull Requests.
GitHub
Create a fine-grained personal access token with "commit statuses" read and write access.
Then create a secret in AWS Secrets Manager
named /PROJECT_NAME/githubAuthorization
with the generated token:
{
"header": "Bearer xxx"
}
Bitbucket
Create an access token in Bitbucket repository settings
with repository:write
access.
Then create a secret in AWS Secrets Manager
named /PROJECT_NAME/bitbucketAuthorization
with the generated token:
{
"header": "Bearer xxx"
}
5. Bootstrap the CDK
Bootstrap the CDK on the account holding the CI pipeline and all other accounts the pipeline will be deploying to.
When bootstrapping other accounts, add the --trust
parameter
with the account ID of the account holding the pipeline.
6. Deploy the CI Stack
Run:
cdk deploy -c ci=true
7. Setup source repository mirroring
Because of multiple drawbacks of "native" CodePipeline and CodeBuild integrations with GitHub and Bitbucket, the CI builds use CodeCommit as a source. You must configure GitHub / Bitbucket to mirror the repository to CodeCommit.
CI stack creates a CodeCommit repository (named the same as the projectName
context value)
and IAM user {PROJECT_NAME}-ci-repository-mirror-user
with access to it.
GitHub
-
Create an SSH key pair with
ssh-keygen -t rsa -b 4096
command. -
Upload the public key as an SSH key for AWS CodeCommit in the created IAM user security credentials settings.
-
Create secrets in the GitHub repository settings under "Secrets and variables" -> "Actions":
CODECOMMIT_SSH_PRIVATE_KEY
- the private key generated in step 1.CODECOMMIT_SSH_PRIVATE_KEY_ID
- the SSH key ID of uploaded key from IAM user.
-
Create
.github/workflows/mirror-repository.yml
file (update theREGION
andPROJECT_NAME
intarget_repo_url
):
name: Mirror to CodeCommit
on: [ push, delete ]
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: pixta-dev/repository-mirroring-action@v1
with:
target_repo_url: ssh://git-codecommit.REGION.amazonaws.com/v1/repos/PROJECT_NAME
ssh_private_key: ${{ secrets.CODECOMMIT_SSH_PRIVATE_KEY }}
ssh_username: ${{ secrets.CODECOMMIT_SSH_PRIVATE_KEY_ID }}
Bitbucket
-
Create an SSH key pair in the Bitbucket repository Pipeline config.
-
Upload the public key as an SSH key for AWS CodeCommit in the created IAM user security credentials settings.
-
Create secrets in the Bitbucket repository Pipeline settings:
CODECOMMIT_SSH_PRIVATE_KEY
- the private key generated in step 1.CODECOMMIT_SSH_PRIVATE_KEY_ID
- the SSH key ID of uploaded key from IAM user.
-
Put
git-codecommit.REGION.amazonaws.com
in Bitbucket repository SSH Keys Known hosts (update theREGION
). -
Create
bitbucket-pipelines.yml
file (update theREGION
andPROJECT_NAME
):
image: atlassian/default-image:4
clone:
depth: full
pipelines:
default:
- step:
name: Sync to CodeCommit
script:
- echo "User ${SSH_KEY_ID}" >> ~/.ssh/config
# fetch all branches to mirror the whole repository
- for remote in `git branch -r | grep -v -- '->' | grep -v -- "${BITBUCKET_BRANCH}"`; do git branch --track ${remote#origin/} $remote; done
# mirror repository; it will remove deleted branches as well
- git push --mirror ssh://git-codecommit.REGION.amazonaws.com/v1/repos/REPOSITORY-NAME
Deploy development environment
Run:
cdk deploy -c env=MYENV --all
to deploy arbitrary environments.
Parameters
Name | Type | Description |
---|---|---|
stacks | object |
An object with a create() method to create Stacks for the application.
The same Stacks will be deployed with main pipeline, feature-branch builds, and local deployments. |
packageManager | npm | pnpm |
Package manager used in the repository.
If provided, the install commands will be set to install dependencies using given package manager. |
commands | object |
Commands executed to build and deploy the application.
Commands executed on particular builds:
|
cdkOutputDirectory | string |
The location where CDK outputs synthetized files.
Corresponds to the CDK Pipelines |
pipeline | object[] |
CodePipeline deployment pipeline for the main repository branch.
Can contain environments to deploy and waves that deploy multiple environments in parallel. Each environment and wave can have pre and post commands that will be executed before and after the environment or wave deployment. |
codeBuild | object | Override CodeBuild properties, used for the main pipeline as well as feature branch ephemeral environments deploys and destroys. |
codePipeline | object | Override CodePipeline properties. |
slackNotifications | object | Configuration for Slack notifications. Requires configuring AWS Chatbot client manually first. |
Notifications and alarms
Stack creates SNS Topics with notifications for main pipeline failures and feature branch build failures. Their ARNs are saved in SSM Parameters and outputed by the stack:
-
main pipeline failures:
- SSM:
/{projectName}/ci/pipelineFailuresTopicArn
- Stack exported output:
{projectName}-ci-pipelineFailuresTopicArn
- SSM:
-
feature branch build failures:
- SSM:
/{projectName}/ci/featureBranchBuildFailuresTopicArn
- Stack exported output:
{projectName}-ci-featureBranchBuildFailuresTopicArn
- SSM:
If you setup Slack notifications, you can configure those failure notifications to be sent to Slack.
Moreover, if you setup Slack notifications, an additional SNS Topic will be created to which you can send CloudWatch Alarms. It's ARN is provided:
- SSM:
/{projectName}/ci/slackAlarmsTopicArn
- Stack exported output:
{projectName}-ci-slackAlarmsTopicArn
Library development
Project uses jsii to generate packages for different languages.
Install dependencies:
npm install
Build:
npm run build
Install and deploy example application:
cd example
pnpm install
pnpm cdk deploy -c ci=true
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file opinionated-ci-pipeline-1.0.0b1.tar.gz
.
File metadata
- Download URL: opinionated-ci-pipeline-1.0.0b1.tar.gz
- Upload date:
- Size: 402.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2f4bae9aefaa67f90f7e8204aa67aaf4ef72b9ad60c91163b5a8b50fddbc9e2f |
|
MD5 | 2014b664c73549420ff9e94bcfe8bf61 |
|
BLAKE2b-256 | 024bac64656599b634a7796b7d3d37e1ee0e1b77e10b6c760ef171873b7f6ba9 |
File details
Details for the file opinionated_ci_pipeline-1.0.0b1-py3-none-any.whl
.
File metadata
- Download URL: opinionated_ci_pipeline-1.0.0b1-py3-none-any.whl
- Upload date:
- Size: 399.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1c334f88ebcd90a8435766640bf63c333dd860535820b61cc7e9246050dd6443 |
|
MD5 | f61bc8fe6d8cafd1a062784dd80dc014 |
|
BLAKE2b-256 | bddc98062c88e24e912595ebef6b11ab5ca8f6207a4793d65d2d83340cfa2d3e |