Automate code deploys with CI/CD
Continuous Integration and Continuous Delivery (CI/CD) is an industry term that refers to programmatic workflows that automate key parts of the software development lifecycle, including code changes, builds, and testing. CI/CD enables teams to develop faster, more securely, and more reliably.
On Astro, you can use Deployment API keys to automate deploying code changes to a Deployment. Astronomer recommends setting up a CI/CD workflow for all production environments.
You can use the Astronomer CI/CD templates with popular CI/CD management tools, including GitHub Actions and Circle CI.
Benefits
There are many benefits to configuring a CI/CD workflow that automates pushing code changes to Astro. Specifically, you can:
- Deploy new and updated DAGs in a way that streamlines your development process.
- Decrease the maintenance cost of integrating changes, allowing your team to quickly respond in case of an error or failure.
- Enforce continuous, automating testing, which increases code quality and protects your DAGs in production.
Prerequisites
- A Deployment API key ID and secret
- A CI/CD management tool, such as GitHub Actions.
- An Astro project that is hosted in a place that your CI/CD tool can access.
CI/CD templates
Templates allow you to quickly configure individual CI pipelines using popular CI/CD tools. Each template can be implemented as-is to produce a simple CI/CD pipeline. Astronomer recommends reconfiguring the templates to work with your own directory structures, workflows, and best practices.
The CI/CD templates let you:
- Access Deployment API key credentials. These credentials must be set as OS-level environment variables named
ASTRONOMER_KEY_ID
andASTRONOMER_KEY_SECRET
. - Install the latest version of the Astro CLI.
- Run
astro deploy
. This creates a Docker image for your Astro project, authenticates to Astro using your Deployment API key, and pushes the image to your Deployment.
This workflow is equivalent to the following bash script:
# Set Deployment API key credentials as environment variables
$ export ASTRONOMER_KEY_ID="<your-api-key-id>"
$ export ASTRONOMER_KEY_SECRET="<your-api-key-secret>"
# Install the latest version of Astro CLI
$ curl -sSL install.astronomer.io | sudo bash -s
# Build your Astro project into a Docker image and push the image to your Deployment
$ astro deploy
The following templates use Astro CLI v1.0+ to deploy via CI/CD. These templates will not work if you use the astrocloud
executable. To upgrade, see Install the Astro CLI.
GitHub Actions
- Standard
- Multi-branch
- Custom Image
To automate code deploys to a Deployment using GitHub Actions, complete the following setup in a Git-based repository that hosts an Astro project:
Set the following as GitHub secrets:
ASTRONOMER_KEY_ID
=<your-key-id>
ASTRONOMER_KEY_SECRET
=<your-key-secret>
In your project repository, create a new YAML file in
.github/workflows
that includes the following configuration:name: Astronomer CI - Deploy code
on:
push:
branches:
- main
env:
## Sets Deployment API key credentials as environment variables
ASTRONOMER_KEY_ID: ${{ secrets.ASTRONOMER_KEY_ID }}
ASTRONOMER_KEY_SECRET: ${{ secrets.ASTRONOMER_KEY_SECRET }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v2.3.4
- name: Deploy to Astro
run: |
curl -sSL install.astronomer.io | sudo bash -s
astro deploy
The following setup can be used to create a multi-branch CI/CD pipeline using GitHub Actions. A multi-branch pipeline makes can be used to test DAGs in a development Deployment and promote them to a production Deployment. The finished pipeline would deploy your code to Astro as demonstrated in the following diagram:
This setup assumes the following prerequisites:
- You have both a
dev
andmain
branch of an Astro project hosted in a single GitHub repository. - You have respective
dev
andprod
Deployments on Astro where you deploy your GitHub branches to. - You have unique Deployment API keys and secrets for both of your Deployments.
Set the following as GitHub secrets:
PROD_ASTRONOMER_KEY_ID
=<your-prod-key-id>
PROD_ASTRONOMER_KEY_SECRET
=<your-prod-key-secret>
DEV_ASTRONOMER_KEY_ID
=<your-dev-key-id>
DEV_ASTRONOMER_KEY_SECRET
=<your-dev-key-secret>
In your project repository, create a new YAML file in
.github/workflows
that includes the following configuration:name: Astronomer CI - Deploy code (Multiple Branches)
on:
push:
branches: [dev]
pull_request:
types:
- closed
branches: [main]
jobs:
dev-push:
if: github.ref == 'refs/heads/dev'
env:
## Sets DEV Deployment API key credentials as environment variables
ASTRONOMER_KEY_ID: ${{ secrets.DEV_ASTRONOMER_KEY_ID }}
ASTRONOMER_KEY_SECRET: ${{ secrets.DEV_ASTRONOMER_KEY_SECRET }}
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v2.3.4
- name: Deploy to Astro
run: |
curl -sSL install.astronomer.io | sudo bash -s
astro deploy
prod-push:
if: github.event.action == 'closed' && github.event.pull_request.merged == true
env:
## Sets PROD Deployment API key credentials as environment variables
ASTRONOMER_KEY_ID: ${{ secrets.PROD_ASTRONOMER_KEY_ID }}
ASTRONOMER_KEY_SECRET: ${{ secrets.PROD_ASTRONOMER_KEY_SECRET }}
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v2.3.4
- name: Deploy to Astro
run: |
curl -sSL install.astronomer.io | sudo bash -s
astro deploy
If your Astro project requires additional build-time arguments to build an image, you need to define these build arguments using Docker's build-push-action
.
Prerequisites
To complete this setup, you need:
- An Astro project that requires additional build-time arguments to build the Runtime image.
Setup
- Set the following as GitHub secrets:
ASTRONOMER_KEY_ID
=<your-key-id>
ASTRONOMER_KEY_SECRET
=<your-key-secret>
In your project repository, create a new YAML file in
.github/workflows
that includes the following configuration:name: Astronomer CI - Additional build-time args
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
env:
ASTRONOMER_KEY_ID: ${{ secrets.ASTRO_ACCESS_KEY_ID_DEV }}
ASTRONOMER_KEY_SECRET: ${{ secrets.ASTRO_SECRET_ACCESS_KEY_DEV }}
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Create image tag
id: image_tag
run: echo ::set-output name=image_tag::astro-$(date +%Y%m%d%H%M%S)
- name: Build image
uses: docker/build-push-action@v2
with:
tags: ${{ steps.image_tag.outputs.image_tag }}
load: true
# Define your custom image's build arguments, contexts, and connections here using
# the available GitHub Action settings:
# https://github.com/docker/build-push-action#customizing .
# This example uses `build-args` , but your use case might require configuring
# different values.
build-args: |
<your-build-arguments>
- name: Deploy to Astro
run: |
curl -sSL install.astronomer.io | sudo bash -s
astro deploy --image-name ${{ steps.image_tag.outputs.image_tag }}For example, to create a CI/CD pipeline that deploys a project which installs Python packages from a private GitHub repository, you would use the following configuration:
name: Astronomer CI - Custom base image
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
env:
ASTRONOMER_KEY_ID: ${{ secrets.ASTRO_ACCESS_KEY_ID_DEV }}
ASTRONOMER_KEY_SECRET: ${{ secrets.ASTRO_SECRET_ACCESS_KEY_DEV }}
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Create image tag
id: image_tag
run: echo ::set-output name=image_tag::astro-$(date +%Y%m%d%H%M%S)
- name: Create SSH Socket
uses: webfactory/ssh-agent@v0.5.4
with:
# GITHUB_SSH_KEY must be defined as a GitHub secret.
ssh-private-key: ${{ secrets.GITHUB_SSH_KEY }}
- name: (Optional) Test SSH Connection - Should print hello message.
run: (ssh git@github.com) || true
- name: Build image
uses: docker/build-push-action@v2
with:
tags: ${{ steps.image_tag.outputs.image_tag }}
load: true
ssh: |
github=${{ env.SSH_AUTH_SOCK }
- name: Deploy to Astro
run: |
curl -sSL install.astronomer.io | sudo bash -s
astro deploy --image-name ${{ steps.image_tag.outputs.image_tag }}infoIf you need guidance configuring a CI/CD pipeline for a more complex use case involving custom Runtime images, reach out to Astronomer support.
Jenkins
- Standard
- Multi-branch
To automate code deploys to a single Deployment using Jenkins, complete the following setup in a Git-based repository hosting an Astro project:
In your Jenkins pipeline configuration, add the following parameters:
ASTRONOMER_KEY_ID
: Your Deployment API key IDASTRONOMER_KEY_SECRET
: Your Deployment API key secretASTRONOMER_DEPLOYMENT_ID
: The Deployment ID of your production deployment
Be sure to set the values for your API credentials as secret.
At the root of your Git repository, add a Jenkinsfile that includes the following script:
pipeline {
agent any
stages {
stage('Deploy to Astronomer') {
when {
expression {
return env.GIT_BRANCH == "origin/main"
}
}
steps {
script {
sh 'curl -LJO https://github.com/astronomer/astro-cli/releases/download/v1.6.0/astro_1.6.0_linux_amd64.tar.gz'
sh 'tar xzf astro_1.6.0_linux_amd64.tar.gz'
sh "./astro deploy ${ASTRONOMER_DEPLOYMENT_ID} -f"
}
}
}
}
post {
always {
cleanWs()
}
}
}This Jenkinsfile triggers a code push to Astro every time a commit or pull request is merged to the
main
branch of your repository.
To automate code deploys across multiple Deployments using Jenkins, complete the following setup in a Git-based repository hosting an Astro project:
In Jenkins, add the following environment variables:
PROD_ASTRONOMER_KEY_ID
: Your Production Deployment API key IDPROD_ASTRONOMER_KEY_SECRET
: Your Production Deployment API key secretPROD_DEPLOYMENT_ID
: The Deployment ID of your Production DeploymentDEV_ASTRONOMER_KEY_ID
: Your Development Deployment API key IDDEV_ASTRONOMER_KEY_SECRET
: Your Development Deployment API key secretDEV_DEPLOYMENT_ID
: The Deployment ID of your Development Deployment
To set environment variables in Jenkins, on the Jenkins Dashboard go to Manage Jenkins > Configure System > Global Properties > Environment Variables > Add.
Be sure to set the values for your API credentials as secret.
At the root of your Git repository, add a Jenkinsfile that includes the following script:
pipeline {
agent any
stages {
stage('Set Environment Variables') {
steps {
script {
if (env.GIT_BRANCH == 'main') {
echo "The git branch is undefined";
env.ASTRONOMER_KEY_ID = env.PROD_ASTRONOMER_KEY_ID;
env.ASTRONOMER_KEY_SECRET = env.PROD_ASTRONOMER_KEY_SECRET;
env.ASTRONOMER_DEPLOYMENT_ID = env.PROD_DEPLOYMENT_ID;
} else if (env.GIT_BRANCH == 'dev') {
echo "The git branch is undefined";
env.ASTRONOMER_KEY_ID = env.DEV_ASTRONOMER_KEY_ID;
env.ASTRONOMER_KEY_SECRET = env.DEV_ASTRONOMER_KEY_SECRET;
env.ASTRONOMER_DEPLOYMENT_ID = env.DEV_DEPLOYMENT_ID;
} else {
echo "This git branch undefined is not configured in this pipeline."
}
}
}
}
stage('Deploy to Astronomer') {
steps {
script {
sh 'curl -LJO https://github.com/astronomer/astro-cli/releases/download/v1.6.0/astro_1.6.0_linux_amd64.tar.gz'
sh 'tar xzf astro_1.6.0_linux_amd64.tar.gz'
sh "./astro deploy ${ASTRONOMER_DEPLOYMENT_ID} -f"
}
}
}
}
post {
always {
cleanWs()
}
}
}
}This Jenkinsfile triggers a code push to an Astro Deployment every time a commit or pull request is merged to the
dev
ormain
branch of your repository.
AWS CodeBuild
- Standard
- Multi-branch
To automate code deploys to a single Deployment using AWS CodeBuild, complete the following setup in a Git-based repository hosting an Astro project:
In your AWS CodeBuild pipeline configuration, add the following environment variables:
ASTRONOMER_KEY_ID
: Your Deployment API key IDASTRONOMER_KEY_SECRET
: Your Deployment API key secretASTRONOMER_DEPLOYMENT_ID
: The Deployment ID of your production deployment
Be sure to set the values for your API credentials as secret.
At the root of your Git repository, add a buildspec.yml file that includes the following script:
version: 0.2
phases:
install:
runtime-versions:
python: latest
build:
commands:
- echo "${CODEBUILD_WEBHOOK_HEAD_REF}"
- export ASTRONOMER_KEY_ID="${ASTRONOMER_KEY_ID}"
- export ASTRONOMER_KEY_SECRET="${ASTRONOMER_KEY_SECRET}"
- curl -sSL install.astronomer.io | sudo bash -s
- astro deploy "${ASTRONOMER_DEPLOYMENT_ID}" -fIn your AWS CodeBuild project, create a webhook event for the source provider where your Astro project is hosted, such as BitBucket or GitHub. When configuring the webhook, select an event type of
PUSH
.
Your buildspec.yml file now triggers a code push to an Astro Deployment every time a commit or pull request is merged to the main
branch of your repository.
To automate code deploys across multiple Deployments using AWS CodeBuild, complete the following setup in a Git-based repository hosting an Astro project:
In your AWS CodeBuild pipeline configuration, add the following environment variables:
PROD_ASTRONOMER_KEY_ID
: Your Production Deployment API key IDPROD_ASTRONOMER_KEY_SECRET
: Your Production Deployment API key secretPROD_DEPLOYMENT_ID
: The Deployment ID of your Production DeploymentDEV_ASTRONOMER_KEY_ID
: Your Development Deployment API key IDDEV_ASTRONOMER_KEY_SECRET
: Your Development Deployment API key secretDEV_DEPLOYMENT_ID
: The Deployment ID of your Development Deployment
At the root of your Git repository, add a buildspec.yml that includes the following script:
version: 0.2
phases:
install:
runtime-versions:
python: latest
build:
commands:
- |
if expr "${CODEBUILD_WEBHOOK_HEAD_REF}" : "refs/heads/main" >/dev/null; then
export ASTRONOMER_KEY_ID="${PROD_ASTRONOMER_KEY_ID}"
export ASTRONOMER_KEY_SECRET="${PROD_ASTRONOMER_KEY_SECRET}"
curl -sSL install.astronomer.io | sudo bash -s
astro deploy "${PROD_DEPLOYMENT_ID}" -f
fi
- |
if expr "${CODEBUILD_WEBHOOK_HEAD_REF}" : "refs/heads/dev" >/dev/null; then
export ASTRONOMER_KEY_ID="${DEV_ASTRONOMER_KEY_ID}"
export ASTRONOMER_KEY_SECRET="${DEV_ASTRONOMER_KEY_SECRET}"
curl -sSL install.astronomer.io | sudo bash -s
astro deploy "${DEV_DEPLOYMENT_ID}" -f
fi- In your AWS CodeBuild project, create a webhook event for the source provider where your Astro project is hosted, such as BitBucket or GitHub. When configuring the webhook, select an event type of
PUSH
.
- In your AWS CodeBuild project, create a webhook event for the source provider where your Astro project is hosted, such as BitBucket or GitHub. When configuring the webhook, select an event type of
Your buildspec.yml file now triggers a code push to an Astro Deployment every time a commit or pull request is merged to the main
branch of your repository.
CircleCI
To automate code deploys to a Deployment using CircleCI, complete the following setup in a Git-based repository that hosts an Astro project:
Set the following environment variables in a CircleCI context:
ASTRONOMER_KEY_ID
=<your-key-id>
ASTRONOMER_KEY_SECRET
=<your-key-secret>
Create a new YAML file in
.circleci/config.yml
that includes the following configuration:# Use the latest 2.1 version of CircleCI pipeline process engine.
# See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1
orbs:
docker: circleci/docker@2.0.1
github-cli: circleci/github-cli@2.0.0
# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
build_image_and_deploy:
docker:
- image: cimg/base:stable
# Add steps to the job
# See: https://circleci.com/docs/2.0/configuration-reference/#steps
steps:
- setup_remote_docker:
version: 20.10.11
- checkout
- run:
name: "Setup custom environment variables"
command: |
echo export ASTRONOMER_KEY_ID=${ASTRONOMER_KEY_ID} >> $BASH_ENV
echo export ASTRONOMER_KEY_SECRET=${ASTRONOMER_KEY_SECRET} >> $BASH_ENV
- run:
name: "Deploy to Astro"
command: |
curl -sSL install.astronomer.io | sudo bash -s
astro deploy -f
# Invoke jobs via workflows
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
workflows:
version: 2.1
build-and-deploy-prod:
jobs:
- build_image_and_deploy:
context:
- <YOUR-CIRCLE-CI-CONTEXT>
filters:
branches:
only:
- main
Drone
To automate code deploys to a Deployment using a Docker-based Drone CI pipeline, complete the following setup in a Git-based repository that hosts an Astro project.
Prerequisites
This pipeline configuration requires:
- A functional Drone server and Docker runner.
- A user with admin privileges to your Drone server.
Set the following environment variables as repository-level secrets on Drone:
ASTRONOMER_KEY_ID
=<your-key-id>
ASTRONOMER_KEY_SECRET
=<your-key-secret>
In your Drone server, open your Astro project repository and go to Settings > General. Under Project Settings, turn on the Trusted setting.
In the top level of your Git repository, create a file called
.drone.yml
that includes the following configuration:---
kind: pipeline
type: docker
name: deploy
steps:
- name: install
image: debian
commands:
- apt-get update
- apt-get -y install curl
- curl -sSL install.astronomer.io | sudo bash -s
- name: wait
image: docker:dind
volumes:
- name: dockersock
path: /var/run
commands:
- sleep 5
- name: deploy
image: docker:dind
volumes:
- name: dockersock
path: /var/run
commands:
- astro deploy -f
depends on:
- wait
environment:
ASTRONOMER_KEY_ID:
from_secret: ASTRONOMER_KEY_ID
ASTRONOMER_KEY_SECRET:
from_secret: ASTRONOMER_KEY_SECRET
services:
- name: docker
image: docker:dind
privileged: true
volumes:
- name: dockersock
path: /var/run
volumes:
- name: dockersock
temp: {}
trigger:
branch:
- main
event:
- push
GitLab
- Standard
- Multi-branch
To automate code deploys to a Deployment using GitLab, complete the following setup in your GitLab repository that hosts an Astro project:
In GitLab, go to Project Settings > CI/CD > Variables and set the following environment variables:
ASTRONOMER_KEY_ID
=<your-key-id>
ASTRONOMER_KEY_SECRET
=<your-key-secret>
Go to the Editor option in your project's CI/CD section and commit the following:
---
astro_deploy:
stage: deploy
image: docker:latest
services:
- docker:dind
variables:
ASTRONOMER_KEY_ID: $ASTRONOMER_KEY_ID
ASTRONOMER_KEY_SECRET: $ASTRONOMER_KEY_SECRET
before_script:
- apk add --update curl && rm -rf /var/cache/apk/*
- apk add bash
script:
- curl -sSL install.astronomer.io | bash -s
- astro deploy -f
only:
- main
To automate code deploys to Astro across multiple environments using GitLab, complete the following setup in your GitLab repository that hosts an Astro project:
In GitLab, go to Project Settings > CI/CD > Variables and set the following environment variables:
DEV_ASTRONOMER_KEY_ID
=<your-dev-key-id>
DEV_ASTRONOMER_KEY_SECRET
=<your-dev-key-secret>
PROD_ASTRONOMER_KEY_ID
=<your-prod-key-id>
PROD_ASTRONOMER_KEY_SECRET
=<your-prod-key-secret>
When you create environment variables that will be used in multiple branches, you may want to protect the branch they are being used in. Otherwise, uncheck the Protect variable
flag when you create the variable in GitLab. For more information on protected branches, see GitLab documentation.
Go to the Editor option in your project's CI/CD section and commit the following:
---
astro_deploy_dev:
stage: deploy
image: docker:latest
services:
- docker:dind
variables:
ASTRONOMER_KEY_ID: $DEV_ASTRONOMER_KEY_ID
ASTRONOMER_KEY_SECRET: $DEV_ASTRONOMER_KEY_SECRET
before_script:
- apk add --update curl && rm -rf /var/cache/apk/*
- apk add bash
script:
- curl -sSL install.astronomer.io | bash -s
- astro deploy -f
only:
- dev
astro_deploy_prod:
stage: deploy
image: docker:latest
services:
- docker:dind
variables:
ASTRONOMER_KEY_ID: $PROD_ASTRONOMER_KEY_ID
ASTRONOMER_KEY_SECRET: $PROD_ASTRONOMER_KEY_SECRET
before_script:
- apk add --update curl && rm -rf /var/cache/apk/*
- apk add bash
script:
- curl -sSL install.astronomer.io | bash -s
- astro deploy -f
only:
- main
Bitbucket
To automate code deploys to a Deployment using Bitbucket, complete the following setup in a Git-based repository that hosts an Astro project:
Set the following environment variables as Bitbucket pipeline variables:
ASTRONOMER_KEY_ID
=<your-key-id>
ASTRONOMER_KEY_SECRET
=<your-key-secret>
Create a new YAML file in
bitbucket-pipelines.yml
at the root of the repository that includes the following configuration:
pipelines:
pull-requests: # The branch pattern under pull requests defines the *source* branch.
dev:
- step:
name: Deploy to Production
deployment: Production
script:
- curl -sSL install.astronomer.io | sudo bash -s
- astro deploy
services:
- docker
Azure DevOps
To automate code deploys to a Deployment using Azure DevOps, complete the following setup in a Git-based repository that hosts an Astro project:
Set the following environment variables as DevOps pipeline variables:
ASTRONOMER_KEY_ID
=<your-key-id>
ASTRONOMER_KEY_SECRET
=<your-key-secret>
Create a new YAML file in
astro-devops-cicd.yaml
at the root of the repository that includes the following configuration:
trigger:
- main
pr: none
stages:
- stage: deploy
jobs:
- job: deploy_image
pool:
vmImage: 'Ubuntu-latest'
steps:
- script: |
curl -sSL install.astronomer.io | sudo bash -s
astro deploy
env:
ASTRONOMER_KEY_ID: $(ASTRONOMER_KEY_ID)
ASTRONOMER_KEY_SECRET: $(ASTRONOMER_KEY_SECRET)