DEV Community

Ran Isenberg for AWS Community Builders

Posted on • Edited on • Originally published at ranthebuilder.cloud

25

Deploy to AWS with GitHub Actions and AWS CDK

[https://www.ranthebuilder.cloud/](https://www.ranthebuilder.cloud/)

This blog was originally published on my website “Ran The Builder”.

This blog explains how you can use AWS CDK to deploy to your AWS account using GitHub Actions CI/CD pipeline.

Feel free to use the code snippets as you please.

Click here and here to view a fully working GitHub AWS Serverless service template that uses the same snippet.

Going Over The Job Steps

Let’s go over the CI/CD pipeline steps:

  1. Environment setup

  2. AWS account setup

  3. Run linters & unit tests

  4. Deploy stack

  5. Run E2E tests

  6. Destroy stack (for dev stack only)

Environment Setup

Python & Node Setup

name: AWS Service CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: "16"
view raw env_setup.yml hosted with ❤ by GitHub

This snippet will setup Python 3.9 and Node v16 in the CI/CD runner.

Setup AWS CDK

name: AWS Service CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Install Python dependencies and CDK
run: |
python -m pip install --upgrade pip
# install your Python dependencies here
npm install -g aws-cdk
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@master
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: "us-east-1"
- name: Deploy to AWS
run: cdk deploy --app="python3 ${PWD}/cdk/my_service/app.py" --require-approval=never
- name: Destroy stack
run: cdk destroy --app="python3 ${PWD}/cdk/my_service/app.py" --force
view raw cdk-python.yml hosted with ❤ by GitHub

It’s recommended to use latest pip and AWS CDK version.

In line 4, you should install your Python dependencies with either pip, pipenv, or poetry, depending on your weapon of choice to manage Python dependencies.

These dependencies include development dependencies (pytest, linters, etc.) and service runtime dependencies.

Setup AWS Secrets

You must set up GitHub’s repository secrets for this snippet to work.

Under Settings/Secrets/Actions, add ‘AWS_SECRET_KEY’ and ‘AWS_ACCESS_KEY’.

These secrets are used in a predefined IAM role you created for your CI/CD process.

This is a simple example; however, for security reasons, it is best to use an SSO solution (out of the scope of this guide).

The yaml config:

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@master
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: "us-east-1"
view raw secrets.yml hosted with ❤ by GitHub

In line 7, choose your AWS region of choice.

Linters & Unit Tests

Right before deployment, it is recommended to run linters such as:

  1. pylint/flake8

  2. pre-commit checks

  3. yapf/black

  4. Code complexity checks (radon/xenon)

See the linters example and configuration at my GitHub template here and the makefile that runs the linters commands here.

Once the linters finish, run unit tests as a first service logic gate.

Deploy Time

- name: Deploy to AWS
run: cdk deploy --app="python3 ${PWD}/cdk/my_service/app.py" --require-approval=never
view raw deploy.yml hosted with ❤ by GitHub

In line3, you must set the correct path to your CDK ‘app.py’ file.

I usually put all the CDK project files in a ‘cdk’ folder instead of the root project path.

E2E Tests

Once deployment is completed, you should run your E2E tests and make sure your service runs properly on AWS. You can use pytest to create REST API requests or other triggers to test your deployed service.

Destroy Stack

This step is relevant only for local stack or pull requests where you want to destroy the stack in the end.

- name: Destroy stack
run: cdk destroy --app="python3 ${PWD}/cdk/my_service/app.py" --force
view raw destroy.yml hosted with ❤ by GitHub

As in the deployment stage, make sure set the correct path to your CDK ‘app.py’ file.

The Full Flow

name: AWS Service CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: "16"
- name: Install Python dependencies and CDK
run: |
python -m pip install --upgrade pip
# install your Python dependencies here
npm install -g aws-cdk
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@master
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: "us-east-1"
- name: Deploy to AWS
run: cdk deploy --app="python3 ${PWD}/cdk/my_service/app.py" --require-approval=never
- name: Destroy stack
run: cdk destroy --app="python3 ${PWD}/cdk/my_service/app.py" --force
view raw cdk-python.yml hosted with ❤ by GitHub

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (0)

Best Practices for Running  Container WordPress on AWS (ECS, EFS, RDS, ELB) using CDK cover image

Best Practices for Running Container WordPress on AWS (ECS, EFS, RDS, ELB) using CDK

This post discusses the process of migrating a growing WordPress eShop business to AWS using AWS CDK for an easily scalable, high availability architecture. The detailed structure encompasses several pillars: Compute, Storage, Database, Cache, CDN, DNS, Security, and Backup.

Read full post