├── backups
├── .env
├── cdk.json
├── tsconfig.json
├── package.json
└── index.ts
├── batch
├── .env
├── cdk.json
├── README.md
├── package.json
├── tsconfig.json
├── lambdaHandler.js
└── index.ts
├── docdb-lambda-api
├── .gitignore
├── cdk.json
├── .env
├── README.md
├── src
│ ├── package.json
│ ├── getLongURL.ts
│ ├── urlShortener.ts
│ └── lib.ts
├── tsconfig.json
├── package.json
└── index.ts
├── sagemaker
├── .env
├── cdk.json
├── README.md
├── package.json
├── tsconfig.json
└── index.ts
├── ec2-basics
├── .env
├── cdk.json
├── README.md
├── package.json
├── tsconfig.json
└── index.ts
├── ec2-jenkins
├── .env
├── cdk.json
├── tsconfig.json
├── package.json
├── README.md
├── lib.ts
└── index.ts
├── ecs-go-api
├── .env
├── cdk.json
├── api
│ ├── go.mod
│ ├── go.sum
│ ├── Dockerfile
│ └── main.go
├── README.md
├── package.json
├── tsconfig.json
└── index.ts
├── eks-cluster
├── .env
├── graphql-api
│ ├── start
│ ├── Dockerfile
│ ├── package.json
│ └── app.js
├── cdk.json
├── go-api
│ ├── go.mod
│ ├── go.sum
│ ├── Dockerfile
│ └── main.go
├── package.json
├── tsconfig.json
├── README.md
├── templates.ts
└── index.ts
├── elb-lambda-api
├── .env
├── cdk.json
├── README.md
├── package.json
├── tsconfig.json
├── index.ts
└── lambda-handler.py
├── empty-template
├── .env
├── cdk.json
├── index.ts
├── package.json
└── tsconfig.json
├── rds-proxy
├── cdk.json
├── .env
├── src
│ ├── lib.js
│ ├── package.json
│ └── handler.js
├── package.json
├── tsconfig.json
└── index.ts
├── serverless-eks
├── .env
├── graphql-api
│ ├── start
│ ├── Dockerfile
│ ├── package.json
│ └── app.js
├── cdk.json
├── go-api
│ ├── go.mod
│ ├── go.sum
│ ├── Dockerfile
│ └── main.go
├── package.json
├── tsconfig.json
├── templates.ts
├── README.md
└── index.ts
├── cognito-userpool
├── .env
├── cdk.json
├── README.md
├── package.json
├── tsconfig.json
└── index.ts
├── keyspaces-cassandra
├── .env
├── cdk.json
├── package.json
├── tsconfig.json
└── index.ts
├── lambda-functionURL
├── .env
├── cdk.json
├── src
│ └── lambdaHandler.mjs
├── package.json
├── tsconfig.json
└── index.ts
├── lambda-python-api
├── .env
├── cdk.json
├── README.md
├── package.json
├── tsconfig.json
├── lib.ts
├── index.ts
└── lambda-handler.py
├── sqs-lambda-dynamodb
├── .env
├── cdk.json
├── package.json
├── tsconfig.json
├── README.md
├── lambdaHandler.js
└── index.ts
├── transit-gateway
├── .env
├── cdk.json
├── README.md
├── package.json
├── tsconfig.json
└── index.ts
├── wordpress-ha
├── cdk.json
├── README.md
├── .env
├── package.json
├── tsconfig.json
└── index.ts
├── dynamo-streams-lambda
├── .env
├── cdk.json
├── README.md
├── stream-handler.py
├── package.json
├── tsconfig.json
└── index.ts
├── elasticsearch-cluster
├── .env
├── cdk.json
├── README.md
├── package.json
├── tsconfig.json
└── index.ts
├── assets
├── sagemaker1.png
├── sagemaker2.png
├── lambda-api-python.png
└── sqs-lambda-dynamo.png
├── .gitignore
└── README.md
/backups/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/batch/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/docdb-lambda-api/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
2 | *.d.ts
3 | *.pem
4 |
--------------------------------------------------------------------------------
/sagemaker/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/backups/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/batch/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/ec2-basics/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/ec2-jenkins/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/ecs-go-api/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/eks-cluster/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/eks-cluster/graphql-api/start:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | npm start
--------------------------------------------------------------------------------
/elb-lambda-api/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/empty-template/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/rds-proxy/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/sagemaker/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/serverless-eks/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/serverless-eks/graphql-api/start:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | npm start
--------------------------------------------------------------------------------
/cognito-userpool/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/ec2-basics/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/ec2-jenkins/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/ecs-go-api/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/eks-cluster/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/elb-lambda-api/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/empty-template/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/keyspaces-cassandra/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/lambda-functionURL/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/lambda-python-api/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/serverless-eks/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/sqs-lambda-dynamodb/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/transit-gateway/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/wordpress-ha/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/cognito-userpool/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/docdb-lambda-api/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/dynamo-streams-lambda/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/elasticsearch-cluster/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
--------------------------------------------------------------------------------
/keyspaces-cassandra/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/lambda-functionURL/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/lambda-python-api/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/sqs-lambda-dynamodb/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/transit-gateway/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/dynamo-streams-lambda/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/elasticsearch-cluster/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node index"
3 | }
4 |
--------------------------------------------------------------------------------
/docdb-lambda-api/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
3 | MASTER_USER_PASSWORD=""
--------------------------------------------------------------------------------
/assets/sagemaker1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TysonWorks/cdk-examples/HEAD/assets/sagemaker1.png
--------------------------------------------------------------------------------
/assets/sagemaker2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TysonWorks/cdk-examples/HEAD/assets/sagemaker2.png
--------------------------------------------------------------------------------
/rds-proxy/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION=""
3 | DB_USER="myuser"
4 | DB_PORT="3306"
5 | DB_NAME="proxy"
--------------------------------------------------------------------------------
/assets/lambda-api-python.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TysonWorks/cdk-examples/HEAD/assets/lambda-api-python.png
--------------------------------------------------------------------------------
/assets/sqs-lambda-dynamo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TysonWorks/cdk-examples/HEAD/assets/sqs-lambda-dynamo.png
--------------------------------------------------------------------------------
/wordpress-ha/README.md:
--------------------------------------------------------------------------------
1 | # Wordpress on AWS
2 |
3 | Highly available, horizontally scalable Wordpress installation using ECS and RDS.
--------------------------------------------------------------------------------
/ecs-go-api/api/go.mod:
--------------------------------------------------------------------------------
1 | module cdk-examples/typescript/ecs-go-api/api
2 |
3 | go 1.12
4 |
5 | require github.com/gorilla/mux v1.7.2
6 |
--------------------------------------------------------------------------------
/wordpress-ha/.env:
--------------------------------------------------------------------------------
1 | AWS_ACCOUNT_ID=""
2 | AWS_REGION="us-east-1"
3 | DB_USER=""
4 | DB_PASSWORD=""
5 | DB_PORT="3306"
6 | DB_NAME="wordpress"
--------------------------------------------------------------------------------
/batch/README.md:
--------------------------------------------------------------------------------
1 | ## AWS Batch
2 |
3 | ### Accompanying blog post
4 | https://medium.com/tysonworks/manage-batch-jobs-with-aws-batch-1f91229b1b6e
--------------------------------------------------------------------------------
/eks-cluster/go-api/go.mod:
--------------------------------------------------------------------------------
1 | module cdk-examples/typescript/ecs-go-api/api
2 |
3 | go 1.12
4 |
5 | require github.com/gorilla/mux v1.7.2
6 |
--------------------------------------------------------------------------------
/serverless-eks/go-api/go.mod:
--------------------------------------------------------------------------------
1 | module cdk-examples/typescript/ecs-go-api/api
2 |
3 | go 1.12
4 |
5 | require github.com/gorilla/mux v1.7.2
6 |
--------------------------------------------------------------------------------
/cognito-userpool/README.md:
--------------------------------------------------------------------------------
1 | ## Cognito User Pool
2 |
3 | This example will deploy a Cognito User Pool and User Pool Client for interacting with the User Pool.
--------------------------------------------------------------------------------
/rds-proxy/src/lib.js:
--------------------------------------------------------------------------------
1 | function sleep(ms) {
2 | return new Promise(resolve => setTimeout(resolve, ms));
3 | }
4 |
5 | module.exports = {
6 | sleep
7 | };
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | cdk.context.json
4 | package-lock.json
5 | __pycache__
6 | *~
7 | .vscode
8 | node_modules
9 | .cdk.staging
10 | cdk.out
11 | notes.txt
12 |
--------------------------------------------------------------------------------
/ecs-go-api/api/go.sum:
--------------------------------------------------------------------------------
1 | github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I=
2 | github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
3 |
--------------------------------------------------------------------------------
/eks-cluster/go-api/go.sum:
--------------------------------------------------------------------------------
1 | github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I=
2 | github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
3 |
--------------------------------------------------------------------------------
/serverless-eks/go-api/go.sum:
--------------------------------------------------------------------------------
1 | github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I=
2 | github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
3 |
--------------------------------------------------------------------------------
/ec2-basics/README.md:
--------------------------------------------------------------------------------
1 | ## EC2 Basics
2 | This example will deploy a EC2 instance to a new VPC and default public subnet. It will also create a new security group with SSH access and it will use the latest AMAZON Linux AMI.
--------------------------------------------------------------------------------
/eks-cluster/graphql-api/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY . .
6 |
7 | RUN npm i npm@latest -g
8 | RUN npm install --only=production
9 |
10 | EXPOSE 8090
11 |
12 | ENTRYPOINT ["/bin/sh", "start"]
--------------------------------------------------------------------------------
/serverless-eks/graphql-api/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY . .
6 |
7 | RUN npm i npm@latest -g
8 | RUN npm install --only=production
9 |
10 | EXPOSE 8090
11 |
12 | ENTRYPOINT ["/bin/sh", "start"]
--------------------------------------------------------------------------------
/dynamo-streams-lambda/README.md:
--------------------------------------------------------------------------------
1 | ## DynamoDB Streams with Lambda
2 | This example will deploy a Lambda function written in Python and a DynamoDB table. Lambda function will get invoked by the changes to DynamoDB table using DynamoDB streams.
--------------------------------------------------------------------------------
/docdb-lambda-api/README.md:
--------------------------------------------------------------------------------
1 | ## URL Shortener with DocumentDB, Lambda and API Gateway
2 |
3 | This example will deploy a DocumentDB cluster and Lambda functions exposed via API Gateway.
4 |
5 | ### Accompanying blog post
6 | https://medium.com/tysonworks/create-and-deploy-simple-url-shortener-with-aws-cdk-and-documentdb-875ab99d51f5
7 |
--------------------------------------------------------------------------------
/lambda-functionURL/src/lambdaHandler.mjs:
--------------------------------------------------------------------------------
1 | export async function handler(event, context, callback) {
2 | try {
3 | console.log("Event:", JSON.stringify(event));
4 | return callback(null, "Hello, function URL.");
5 | } catch(err) {
6 | console.error("Error", err);
7 | return callback("Error");
8 | }
9 | }
--------------------------------------------------------------------------------
/rds-proxy/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "src",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "handler.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "dependencies": {
10 | "mysql": "^2.18.1",
11 | "mysql2": "^2.1.0"
12 | },
13 | "author": "",
14 | "license": "ISC"
15 | }
16 |
--------------------------------------------------------------------------------
/dynamo-streams-lambda/stream-handler.py:
--------------------------------------------------------------------------------
1 | def handler(event, context):
2 | for record in event["Records"]:
3 | if "NewImage" in record["dynamodb"]:
4 | print("New image {}".format(record["dynamodb"]["NewImage"]))
5 | if "OldImage" in record["dynamodb"]:
6 | print("Old image {}".format(record["dynamodb"]["OldImage"]))
7 | return "done"
--------------------------------------------------------------------------------
/sagemaker/README.md:
--------------------------------------------------------------------------------
1 | ## Sagemaker Notebook Example
2 | This example will deploy a VPC, Security Group, IAM Role and a Sagemaker Notebook instance.
3 |
4 | After the successful deployment, head over to the Sagemaker console
5 |
6 |
7 | Click Open Jupyter Button to launch Jupyter notebook
8 |
--------------------------------------------------------------------------------
/ecs-go-api/api/Dockerfile:
--------------------------------------------------------------------------------
1 | # Multi-stage layout
2 | FROM golang:1.12 as builder
3 |
4 | ENV GO111MODULE=on
5 |
6 | WORKDIR /app
7 |
8 | COPY go.mod .
9 | COPY go.sum .
10 |
11 | RUN go mod download
12 |
13 | COPY . .
14 |
15 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
16 |
17 | FROM scratch
18 | COPY --from=builder /app/api /app/
19 | EXPOSE 8080
20 | ENTRYPOINT ["/app/api"]
--------------------------------------------------------------------------------
/eks-cluster/go-api/Dockerfile:
--------------------------------------------------------------------------------
1 | # Multi-stage layout
2 | FROM golang:1.12 as builder
3 |
4 | ENV GO111MODULE=on
5 |
6 | WORKDIR /app
7 |
8 | COPY go.mod .
9 | COPY go.sum .
10 |
11 | RUN go mod download
12 |
13 | COPY . .
14 |
15 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
16 |
17 | FROM scratch
18 | COPY --from=builder /app/api /app/
19 | EXPOSE 8080
20 | ENTRYPOINT ["/app/api"]
--------------------------------------------------------------------------------
/serverless-eks/go-api/Dockerfile:
--------------------------------------------------------------------------------
1 | # Multi-stage layout
2 | FROM golang:1.12 as builder
3 |
4 | ENV GO111MODULE=on
5 |
6 | WORKDIR /app
7 |
8 | COPY go.mod .
9 | COPY go.sum .
10 |
11 | RUN go mod download
12 |
13 | COPY . .
14 |
15 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
16 |
17 | FROM scratch
18 | COPY --from=builder /app/api /app/
19 | EXPOSE 8080
20 | ENTRYPOINT ["/app/api"]
--------------------------------------------------------------------------------
/eks-cluster/graphql-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "graphql-api",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "node app.js"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "apollo-server-express": "^2.9.3",
14 | "express": "^4.17.1",
15 | "helmet": "^3.21.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/serverless-eks/graphql-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "graphql-api",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "node app.js"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "apollo-server-express": "^2.9.3",
14 | "express": "^4.17.1",
15 | "helmet": "^3.21.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/docdb-lambda-api/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "src",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "getLongURL.js",
6 | "scripts": {
7 | "build": "tsc",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "mongodb": "^3.3.0-beta2",
14 | "shortid": "^2.2.14"
15 | },
16 | "devDependencies": {
17 | "@types/shortid": "0.0.29"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ecs-go-api/README.md:
--------------------------------------------------------------------------------
1 | ## ECS GO API Example
2 |
3 | For this example, you have to bootstrap the CDK project for building and pushing the local container image to ECR.
4 |
5 | After installing the dependencies and setting up the environment variables, run
6 | `cdk bootstrap`
7 |
8 | You can deploy the stack after the bootstrap step
9 | `cdk deploy`
10 |
11 | ### Accompanying blog post
12 | https://medium.com/tysonworks/deploy-go-applications-to-ecs-using-aws-cdk-1a97d85bb4cb
13 |
--------------------------------------------------------------------------------
/elb-lambda-api/README.md:
--------------------------------------------------------------------------------
1 | ## Elastic Load Balancer Lambda API
2 | This example will deploy a Lambda function written in Python and Application Load Balancer using Lambda Function as a target. Lambda function will return a random poem from external API (http://poetrydb.org) as a JSON response.
3 |
4 |
5 | After the successful deployment you will get an url similiar to this.
6 | `Lambd-alb8A-1OC475PK74UO8-801587863.us-west-1.elb.amazonaws.com`
7 |
8 |
9 | Hit the URL and you should get a successful JSON response.
10 |
--------------------------------------------------------------------------------
/empty-template/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import { config } from "dotenv";
3 | import { Construct } from "constructs";
4 | config();
5 |
6 | class EmptyStack extends cdk.Stack {
7 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
8 | super(scope, id, props);
9 | }
10 | }
11 |
12 | const app = new cdk.App();
13 | new EmptyStack(app, "EmptyStack", {
14 | env: {
15 | account: process.env.AWS_ACCOUNT_ID,
16 | region: process.env.AWS_REGION
17 | }
18 | });
--------------------------------------------------------------------------------
/lambda-python-api/README.md:
--------------------------------------------------------------------------------
1 | ## Lambda API Gateway
2 | This example will deploy a Lambda function written in Python and API Gateway with one resource. Lambda function will return one random poem from external API (http://poetrydb.org) as a JSON response.
3 |
4 |
5 |
6 |
7 | After the successful deployment you will get an url similiar to this.
8 | `https://ygnbp5okp4.execute-api.us-west-1.amazonaws.com/prod/`
9 |
10 | Append `poems` to this url and try to reach it. You'll get a poem with details as a JSON response.
--------------------------------------------------------------------------------
/transit-gateway/README.md:
--------------------------------------------------------------------------------
1 | ## Transit Gateway
2 | This example will demonstrate the Transit Gateway offering from AWS. This stack will create three different VPCs, three different instances in those VPCs and a Transit Gateway with necessary resources to connect these networks.
3 |
4 | Two of the instances will include the user-data script, which includes Nginx installation and starting the Nginx service. We will connect to the second instance via EC2 Instance Connect on the EC2 console, then we will try to reach private DNS addresses of the other two instances(instance1 and instance3) via curl command, which should work as expected.
--------------------------------------------------------------------------------
/ec2-basics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ec2-basics",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk"
8 | },
9 | "devDependencies": {
10 | "aws-cdk": "2.53.0",
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "jest": "^27.5.1",
16 | "ts-jest": "^27.1.4",
17 | "ts-node": "^10.9.1",
18 | "typescript": "~3.9.7"
19 | },
20 | "dependencies": {
21 | "aws-cdk-lib": "2.53.0",
22 | "constructs": "^10.0.0",
23 | "dotenv": "^8.2.0"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/batch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "batch",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/sagemaker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sagemaker",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
--------------------------------------------------------------------------------
/ecs-go-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ecs-go-api",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/elasticsearch-cluster/README.md:
--------------------------------------------------------------------------------
1 | ## ElasticSearch Cluster
2 | This example will deploy an ElasticSearch cluster using AWS CDK.
3 |
4 |
5 | For enabling VPC, you need to comment out necessary lines and create a VPN connection to VPC for interacting with Kibana and ElasticSearch API.
6 |
7 |
8 | After the successful deployment you will get an output similiar to this.
9 |
10 | ```ElasticSearchStack.domain = search-es-domain-zq3r5qgq2b5ecvctp7pry6vupu.us-east-1.es.amazonaws.com```
11 | ```ElasticSearchStack.kibana = search-es-domain-zq3r5qgq2b5ecvctp7pry6vupu.us-east-1.es.amazonaws.com/_plugin/kibana/```
12 |
13 | Go to Kibana URL, you should see the Kibana setup page.
14 |
--------------------------------------------------------------------------------
/rds-proxy/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rds-proxy",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/cognito-userpool/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cognito-userpool",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "aws-cdk": "2.53.0",
12 | "@types/babel__traverse": "7.18.2",
13 | "@types/jest": "^27.5.2",
14 | "@types/node": "10.17.27",
15 | "@types/prettier": "2.6.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
--------------------------------------------------------------------------------
/eks-cluster/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eks-cluster",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/empty-template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "empty-template",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "aws-cdk": "2.53.0",
12 | "@types/babel__traverse": "7.18.2",
13 | "@types/jest": "^27.5.2",
14 | "@types/node": "10.17.27",
15 | "@types/prettier": "2.6.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
--------------------------------------------------------------------------------
/wordpress-ha/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wordpress-ha",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/elb-lambda-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "elb-lambda-api",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lambda-functionURL/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lambda-functionURL",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "aws-cdk": "2.53.0",
12 | "@types/babel__traverse": "7.18.2",
13 | "@types/jest": "^27.5.2",
14 | "@types/node": "10.17.27",
15 | "@types/prettier": "2.6.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
--------------------------------------------------------------------------------
/serverless-eks/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "serverless-eks",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/transit-gateway/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "transit-gateway",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/keyspaces-cassandra/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "keyspaces-cassandra",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "aws-cdk": "2.53.0",
12 | "@types/babel__traverse": "7.18.2",
13 | "@types/jest": "^27.5.2",
14 | "@types/node": "10.17.27",
15 | "@types/prettier": "2.6.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
--------------------------------------------------------------------------------
/lambda-python-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lambda-python-api",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/backups/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/batch/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/sqs-lambda-dynamodb/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sqs-lambda-dynamodb",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/batch/lambdaHandler.js:
--------------------------------------------------------------------------------
1 | const Batch = require("aws-sdk").Batch;
2 |
3 | const batch = new Batch({
4 | region: process.env.REGION
5 | });
6 |
7 | async function handler(event, context, callback) {
8 | try {
9 | const jobName = `job_${Date.now()}`;
10 | await batch.submitJob({
11 | jobDefinition: process.env.JOB_DEFINITION,
12 | jobQueue: process.env.JOB_QUEUE,
13 | jobName
14 | }).promise();
15 | console.log("Job submitted", jobName);
16 | callback(null, "done");
17 | } catch(err) {
18 | console.error(err);
19 | callback("Internal error");
20 | }
21 | }
22 |
23 | module.exports.handler = handler;
--------------------------------------------------------------------------------
/dynamo-streams-lambda/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dynamo-streams-lambda",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ec2-basics/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/ec2-jenkins/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/ecs-go-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/eks-cluster/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/elasticsearch-cluster/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "elasticsearch-cluster",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/rds-proxy/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/sagemaker/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/wordpress-ha/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/cognito-userpool/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/docdb-lambda-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/elb-lambda-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/empty-template/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/lambda-python-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/serverless-eks/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/transit-gateway/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/backups/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backups",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "cdk-backup-plan": "^0.0.3",
24 | "constructs": "^10.0.0",
25 | "dotenv": "^8.2.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/dynamo-streams-lambda/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/elasticsearch-cluster/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/keyspaces-cassandra/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/lambda-functionURL/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/sqs-lambda-dynamodb/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target":"ES2018",
4 | "module": "commonjs",
5 | "lib": ["es2016", "es2017.object", "es2017.string"],
6 | "declaration": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "strictNullChecks": true,
10 | "noImplicitThis": true,
11 | "alwaysStrict": true,
12 | "noUnusedLocals": false,
13 | "noUnusedParameters": false,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": false,
16 | "inlineSourceMap": true,
17 | "inlineSources": true,
18 | "experimentalDecorators": true,
19 | "strictPropertyInitialization":false
20 | },
21 | "exclude": ["cdk.out"]
22 | }
23 |
--------------------------------------------------------------------------------
/eks-cluster/graphql-api/app.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const { ApolloServer, gql } = require("apollo-server-express");
3 | const helmet = require("helmet");
4 |
5 | const typeDefs = gql`
6 | type Query {
7 | hello: String
8 | date: String
9 | }
10 | `;
11 |
12 | const resolvers = {
13 | Query: {
14 | hello: () => "Hello from EKS example",
15 | date: () => new Date().toISOString()
16 | },
17 | };
18 |
19 | const server = new ApolloServer({ typeDefs, resolvers });
20 |
21 | const app = express();
22 | app.use(helmet());
23 | server.applyMiddleware({ app });
24 |
25 | app.listen({ port: 8090 }, () =>
26 | console.log(`Server started on port 8090, ${server.graphqlPath}`)
27 | );
--------------------------------------------------------------------------------
/docdb-lambda-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docdb-lambda-api",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "constructs": "^10.0.0",
24 | "dotenv": "^8.2.0",
25 | "mongodb": "^5.0.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/serverless-eks/graphql-api/app.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const { ApolloServer, gql } = require("apollo-server-express");
3 | const helmet = require("helmet");
4 |
5 | const typeDefs = gql`
6 | type Query {
7 | hello: String
8 | date: String
9 | }
10 | `;
11 |
12 | const resolvers = {
13 | Query: {
14 | hello: () => "Hello from EKS example",
15 | date: () => new Date().toISOString()
16 | },
17 | };
18 |
19 | const server = new ApolloServer({ typeDefs, resolvers });
20 |
21 | const app = express();
22 | app.use(helmet());
23 | server.applyMiddleware({ app });
24 |
25 | app.listen({ port: 8090 }, () =>
26 | console.log(`Server started on port 8090, ${server.graphqlPath}`)
27 | );
--------------------------------------------------------------------------------
/ec2-jenkins/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ec2-jenkins",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "build": "tsc",
6 | "watch": "tsc -w",
7 | "cdk": "cdk",
8 | "test": "jest"
9 | },
10 | "devDependencies": {
11 | "@types/babel__traverse": "7.18.2",
12 | "@types/jest": "^27.5.2",
13 | "@types/node": "10.17.27",
14 | "@types/prettier": "2.6.0",
15 | "aws-cdk": "2.53.0",
16 | "jest": "^27.5.1",
17 | "ts-jest": "^27.1.4",
18 | "ts-node": "^10.9.1",
19 | "typescript": "~3.9.7"
20 | },
21 | "dependencies": {
22 | "aws-cdk-lib": "2.53.0",
23 | "axios": "^1.3.1",
24 | "cheerio": "^1.0.0-rc.12",
25 | "constructs": "^10.0.0",
26 | "dotenv": "^8.2.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ec2-jenkins/README.md:
--------------------------------------------------------------------------------
1 | ## EC2 Jenkins Example
2 | This example will deploy an EC2 instance to a new VPC & default public subnet and a 100 gb EBS volume. It will get the latest `Jenkins Public Bitnami AMI` from the Bitnami website using `cheerio`.
3 |
4 | You will see the output url after the successful deployment. Open the URL in browser and you will see a login screen. In order to get pre-configured user credentials, head over to the EC2 console. Right click on `jenkins-instance` -> Instance Settings -> Get System Log
5 |
6 |
7 |
8 |
9 |
10 | Use these credentials to login.
11 |
--------------------------------------------------------------------------------
/sqs-lambda-dynamodb/README.md:
--------------------------------------------------------------------------------
1 | ## SQS Lambda and DynamoDB Stack
2 | This example will deploy a SQS queue, a DynamoDB table and a Lambda function written in Javacript. Lambda function will get triggered by incoming SQS messages. It will process the incoming message and processed data will be added to DynamoDB table.
3 |
4 |
5 |
6 | You will see a SQS URL after the successful deployment. Use `aws-cli` to send basic message for testing the CDK Stack.
7 |
8 | ```
9 | aws sqs send-message --queue-url https://sqs.us-west-1.amazonaws.com/[ACCOUNT_ID]/Orders --message-body "{\"items\": [\"coffee\", \"gum\"], \"customerId\": \"qm1h324k\"}" --delay-seconds 2 --profile your_profile --region us-west-1
10 | ```
11 |
12 | You should be seeing the new item in DynamoDB table.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Examples using AWS CDK (Cloud Development Kit)
2 |
3 | ### How to Deploy Examples
4 |
5 | Install the CDK CLI globally
6 | `npm install -g aws-cdk`
7 |
8 | Change directory to any example
9 | `cd sagemaker`
10 |
11 | Install dependencies
12 | `npm install`
13 |
14 | Set environment variables
15 | `vim .env`
16 |
17 | Deploy using the CDK CLI
18 | `cdk deploy`
19 |
20 | or deploy to non-default AWS profile
21 | `cdk deploy --profile my_profile`
22 |
23 | ### Other CLI Commands
24 |
25 | - `cdk diff` Prints out the difference in stacks
26 |
27 | - `cdk destroy` Removes the stack
28 |
29 | - `cdk list` List the applications in given folder
30 |
31 | - `cdk synth` Synthesizes and prints the CloudFormation template for the stack
32 |
33 | - `cdk init` Generates a new cdk project
34 |
35 | - `cdk doctor` Checks the CDK setup
36 |
--------------------------------------------------------------------------------
/docdb-lambda-api/src/getLongURL.ts:
--------------------------------------------------------------------------------
1 |
2 | import { APIGatewayEvent, Context, Callback } from "aws-lambda";
3 |
4 | import { connectToDB, success, redirect, notFound } from "./lib";
5 | import { MongoClient } from "mongodb";
6 |
7 | const DB_NAME = process.env.DB_NAME as string;
8 |
9 | let dbClient: MongoClient;
10 |
11 | export async function handler(event: APIGatewayEvent, context: Context, callback: Callback) {
12 | try {
13 | dbClient = await connectToDB();
14 | const db = dbClient.db(DB_NAME);
15 | const id = event.pathParameters!["id"];
16 | const dbItem = await db.collection("urls").findOne({shortId: id});
17 | if(!dbItem) {
18 | return callback(null, notFound({}));
19 | }
20 | return callback(null, redirect(dbItem.url));
21 | } catch(err) {
22 | console.error(err);
23 | return callback("Internal error");
24 | } finally {
25 | await dbClient.close();
26 | }
27 | }
--------------------------------------------------------------------------------
/serverless-eks/templates.ts:
--------------------------------------------------------------------------------
1 | export function getKubernetesTemplates(
2 | repo: any,
3 | name: string,
4 | containerPort: number,
5 | replicaNumber: number
6 | ) {
7 | return [
8 | {
9 | apiVersion: "apps/v1",
10 | kind: "Deployment",
11 | metadata: { name },
12 | spec: {
13 | replicas: replicaNumber,
14 | selector: { matchLabels: { app: name } },
15 | template: {
16 | metadata: {
17 | labels: { app: name }
18 | },
19 | spec: {
20 | containers: [
21 | {
22 | name: name,
23 | image: repo.imageUri,
24 | ports: [{ containerPort }]
25 | }
26 | ]
27 | }
28 | }
29 | }
30 | }
31 | ]
32 | }
--------------------------------------------------------------------------------
/sqs-lambda-dynamodb/lambdaHandler.js:
--------------------------------------------------------------------------------
1 | const DynamoDB = require("aws-sdk").DynamoDB
2 |
3 | const dynamoDb = new DynamoDB.DocumentClient({
4 | region: process.env.REGION
5 | });
6 |
7 | async function handler(event, context, callback) {
8 | try {
9 | for(const record of event.Records) {
10 | const input = JSON.parse(JSON.parse(JSON.stringify(record.body)));
11 | const item = {
12 | id: record.messageId,
13 | timestamp: Date.now(),
14 | items: input.items,
15 | customerId: input.customerId,
16 | sqsMessageAttributes: record.attributes
17 | }
18 | const dbParams = {
19 | TableName: process.env.TABLE_NAME,
20 | Item: item
21 | }
22 | await dynamoDb.put(dbParams).promise();
23 | }
24 | callback(null, "done");
25 | } catch(err) {
26 | console.error(err);
27 | callback("Internal server error");
28 | }
29 | }
30 |
31 | module.exports.handler = handler;
--------------------------------------------------------------------------------
/serverless-eks/README.md:
--------------------------------------------------------------------------------
1 | ## EKS Fargate Example
2 | This example will deploy an EKS cluster with Fargate capability.
3 |
4 | `go-api` folder consist of sample REST API written in Go
5 | `graphql-api` folder consists of GraphQL server written in Nodejs
6 |
7 | After the successful deployment you will see two commands. Use first one to setup your `kubectl` config
8 | `aws eks update-kubeconfig --name ekscluster --region us-east-1 --role-arn arn:aws:iam::111111111111:role/EKSClusterStack-masterroleEF831F2F-8ZOJQU6ROPCT --profile your_profile`
9 |
10 | This command will set the Kubernetes config needed for you to use `kubectl` to control your cluster
11 |
12 | After the initial deployment, pods in all namespaces would stuck in "Pending" state. We need to manually restart all deployments to schedule them on Fargate nodes.
13 | `kubectl rollout restart deployments -n kube-system`
14 | `kubectl rollout restart deployments`
15 |
16 | After that, try getting the running pods in default namespace
17 | `kubectl get pods`
18 |
19 | Forward ports to localhost
20 | `kubectl port-forward deployment/go-api 8080:8080`
--------------------------------------------------------------------------------
/docdb-lambda-api/src/urlShortener.ts:
--------------------------------------------------------------------------------
1 |
2 | import { APIGatewayEvent, Context, Callback } from "aws-lambda";
3 | import { MongoClient } from "mongodb";
4 | import { generate } from "shortid";
5 | import { connectToDB, success } from "./lib";
6 |
7 | const DB_NAME = process.env.DB_NAME as string;
8 | let dbClient: MongoClient;
9 |
10 | export async function handler(event: APIGatewayEvent, context: Context, callback: Callback){
11 | try {
12 | console.log(event);
13 | dbClient = await connectToDB();
14 | const body = JSON.parse(event.body as string);
15 | const db = dbClient.db(DB_NAME);
16 | const shortId = generate();
17 | await db.collection("urls").insertOne({
18 | url: body.url,
19 | createdAt: new Date().toUTCString(),
20 | shortId,
21 | requesterIP: event.requestContext.identity.sourceIp
22 | });
23 | const baseURL = `https://${event.requestContext.domainName}${event.requestContext.path}`;
24 | callback(null, success({shortUrl: `${baseURL}/${shortId}`}));
25 | } catch(err) {
26 | console.error(err);
27 | callback("Internal error");
28 | } finally {
29 | await dbClient.close();
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/lambda-functionURL/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as lambda from "aws-cdk-lib/aws-lambda";
3 | import { config } from "dotenv";
4 | import { Construct } from "constructs";
5 | config();
6 |
7 | class LambdaFunctionURLStack extends cdk.Stack {
8 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
9 | super(scope, id, props);
10 |
11 | const lambdaFunction = new lambda.Function(this, "function-url", {
12 | functionName: "function-url",
13 | runtime: lambda.Runtime.NODEJS_18_X,
14 | code: new lambda.AssetCode("src"),
15 | handler: "lambdaHandler.handler",
16 | timeout: cdk.Duration.seconds(60)
17 | });
18 |
19 | const cors = {
20 | allowedOrigins: ['*'],
21 | };
22 | const functionURL = lambdaFunction.addFunctionUrl({authType: lambda.FunctionUrlAuthType.NONE, cors});
23 |
24 | new cdk.CfnOutput(this, "URLS", {
25 | value: functionURL.url
26 | });
27 |
28 | }
29 | }
30 |
31 | const app = new cdk.App();
32 | new LambdaFunctionURLStack(app, "LambdaFunctionURLStack", {
33 | env: {
34 | account: process.env.AWS_ACCOUNT_ID,
35 | region: process.env.AWS_REGION
36 | }
37 | });
--------------------------------------------------------------------------------
/eks-cluster/README.md:
--------------------------------------------------------------------------------
1 | ## EKS Cluster Example
2 | This example will deploy an EKS cluster, worker nodes, ECR repositories and two services written in Python and NodeJs. Services include Kubernetes resources such as Service, Deployment and Horizontal Pod Scaler templates.
3 |
4 | `go-api` folder consist of sample REST API written in Go
5 |
6 | `graphql-api` folder consists of GraphQL server written in Nodejs
7 |
8 |
9 | After the successful deployment you will see two commands. Use first one to setup your `kubectl` config
10 |
11 | `aws eks update-kubeconfig --name ekscluster --region us-east-1 --role-arn arn:aws:iam::111111111111:role/EKSClusterStack-masterroleEF831F2F-8ZOJQU6ROPCT --profile your_profile`
12 |
13 | This command will set the Kubernetes config needed for you to use `kubectl` to control your cluster
14 |
15 | `kubectl get svc`
16 |
17 | This will show Service resources and external domain information.
18 |
19 | For trying out grapql-api service go to: `{DOMAIN_URL}/graphql`
20 |
21 | For trying out go-api service go to : `{DOMAIN_URL}/dogs`
22 |
23 | You will need to deploy Metrics Server to get HPA working correctly.
24 | https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/metrics-server
25 |
26 | Destroy resources after you are done with the example
27 | `cdk destroy --profile your_profile`
--------------------------------------------------------------------------------
/docdb-lambda-api/src/lib.ts:
--------------------------------------------------------------------------------
1 | import { MongoClient } from "mongodb";
2 | import { readFileSync } from "fs"
3 |
4 | const DB_URL = process.env.DB_URL as string;
5 | const ca = [readFileSync(`${__dirname}/rds-combined-ca-bundle.pem`)];
6 |
7 | export async function connectToDB() {
8 | const client = await MongoClient.connect(DB_URL as string, { ssl: true, sslValidate: true, sslCA: ca, useNewUrlParser: true });
9 | return client;
10 | }
11 |
12 | export function success(body: object): object {
13 | return buildResponse(200, body);
14 | }
15 |
16 | export function failure(body: object): object {
17 | return buildResponse(500, body);
18 | }
19 |
20 | export function notFound(body: object): object {
21 | return buildResponse(404, body);
22 | }
23 |
24 | export function redirect(location: string) {
25 | return {
26 | statusCode: 302,
27 | headers: {
28 | "Access-Control-Allow-Origin": "*",
29 | "Access-Control-Allow-Credentials": true,
30 | Location: location,
31 | }
32 | }
33 | }
34 |
35 | function buildResponse(statusCode: number, body: object): object {
36 | return {
37 | statusCode: statusCode,
38 | headers: {
39 | "Access-Control-Allow-Origin": "*",
40 | "Access-Control-Allow-Credentials": true
41 | },
42 | body: JSON.stringify(body)
43 | };
44 | }
45 |
--------------------------------------------------------------------------------
/lambda-python-api/lib.ts:
--------------------------------------------------------------------------------
1 | import apigateway = require("aws-cdk-lib/aws-apigateway");
2 |
3 | export function addCorsOptions(apiResource: apigateway.IResource) {
4 | apiResource.addMethod('OPTIONS', new apigateway.MockIntegration({
5 | integrationResponses: [{
6 | statusCode: '200',
7 | responseParameters: {
8 | 'method.response.header.Access-Control-Allow-Headers': "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'",
9 | 'method.response.header.Access-Control-Allow-Origin': "'*'",
10 | 'method.response.header.Access-Control-Allow-Credentials': "'false'",
11 | 'method.response.header.Access-Control-Allow-Methods': "'OPTIONS,GET,PUT,POST,DELETE'",
12 | },
13 | }],
14 | passthroughBehavior: apigateway.PassthroughBehavior.NEVER,
15 | requestTemplates: {
16 | "application/json": "{\"statusCode\": 200}"
17 | },
18 | }), {
19 | methodResponses: [{
20 | statusCode: '200',
21 | responseParameters: {
22 | 'method.response.header.Access-Control-Allow-Headers': true,
23 | 'method.response.header.Access-Control-Allow-Methods': true,
24 | 'method.response.header.Access-Control-Allow-Credentials': true,
25 | 'method.response.header.Access-Control-Allow-Origin': true,
26 | },
27 | }]
28 | })
29 | }
--------------------------------------------------------------------------------
/ecs-go-api/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib/core";
2 | import * as ec2 from "aws-cdk-lib/aws-ec2";
3 | import * as ecs from 'aws-cdk-lib/aws-ecs';
4 | import * as ecs_patterns from 'aws-cdk-lib/aws-ecs-patterns';
5 | import { Construct } from "constructs";
6 | import { config } from "dotenv";
7 | config();
8 |
9 | class EcsGoAPIStack extends cdk.Stack {
10 | constructor(scope: Construct, id: string, props?: cdk.StackProps){
11 | super(scope, id, props);
12 |
13 | const vpc = new ec2.Vpc(this, 'vpc', { maxAzs: 2 });
14 |
15 | const cluster = new ecs.Cluster(this, 'Cluster', { vpc });
16 |
17 | const fargateService = new ecs_patterns.ApplicationLoadBalancedFargateService(this, "FargateService", {
18 | cluster,
19 | taskImageOptions: {
20 | image: ecs.ContainerImage.fromAsset(`${__dirname}/api`),
21 | containerPort: 8080,
22 | environment: {
23 | DEPLOYED_DATE: Date.now().toLocaleString()
24 | }
25 | },
26 | desiredCount: 1
27 | });
28 |
29 | new cdk.CfnOutput(this, 'LoadBalancerDNS', { value: fargateService.loadBalancer.loadBalancerDnsName });
30 | }
31 | }
32 |
33 | const app = new cdk.App();
34 | new EcsGoAPIStack(app, "EcsGoAPIStack", {
35 | env: {
36 | account: process.env.AWS_ACCOUNT_ID,
37 | region: process.env.AWS_REGION,
38 | }
39 | });
40 |
--------------------------------------------------------------------------------
/lambda-python-api/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from 'aws-cdk-lib';
2 | import * as lambda from 'aws-cdk-lib/aws-lambda';
3 | import * as apigateway from "aws-cdk-lib/aws-apigateway";
4 | import { readFileSync } from "fs";
5 | import { addCorsOptions } from "./lib";
6 | import { Construct } from "constructs";
7 | import { config } from "dotenv";
8 | config();
9 |
10 | class LambdaPythonAPIStack extends cdk.Stack {
11 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
12 | super(scope, id, props);
13 |
14 | const srcPath = `${__dirname}/lambda-handler.py`;
15 | const lambdaFunction = new lambda.Function(this, "FindPoems", {
16 | code: new lambda.InlineCode(readFileSync(srcPath, { encoding: 'utf-8' })),
17 | handler: 'index.handler',
18 | timeout: cdk.Duration.seconds(30),
19 | runtime: lambda.Runtime.PYTHON_3_7
20 | });
21 |
22 | const api = new apigateway.RestApi(this, 'FindPoemsAPI', {
23 | restApiName: 'Find Poems API'
24 | });
25 | const poems = api.root.addResource("poems");
26 | const lambdaIntegration = new apigateway.LambdaIntegration(lambdaFunction);
27 | poems.addMethod('GET', lambdaIntegration);
28 | addCorsOptions(poems)
29 | }
30 | }
31 |
32 | const app = new cdk.App();
33 | new LambdaPythonAPIStack(app, "LambdaPythonAPIStack", {
34 | env: {
35 | region: process.env.AWS_REGION,
36 | account: process.env.AWS_ACCOUNT_ID
37 | }
38 | });
--------------------------------------------------------------------------------
/keyspaces-cassandra/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as cassandra from "aws-cdk-lib/aws-cassandra"
3 | import { config } from "dotenv";
4 | import { Construct } from "constructs";
5 | config();
6 |
7 | class CassandraStack extends cdk.Stack {
8 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
9 | super(scope, id, props);
10 |
11 | const keyspace = new cassandra.CfnKeyspace(this, "keyspace", {
12 | keyspaceName: "cdkkeyspace"
13 | });
14 |
15 | const table = new cassandra.CfnTable(this, "table", {
16 | keyspaceName: keyspace.keyspaceName as string,
17 | tableName: "cdktable",
18 | partitionKeyColumns: [
19 | {columnName: "id", columnType: "text"},
20 | {columnName: "name", columnType: "text"},
21 | {columnName: "region", columnType: "text"},
22 | {columnName: "role", columnType: "text"}
23 | ]
24 | });
25 |
26 | table.addDependsOn(keyspace);
27 |
28 | new cdk.CfnOutput(this, "keyspace-name", {
29 | value: keyspace.keyspaceName as string
30 | });
31 |
32 | new cdk.CfnOutput(this, "table-name", {
33 | value: table.tableName as string
34 | });
35 |
36 | }
37 | }
38 |
39 | const app = new cdk.App();
40 | new CassandraStack(app, "CassandraStack", {
41 | env: {
42 | account: process.env.AWS_ACCOUNT_ID,
43 | region: process.env.AWS_REGION
44 | }
45 | });
--------------------------------------------------------------------------------
/cognito-userpool/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as cognito from "aws-cdk-lib/aws-cognito";
3 | import { Construct } from 'constructs';
4 | import { config } from "dotenv";
5 | config();
6 |
7 | class CognitoUserPoolStack extends cdk.Stack {
8 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
9 | super(scope, id, props);
10 |
11 | const userPool = new cognito.CfnUserPool(this, "user-pool", {
12 | userPoolName: "user-pool",
13 | usernameAttributes: [
14 | "email",
15 | "phone_number"
16 | ],
17 | policies: {
18 | passwordPolicy: {
19 | minimumLength: 6,
20 | requireLowercase: false,
21 | requireNumbers: true,
22 | requireUppercase: false,
23 | temporaryPasswordValidityDays: 7
24 | }
25 | },
26 | });
27 | const userPoolClient = new cognito.CfnUserPoolClient(this, "user-pool-client", {
28 | userPoolId: userPool.ref,
29 | clientName: "web-client",
30 | generateSecret: false
31 | });
32 | userPoolClient.addDependsOn(userPool);
33 | new cdk.CfnOutput(this, "userpool-name", {value: userPool.userPoolName as string});
34 | }
35 | }
36 |
37 | const app = new cdk.App();
38 | new CognitoUserPoolStack(app, "CognitoUserPoolStack", {
39 | env: {
40 | account: process.env.AWS_ACCOUNT_ID,
41 | region: process.env.AWS_REGION
42 | }
43 | });
--------------------------------------------------------------------------------
/ec2-basics/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from 'aws-cdk-lib';
2 | import * as ec2 from "aws-cdk-lib/aws-ec2";
3 | import { config } from "dotenv";
4 | import { Construct } from 'constructs';
5 | config();
6 |
7 | class EC2BasicsStack extends cdk.Stack {
8 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
9 | super(scope, id, props);
10 |
11 | // Create a new VPC
12 | const vpc = new ec2.Vpc(this, 'VPC');
13 |
14 | // Open port 22 for SSH connection from anywhere
15 | const mySecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
16 | vpc,
17 | securityGroupName: "my-test-sg",
18 | description: 'Allow ssh access to ec2 instances from anywhere',
19 | allowAllOutbound: true
20 | });
21 | mySecurityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'allow public ssh access')
22 |
23 | // We are using the latest AMAZON LINUX AMI
24 | const awsAMI = new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 });
25 |
26 | // We define the instance details here
27 | const ec2Instance = new ec2.Instance(this, 'Instance', {
28 | vpc,
29 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
30 | machineImage: awsAMI,
31 | securityGroup: mySecurityGroup,
32 | vpcSubnets: {
33 | subnetType: ec2.SubnetType.PUBLIC
34 | },
35 | });
36 |
37 | new cdk.CfnOutput(this, "ip-address", {value: ec2Instance.instancePublicIp});
38 | }
39 | }
40 |
41 | const app = new cdk.App();
42 | new EC2BasicsStack(app, "EC2BasicsStack", {
43 | env: {
44 | region: process.env.AWS_REGION,
45 | account: process.env.AWS_ACCOUNT_ID
46 | }
47 | });
--------------------------------------------------------------------------------
/sagemaker/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as sagemaker from "aws-cdk-lib/aws-sagemaker";
3 | import * as ec2 from "aws-cdk-lib/aws-ec2";
4 | import * as iam from "aws-cdk-lib/aws-iam";
5 | import { Construct } from "constructs";
6 | import { config } from "dotenv";
7 | config();
8 |
9 | class SagemakerStack extends cdk.Stack {
10 | constructor(construct: Construct, id: string, props?: cdk.StackProps) {
11 | super(construct, id, props);
12 |
13 | const vpc = new ec2.Vpc(this, "vpc", {
14 | maxAzs: 3
15 | });
16 |
17 | const sg = new ec2.SecurityGroup(this, "sg", {
18 | vpc
19 | });
20 |
21 | const role = new iam.Role(this, "service-role", {
22 | assumedBy: new iam.ServicePrincipal("sagemaker.amazonaws.com"),
23 | managedPolicies: [
24 | iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonS3FullAccess"),
25 | iam.ManagedPolicy.fromAwsManagedPolicyName("CloudWatchLogsFullAccess")
26 | ],
27 | });
28 |
29 | const notebook = new sagemaker.CfnNotebookInstance(this, "notebook", {
30 | notebookInstanceName: "cdk-notebook",
31 | directInternetAccess: "Enabled",
32 | securityGroupIds: [sg.securityGroupId],
33 | instanceType: "ml.t3.medium",
34 | roleArn: role.roleArn,
35 | rootAccess: "Enabled",
36 | subnetId: vpc.publicSubnets[0].subnetId
37 | });
38 | new cdk.CfnOutput(this, "sagemaker", {value: notebook.ref});
39 | }
40 | }
41 |
42 | const app = new cdk.App();
43 | new SagemakerStack(app, "SagemakerStack", {
44 | env: {
45 | account: process.env.ACCOUNT_ID,
46 | region: process.env.AWS_REGION
47 | }
48 | });
--------------------------------------------------------------------------------
/dynamo-streams-lambda/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
3 | import * as lambda from "aws-cdk-lib/aws-lambda";
4 | import {readFileSync} from "fs";
5 | import { Construct } from "constructs";
6 | import { config } from "dotenv";
7 | config();
8 |
9 | class DynamoStreamsLambdaStack extends cdk.Stack {
10 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
11 | super(scope, id, props);
12 |
13 | const srcPath = `${__dirname}/stream-handler.py`;
14 | const streamLambda = new lambda.Function(this, "StreamHandler", {
15 | functionName: "StreamHandler",
16 | code: new lambda.InlineCode(readFileSync(srcPath, { encoding: 'utf-8' })),
17 | handler: 'index.handler',
18 | timeout: cdk.Duration.seconds(30),
19 | runtime: lambda.Runtime.PYTHON_3_7
20 | })
21 |
22 | const dogsTable = new dynamodb.Table(this, "DogsTable", {
23 | tableName: "DogsTable",
24 | partitionKey: {name: "id", type: dynamodb.AttributeType.STRING},
25 | billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
26 | stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES
27 | });
28 | dogsTable.grantStreamRead(streamLambda);
29 | streamLambda.addEventSourceMapping("EventSourceMapping", {
30 | eventSourceArn: dogsTable.tableStreamArn as string,
31 | enabled: true,
32 | startingPosition: lambda.StartingPosition.LATEST
33 | })
34 | }
35 | }
36 |
37 | const app = new cdk.App();
38 | new DynamoStreamsLambdaStack(app, "DynamoStreamsLambdaStack", {
39 | env: {
40 | region: process.env.AWS_REGION,
41 | account: process.env.AWS_ACCOUNT_ID
42 | }
43 | });
--------------------------------------------------------------------------------
/elb-lambda-api/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from 'aws-cdk-lib';
2 | import * as lambda from 'aws-cdk-lib/aws-lambda';
3 | import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
4 | import * as elbv2Targets from "aws-cdk-lib/aws-elasticloadbalancingv2-targets";
5 | import * as ec2 from "aws-cdk-lib/aws-ec2";
6 | import { readFileSync } from 'fs';
7 | import { Construct } from "constructs";
8 | import { config } from "dotenv";
9 | config();
10 |
11 | class ElbLambdaStack extends cdk.Stack {
12 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
13 | super(scope, id, props);
14 |
15 | const vpc = new ec2.Vpc(this, 'VPC', { maxAzs: 2 });
16 |
17 | const srcPath = `${__dirname}/lambda-handler.py`;
18 | const lambdaFunction = new lambda.Function(this, 'random-word-generator', {
19 | code: new lambda.InlineCode(readFileSync(srcPath, { encoding: 'utf-8' })),
20 | handler: 'index.handler',
21 | timeout: cdk.Duration.seconds(300),
22 | runtime: lambda.Runtime.PYTHON_3_7,
23 | vpc
24 | });
25 |
26 | const alb = new elbv2.ApplicationLoadBalancer(this, "alb", {
27 | vpc,
28 | internetFacing: true
29 | });
30 |
31 | const lambdaTarget = new elbv2Targets.LambdaTarget(lambdaFunction);
32 |
33 | const listener = alb.addListener("listener", {
34 | port: 80
35 | });
36 |
37 | listener.addTargets("targets", {
38 | targets: [lambdaTarget]
39 | });
40 |
41 | listener.connections.allowDefaultPortFromAnyIpv4('Open to the world');
42 |
43 | new cdk.CfnOutput(this, "ElbDomain", {value: alb.loadBalancerDnsName});
44 | }
45 | }
46 |
47 |
48 | const app = new cdk.App();
49 | new ElbLambdaStack(app, "ElbLambdaStack", {
50 | env: {
51 | account: process.env.AWS_ACCOUNT_ID,
52 | region: process.env.AWS_REGION
53 | }
54 | });
--------------------------------------------------------------------------------
/rds-proxy/src/handler.js:
--------------------------------------------------------------------------------
1 | const mysql = require("mysql2/promise");
2 | const { RDS } = require("aws-sdk");
3 | const { sleep } = require("./lib");
4 |
5 | async function handler(event, context, callback) {
6 | console.log(process.env);
7 | try {
8 | const { REGION, DB_HOST, DB_PORT, DB_USER, PROXY_HOST, DB_NAME } = process.env;
9 | const rdsSigner = new RDS.Signer({
10 | region: REGION,
11 | hostname: PROXY_HOST,
12 | port: +DB_PORT,
13 | username: DB_USER,
14 | });
15 |
16 | const authToken = rdsSigner.getAuthToken({
17 | username: DB_USER,
18 | });
19 |
20 | for (let i = 0; i < 120; i++) {
21 | const connection = await mysql.createConnection({
22 | host: PROXY_HOST,
23 | user: DB_USER,
24 | database: DB_NAME,
25 | port: +DB_PORT,
26 | password: authToken,
27 | ssl: { rejectUnauthorized: false },
28 | authSwitchHandler: function (data, callback) {
29 | if (data.pluginName === "mysql_clear_password") {
30 | let password = authToken + "\0";
31 | let buffer = Buffer.from(password);
32 | callback(null, password);
33 | }
34 | },
35 | });
36 |
37 | connection.on("connect", () => {
38 | console.log("Connected to database");
39 | });
40 |
41 | connection.on("end", () => {
42 | console.log("Connection closed");
43 | });
44 |
45 | connection.on("error", (err) => {
46 | console.error("Error", err);
47 | });
48 | await connection.execute("SHOW DATABASES")
49 | await sleep(1000);
50 | connection.end();
51 | }
52 |
53 | callback(null, "done");
54 | } catch (err) {
55 | console.error(err);
56 | callback(err);
57 | }
58 | }
59 |
60 | module.exports = {
61 | handler,
62 | };
63 |
--------------------------------------------------------------------------------
/eks-cluster/templates.ts:
--------------------------------------------------------------------------------
1 | export function getKubernetesTemplates(
2 | repo: any,
3 | name: string,
4 | containerPort: number,
5 | replicaNumber: number,
6 | minReplicas: number,
7 | maxReplicas: number,
8 | targetCPUUtilizationPercentage: number
9 | ) {
10 | return [
11 | {
12 | apiVersion: "v1",
13 | kind: "Service",
14 | metadata: { name },
15 | spec: {
16 | type: "LoadBalancer",
17 | ports: [{ port: 80, targetPort: containerPort }],
18 | selector: { app: name }
19 | }
20 | },
21 | {
22 | apiVersion: "apps/v1",
23 | kind: "Deployment",
24 | metadata: { name },
25 | spec: {
26 | replicas: replicaNumber,
27 | selector: { matchLabels: { app: name } },
28 | template: {
29 | metadata: {
30 | labels: { app: name }
31 | },
32 | spec: {
33 | containers: [
34 | {
35 | name: name,
36 | image: repo.imageUri,
37 | ports: [{ containerPort }]
38 | }
39 | ]
40 | }
41 | }
42 | }
43 | },
44 | {
45 | apiVersion: "autoscaling/v1",
46 | kind: "HorizontalPodAutoscaler",
47 | metadata: { name },
48 | spec: {
49 | maxReplicas,
50 | minReplicas,
51 | targetCPUUtilizationPercentage,
52 | scaleTargetRef: {
53 | apiVersion: "extensions/v1beta1",
54 | kind: "Deployment",
55 | name
56 | }
57 | }
58 | }
59 | ]
60 | }
--------------------------------------------------------------------------------
/sqs-lambda-dynamodb/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as sqs from 'aws-cdk-lib/aws-sqs';
3 | import * as lambda from "aws-cdk-lib/aws-lambda";
4 | import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
5 | import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';
6 | import { readFileSync } from "fs";
7 | import { Construct } from "constructs";
8 | import { config } from "dotenv";
9 | config();
10 |
11 | class SQSLambdaDynamodbStack extends cdk.Stack {
12 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
13 | super(scope, id, props);
14 |
15 | const queue = new sqs.Queue(this, "Orders", {
16 | queueName: "Orders"
17 | });
18 |
19 | const table = new dynamodb.Table(this, "OrdersTable", {
20 | tableName: "OrdersTable",
21 | partitionKey: {name: "id", type: dynamodb.AttributeType.STRING},
22 | billingMode: dynamodb.BillingMode.PAY_PER_REQUEST
23 | });
24 |
25 | const srcPath = `${__dirname}/lambdaHandler.js`;
26 | const lambdaFunction = new lambda.Function(this, "ProcessOrder", {
27 | functionName: "ProcessOrder",
28 | code: new lambda.InlineCode(readFileSync(srcPath, {encoding: "utf-8"})),
29 | handler: "index.handler",
30 | timeout: cdk.Duration.seconds(30),
31 | runtime: lambda.Runtime.NODEJS_8_10,
32 | environment: {
33 | TABLE_NAME: table.tableName,
34 | REGION: process.env.AWS_REGION as string
35 | },
36 | events: [
37 | new SqsEventSource(queue)
38 | ]
39 | });
40 | table.grantWriteData(lambdaFunction);
41 | new cdk.CfnOutput(this, 'QueueURL', {
42 | value: queue.queueUrl
43 | });
44 | }
45 | }
46 |
47 | const app = new cdk.App();
48 | new SQSLambdaDynamodbStack(app, "SQSLambdaDynamodbStack", {
49 | env: {
50 | account: process.env.AWS_ACCOUNT_ID,
51 | region: process.env.AWS_REGION
52 | }
53 | })
54 |
55 |
--------------------------------------------------------------------------------
/ec2-jenkins/lib.ts:
--------------------------------------------------------------------------------
1 | import cheerio = require("cheerio");
2 | import axios from "axios";
3 |
4 | const bitnamiURL = "https://bitnami.com/stack/jenkins/cloud/aws/amis";
5 |
6 | export async function getLatestJenkinsAMI(region: string): Promise {
7 | try {
8 | const regionSelection = mapRegionSelector(region)
9 | const selector = `${regionSelection} > table > tbody > tr > td:nth-child(3) > span.clouds__amis__link > a`;
10 | const result = await axios.get(bitnamiURL);
11 | const $ = cheerio.load(result.data);
12 | const res = $(selector).text();
13 | return res;
14 | } catch(err) {
15 | console.error(err);
16 | return "error";
17 | }
18 | }
19 |
20 | function mapRegionSelector(region: string): string {
21 | switch(region) {
22 | case "us-west-1":
23 | return "#us-west-\\(n\\.-california\\)";
24 | case "us-west-2":
25 | return "#us-west-\\(oregon\\)";
26 | case "us-east-1":
27 | return "#us-east-\\(n\\.-virginia\\)";
28 | case "us-east-2":
29 | return "#us-east-\\(ohio\\)";
30 | case "ca-central-1":
31 | return "#canada-\\(central\\)";
32 | case "eu-central-1":
33 | return "#eu-\\(frankfurt\\)";
34 | case "eu-west-1":
35 | return "#eu-\\(ireland\\)";
36 | case "eu-west-2":
37 | return "#eu-\\(london\\)";
38 | case "eu-west-3":
39 | return "#eu-\\(paris\\)";
40 | case "eu-north-1":
41 | return "#eu-\\(stockholm\\)";
42 | case "ap-east-1":
43 | return "#asia-pacific-\\(hong-kong\\)";
44 | case "ap-southeast-1":
45 | return "#asia-pacific-\\(singapore\\)";
46 | case "ap-southeast-2":
47 | return "#asia-pacific-\\(sydney\\)";
48 | case "ap-south-1":
49 | return "#asia-pacific-\\(mumbai\\)";
50 | case "ap-northeast-1":
51 | return "#asia-pacific-\\(tokyo\\)";
52 | case "ap-northeast-2":
53 | return "#asia-pacific-\\(seoul\\)";
54 | case "sa-east-1":
55 | return "#south-america-\\(sao-paulo\\)";
56 | case "me-south-1":
57 | return "#middle-east-\\(bahrain\\)";
58 | default:
59 | return "#us-west-\\(oregon\\)";
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/ec2-jenkins/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as ec2 from "aws-cdk-lib/aws-ec2";
3 | import { getLatestJenkinsAMI } from "./lib";
4 | import { Construct } from "constructs";
5 | import { config } from "dotenv";
6 | config();
7 |
8 | interface EC2JenkinsStackProps {
9 | env: any;
10 | ami: string;
11 | }
12 |
13 | class EC2JenkinsStack extends cdk.Stack {
14 | constructor(scope: Construct, id: string, props: EC2JenkinsStackProps) {
15 | super(scope, id, props);
16 |
17 | // Create a new VPC
18 | const vpc = new ec2.Vpc(this, 'VPC');
19 |
20 | const mySecurityGroup = new ec2.SecurityGroup(this, 'jenkins-sg', {
21 | vpc,
22 | securityGroupName: "jenkins-sg",
23 | allowAllOutbound: true
24 | });
25 | mySecurityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'allow public ssh access')
26 | mySecurityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(80), "Jenkins port");
27 |
28 | const region = props.env.region as string;
29 | const ec2Instance = new ec2.Instance(this, 'Instance', {
30 | vpc,
31 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
32 | machineImage: ec2.MachineImage.genericLinux({
33 | [region]: props.ami
34 | }),
35 | securityGroup: mySecurityGroup,
36 | vpcSubnets: {
37 | subnetType: ec2.SubnetType.PUBLIC
38 | },
39 | blockDevices: [{
40 | deviceName: "/dev/xvdb",
41 | volume: ec2.BlockDeviceVolume.ebs(100, {
42 | deleteOnTermination: true,
43 | encrypted: true
44 | }),
45 | mappingEnabled: true
46 | }]
47 | });
48 |
49 | new cdk.CfnOutput(this, "EC2 URL", {
50 | value: ec2Instance.instancePublicDnsName
51 | });
52 |
53 | }
54 | }
55 |
56 | (async()=>{
57 | const jenkinsAMI = await getLatestJenkinsAMI(process.env.AWS_REGION as string);
58 | const app = new cdk.App();
59 | new EC2JenkinsStack(app, "EC2JenkinsStack", {
60 | env: {
61 | account: process.env.AWS_ACCOUNT_ID,
62 | region: process.env.AWS_REGION,
63 | },
64 | ami: jenkinsAMI
65 | })
66 | })();
--------------------------------------------------------------------------------
/ecs-go-api/api/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | // "fmt"
5 | "net/http"
6 | "encoding/json"
7 | "math/rand"
8 | "os"
9 | "os/signal"
10 | "syscall"
11 | "time"
12 | "context"
13 | "log"
14 |
15 | "github.com/gorilla/mux"
16 | )
17 |
18 | type Dog struct {
19 | Name string `json:"name"`
20 | Age int `json:"age"`
21 | Toy *Toy `json:"toy,omitempty"`
22 | }
23 |
24 | type Toy struct {
25 | Name string `json:"name"`
26 | Color string `json:"color"`
27 | }
28 |
29 | var dogNames = []string{"Rex", "Max", "Molly", "Loki", "Jax"}
30 | var toyNames = []string{"Tennis Ball", "Rope", "Bear", "Dumbell"}
31 | var toyColors = []string{"Red", "Yellow", "Blue", "Green", "Brown"}
32 |
33 | func main() {
34 | r := mux.NewRouter()
35 | r.HandleFunc("/dogs/{name}", handleGetDog).Methods("GET")
36 | r.HandleFunc("/dogs", handleGetDogs).Methods("GET")
37 | server := &http.Server{
38 | Handler: r,
39 | Addr: ":8080",
40 | ReadTimeout: 5 * time.Second,
41 | WriteTimeout: 5 * time.Second,
42 | }
43 |
44 | go func() {
45 | log.Println("Starting server")
46 | if err := server.ListenAndServe(); err != nil {
47 | log.Fatal(err)
48 | }
49 | }()
50 |
51 | waitForShutdown(server)
52 | }
53 |
54 | func handleGetDog(w http.ResponseWriter, r *http.Request) {
55 | vars := mux.Vars(r)
56 | name := vars["name"]
57 | dog := Dog {
58 | Name: name,
59 | Age: rand.Intn(20),
60 | Toy: &Toy{
61 | Name: toyNames[rand.Intn(len(toyNames))],
62 | Color: toyColors[rand.Intn(len(toyColors))],
63 | },
64 | }
65 | res, err := json.Marshal(dog)
66 | if (err != nil) {
67 | panic(err)
68 | }
69 |
70 | w.Header().Set("Content-Type", "application/json")
71 | w.Write(res)
72 | }
73 |
74 | func handleGetDogs(w http.ResponseWriter, r *http.Request) {
75 | dogs := []Dog{}
76 | for _, dogName := range dogNames {
77 | dogs = append(dogs,
78 | Dog{
79 | Name: dogName,
80 | Age: rand.Intn(20),
81 | },
82 | )
83 | }
84 | res, err := json.Marshal(dogs)
85 | if (err != nil) {
86 | panic(err)
87 | }
88 | w.Header().Set("Content-Type", "application/json")
89 | w.Write(res)
90 | }
91 |
92 | func waitForShutdown(server *http.Server) {
93 | interruptChan := make(chan os.Signal, 1)
94 | signal.Notify(interruptChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
95 |
96 | <-interruptChan
97 |
98 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
99 | defer cancel()
100 | server.Shutdown(ctx)
101 |
102 | log.Println("Shutting down")
103 | os.Exit(0)
104 | }
--------------------------------------------------------------------------------
/eks-cluster/go-api/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | // "fmt"
5 | "net/http"
6 | "encoding/json"
7 | "math/rand"
8 | "os"
9 | "os/signal"
10 | "syscall"
11 | "time"
12 | "context"
13 | "log"
14 |
15 | "github.com/gorilla/mux"
16 | )
17 |
18 | type Dog struct {
19 | Name string `json:"name"`
20 | Age int `json:"age"`
21 | Toy *Toy `json:"toy,omitempty"`
22 | }
23 |
24 | type Toy struct {
25 | Name string `json:"name"`
26 | Color string `json:"color"`
27 | }
28 |
29 | var dogNames = []string{"Rex", "Max", "Molly", "Loki", "Jax"}
30 | var toyNames = []string{"Tennis Ball", "Rope", "Bear", "Dumbell"}
31 | var toyColors = []string{"Red", "Yellow", "Blue", "Green", "Brown"}
32 |
33 | func main() {
34 | r := mux.NewRouter()
35 | r.HandleFunc("/dogs/{name}", handleGetDog).Methods("GET")
36 | r.HandleFunc("/dogs", handleGetDogs).Methods("GET")
37 | server := &http.Server{
38 | Handler: r,
39 | Addr: ":8080",
40 | ReadTimeout: 5 * time.Second,
41 | WriteTimeout: 5 * time.Second,
42 | }
43 |
44 | go func() {
45 | log.Println("Starting server")
46 | if err := server.ListenAndServe(); err != nil {
47 | log.Fatal(err)
48 | }
49 | }()
50 |
51 | waitForShutdown(server)
52 | }
53 |
54 | func handleGetDog(w http.ResponseWriter, r *http.Request) {
55 | vars := mux.Vars(r)
56 | name := vars["name"]
57 | dog := Dog {
58 | Name: name,
59 | Age: rand.Intn(20),
60 | Toy: &Toy{
61 | Name: toyNames[rand.Intn(len(toyNames))],
62 | Color: toyColors[rand.Intn(len(toyColors))],
63 | },
64 | }
65 | res, err := json.Marshal(dog)
66 | if (err != nil) {
67 | panic(err)
68 | }
69 |
70 | w.Header().Set("Content-Type", "application/json")
71 | w.Write(res)
72 | }
73 |
74 | func handleGetDogs(w http.ResponseWriter, r *http.Request) {
75 | dogs := []Dog{}
76 | for _, dogName := range dogNames {
77 | dogs = append(dogs,
78 | Dog{
79 | Name: dogName,
80 | Age: rand.Intn(20),
81 | },
82 | )
83 | }
84 | res, err := json.Marshal(dogs)
85 | if (err != nil) {
86 | panic(err)
87 | }
88 | w.Header().Set("Content-Type", "application/json")
89 | w.Write(res)
90 | }
91 |
92 | func waitForShutdown(server *http.Server) {
93 | interruptChan := make(chan os.Signal, 1)
94 | signal.Notify(interruptChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
95 |
96 | <-interruptChan
97 |
98 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
99 | defer cancel()
100 | server.Shutdown(ctx)
101 |
102 | log.Println("Shutting down")
103 | os.Exit(0)
104 | }
--------------------------------------------------------------------------------
/serverless-eks/go-api/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | // "fmt"
5 | "net/http"
6 | "encoding/json"
7 | "math/rand"
8 | "os"
9 | "os/signal"
10 | "syscall"
11 | "time"
12 | "context"
13 | "log"
14 |
15 | "github.com/gorilla/mux"
16 | )
17 |
18 | type Dog struct {
19 | Name string `json:"name"`
20 | Age int `json:"age"`
21 | Toy *Toy `json:"toy,omitempty"`
22 | }
23 |
24 | type Toy struct {
25 | Name string `json:"name"`
26 | Color string `json:"color"`
27 | }
28 |
29 | var dogNames = []string{"Rex", "Max", "Molly", "Loki", "Jax"}
30 | var toyNames = []string{"Tennis Ball", "Rope", "Bear", "Dumbell"}
31 | var toyColors = []string{"Red", "Yellow", "Blue", "Green", "Brown"}
32 |
33 | func main() {
34 | r := mux.NewRouter()
35 | r.HandleFunc("/dogs/{name}", handleGetDog).Methods("GET")
36 | r.HandleFunc("/dogs", handleGetDogs).Methods("GET")
37 | server := &http.Server{
38 | Handler: r,
39 | Addr: ":8080",
40 | ReadTimeout: 5 * time.Second,
41 | WriteTimeout: 5 * time.Second,
42 | }
43 |
44 | go func() {
45 | log.Println("Starting server")
46 | if err := server.ListenAndServe(); err != nil {
47 | log.Fatal(err)
48 | }
49 | }()
50 |
51 | waitForShutdown(server)
52 | }
53 |
54 | func handleGetDog(w http.ResponseWriter, r *http.Request) {
55 | vars := mux.Vars(r)
56 | name := vars["name"]
57 | dog := Dog {
58 | Name: name,
59 | Age: rand.Intn(20),
60 | Toy: &Toy{
61 | Name: toyNames[rand.Intn(len(toyNames))],
62 | Color: toyColors[rand.Intn(len(toyColors))],
63 | },
64 | }
65 | res, err := json.Marshal(dog)
66 | if (err != nil) {
67 | panic(err)
68 | }
69 |
70 | w.Header().Set("Content-Type", "application/json")
71 | w.Write(res)
72 | }
73 |
74 | func handleGetDogs(w http.ResponseWriter, r *http.Request) {
75 | dogs := []Dog{}
76 | for _, dogName := range dogNames {
77 | dogs = append(dogs,
78 | Dog{
79 | Name: dogName,
80 | Age: rand.Intn(20),
81 | },
82 | )
83 | }
84 | res, err := json.Marshal(dogs)
85 | if (err != nil) {
86 | panic(err)
87 | }
88 | w.Header().Set("Content-Type", "application/json")
89 | w.Write(res)
90 | }
91 |
92 | func waitForShutdown(server *http.Server) {
93 | interruptChan := make(chan os.Signal, 1)
94 | signal.Notify(interruptChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
95 |
96 | <-interruptChan
97 |
98 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
99 | defer cancel()
100 | server.Shutdown(ctx)
101 |
102 | log.Println("Shutting down")
103 | os.Exit(0)
104 | }
--------------------------------------------------------------------------------
/eks-cluster/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib/core";
2 | import * as eks from "aws-cdk-lib/aws-eks";
3 | import * as ec2 from "aws-cdk-lib/aws-ec2";
4 | import * as iam from "aws-cdk-lib/aws-iam";
5 | import * as ecrAssets from "aws-cdk-lib/aws-ecr-assets";
6 | import { getKubernetesTemplates } from "./templates";
7 | import { Construct } from "constructs";
8 | import { config } from "dotenv";
9 | config();
10 |
11 | class EKSClusterStack extends cdk.Stack {
12 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
13 | super(scope, id, props);
14 |
15 | const vpc = new ec2.Vpc(this, "vpc", {
16 | maxAzs: 3
17 | });
18 |
19 | const mastersRole = new iam.Role(this, 'master-role', {
20 | assumedBy: new iam.AccountRootPrincipal()
21 | });
22 |
23 | const cluster = new eks.Cluster(this, "cluster", {
24 | version: eks.KubernetesVersion.V1_23,
25 | defaultCapacityInstance: new ec2.InstanceType("m5.large"),
26 | defaultCapacity: 2,
27 | clusterName: "ekscluster",
28 | vpc,
29 | mastersRole
30 | });
31 |
32 | const goAPIRepo = new ecrAssets.DockerImageAsset(this, "go-api-repo", {
33 | directory: "go-api",
34 | });
35 |
36 | const graphqlAPIRepo = new ecrAssets.DockerImageAsset(this, "graphql-api-repo", {
37 | directory: "graphql-api"
38 | });
39 |
40 | const goAPIResource = new eks.KubernetesManifest(this, "go-api-resource", {
41 | cluster,
42 | manifest: getKubernetesTemplates(
43 | goAPIRepo, //repo
44 | "go-api", //resource name
45 | 8080, //container port
46 | 2, //replica number
47 | 2, // min replicas for hpa
48 | 4, // max replicas for hpa
49 | 70 // hpa cpu util. target
50 | )
51 | });
52 |
53 | const graphqlAPIResource = new eks.KubernetesManifest(this, "graphql-api-resource", {
54 | cluster,
55 | manifest: getKubernetesTemplates(
56 | graphqlAPIRepo, //repo
57 | "graphql-api", //resource name
58 | 8090, //container port
59 | 2, //replica number
60 | 2, // min replicas for hpa
61 | 4, // max replicas for hpa
62 | 70 // hpa cpu util. target
63 | )
64 | });
65 |
66 | }
67 | }
68 |
69 | const app = new cdk.App();
70 | const stack = new EKSClusterStack(app, "EKSClusterStack", {
71 | env: {
72 | region: process.env.AWS_REGION,
73 | account: process.env.AWS_ACCOUNT_ID
74 | }
75 | });
--------------------------------------------------------------------------------
/serverless-eks/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as eks from "aws-cdk-lib/aws-eks";
3 | import * as ec2 from "aws-cdk-lib/aws-ec2";
4 | import * as iam from "aws-cdk-lib/aws-iam";
5 | import * as ecrAssets from "aws-cdk-lib/aws-ecr-assets";
6 | import { getKubernetesTemplates } from "./templates";
7 | import { Construct } from "constructs";
8 | import { config } from "dotenv";
9 | config();
10 |
11 | class ServerlessEKSStack extends cdk.Stack {
12 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
13 | super(scope, id, props);
14 |
15 | const vpc = new ec2.Vpc(this, "vpc", {
16 | maxAzs: 3
17 | });
18 |
19 | const mastersRole = new iam.Role(this, 'masters-role', {
20 | assumedBy: new iam.AccountRootPrincipal()
21 | });
22 |
23 | const fargateProfileRole = new iam.Role(this, "fargate-profile-role", {
24 | assumedBy: new iam.ServicePrincipal("eks-fargate-pods.amazonaws.com"),
25 | managedPolicies: [
26 | iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonEKSFargatePodExecutionRolePolicy")
27 | ]
28 | })
29 |
30 | const cluster = new eks.FargateCluster(this, "fargate-cluster", {
31 | version: eks.KubernetesVersion.V1_19,
32 | clusterName: "sls-eks",
33 | vpc,
34 | mastersRole,
35 | coreDnsComputeType: eks.CoreDnsComputeType.FARGATE,
36 | defaultProfile: {
37 | fargateProfileName: "default-profile",
38 | selectors: [
39 | { namespace: "default" },
40 | { namespace: "kube-system" }
41 | ],
42 | podExecutionRole: fargateProfileRole
43 | }
44 | });
45 |
46 | const goAPIRepo = new ecrAssets.DockerImageAsset(this, "go-api-docker", {
47 | directory: "go-api"
48 | });
49 |
50 | const graphqlAPIRepo = new ecrAssets.DockerImageAsset(this, "graphql-docker", {
51 | directory: "graphql-api"
52 | });
53 |
54 | const apiTemplates = getKubernetesTemplates(
55 | goAPIRepo, //repo
56 | "go-api", //resource name
57 | 8080, //container port,
58 | 2 //replica number
59 | );
60 | cluster.addManifest("api-resource", ...apiTemplates);
61 |
62 | const graphqlTemplates = getKubernetesTemplates(
63 | graphqlAPIRepo, //repo
64 | "graphql-api", //resource name
65 | 8090, //container port,
66 | 2 //replica number
67 | );
68 | cluster.addManifest("graphql-resource", ...graphqlTemplates);
69 | }
70 | }
71 |
72 | const app = new cdk.App();
73 | const stack = new ServerlessEKSStack(app, "ServerlessEksStack", {
74 | env: {
75 | region: process.env.AWS_REGION,
76 | account: process.env.AWS_ACCOUNT_ID
77 | }
78 | });
--------------------------------------------------------------------------------
/elasticsearch-cluster/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as es from "aws-cdk-lib/aws-elasticsearch";
3 | import * as ec2 from "aws-cdk-lib/aws-ec2";
4 | import { Construct } from "constructs";
5 | import { config } from "dotenv";
6 | config();
7 |
8 | const DOMAIN_NAME = "es-domain";
9 |
10 | export class ElasticSearchStack extends cdk.Stack {
11 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
12 | super(scope, id, props);
13 |
14 | // Comment out for enabling VPC
15 | const vpc = new ec2.Vpc(this, "vpc", {
16 | maxAzs: 3
17 | });
18 | const sg = new ec2.SecurityGroup(this, "sg", {
19 | vpc,
20 | allowAllOutbound: true,
21 | securityGroupName: "es-sg"
22 | });
23 | sg.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(80), "Allow access to port 80");
24 | sg.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(443), "Allow access to port 443");
25 |
26 | const domain = new es.CfnDomain(this, "es-domain", {
27 | vpcOptions: {
28 | subnetIds: vpc.publicSubnets.slice(0,2).map(subnet=>subnet.subnetId),
29 | securityGroupIds: [sg.securityGroupId]
30 | },
31 | domainName: DOMAIN_NAME,
32 | elasticsearchVersion: "6.8",
33 | elasticsearchClusterConfig: {
34 | instanceType: "t2.medium.elasticsearch",
35 | dedicatedMasterEnabled: true,
36 | dedicatedMasterCount: 2,
37 | dedicatedMasterType: "t2.medium.elasticsearch",
38 | instanceCount: 2,
39 | zoneAwarenessEnabled: true,
40 | zoneAwarenessConfig: {
41 | availabilityZoneCount: 2
42 | }
43 | },
44 | ebsOptions: {
45 | ebsEnabled: true,
46 | volumeSize: 35,
47 | volumeType: "io1",
48 | iops: 1000
49 | },
50 | accessPolicies: {
51 | Version: "2012-10-17",
52 | Statement: [
53 | {
54 | Effect: "Allow",
55 | Principal: {
56 | "AWS": "*"
57 | },
58 | "Action":"es:*",
59 | "Resource":`arn:aws:es:${process.env.AWS_REGION}:${process.env.ACCOUNT_ID}:domain/${DOMAIN_NAME}/*`
60 | }
61 | ]
62 | }
63 | });
64 |
65 | new cdk.CfnOutput(this, "domain", {value: domain.attrDomainEndpoint as string})
66 | new cdk.CfnOutput(this, "kibana", {value: `${domain.attrDomainEndpoint}/_plugin/kibana/` as string})
67 | }
68 | }
69 |
70 | const app = new cdk.App();
71 | new ElasticSearchStack(app, "ElasticSearchStack", {
72 | env: {
73 | account: process.env.AWS_ACCOUNT_ID,
74 | region: process.env.AWS_REGION
75 | }
76 | });
--------------------------------------------------------------------------------
/wordpress-ha/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as ec2 from "aws-cdk-lib/aws-ec2";
3 | import * as rds from "aws-cdk-lib/aws-rds";
4 | import * as ecs_patterns from "aws-cdk-lib/aws-ecs-patterns";
5 | import * as ecs from "aws-cdk-lib/aws-ecs";
6 | import { Construct } from "constructs";
7 | require('dotenv').config();
8 |
9 | const DB_PORT = +(process.env["DB_PORT"] as string);
10 | const DB_NAME = process.env["DB_NAME"] as string;
11 | const DB_USER = process.env["DB_USER"] as string
12 | const DB_PASSWORD = process.env["DB_PASSWORD"] as string;
13 |
14 | class WordpressHAStack extends cdk.Stack {
15 | constructor(construct: Construct, id: string, props?: cdk.StackProps) {
16 | super(construct, id, props);
17 |
18 | const vpc = new ec2.Vpc(this, "vpc", {
19 | maxAzs: 3
20 | });
21 |
22 | const wordpressSg = new ec2.SecurityGroup(this, "wp-sg", {
23 | vpc: vpc,
24 | description: 'Wordpress SG'
25 | });
26 |
27 | const dbCluster = new rds.DatabaseCluster(this, "db-cluster", {
28 | clusterIdentifier: "db-cluster",
29 | defaultDatabaseName: DB_NAME,
30 | engine: rds.DatabaseClusterEngine.AURORA,
31 | port: DB_PORT,
32 | credentials: {
33 | username: DB_USER,
34 | password: cdk.SecretValue.plainText(DB_PASSWORD)
35 | },
36 | instanceProps: {
37 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
38 | vpc,
39 | securityGroups: [wordpressSg]
40 | }
41 | });
42 |
43 | const cluster = new ecs.Cluster(this, "ecs-cluster", {
44 | vpc,
45 | });
46 |
47 | cluster.connections.addSecurityGroup(wordpressSg);
48 |
49 | const wordpressService = new ecs_patterns.ApplicationLoadBalancedEc2Service(this, "wordpress-service", {
50 | cluster,
51 | memoryLimitMiB: 1024,
52 | taskImageOptions: {
53 | image: ecs.ContainerImage.fromRegistry('wordpress'),
54 | environment: {
55 | WORDPRESS_DB_HOST: dbCluster.clusterEndpoint.socketAddress,
56 | WORDPRESS_DB_USER: DB_USER,
57 | WORDPRESS_DB_PASSWORD: DB_PASSWORD,
58 | WORDPRESS_DB_NAME: DB_NAME,
59 | },
60 | },
61 | desiredCount: 2,
62 | });
63 |
64 | const scalableTarget = wordpressService.service.autoScaleTaskCount({
65 | minCapacity: 2,
66 | maxCapacity: 5
67 | });
68 | scalableTarget.scaleOnCpuUtilization('task-cpu-scaling', {
69 | targetUtilizationPercent: 20,
70 | });
71 | }
72 | }
73 |
74 | const app = new cdk.App();
75 | new WordpressHAStack(app, "WordpressStack", {
76 | env: {
77 | account: process.env.AWS_ACCOUNT_ID,
78 | region: process.env.AWS_REGION
79 | }
80 | })
81 |
82 |
--------------------------------------------------------------------------------
/backups/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as rds from "aws-cdk-lib/aws-rds";
3 | import * as backup from "aws-cdk-lib/aws-backup";
4 | import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
5 | import * as ec2 from "aws-cdk-lib/aws-ec2";
6 | import { Backup, BackupProps } from "cdk-backup-plan";
7 | import { config } from "dotenv";
8 | import { Construct } from "constructs";
9 | config();
10 |
11 | class AWSBackupStack extends cdk.Stack {
12 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
13 | super(scope, id, props);
14 |
15 | const dynamoTable = new dynamodb.Table(this, "dynamo-table", {
16 | tableName: "dynamo-table",
17 | partitionKey: { name: "id", type: dynamodb.AttributeType.STRING },
18 | billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
19 | removalPolicy: cdk.RemovalPolicy.DESTROY
20 | });
21 |
22 | const vpc = ec2.Vpc.fromLookup(this, "vpc", {
23 | isDefault: true,
24 | });
25 |
26 | // We define the instance details here
27 | const ec2Instance = new ec2.Instance(this, 'Instance', {
28 | vpc,
29 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
30 | machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 })
31 | });
32 |
33 |
34 | const auroraCluster = new rds.ServerlessCluster(this, "rds-cluster", {
35 | engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL,
36 | enableDataApi: true,
37 | parameterGroup: rds.ParameterGroup.fromParameterGroupName(this, 'ParameterGroup', "default.aurora-postgresql10"),
38 | });
39 |
40 | const dynamoBackup = new Backup(this, "dynamo-backup", {
41 | backupPlanName: "dynamo-backup",
42 | backupRateHour: 2,
43 | backupCompletionWindow: cdk.Duration.hours(2),
44 | resources: [backup.BackupResource.fromDynamoDbTable(dynamoTable)],
45 | });
46 |
47 | const auroraBackup = new Backup(this, "aurora-backup", {
48 | backupPlanName: "aurora-backup",
49 | backupRateHour: 2,
50 | backupCompletionWindow: cdk.Duration.hours(2),
51 | resources: [backup.BackupResource.fromRdsServerlessCluster(auroraCluster)]
52 | });
53 |
54 |
55 | const ec2Backup = new Backup(this, "ec2-backup", {
56 | backupPlanName: "ec2-backup",
57 | backupRateHour: 2,
58 | backupCompletionWindow: cdk.Duration.hours(2),
59 | resources: [backup.BackupResource.fromEc2Instance(ec2Instance)]
60 | });
61 |
62 | new cdk.CfnOutput(this, "dynamo-backup-id", {
63 | value: dynamoBackup.backupPlan.backupPlanId
64 | });
65 |
66 | new cdk.CfnOutput(this, "aurora-backup-id", {
67 | value: auroraBackup.backupPlan.backupPlanId
68 | });
69 |
70 | new cdk.CfnOutput(this, "ec2-backup-id", {
71 | value: ec2Backup.backupPlan.backupPlanId
72 | });
73 |
74 | }
75 | }
76 |
77 | const app = new cdk.App();
78 | new AWSBackupStack(app, "AWSBackupStack", {
79 | env: {
80 | account: process.env.AWS_ACCOUNT_ID,
81 | region: process.env.AWS_REGION
82 | }
83 | });
--------------------------------------------------------------------------------
/lambda-python-api/lambda-handler.py:
--------------------------------------------------------------------------------
1 | import json
2 | import urllib.request
3 | import random
4 |
5 | authors = [
6 | "Adam Lindsay Gordon",
7 | "Alan Seeger",
8 | "Alexander Pope",
9 | "Algernon Charles Swinburne",
10 | "Ambrose Bierce",
11 | "Amy Levy",
12 | "Andrew Marvell",
13 | "Ann Taylor",
14 | "Anne Bradstreet",
15 | "Anne Bronte",
16 | "Anne Killigrew",
17 | "Anne Kingsmill Finch",
18 | "Annie Louisa Walker",
19 | "Arthur Hugh Clough",
20 | "Ben Jonson",
21 | "Charles Kingsley",
22 | "Charles Sorley",
23 | "Charlotte Bronte",
24 | "Charlotte Smith",
25 | "Christina Rossetti",
26 | "Christopher Marlowe",
27 | "Christopher Smart",
28 | "Coventry Patmore",
29 | "Edgar Allan Poe",
30 | "Edmund Spenser",
31 | "Edward Fitzgerald",
32 | "Edward Lear",
33 | "Edward Taylor",
34 | "Edward Thomas",
35 | "Eliza Cook",
36 | "Elizabeth Barrett Browning",
37 | "Emily Bronte",
38 | "Emily Dickinson",
39 | "Emma Lazarus",
40 | "Ernest Dowson",
41 | "Eugene Field",
42 | "Francis Thompson",
43 | "Geoffrey Chaucer",
44 | "George Eliot",
45 | "George Gordon, Lord Byron",
46 | "George Herbert",
47 | "George Meredith",
48 | "Gerard Manley Hopkins",
49 | "Helen Hunt Jackson",
50 | "Henry David Thoreau",
51 | "Henry Vaughan",
52 | "Henry Wadsworth Longfellow",
53 | "Hugh Henry Brackenridge",
54 | "Isaac Watts",
55 | "James Henry Leigh Hunt",
56 | "James Thomson",
57 | "James Whitcomb Riley",
58 | "Jane Austen",
59 | "Jane Taylor",
60 | "John Clare",
61 | "John Donne",
62 | "John Dryden",
63 | "John Greenleaf Whittier",
64 | "John Keats",
65 | "John McCrae",
66 | "John Milton",
67 | "John Trumbull",
68 | "John Wilmot",
69 | "Jonathan Swift",
70 | "Joseph Warton",
71 | "Joyce Kilmer",
72 | "Julia Ward Howe",
73 | "Jupiter Hammon",
74 | "Katherine Philips",
75 | "Lady Mary Chudleigh",
76 | "Lewis Carroll",
77 | "Lord Alfred Tennyson",
78 | "Louisa May Alcott",
79 | "Major Henry Livingston, Jr.",
80 | "Mark Twain",
81 | "Mary Elizabeth Coleridge",
82 | "Matthew Arnold",
83 | "Matthew Prior",
84 | "Michael Drayton",
85 | "Oliver Goldsmith",
86 | "Oliver Wendell Holmes",
87 | "Oscar Wilde",
88 | "Paul Laurence Dunbar",
89 | "Percy Bysshe Shelley",
90 | "Philip Freneau",
91 | "Phillis Wheatley",
92 | "Ralph Waldo Emerson",
93 | "Richard Crashaw",
94 | "Richard Lovelace",
95 | "Robert Browning",
96 | "Robert Burns",
97 | "Robert Herrick",
98 | "Robert Louis Stevenson",
99 | "Robert Southey",
100 | "Robinson",
101 | "Rupert Brooke",
102 | "Samuel Coleridge",
103 | "Samuel Johnson",
104 | "Sarah Flower Adams",
105 | "Sidney Lanier",
106 | "Sir John Suckling",
107 | "Sir Philip Sidney",
108 | "Sir Thomas Wyatt",
109 | "Sir Walter Raleigh",
110 | "Sir Walter Scott",
111 | "Stephen Crane",
112 | "Thomas Campbell",
113 | "Thomas Chatterton",
114 | "Thomas Flatman",
115 | "Thomas Gray",
116 | "Thomas Hood",
117 | "Thomas Moore",
118 | "Thomas Warton",
119 | "Walt Whitman",
120 | "Walter Savage Landor",
121 | "Wilfred Owen",
122 | "William Allingham",
123 | "William Barnes",
124 | "William Blake",
125 | "William Browne",
126 | "William Cowper",
127 | "William Cullen Bryant",
128 | "William Ernest Henley",
129 | "William Lisle Bowles",
130 | "William Morris",
131 | "William Shakespeare",
132 | "William Topaz McGonagall",
133 | "William Vaughn Moody",
134 | "William Wordsworth"
135 | ]
136 |
137 | poet_api_url = "poetrydb.org"
138 |
139 | def handler(event, context):
140 | author = authors[random.randint(0, len(authors)-1)]
141 | url = urllib.parse.quote("{}/author/{}".format(poet_api_url, author))
142 | url = "http://{}".format(url)
143 | response = json.loads(urllib.request.urlopen(url).read())
144 | return {
145 | "statusCode": 200,
146 | "body": json.dumps(response[random.randint(0, len(response)-1)])
147 | }
--------------------------------------------------------------------------------
/elb-lambda-api/lambda-handler.py:
--------------------------------------------------------------------------------
1 | import json
2 | import urllib.request
3 | import random
4 |
5 | authors = [
6 | "Adam Lindsay Gordon",
7 | "Alan Seeger",
8 | "Alexander Pope",
9 | "Algernon Charles Swinburne",
10 | "Ambrose Bierce",
11 | "Amy Levy",
12 | "Andrew Marvell",
13 | "Ann Taylor",
14 | "Anne Bradstreet",
15 | "Anne Bronte",
16 | "Anne Killigrew",
17 | "Anne Kingsmill Finch",
18 | "Annie Louisa Walker",
19 | "Arthur Hugh Clough",
20 | "Ben Jonson",
21 | "Charles Kingsley",
22 | "Charles Sorley",
23 | "Charlotte Bronte",
24 | "Charlotte Smith",
25 | "Christina Rossetti",
26 | "Christopher Marlowe",
27 | "Christopher Smart",
28 | "Coventry Patmore",
29 | "Edgar Allan Poe",
30 | "Edmund Spenser",
31 | "Edward Fitzgerald",
32 | "Edward Lear",
33 | "Edward Taylor",
34 | "Edward Thomas",
35 | "Eliza Cook",
36 | "Elizabeth Barrett Browning",
37 | "Emily Bronte",
38 | "Emily Dickinson",
39 | "Emma Lazarus",
40 | "Ernest Dowson",
41 | "Eugene Field",
42 | "Francis Thompson",
43 | "Geoffrey Chaucer",
44 | "George Eliot",
45 | "George Gordon, Lord Byron",
46 | "George Herbert",
47 | "George Meredith",
48 | "Gerard Manley Hopkins",
49 | "Helen Hunt Jackson",
50 | "Henry David Thoreau",
51 | "Henry Vaughan",
52 | "Henry Wadsworth Longfellow",
53 | "Hugh Henry Brackenridge",
54 | "Isaac Watts",
55 | "James Henry Leigh Hunt",
56 | "James Thomson",
57 | "James Whitcomb Riley",
58 | "Jane Austen",
59 | "Jane Taylor",
60 | "John Clare",
61 | "John Donne",
62 | "John Dryden",
63 | "John Greenleaf Whittier",
64 | "John Keats",
65 | "John McCrae",
66 | "John Milton",
67 | "John Trumbull",
68 | "John Wilmot",
69 | "Jonathan Swift",
70 | "Joseph Warton",
71 | "Joyce Kilmer",
72 | "Julia Ward Howe",
73 | "Jupiter Hammon",
74 | "Katherine Philips",
75 | "Lady Mary Chudleigh",
76 | "Lewis Carroll",
77 | "Lord Alfred Tennyson",
78 | "Louisa May Alcott",
79 | "Major Henry Livingston, Jr.",
80 | "Mark Twain",
81 | "Mary Elizabeth Coleridge",
82 | "Matthew Arnold",
83 | "Matthew Prior",
84 | "Michael Drayton",
85 | "Oliver Goldsmith",
86 | "Oliver Wendell Holmes",
87 | "Oscar Wilde",
88 | "Paul Laurence Dunbar",
89 | "Percy Bysshe Shelley",
90 | "Philip Freneau",
91 | "Phillis Wheatley",
92 | "Ralph Waldo Emerson",
93 | "Richard Crashaw",
94 | "Richard Lovelace",
95 | "Robert Browning",
96 | "Robert Burns",
97 | "Robert Herrick",
98 | "Robert Louis Stevenson",
99 | "Robert Southey",
100 | "Robinson",
101 | "Rupert Brooke",
102 | "Samuel Coleridge",
103 | "Samuel Johnson",
104 | "Sarah Flower Adams",
105 | "Sidney Lanier",
106 | "Sir John Suckling",
107 | "Sir Philip Sidney",
108 | "Sir Thomas Wyatt",
109 | "Sir Walter Raleigh",
110 | "Sir Walter Scott",
111 | "Stephen Crane",
112 | "Thomas Campbell",
113 | "Thomas Chatterton",
114 | "Thomas Flatman",
115 | "Thomas Gray",
116 | "Thomas Hood",
117 | "Thomas Moore",
118 | "Thomas Warton",
119 | "Walt Whitman",
120 | "Walter Savage Landor",
121 | "Wilfred Owen",
122 | "William Allingham",
123 | "William Barnes",
124 | "William Blake",
125 | "William Browne",
126 | "William Cowper",
127 | "William Cullen Bryant",
128 | "William Ernest Henley",
129 | "William Lisle Bowles",
130 | "William Morris",
131 | "William Shakespeare",
132 | "William Topaz McGonagall",
133 | "William Vaughn Moody",
134 | "William Wordsworth"
135 | ]
136 |
137 | poet_api_url = "poetrydb.org"
138 |
139 | def handler(event, context):
140 | author = authors[random.randint(0, len(authors)-1)]
141 | url = urllib.parse.quote("{}/author/{}".format(poet_api_url, author))
142 | url = "http://{}".format(url)
143 | response = json.loads(urllib.request.urlopen(url).read())
144 | return {
145 | "statusCode": 200,
146 | "body": json.dumps(response[random.randint(0, len(response)-1)]),
147 | "statusDescription": "200 OK",
148 | "isBase64Encoded": False,
149 | "headers": {
150 | "Content-Type": "application/json"
151 | },
152 | }
--------------------------------------------------------------------------------
/docdb-lambda-api/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as lambda from "aws-cdk-lib/aws-lambda";
3 | import * as apigateway from "aws-cdk-lib/aws-apigateway";
4 | import * as docdb from "aws-cdk-lib/aws-docdb";
5 | import * as ec2 from "aws-cdk-lib/aws-ec2";
6 | import { Construct } from "constructs";
7 | import { config } from "dotenv";
8 | config();
9 |
10 | class DocdbLambdaAPIStack extends cdk.Stack {
11 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
12 | super(scope, id, props);
13 |
14 | const vpcCidr = "10.0.0.0/21";
15 | const port = 27017;
16 |
17 | const vpc = new ec2.Vpc(this, "vpc", {
18 | cidr: vpcCidr,
19 | subnetConfiguration: [
20 | {
21 | subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
22 | cidrMask: 24,
23 | name: "PrivateSubnet1"
24 | },
25 | {
26 | subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
27 | cidrMask: 24,
28 | name: "PrivateSubnet2"
29 | },
30 | {
31 | subnetType: ec2.SubnetType.PUBLIC,
32 | cidrMask: 28,
33 | name: "PublicSubnet1"
34 | }
35 | ]
36 | });
37 |
38 | const sg = new ec2.SecurityGroup(this, "docdb-lambda-sg", {
39 | vpc,
40 | securityGroupName: "docdb-lambda-sg"
41 | });
42 |
43 | const subnetGroup = new docdb.CfnDBSubnetGroup(this, "subnet-group", {
44 | subnetIds: vpc.privateSubnets.map(x=>x.subnetId),
45 | dbSubnetGroupName: "subnet-group",
46 | dbSubnetGroupDescription: "Subnet Group for DocDB"
47 | });
48 |
49 | const dbCluster = new docdb.CfnDBCluster(this, "db-cluster", {
50 | storageEncrypted: true,
51 | availabilityZones: vpc.availabilityZones.splice(3),
52 | dbClusterIdentifier: "docdb",
53 | masterUsername: "dbuser",
54 | masterUserPassword: process.env.MASTER_USER_PASSWORD as string,
55 | vpcSecurityGroupIds: [sg.securityGroupId],
56 | dbSubnetGroupName: subnetGroup.dbSubnetGroupName,
57 | port
58 | });
59 | dbCluster.addDependsOn(subnetGroup)
60 |
61 | const dbInstance = new docdb.CfnDBInstance(this, "db-instance", {
62 | dbClusterIdentifier: dbCluster.ref,
63 | autoMinorVersionUpgrade: true,
64 | dbInstanceClass: "db.r5.large",
65 | dbInstanceIdentifier: "staging"
66 | });
67 | dbInstance.addDependsOn(dbCluster);
68 |
69 | sg.addIngressRule(ec2.Peer.ipv4(vpcCidr), ec2.Port.tcp(port));
70 |
71 | const DB_URL = `mongodb://${dbCluster.masterUsername}:${dbCluster.masterUserPassword}@${dbCluster.attrEndpoint}:${dbCluster.attrPort}`
72 | const DB_NAME = dbInstance.dbInstanceIdentifier as string;
73 |
74 | const urlShortener = new lambda.Function(this, "urlShortener", {
75 | functionName: "urlShortener",
76 | runtime: lambda.Runtime.NODEJS_10_X,
77 | vpc,
78 | code: new lambda.AssetCode("src"),
79 | handler: "urlShortener.handler",
80 | timeout: cdk.Duration.seconds(60),
81 | securityGroups: [sg],
82 | environment: {
83 | DB_URL,
84 | DB_NAME
85 | },
86 | });
87 |
88 | const getLongURL = new lambda.Function(this, "getLongURL", {
89 | functionName: "getLongURL",
90 | runtime: lambda.Runtime.NODEJS_10_X,
91 | vpc,
92 | code: new lambda.AssetCode("src"),
93 | handler: "getLongURL.handler",
94 | timeout: cdk.Duration.seconds(60),
95 | securityGroups: [sg],
96 | environment: {
97 | DB_URL,
98 | DB_NAME
99 | }
100 | });
101 |
102 | const api = new apigateway.RestApi(this, "api", {
103 | restApiName: "url-shortener"
104 | });
105 |
106 | const urls = api.root.addResource("urls")
107 | const urlShortenerLambdaIntegration = new apigateway.LambdaIntegration(urlShortener);
108 | urls.addMethod("POST", urlShortenerLambdaIntegration);
109 |
110 | const singleURL = urls.addResource(`{id}`);
111 | const getLongURLLambdaIntegration = new apigateway.LambdaIntegration(getLongURL);
112 | singleURL.addMethod("GET", getLongURLLambdaIntegration);
113 |
114 | new cdk.CfnOutput(this, "db-url", {
115 | value: DB_URL
116 | });
117 | }
118 | }
119 |
120 | const app = new cdk.App();
121 | new DocdbLambdaAPIStack(app, "DocdbLambdaAPIStack", {
122 | env: {
123 | region: process.env.AWS_REGION,
124 | account: process.env.AWS_ACCOUNT_ID
125 | }
126 | });
--------------------------------------------------------------------------------
/rds-proxy/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as rds from "aws-cdk-lib/aws-rds";
3 | import * as ec2 from "aws-cdk-lib/aws-ec2";
4 | import * as iam from "aws-cdk-lib/aws-iam";
5 | import * as lambda from "aws-cdk-lib/aws-lambda";
6 | import { config } from "dotenv";
7 | config();
8 |
9 | const DB_PORT = process.env["DB_PORT"] as string;
10 | const DB_NAME = process.env["DB_NAME"] as string;
11 | const DB_USER = process.env["DB_USER"] as string
12 | const NUM_OF_LAMBDA_FUNCTIONS = 10;
13 |
14 | class RdsProxyStack extends cdk.Stack {
15 | constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
16 | super(scope, id, props);
17 |
18 | const vpc = new ec2.Vpc(this, "vpc", {
19 | maxAzs: 3
20 | });
21 |
22 | const dbClusterSg = new ec2.SecurityGroup(this, "db-instance-sg", {
23 | vpc,
24 | description: 'RDS Cluster SG'
25 | });
26 |
27 | const lambdaSg = new ec2.SecurityGroup(this, "lambda-sg", {
28 | vpc,
29 | description: "Lambda SG"
30 | });
31 |
32 | const dbProxySg = new ec2.SecurityGroup(this, "db-proxy-sg", {
33 | vpc,
34 | description: "RDS Proxy SG"
35 | });
36 |
37 | dbClusterSg.addIngressRule(lambdaSg, ec2.Port.tcp(+DB_PORT));
38 | dbProxySg.addIngressRule(lambdaSg, ec2.Port.tcp(+DB_PORT));
39 | dbClusterSg.addIngressRule(dbProxySg, ec2.Port.tcp(+DB_PORT));
40 |
41 |
42 | const dbCluster = new rds.DatabaseCluster(this, "db-cluster", {
43 | clusterIdentifier: "db-cluster",
44 | defaultDatabaseName: DB_NAME,
45 | engine: rds.DatabaseClusterEngine.AURORA_MYSQL,
46 | port: +DB_PORT,
47 | instanceProps: {
48 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
49 | vpc,
50 | securityGroups: [dbClusterSg]
51 | },
52 | removalPolicy: cdk.RemovalPolicy.DESTROY,
53 | instanceIdentifierBase: "dbcluster",
54 | credentials: {
55 | username: DB_USER
56 | }
57 | });
58 |
59 | const dbProxy = new rds.DatabaseProxy(this, "db-proxy", {
60 | vpc,
61 | vpcSubnets: {
62 | subnetType: ec2.SubnetType.PUBLIC
63 | },
64 | borrowTimeout: cdk.Duration.seconds(30),
65 | proxyTarget: rds.ProxyTarget.fromCluster(dbCluster),
66 | secrets: [dbCluster.secret!],
67 | dbProxyName: "db-proxy",
68 | securityGroups: [dbProxySg],
69 | requireTLS: true,
70 | iamAuth: true
71 | });
72 |
73 | const lambdaRole = new iam.Role(this, "lambda-role", {
74 | roleName: "lambda-role",
75 | assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
76 | inlinePolicies: {
77 | "rds-connect": new iam.PolicyDocument({
78 | statements: [
79 | new iam.PolicyStatement({
80 | actions: [ "rds-db:connect" ],
81 | resources: ["*"]
82 | }),
83 | new iam.PolicyStatement({
84 | actions: [
85 | "logs:CreateLogGroup",
86 | "logs:CreateLogStream",
87 | "logs:PutLogEvents",
88 | "ec2:CreateNetworkInterface",
89 | "ec2:DescribeNetworkInterfaces",
90 | "ec2:DeleteNetworkInterface"
91 | ],
92 | resources: ["*"]
93 | })
94 | ]
95 | })
96 | }
97 | });
98 |
99 | for(let i=0; ix.subnetId),
95 | securityGroupIds: [sg.securityGroupId]
96 | },
97 | serviceRole: batchServiceRole.roleArn,
98 | type: "MANAGED",
99 | state: "ENABLED"
100 | });
101 | computeEnvironemnt.addDependsOn(instanceProfile);
102 |
103 | const jobQueue = new batch.CfnJobQueue(this, "job-queue", {
104 | jobQueueName,
105 | priority: 1,
106 | state: "ENABLED",
107 | computeEnvironmentOrder: [
108 | {order: 1, computeEnvironment: computeEnvironemnt.computeEnvironmentName as string}
109 | ]
110 | });
111 | jobQueue.addDependsOn(computeEnvironemnt);
112 |
113 | const lambdaFunction = new lambda.Function(this, "lambda-function", {
114 | functionName,
115 | code: new lambda.InlineCode(readFileSync(srcPath, {encoding: "utf-8"})),
116 | handler: "index.handler",
117 | timeout: cdk.Duration.seconds(30),
118 | runtime: lambda.Runtime.NODEJS_8_10,
119 | environment: {
120 | REGION: process.env.AWS_REGION as string,
121 | JOB_DEFINITION: jobDefinitionName,
122 | JOB_QUEUE: jobQueueName
123 | },
124 | initialPolicy: [jobSubmitStatement]
125 | });
126 | const rule = new events.Rule(this, 'event-rule', {
127 | schedule: events.Schedule.expression('rate(4 hours)')
128 | });
129 | rule.addTarget(new targets.LambdaFunction(lambdaFunction));
130 | }
131 | }
132 |
133 | const app = new cdk.App();
134 | new BatchStack(app, "BatchStack", {
135 | env: {
136 | account: process.env.AWS_ACCOUNT_ID,
137 | region: process.env.AWS_REGION,
138 | }
139 | });
--------------------------------------------------------------------------------
/transit-gateway/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "aws-cdk-lib";
2 | import * as ec2 from "aws-cdk-lib/aws-ec2";
3 | import { Construct } from "constructs";
4 | import { config } from "dotenv";
5 | config();
6 |
7 | class TransitGatewayStack extends cdk.Stack {
8 | constructor(scope: Construct, id: string, props?: cdk.StackProps) {
9 | super(scope, id, props);
10 |
11 | const vpc1 = new ec2.Vpc(this, "vpc1", {
12 | maxAzs: 2,
13 | cidr: "10.10.0.0/24",
14 | enableDnsSupport: true,
15 | natGateways: 1
16 | });
17 |
18 | const vpc2 = new ec2.Vpc(this, "vpc2", {
19 | maxAzs: 2,
20 | cidr: "192.168.1.0/24",
21 | enableDnsSupport: true,
22 | natGateways: 1
23 | });
24 |
25 | const vpc3 = new ec2.Vpc(this, "vpc3", {
26 | maxAzs: 2,
27 | cidr: "172.168.1.0/24",
28 | enableDnsSupport: true,
29 | natGateways: 1
30 | });
31 |
32 | const sg1 = new ec2.SecurityGroup(this, 'sg1', {
33 | vpc: vpc1,
34 | securityGroupName: "sg1",
35 | });
36 | sg1.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(80), 'allow port 80');
37 | sg1.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'allow port 22');
38 |
39 | const sg2 = new ec2.SecurityGroup(this, 'sg2', {
40 | vpc: vpc2,
41 | securityGroupName: "sg2",
42 | });
43 | sg2.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'allow port 22');
44 |
45 | const sg3 = new ec2.SecurityGroup(this, "sg3", {
46 | vpc: vpc3,
47 | securityGroupName: "sg3"
48 | });
49 | sg3.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(80), 'allow port 80');
50 | sg3.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'allow port 22');
51 |
52 | const userData = ec2.UserData.forLinux();
53 | userData.addCommands("sudo amazon-linux-extras install nginx1.12 -y");
54 | userData.addCommands("sudo chkconfig nginx on");
55 | userData.addCommands("sudo service nginx start");
56 |
57 | const instance1 = new ec2.Instance(this, "instance1", {
58 | instanceName: "instance1",
59 | vpc: vpc1,
60 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
61 | machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
62 | vpcSubnets: {
63 | subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
64 | },
65 | securityGroup: sg1,
66 | userData
67 | });
68 |
69 | const instance2 = new ec2.Instance(this, "instance2", {
70 | instanceName: "instance2",
71 | vpc: vpc2,
72 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
73 | machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
74 | vpcSubnets: {
75 | subnetType: ec2.SubnetType.PUBLIC,
76 | },
77 | securityGroup: sg2
78 | });
79 |
80 | const instance3 = new ec2.Instance(this, "instance3", {
81 | instanceName: "instance3",
82 | vpc: vpc3,
83 | instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
84 | machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
85 | vpcSubnets: {
86 | subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
87 | },
88 | securityGroup: sg3,
89 | userData
90 | });
91 |
92 | const transitGateway = new ec2.CfnTransitGateway(this, "transit-gateway", {
93 | autoAcceptSharedAttachments: "enable",
94 | defaultRouteTableAssociation: "enable",
95 | dnsSupport: "enable"
96 | });
97 |
98 | const attachment1 = new ec2.CfnTransitGatewayAttachment(this, "tg-attachment1", {
99 | vpcId: vpc1.vpcId,
100 | transitGatewayId: transitGateway.ref,
101 | subnetIds: [vpc1.privateSubnets[0].subnetId, vpc1.privateSubnets[1].subnetId]
102 | });
103 | attachment1.addDependsOn(transitGateway);
104 | const attachment2 = new ec2.CfnTransitGatewayAttachment(this, "tg-attachment2", {
105 | vpcId: vpc2.vpcId,
106 | transitGatewayId: transitGateway.ref,
107 | subnetIds: [vpc2.privateSubnets[0].subnetId, vpc2.privateSubnets[1].subnetId]
108 | });
109 | attachment2.addDependsOn(transitGateway);
110 | const attachment3 = new ec2.CfnTransitGatewayAttachment(this, "tg-attachment3", {
111 | vpcId: vpc3.vpcId,
112 | transitGatewayId: transitGateway.ref,
113 | subnetIds: [vpc3.privateSubnets[0].subnetId, vpc3.privateSubnets[1].subnetId]
114 | });
115 | attachment3.addDependsOn(transitGateway);
116 |
117 | const vpc1Subnets = [...vpc1.privateSubnets, ...vpc1.publicSubnets];
118 | const vpc2Subnets = [...vpc2.privateSubnets, ...vpc2.publicSubnets];
119 | const vpc3Subnets = [...vpc3.privateSubnets, ...vpc3.publicSubnets];
120 |
121 | // Add routes to every subnet
122 | vpc1Subnets.map((subnet, i)=>{
123 | new ec2.CfnRoute(this, `vpc1.2-${i}`, {
124 | routeTableId: subnet.routeTable.routeTableId,
125 | destinationCidrBlock: vpc2.vpcCidrBlock,
126 | transitGatewayId: transitGateway.ref
127 | }).addDependsOn(attachment1);
128 |
129 | new ec2.CfnRoute(this, `vpc1.3-${i}`, {
130 | routeTableId: subnet.routeTable.routeTableId,
131 | destinationCidrBlock: vpc3.vpcCidrBlock,
132 | transitGatewayId: transitGateway.ref
133 | }).addDependsOn(attachment1);
134 | });
135 |
136 | // Add routes to every subnet
137 | vpc2Subnets.map((subnet, i)=>{
138 | new ec2.CfnRoute(this, `vpc2.1-${i}`, {
139 | routeTableId: subnet.routeTable.routeTableId,
140 | destinationCidrBlock: vpc1.vpcCidrBlock,
141 | transitGatewayId: transitGateway.ref
142 | }).addDependsOn(attachment2);
143 | new ec2.CfnRoute(this, `vpc2.3-${i}`, {
144 | routeTableId: subnet.routeTable.routeTableId,
145 | destinationCidrBlock: vpc3.vpcCidrBlock,
146 | transitGatewayId: transitGateway.ref
147 | }).addDependsOn(attachment2);
148 | });
149 |
150 | // Add routes to every subnet
151 | vpc3Subnets.map((subnet, i)=>{
152 | new ec2.CfnRoute(this, `vpc3.1-${i}`, {
153 | routeTableId: subnet.routeTable.routeTableId,
154 | destinationCidrBlock: vpc1.vpcCidrBlock,
155 | transitGatewayId: transitGateway.ref
156 | }).addDependsOn(attachment3);
157 | new ec2.CfnRoute(this, `vpc3.2-${i}`, {
158 | routeTableId: subnet.routeTable.routeTableId,
159 | destinationCidrBlock: vpc2.vpcCidrBlock,
160 | transitGatewayId: transitGateway.ref
161 | }).addDependsOn(attachment3);
162 | });
163 |
164 | new cdk.CfnOutput(this, "instance1-dns", {value: instance1.instancePrivateDnsName});
165 | new cdk.CfnOutput(this, "instance2-dns", {value: instance2.instancePrivateDnsName});
166 | new cdk.CfnOutput(this, "instance3-dns", {value: instance3.instancePrivateDnsName});
167 | }
168 | }
169 |
170 | const app = new cdk.App();
171 | new TransitGatewayStack(app, "TransitGatewayStack", {
172 | env: {
173 | account: process.env.AWS_ACCOUNT_ID,
174 | region: process.env.AWS_REGION
175 | }
176 | });
--------------------------------------------------------------------------------