-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
OAwan
committed
Jul 8, 2020
1 parent
89d66bb
commit 9b2441c
Showing
13 changed files
with
12,255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
*.js | ||
!jest.config.js | ||
*.d.ts | ||
node_modules | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out | ||
|
||
# Parcel default cache directory | ||
.parcel-cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.ts | ||
!*.d.ts | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Easy CDK deploy ECS Fargate Demo | ||
|
||
This is a demo that use CDK to build **ECS Fargate Task Definition**, **ECS Service**, **Log Group**, **Security Group**, **ELB**...etc. | ||
|
||
> Note: Base on existion Network Stack or Default. | ||
## Useful commands | ||
|
||
* `npm run build` compile typescript to js | ||
* `npm run watch` watch for changes and compile | ||
* `npm run test` perform the jest unit tests | ||
* `cdk deploy` deploy this stack to your default AWS account/region | ||
* `cdk diff` compare deployed stack with current state | ||
* `cdk synth` emits the synthesized CloudFormation template |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#!/usr/bin/env node | ||
import * as readlineSync from 'readline-sync'; | ||
import 'source-map-support/register'; | ||
import * as cdk from '@aws-cdk/core'; | ||
import { CdkFargateDemoStack } from '../lib/cdk-fargate-demo-stack'; | ||
|
||
if (!process.env['ENV_ACCOUNT'] || !process.env['ENV_REGION']) { | ||
process.env['ENV_ACCOUNT'] = readlineSync.question('> 請輸入 aws account id: '); | ||
process.env['ENV_REGION'] = readlineSync.question('> 請輸入 stack 建立之 region (default: ap-northeast-1): ') || 'ap-northeast-1'; | ||
process.env['VPC_NAME'] = readlineSync.question('> 請輸入以建立的 VPC name (default: default): '); | ||
} | ||
|
||
const app = new cdk.App(); | ||
new CdkFargateDemoStack(app, 'CdkFargateDemoStack', { | ||
env: { | ||
account: process.env['ENV_ACCOUNT'], | ||
region: process.env['ENV_REGION'] | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
{ | ||
"vpc-provider:account=084664864843:filter.isDefault=true:region=ap-northeast-1:returnAsymmetricSubnets=true": { | ||
"vpcId": "vpc-fcf4459b", | ||
"vpcCidrBlock": "172.31.0.0/16", | ||
"availabilityZones": [], | ||
"subnetGroups": [ | ||
{ | ||
"name": "Public", | ||
"type": "Public", | ||
"subnets": [ | ||
{ | ||
"subnetId": "subnet-a0b5ffe9", | ||
"cidr": "172.31.32.0/20", | ||
"availabilityZone": "ap-northeast-1a", | ||
"routeTableId": "rtb-0b300e6c" | ||
}, | ||
{ | ||
"subnetId": "subnet-32991f69", | ||
"cidr": "172.31.0.0/20", | ||
"availabilityZone": "ap-northeast-1c", | ||
"routeTableId": "rtb-0b300e6c" | ||
}, | ||
{ | ||
"subnetId": "subnet-14a8863c", | ||
"cidr": "172.31.16.0/20", | ||
"availabilityZone": "ap-northeast-1d", | ||
"routeTableId": "rtb-0b300e6c" | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
"vpc-provider:account=084664864843:filter.tag:Name=alpha:region=ap-northeast-1:returnAsymmetricSubnets=true": { | ||
"vpcId": "vpc-05900fcaa6ee08b33", | ||
"vpcCidrBlock": "172.32.0.0/16", | ||
"availabilityZones": [], | ||
"subnetGroups": [ | ||
{ | ||
"name": "Private", | ||
"type": "Private", | ||
"subnets": [ | ||
{ | ||
"subnetId": "subnet-049a09f8c50809857", | ||
"cidr": "172.32.111.0/24", | ||
"availabilityZone": "ap-northeast-1c", | ||
"routeTableId": "rtb-0330d717fdf6f4ca8" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Public", | ||
"type": "Public", | ||
"subnets": [ | ||
{ | ||
"subnetId": "subnet-01af5aba6cbd72d20", | ||
"cidr": "172.32.11.0/24", | ||
"availabilityZone": "ap-northeast-1a", | ||
"routeTableId": "rtb-0330d717fdf6f4ca8" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"app": "npx ts-node bin/cdk-fargate-demo.ts", | ||
"context": { | ||
"@aws-cdk/core:enableStackNameDuplicates": "true", | ||
"aws-cdk:enableDiffNoFail": "true" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module.exports = { | ||
roots: ['<rootDir>/test'], | ||
testMatch: ['**/*.test.ts'], | ||
transform: { | ||
'^.+\\.tsx?$': 'ts-jest' | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import * as cdk from '@aws-cdk/core'; | ||
import * as iam from '@aws-cdk/aws-iam'; | ||
import * as ecs from '@aws-cdk/aws-ecs'; | ||
import * as ec2 from '@aws-cdk/aws-ec2'; | ||
import * as log from '@aws-cdk/aws-logs'; | ||
import * as elb from '@aws-cdk/aws-elasticloadbalancingv2'; | ||
import * as ecr from '@aws-cdk/aws-ecr'; | ||
|
||
const stackPolicy = { | ||
removalPolicy: cdk.RemovalPolicy.DESTROY, | ||
}; | ||
|
||
export class CdkFargateDemoStack extends cdk.Stack { | ||
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { | ||
super(scope, id, props); | ||
|
||
// Env Args | ||
const { PROJ_NAME = 'demo', VPC_NAME } = process.env; | ||
|
||
// VPC | ||
const vpc_opts = !!VPC_NAME ? { vpcName: VPC_NAME } : { isDefault: true }; // use specified or default vpc | ||
const vpc = ec2.Vpc.fromLookup(this, `${PROJ_NAME}-vpc`, vpc_opts); | ||
|
||
// Subnet (Public Subnet),需綁定為指向 natgateway 之 route table | ||
const public_subnet_1 = ec2.Subnet.fromSubnetAttributes(this, `${PROJ_NAME}-public-subnet-1`, { | ||
availabilityZone: 'ap-northeast-1c', | ||
subnetId:'subnet-049a09f8c50809857', | ||
routeTableId: 'rtb-0330d717fdf6f4ca8' | ||
}); | ||
const public_subnet_2 = ec2.Subnet.fromSubnetAttributes(this, `${PROJ_NAME}-public-subnet-2`, { | ||
availabilityZone: 'ap-northeast-1c', | ||
subnetId:'subnet-093901b3ac2a36f85', | ||
routeTableId: 'rtb-0330d717fdf6f4ca8' | ||
}); | ||
|
||
// Security Group | ||
const securityGroup = new ec2.SecurityGroup(this, `${PROJ_NAME}-security-group`, { | ||
vpc, | ||
allowAllOutbound: true, | ||
securityGroupName: PROJ_NAME, | ||
}); | ||
// Add Inbound | ||
securityGroup.addIngressRule(ec2.Peer.ipv4('172.32.0.0/16'), ec2.Port.allTraffic(), 'VPC-Alpha'); | ||
securityGroup.addIngressRule(ec2.Peer.ipv4('0.0.0.0/16'), ec2.Port.allTraffic(), 'ALL'); | ||
// securityGroup.addIngressRule(ec2.Peer.ipv4('0.0.0.0/32'), ec2.Port.tcp(80), 'Office'); | ||
// ... Other Inbound ... | ||
|
||
// Log Group | ||
const logGroup = new log.LogGroup(this, `${PROJ_NAME}-log-group`, { | ||
...stackPolicy, | ||
logGroupName: `/ecs/${PROJ_NAME}`, | ||
retention: log.RetentionDays.INFINITE, // The number of days to retain the log events in the specified log group. | ||
}); | ||
|
||
// ELB - Target Group | ||
const targetGroup = new elb.ApplicationTargetGroup(this, `${PROJ_NAME}-target-group`, { | ||
vpc, | ||
targetGroupName: PROJ_NAME, | ||
targetType: elb.TargetType.IP, | ||
protocol: elb.ApplicationProtocol.HTTP, | ||
port: 80, | ||
|
||
// Customize healthCheck with your Service | ||
// healthCheck: { | ||
// path: '/ping', | ||
// healthyThresholdCount: 5, | ||
// unhealthyThresholdCount: 2, | ||
// timeout: cdk.Duration.seconds(5), | ||
// interval: cdk.Duration.seconds(30), | ||
// healthyHttpCodes: '200', | ||
// }, | ||
}); | ||
|
||
// ELB - Load Balancer | ||
const loadBalancer = new elb.ApplicationLoadBalancer(this, `${PROJ_NAME}-load-balancer`, { | ||
vpc, | ||
securityGroup, | ||
internetFacing: true, // for Public facing | ||
ipAddressType: elb.IpAddressType.IPV4, | ||
loadBalancerName: PROJ_NAME, | ||
vpcSubnets: { | ||
subnets: [public_subnet_1, public_subnet_2], | ||
}, | ||
}); | ||
// Add Listener | ||
loadBalancer.addListener(`${PROJ_NAME}-listener`, { | ||
protocol: elb.ApplicationProtocol.HTTP, | ||
port: 80, | ||
defaultTargetGroups: [targetGroup], | ||
}); | ||
|
||
// ECR | ||
const ecrRepo = ecr.Repository.fromRepositoryName(this, `${PROJ_NAME}-ecr`, 'amazon-ecs-sample'); | ||
|
||
// ECS - Fargate Task Definition | ||
const account = props?.env?.account || ''; | ||
const taskRole = iam.Role.fromRoleArn( | ||
this, | ||
`${PROJ_NAME}-task-role`, | ||
`arn:aws:iam::${account}:role/ecsTaskExecutionRole`, | ||
{ | ||
mutable: false, | ||
}, | ||
); | ||
const fargateTaskDefinition = new ecs.FargateTaskDefinition(this, `${PROJ_NAME}-task-definition`, { // or use TaskDefinition and specified compatibility to FARGATE | ||
family: PROJ_NAME, | ||
memoryLimitMiB: 2048, | ||
cpu: 1024, | ||
taskRole, | ||
executionRole: taskRole, | ||
}); | ||
// Add Container | ||
fargateTaskDefinition.addContainer(`${PROJ_NAME}-container`, { | ||
// Use an image from ECR repo | ||
image: ecs.ContainerImage.fromEcrRepository(ecrRepo, 'latest'), | ||
|
||
// Use an image from DockerHub | ||
// image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), | ||
|
||
cpu: 1024, | ||
environment: { | ||
AWS_DEFAULT_REGION: 'ap-northeast-1', | ||
// ... env args ... | ||
}, | ||
memoryReservationMiB: 500, | ||
memoryLimitMiB: 2048, | ||
|
||
// 指定 logging group | ||
logging: new ecs.AwsLogDriver({ | ||
streamPrefix: 'ecs', | ||
logGroup, | ||
}), | ||
}) | ||
// Add listen port | ||
.addPortMappings({ | ||
containerPort: 80, | ||
hostPort: 80, | ||
}); | ||
|
||
// ECS - Fargate Service | ||
const cluster = new ecs.Cluster(this, `${PROJ_NAME}-cluster`, { vpc }); | ||
const svc = new ecs.FargateService(this, `${PROJ_NAME}-service`, { | ||
cluster, | ||
taskDefinition: fargateTaskDefinition | ||
}); | ||
|
||
// Let loadbalancer loadbalance to this Service of the TargetGroup | ||
targetGroup.addTarget(svc); | ||
|
||
new cdk.CfnOutput(this, `${PROJ_NAME}-url`, { | ||
value: `https://${loadBalancer.loadBalancerDnsName}` | ||
}); | ||
} | ||
} |
Oops, something went wrong.