CDK App with Github Action
Background
In our business use case, we need to create a proxy server to redirect traffic from a specific region. To achieve this, we leverage on aws lambda + api gateway with proper CORs setting, and allowed methods.
At first, we did this in aws console directly. It works fine, however, it would be more maintainable if we could achieve infra as code, benefits would be:
- Speed
- Low risk of human errors
- Improved consistency
- Eliminate configuration drift - correct source change mistake along with the pipeline deployment
- Improved security strategies
- Stable and scalable env
- Self documentation
CDK Introduction
Concepts
- CDK
- Cloud Development Kit, is a framework for defining cloud infrastructure in code (IaC) and provisioning it through AWS CloudFormation.
- We could leverage this tool to quickly build reliable, scalable, cost-effective applications in the cloud with the considerable expressive power of a programming language. AWS CDK Developer Guide
- Construct
- the basic building blocks of AWS CDK apps.
- encode configuration detail, boilerplate, and glue logic for using one or multiple AWS services.
- CloudFormation
- CloudFormation gives an easy way to create a collection of related AWS and third-party resources, and provision and manage them in an orderly and predictable fashion
- Repeatable deployment, easy rollback, and drift detection
- Using a configuration language (YAML or JSON)
- Stacks
- a collection of AWS resources that you can manage as a single unit in CloudFormation
How does CDK work?
- AWS CDK takes the code we write (Stacks and Construct)
- Compiles it down to CloudFormation
- During cdk deployment, cloudFormation will help us create all resources we defined in CDK
Benefits of Using CDK
- Customize, share, and reuse constructs
- Type
- L1 Construct
- CFN Resources – directly represent all resources available in AWS CloudFormation
- L2 Construct
- L2, also represent AWS resources, but with a higher-level, intent-based API.
- Incorporate the defaults, boilerplate, and glue logic you’d be writing yourself with a CFN Resource construct
- L3 Construct
- patterns.
- These constructs are designed to help you complete common tasks in AWS, often involving multiple kinds of resources
- aws-ecs-patterns.ApplicationLoadBalancedFargateService construct
- represents an architecture that includes an AWS Fargate container cluster employing an Application Load Balancer.
- help you to define load balancer, fargate service, ECS, ECR
- we could also define our network setting like VPC, subnet, cloudMap inside the construct
- L1 Construct
- Type
- Powered by AWS CloudFormation
- repeatable deployment, easy rollback, and drift detection
- Use familiar programming languages, tools, and workflows
Per the guide, inside Amazon, new features would be first developed in typescript, then leverage on some parsing tool to translate to different languages. Thus in this MVP, I’ll also use typescript.
Development Process
Prerequisite: You need to at least have permission to the corresponding aws account to move forward
- The development loop consists of
- Check CDK Doc, try to use constructs
- Run
cdk diff
andcdk synth
- check the output and make sure the changes are expected
- Run
cdk deploy
to deploy aws resources- You should be able to see corresponding stacks in AWS Console - CloudFormation
- Once the stack is deployed successfully, you should be able to see resources get created
- If you find something wrong, you could just change the code, CDK and CloudFormation will help to take care of the update of your stack
- If the stack is in some convoluted status, you could try to do
cdk destroy
or just manually delete the corresponding stack from the CloudFormation console page- remember the deletion needs to be started with the higher level stack, if there are some other stacks that rely on your current to-be-deleted stack, your deletion would not be able to finish
- could happen when you deal with ALB/ NLB
Build CDK app using constructs
- CDK has different level construct per guide. In our case, we should try our best to interact with high-level constructs/ patterns which have common tasks predefined. One good example would be ApplicationLoadBalancedFargateService, we could leverage on such construct directly instead of defining load balancer, route table, IAM roles, ECR, ECS, Fargate, etc. on our own. It could save a lot of time, and also help us insist on the best practice per Amazon team guidance.
- CDK API Doc would be a great reference during the development
- One example in our case
export class DemoStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const handler = new lambda.Function(this, "handler", {
runtime: lambda.Runtime.NODEJS_16_X,
code: lambda.Code.fromAsset("resource"),
handler: "index.handler",
timeout: cdk.Duration.seconds(30),
});
const lambdaIntegration = new HttpLambdaIntegration(
"LambdaIntegration",
handler
);
const httpApi = new apigatewayv2.HttpApi(this, "test", {
apiName: "api-gateway",
corsPreflight: {
allowOrigins: [
"https://llchen60.com",
],
allowHeaders: ["paul",],
allowMethods: [apigatewayv2.CorsHttpMethod.GET],
},
createDefaultStage: false,
});
httpApi.addStage("prod", {
stageName: "prod",
autoDeploy: true,
});
httpApi.addRoutes({
path: "/llchen/{path+}",
methods: [apigatewayv2.HttpMethod.GET],
integration: lambdaIntegration,
});
}
}
const app = new cdk.App();
new DemoStack(app, "DemoStack");
cdk diff
to check local changes
- Compares the specified stack and its dependencies with the deployed stacks or a local CloudFormation template
- We should make sure the diff change are what we want locally before deployment
cdk synth
to generate CloudFormation file
- Synthesizes and prints the CloudFormation template for one or more specified stacks
- One Example when we generate our lambda server with api gateway
- IAM Role
- S3 Bucket for Code
- Lamda handler
- Api Gateway
- Metadatas for defined resources
**cdk deploy
- deploy to CloudFormation
- Deploys one or more specified stacks
- Log would show the change and deployment progress
Useful Commands
// install cdk globally
npm install -g aws-cdk
// configure access token, secret, account id, preferred region here
aws configure
mkdir cdkAppDictName
cdk init app --language typescript
// check command guide for reference https://docs.aws.amazon.com/cdk/v2/guide/cli.html
// list stacks in the app
cdk list
// synthesize the prints the cloudformation template
cdk synth
// bootstrap CDK toolkit stack
cdk bootstrap
cdk destroy
// Compares the specified stack and its dependencies with the deployed stacks or a local CloudFormation template
cdk diff
// Deploys one or more specified stacks
cdk deploy
CI/ CD workflow setup
- After PR, we want to do a automatic deployment in github
- there are couple options we could leverage on, E.G
- buildkite
- github action
- there are couple options we could leverage on, E.G
- In this project, we use github action
Github Action Core Concept
- Workflow
- configurable automated process that will run one or more jobs
- defined in yaml file
- reside under
.github/workflows
- Event
- an activity to trigger a workflow to run
- Job
- a set of steps in a workflow that execute on the same runner
- executed in order
- Action
- Perform a complex but frequently repeated task
- Use action to help reduce the amount of repetitive code
- Runner
- server runs the workflow when they are triggered
Github Action Syntax
- that’s the main part we need to use
- we could define our action under
.github/workflows
, define what events should trigger the workflow - here we also need to define which runner we want to use, we could use public runner offered by github, or we could use self hosted one
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#run-name
Action YML File to integrate with Slack and CDK
- Prerequisite
- this action would need several secrets for us to access slack or aws
- we could generate them in corresponding platform, and put them under github repository secrets section
- Code
name: "cdk deploy"
on:
push:
branches:
- master
jobs:
aws_cdk:
runs-on: "your runner"
steps:
- name: Post to a Slack Channel Before Deployment
id: slack-before-deploy
uses: slackapi/slack-github-action@v1.23.0
with:
# Slack channel id, channel name, or user id to post message.
# See also: https://api.slack.com/methods/chat.postMessage#channels
channel-id: "channel-id"
# For posting a rich message using Block Kit
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Hello World*"
}
}
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
- name: Checkout repo
uses: actions/checkout@v3
- uses: actions/setup-node@v2
with:
node-version: "14"
- 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-west-1
- name: Install dependencies
run: npm install -g yarn && yarn
- name: Synth stack
run: yarn cdk synth
- name: Deploy stack
run: yarn cdk deploy --all
- name: Post to a Slack Channel Post Deployment
id: slack-after-deploy-success
if: ${{ success() }}
uses: slackapi/slack-github-action@v1.23.0
with:
# Slack channel id, channel name, or user id to post message.
# See also: https://api.slack.com/methods/chat.postMessage#channels
channel-id: "channel-id"
# For posting a rich message using Block Kit
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "text msg"
}
}
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
- name: Post to a Slack Channel Post Deployment
id: slack-after-deploy-failure
if: ${{ failure() }}
uses: slackapi/slack-github-action@v1.23.0
with:
# Slack channel id, channel name, or user id to post message.
# See also: https://api.slack.com/methods/chat.postMessage#channels
channel-id: "channel-id"
# For posting a rich message using Block Kit
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "test msg"
}
}
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
That’s literally the whole process for us to integrate CDK with github actions, let me know if you have any questions! :)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 stone2paul@gmail.com
文章标题:CDK App with Github Action
文章字数:1.7k
本文作者:Leilei Chen
发布时间:2023-01-18, 15:08:52
最后更新:2023-01-18, 15:11:50
原始链接:https://www.llchen60.com/CDK-App-with-Github-Action/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。