Skip to main content
DeployJob is a GitHub Actions job that handles deployment of applications to a Kubernetes cluster. It synthesizes cdk8s manifests and applies them using kubectl, with built-in branch protection.

Overview

The DeployJob automates the deployment process by:
  1. Synthesizing cdk8s Kubernetes manifests from TypeScript definitions
  2. Connecting to an AWS EKS cluster
  3. Applying manifests with certificate components first
  4. Deploying the application with pruning enabled
By default, deployments only run on the master branch to prevent accidental production deploys from feature branches.

Constructor

new DeployJob(
  scope: Workflow,
  config?: DeployJobProps,
  overrides?: Partial<JobProps>
)

Parameters

scope
Workflow
required
The cdkactions Workflow instance to add the deploy job to.
config
DeployJobProps
Optional configuration for the deploy job.
config.deployTag
string
default:"${{ github.sha }}"
The Git SHA or tag to use for the deployment. This is passed to the cdk8s synth process as the GIT_SHA environment variable.
config.defaultBranch
string
default:"master"
The branch that deployments are limited to. Deployments will only run when this branch is pushed.
overrides
Partial<JobProps>
Optional overrides for the job configuration. Commonly used to set the needs property to create job dependencies.

Basic Usage

Add a deploy job to a workflow:
import { DeployJob } from '@pennlabs/kraken';
import { Workflow } from 'cdkactions';

const workflow = new Workflow(this, 'deploy-workflow', {
  name: 'Deploy',
  on: 'push',
});

new DeployJob(workflow);

Advanced Usage

Deploy After Build Jobs

Most commonly, the deploy job should wait for build and publish jobs to complete:
import { DjangoProject, ReactProject, DeployJob } from '@pennlabs/kraken';

const django = new DjangoProject(workflow, {
  projectName: 'myproject',
  imageName: 'my-app-backend',
});

const react = new ReactProject(workflow, {
  imageName: 'my-app-frontend',
});

new DeployJob(workflow, {}, {
  needs: [django.publishJobId, react.publishJobId],
});

Custom Branch

Deploy from a different default branch:
new DeployJob(workflow, {
  defaultBranch: 'main',
});

Custom Deploy Tag

Use a custom tag instead of the Git SHA:
new DeployJob(workflow, {
  deployTag: 'v1.0.0',
});

Complete Example

Full workflow with build and deploy:
import { DjangoProject, ReactProject, DeployJob } from '@pennlabs/kraken';
import { Workflow, Stack } from 'cdkactions';

const workflow = new Workflow(this, 'workflow', {
  name: 'Build and Deploy',
  on: 'push',
});

const django = new DjangoProject(workflow, {
  projectName: 'djangoProject',
  path: 'backend',
  imageName: 'project-backend',
});

const reactOne = new ReactProject(workflow, {
  id: 'one',
  path: 'frontendOne',
  imageName: 'project-frontendOne',
});

const reactTwo = new ReactProject(workflow, {
  id: 'two',
  path: 'frontendTwo',
  imageName: 'project-frontendTwo',
});

new DeployJob(workflow, {}, {
  needs: [django.publishJobId, reactOne.publishJobId, reactTwo.publishJobId],
});

Deployment Process

The job executes two main steps:

1. Synthesize Manifests

The first step:
  • Changes to the k8s directory
  • Installs dependencies with yarn install --frozen-lockfile
  • Extracts the repository name from ${{ github.repository }}
  • Runs yarn build to synthesize cdk8s manifests
  • Outputs the release name for use in deployment
Environment variables available during synthesis:
  • GIT_SHA - The deploy tag (defaults to current commit SHA)
  • REPOSITORY - The GitHub repository name
  • AWS_ACCOUNT_ID - The AWS account ID (from secrets)

2. Deploy to Kubernetes

The second step:
  • Updates kubeconfig to connect to the EKS production cluster
  • Applies certificate resources first: kubectl apply -f k8s/dist/ -l app.kubernetes.io/component=certificate
  • Deploys application with pruning: kubectl apply -f k8s/dist/ --prune -l app.kubernetes.io/part-of=$RELEASE_NAME
Required secrets:
  • AWS_ACCOUNT_ID - AWS account containing the EKS cluster
  • GH_AWS_ACCESS_KEY_ID - AWS access key for GitHub Actions
  • GH_AWS_SECRET_ACCESS_KEY - AWS secret key for GitHub Actions

Branch Protection

The job includes a conditional that prevents deployment from non-default branches:
if: github.ref == 'refs/heads/master'
This ensures deployments only occur when pushing to the default branch, preventing accidental production deploys from feature branches or pull requests.

Required Setup

For the DeployJob to work, your repository must have:
  1. A k8s/ directory with cdk8s TypeScript definitions
  2. A k8s/package.json with a build script that runs cdk8s synth
  3. GitHub secrets configured:
    • AWS_ACCOUNT_ID
    • GH_AWS_ACCESS_KEY_ID
    • GH_AWS_SECRET_ACCESS_KEY
  4. Appropriate IAM permissions for the GitHub Actions role to access EKS

See Also

Build docs developers (and LLMs) love