Framework for CI/CD Deployment Guide for AWS Lambda Using GitHub Actions in an LZA Environment
1. Introduction
This guide presents a complete end-to-end process for setting up a CI/CD pipeline to deploy AWS Lambda functions across multiple AWS accounts—specifically Development and Production—using GitHub Actions and AWS CDK (TypeScript). The accounts are provisioned and governed through AWS Landing Zone Accelerator (LZA), which enforces secure, scalable, and compliant multi-account AWS environments.
Architecture Overview
- Developers push code to GitHub
- GitHub Actions pipeline builds and deploys to the Dev Account
- Optional Manual Approval step
- Deployment to Prod Account after approval
Core Technologies
- AWS Landing Zone Accelerator (LZA): Manages multi-account governance
- AWS CDK (TypeScript): Defines serverless architecture as code
- AWS Lambda + API Gateway: Delivers cloud-native functionality
- GitHub Actions: Executes deployment workflows in response to repo events
2. Organizational Unit Design with LZA
AWS Landing Zone Accelerator provisions a standardized, best-practice AWS Organization. Recommended OUs (Organizational Units):
- Root OU
This separation enforces strong governance using Service Control Policies (SCPs), consolidated billing, and automated guardrails.
3. Prerequisites
Required Access
- Admin privileges in Dev and Prod accounts
- Permissions to configure GitHub Actions and secrets
Local Development Environment
Install tools required to define infrastructure and run CDK commands:
brew install node awscli
npm install -g aws-cdk
aws configure
GitHub Repository Setup
Store the following secrets in the GitHub repository:
- AWS_ACCESS_KEY_ID_DEV
- AWS_SECRET_ACCESS_KEY_DEV
- AWS_ACCOUNT_ID_DEV
- AWS_REGION_DEV
- AWS_ACCESS_KEY_ID_PROD
- AWS_SECRET_ACCESS_KEY_PROD
- AWS_ACCOUNT_ID_PROD
- AWS_REGION_PROD
4. IAM and CDK Setup in AWS
IAM Role Setup
Each account requires an IAM role with a trust policy that allows GitHub Actions to assume it:
Trust Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::GITHUB_ACCOUNT_ID:root"
},
"Action": "sts:AssumeRole"
}
]
}
Permissions Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudformation:*",
"lambda:*",
"apigateway:*",
"iam:PassRole",
"s3:*"
],
"Resource": "*"
}
]
}
CDK Bootstrap
Run CDK bootstrap in each account to prepare for deployments:
cdk bootstrap aws://$AWS_ACCOUNT_ID_DEV/$AWS_REGION_DEV
cdk bootstrap aws://$AWS_ACCOUNT_ID_PROD/$AWS_REGION_PROD
More info: CDK Bootstrap Documentation
Recommended by LinkedIn
5. CDK Project Setup
Initialize CDK App
mkdir lambda-cicd && cd lambda-cicd
cdk init app --language typescript
Install CDK Libraries
npm install @aws-cdk/aws-lambda @aws-cdk/aws-apigateway @aws-cdk/aws-lambda-nodejs
Project Structure
.
├── lambda/handler.ts
├── lib/my-cdk-serverless-app-stack.ts
├── bin/my-cdk-serverless-app.ts
├── .github/workflows/deploy.yml
Lambda Code (lambda/handler.ts)
export const helloWorld = async () => {
return {
statusCode: 200,
body: JSON.stringify({ message: 'Hello World!' })
};
};
export const helloWorldKit = async () => {
return {
statusCode: 200,
body: JSON.stringify({ message: 'Hello from Kit!' })
};
};
CDK Stack (lib/my-cdk-serverless-app-stack.ts)
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda-nodejs';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
export class MyCdkServerlessAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const helloWorldLambda = new lambda.NodejsFunction(this, 'HelloWorldFunction', {
entry: 'lambda/handler.ts',
handler: 'helloWorld'
});
const helloWorldKitLambda = new lambda.NodejsFunction(this, 'HelloWorldKitFunction', {
entry: 'lambda/handler.ts',
handler: 'helloWorldKit'
});
const api = new apigateway.RestApi(this, 'MyApi');
api.root.addResource('hello').addMethod('GET', new apigateway.LambdaIntegration(helloWorldLambda));
api.root.addResource('hellokit').addMethod('GET', new apigateway.LambdaIntegration(helloWorldKitLambda));
}
}
6. CI/CD Pipeline with GitHub Actions
GitHub Actions Documentation
Workflow Overview
Trigger: Push to main branch
- Install dependencies
- Build app
- Deploy to Dev
- Await manual approval
- Deploy to Prod
GitHub Actions Workflow (.github/workflows/deploy.yml)
name: Deploy Lambda via CDK
on:
push:
branches: [main]
jobs:
deploy-dev:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci && npm run build
- uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_DEV }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEV }}
aws-region: ${{ secrets.AWS_REGION_DEV }}
- run: npx cdk deploy --require-approval never
deploy-prod:
needs: deploy-dev
runs-on: ubuntu-latest
environment:
name: production
steps:
- name: Await Approval
uses: hmarr/auto-approve-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci && npm run build
- uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_PROD }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_PROD }}
aws-region: ${{ secrets.AWS_REGION_PROD }}
- run: npx cdk deploy --require-approval never
7. Deployment and Verification
Triggering the Pipeline
git checkout -b feature/update
# Make code changes
# Commit and push
# Merge into main to trigger pipeline
Validation
- Monitor workflow: GitHub Actions UI
- AWS Console → CloudFormation → Stack outputs
- Test endpoints:
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/hello
8. Cleanup
Destroy Stacks
AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... npx cdk destroy
Remove Secrets and IAM Roles
- Remove GitHub repository secrets
- Delete temporary IAM users or roles
9. Final Recommendations
- Use GitHub OIDC Federation for credential-less access
- Extend pipeline with unit tests, linting, rollback logic, or canary deployments
- Monitor with Amazon CloudWatch and AWS X-Ray
This solution uses modern DevOps tools to provide a best-practice, production-ready CI/CD pipeline across AWS environments.