Skip to content

Commit 8deddb0

Browse files
Joseph MorrisonJoseph Morrison
Joseph Morrison
authored and
Joseph Morrison
committed
add cost saving , remove nat features
1 parent de367d0 commit 8deddb0

File tree

4 files changed

+111
-64
lines changed

4 files changed

+111
-64
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
ApplicationLoadBalancedFargateService,
3+
ApplicationLoadBalancedServiceRecordType
4+
} from "@aws-cdk/aws-ecs-patterns";
5+
// @ts-ignore
6+
import path from "path";
7+
import {ApplicationProtocol} from "@aws-cdk/aws-elasticloadbalancingv2";
8+
import {Construct} from "@aws-cdk/core";
9+
import {IHostedZone} from "@aws-cdk/aws-route53";
10+
import {ICertificate} from "@aws-cdk/aws-certificatemanager";
11+
import {ICluster, ContainerImage} from "@aws-cdk/aws-ecs";
12+
13+
interface ApplicationLoadBalancedServiceProps {
14+
stack: Construct,
15+
cluster: ICluster,
16+
domainZone: IHostedZone,
17+
domainName: string,
18+
certificate: ICertificate,
19+
imagePath: string,
20+
}
21+
22+
const applicationLoadBalancedService = (
23+
{
24+
stack,
25+
cluster,
26+
domainZone,
27+
domainName,
28+
certificate,
29+
imagePath,
30+
}: ApplicationLoadBalancedServiceProps) => new ApplicationLoadBalancedFargateService(
31+
stack, "WebappFargateService", {
32+
cluster, // Required
33+
cpu: 512, // Default is 256
34+
desiredCount: 1, // Default is 1
35+
assignPublicIp: true,
36+
taskImageOptions: {
37+
containerPort: 3000,
38+
image: ContainerImage.fromAsset(imagePath),
39+
enableLogging: true,
40+
},
41+
memoryLimitMiB: 1024, // Default is 512
42+
domainZone,
43+
protocol: ApplicationProtocol.HTTPS,
44+
domainName,
45+
certificate,
46+
recordType: ApplicationLoadBalancedServiceRecordType.ALIAS,
47+
publicLoadBalancer: true // Default is false
48+
})
49+
50+
export default applicationLoadBalancedService

lib/vpc/vpc.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {Vpc} from "@aws-cdk/aws-ec2";
2+
import {SubnetType} from "@aws-cdk/aws-ec2";
3+
import {Construct} from "@aws-cdk/core";
4+
5+
const vpc = (stack: Construct) => new Vpc(stack, "WebappVpc", {
6+
maxAzs: 2, // Default is all AZs in region
7+
natGateways: 0,
8+
subnetConfiguration: [
9+
{cidrMask: 23, name: 'Public', subnetType: SubnetType.PUBLIC}
10+
]
11+
});
12+
13+
export default vpc;

lib/webapp-stack.ts

+47-64
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,56 @@
11
import * as cdk from '@aws-cdk/core';
2-
import * as ec2 from "@aws-cdk/aws-ec2";
32
import * as ecs from "@aws-cdk/aws-ecs";
4-
import * as ecs_patterns from "@aws-cdk/aws-ecs-patterns";
53
import * as wafv2 from '@aws-cdk/aws-wafv2';
6-
import {ApplicationLoadBalancedServiceRecordType} from "@aws-cdk/aws-ecs-patterns";
74
import {PublicHostedZone} from "@aws-cdk/aws-route53";
8-
import * as path from "path";
95
import {DnsValidatedCertificate} from "@aws-cdk/aws-certificatemanager";
10-
import {ApplicationProtocol} from "@aws-cdk/aws-elasticloadbalancingv2";
116
import WebAppWaf from "./waf/waf";
7+
import vpc from "./vpc/vpc";
8+
import applicationLoadBalancedService from "./applicationLoadBalancedService/applicationLoadBalancedService";
9+
import path from 'path';
1210

1311
export class WebappStack extends cdk.Stack {
14-
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
15-
super(scope, id, props);
16-
// provide domain name in cdk.json or via CLI e.g. -c domain=<sub.mydomain.com | mydomain.com>
17-
const domainName = this.node.tryGetContext('domain') || process.env.DOMAIN_NAME
18-
19-
const domainZone = PublicHostedZone.fromLookup(this, 'PublicHostedZone', {
20-
domainName,
21-
privateZone: false,
22-
})
23-
24-
const natGatewayProvider = ec2.NatProvider.instance({
25-
instanceType: new ec2.InstanceType('t2.micro'),
26-
});
27-
28-
const vpc = new ec2.Vpc(this, "WebappVpc", {
29-
maxAzs: 2, // Default is all AZs in region
30-
natGateways: 2,
31-
natGatewayProvider
32-
});
33-
34-
const cluster = new ecs.Cluster(this, "WebappCluster", {
35-
vpc: vpc
36-
});
37-
38-
const certificate = new DnsValidatedCertificate(this, 'LBCertificate', {
39-
hostedZone: domainZone,
40-
domainName,
41-
})
42-
43-
// Create a load-balanced Fargate service and make it public
44-
const lb = new ecs_patterns.ApplicationLoadBalancedFargateService(this, "WebappFargateService", {
45-
cluster, // Required
46-
cpu: 512, // Default is 256
47-
desiredCount: 1, // Default is 1
48-
taskImageOptions: {
49-
containerPort: 3000,
50-
image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, '../simple'))
51-
},
52-
memoryLimitMiB: 1024, // Default is 512
53-
domainZone,
54-
protocol: ApplicationProtocol.HTTPS,
55-
domainName,
56-
certificate,
57-
recordType: ApplicationLoadBalancedServiceRecordType.ALIAS,
58-
publicLoadBalancer: true // Default is false
59-
})
60-
// Redirects HTTP to HTTPS as default if no configuration provided - ideal!
61-
lb.loadBalancer.addRedirect()
62-
63-
const appWaf = WebAppWaf(this);
64-
65-
// WAF to WebApp
66-
const wafAssoc = new wafv2.CfnWebACLAssociation(this, 'WebApp-waf-assoc', {
67-
resourceArn: lb.loadBalancer.loadBalancerArn,
68-
webAclArn: appWaf.attrArn
69-
});
70-
// attach the waf to load balancer
71-
wafAssoc.node.addDependency(lb.loadBalancer);
72-
}
12+
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
13+
super(scope, id, props);
14+
// provide domain name in cdk.json or via CLI e.g. -c domain=<sub.mydomain.com | mydomain.com>
15+
const domainName = this.node.tryGetContext('domain') || process.env.DOMAIN_NAME
16+
17+
const domainZone = PublicHostedZone.fromLookup(this, 'PublicHostedZone', {
18+
domainName,
19+
privateZone: false,
20+
})
21+
22+
const certificate = new DnsValidatedCertificate(this, 'LBCertificate', {
23+
hostedZone: domainZone,
24+
domainName,
25+
})
26+
27+
const webAppVpc = vpc(this);
28+
29+
const cluster = new ecs.Cluster(this, "WebappCluster", {
30+
vpc: webAppVpc,
31+
containerInsights: true,
32+
});
33+
// Path to application directory with Dockerfile
34+
const imagePath = path.resolve(__dirname, '../simple')
35+
36+
const appService = applicationLoadBalancedService({
37+
stack: this,
38+
cluster,
39+
domainZone,
40+
domainName,
41+
certificate,
42+
imagePath
43+
})
44+
// Redirects HTTP to HTTPS as default if no configuration provided - ideal!
45+
appService.loadBalancer.addRedirect()
46+
47+
const appWaf = WebAppWaf(this);
48+
// WAF to WebApp
49+
const wafAssoc = new wafv2.CfnWebACLAssociation(this, 'WebApp-waf-assoc', {
50+
resourceArn: appService.loadBalancer.loadBalancerArn,
51+
webAclArn: appWaf.attrArn
52+
});
53+
// attach the waf to load balancer
54+
wafAssoc.node.addDependency(appService.loadBalancer);
55+
}
7356
}

tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"compilerOptions": {
3+
"esModuleInterop": true,
34
"target": "ES2018",
45
"module": "commonjs",
56
"lib": ["es2018"],

0 commit comments

Comments
 (0)