Skip to content

Commit

Permalink
Merge pull request #6 from edo92/base
Browse files Browse the repository at this point in the history
Base
  • Loading branch information
edo92 authored Jan 3, 2022
2 parents 9f1b424 + 115bb39 commit 6e816e3
Show file tree
Hide file tree
Showing 5 changed files with 289 additions and 0 deletions.
99 changes: 99 additions & 0 deletions lib/pattern/EcsService/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import * as cdk from "@aws-cdk/core";
import * as ec2 from "@aws-cdk/aws-ec2";
import * as ecs from "@aws-cdk/aws-ecs";
import * as elb from "@aws-cdk/aws-elasticloadbalancingv2";

import { Cluster } from "@construct/cluster";
import { Service } from "@construct/service";
import { TaskDef } from "@construct/taskDef";

import { Listeners } from "./listeners";
import { TargetGroups } from "./targetGroup";
import { TaskContainer } from "./taskContainer";

interface ResourceNames {
familyName: string;
clusterName: string;
applicationName: string;
}

export interface EcsServiceProps {
names: ResourceNames;
vpc: ec2.Vpc;
elb: elb.ApplicationLoadBalancer;
}

export class EcsService extends cdk.Construct {
public readonly listeners: Listeners;
public readonly targetGroups: TargetGroups;

public readonly cluster: ecs.Cluster;
public readonly service: ecs.Ec2Service;
public readonly taskDef: ecs.Ec2TaskDefinition;

constructor(scope: cdk.Construct, id: string, props: EcsServiceProps) {
super(scope, id);

/**
*
* Target Groups
*/
this.targetGroups = new TargetGroups(this, "Target-Group", {
vpc: props.vpc,
});

/**
*
* Listeners
*/
this.listeners = new Listeners(this, "LoadBalancer-Listeners", {
loadBalancer: props.elb,
targetGroups: this.targetGroups,
});

/**
*
* Ecs Cluster
*/
this.cluster = new Cluster(this, "Ecs-Cluster", {
vpc: props.vpc,
clusterName: props.names.clusterName,
});

/**
*
* Task Containers
*/
const container = new TaskContainer(this, "Task-Containers", {
appName: props.names.applicationName,
});

/**
*
* Ecs Task Definition
*/
this.taskDef = new TaskDef(this, "Ecs-TaskDef", {
familyName: props.names.familyName,
appName: props.names.applicationName,
taskContainers: container.allContainers,
});

/**
*
* Ecs Service
*/
this.service = new Service(this, "Ecs-Service", {
cluster: this.cluster,
taskDefinition: this.taskDef,
serviceName: props.names.applicationName,
});

/**
*
* Serivce Connections
*/
this.service.connections.allowFrom(props.elb, ec2.Port.tcp(80));
this.service.connections.allowFrom(props.elb, ec2.Port.tcp(8080));
this.service.attachToApplicationTargetGroup(this.targetGroups.blueGroup);
}
}
72 changes: 72 additions & 0 deletions lib/pattern/EcsService/listeners.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import * as cdk from "@aws-cdk/core";
import * as elb from "@aws-cdk/aws-elasticloadbalancingv2";

interface ITargetGroups {
blueGroup: elb.ApplicationTargetGroup;
greenGroup: elb.ApplicationTargetGroup;
}

interface ListenersProps {
targetGroups: ITargetGroups;
loadBalancer: elb.ApplicationLoadBalancer;
}

export class Listeners extends cdk.Construct {
public readonly prodListenerArnOutputName = "prodListenerArn";
public readonly testListenerArnOutputName = "testListenerArn";

public readonly prodListener: elb.ApplicationListener;
public readonly testListener: elb.ApplicationListener;

constructor(scope: cdk.Construct, id: string, props: ListenersProps) {
super(scope, id);

/**
*
* Listeners
*/
this.prodListener = props.loadBalancer.addListener(`Production-Listener`, {
port: 80,
open: true,
});

this.testListener = props.loadBalancer.addListener("Test-Listener", {
port: 8080,
});

/**
*
* Connectons
*/
this.prodListener.connections.allowDefaultPortFromAnyIpv4("Allow traffic from everywhere");
this.testListener.connections.allowDefaultPortFromAnyIpv4("Allow traffic from everywhere");

/**
*
* Target Groups -> Blue/Green
*/
this.prodListener.addTargetGroups(props.targetGroups.blueGroup.targetGroupName, {
targetGroups: [props.targetGroups.blueGroup],
});

this.testListener.addTargetGroups(props.targetGroups.blueGroup.targetGroupName, {
targetGroups: [props.targetGroups.greenGroup],
});

/**
*
* Outputs
*/
new cdk.CfnOutput(this, "ProdListener-Arn-Output", {
description: "Production Listener Arn",
exportName: this.prodListenerArnOutputName,
value: this.prodListener.listenerArn,
});

new cdk.CfnOutput(this, "TestListener-Arn-Output", {
description: "Test Listener Arn",
exportName: this.testListenerArnOutputName,
value: this.testListener.listenerArn,
});
}
}
49 changes: 49 additions & 0 deletions lib/pattern/EcsService/targetGroup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as cdk from "@aws-cdk/core";
import * as ec2 from "@aws-cdk/aws-ec2";
import * as elb from "@aws-cdk/aws-elasticloadbalancingv2";
import { TargetGroup } from "@construct/targetGroup";

export interface TargetGroupsProps {
vpc: ec2.Vpc;
}

export interface ITargetGroups {
blueGroup: elb.ApplicationTargetGroup;
greenGroup: elb.ApplicationTargetGroup;
}

export class TargetGroups extends cdk.Construct {
public readonly blueTargetGroupName = "Blue-Group";
public readonly greenTargetGroupName = "Green-Group";

public readonly blueGroup: elb.ApplicationTargetGroup;
public readonly greenGroup: elb.ApplicationTargetGroup;

constructor(scope: cdk.Construct, id: string, props: TargetGroupsProps) {
super(scope, id);

/**
*
* Blue Target Group
*/
this.blueGroup = new TargetGroup(this, "Blue-Group", {
port: 80,
vpc: props.vpc,
targetType: elb.TargetType.INSTANCE,
protocol: elb.ApplicationProtocol.HTTP,
targetGroupName: this.blueTargetGroupName,
});

/**
*
* Green Target Group
*/
this.greenGroup = new TargetGroup(this, "Green-Group", {
port: 80,
vpc: props.vpc,
targetType: elb.TargetType.INSTANCE,
protocol: elb.ApplicationProtocol.HTTP,
targetGroupName: this.greenTargetGroupName,
});
}
}
38 changes: 38 additions & 0 deletions lib/pattern/EcsService/taskContainer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as cdk from "@aws-cdk/core";
import { Container, IContainer } from "@construct/container";

export interface ContainerProps {
appName: string;
}

export class TaskContainer extends cdk.Construct {
private _containers: IContainer[];

public get allContainers() {
// eslint-disable-next-line no-underscore-dangle
return this._containers;
}

public registerContainer(containers: IContainer[]) {
// eslint-disable-next-line no-underscore-dangle
this._containers = containers;
}

constructor(scope: cdk.Construct, id: string, props: ContainerProps) {
super(scope, id);

/**
*
* Express Container
*/
const expressContainer = new Container(this, "sampleAppContainer", {
cpu: 1,
containerPort: 80,
memoryLimitMiB: 512,
applicationName: props.appName,
image: Container.image("backend", "latest"),
});

this.registerContainer([expressContainer]);
}
}
31 changes: 31 additions & 0 deletions lib/pattern/Resources/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as cdk from "@aws-cdk/core";
import * as ec2 from "@aws-cdk/aws-ec2";
import * as elb from "@aws-cdk/aws-elasticloadbalancingv2";

export class Resources extends cdk.Construct {
public readonly vpc: ec2.Vpc;
public readonly loadBalancer: elb.ApplicationLoadBalancer;

constructor(scope: cdk.Construct, id: string) {
super(scope, id);

/**
*
* Main Vpc
*/
this.vpc = new ec2.Vpc(this, "Vpc", {
maxAzs: 3,
natGateways: 1,
cidr: "10.1.0.0/16",
});

/**
*
* Application Load Balancer
*/
this.loadBalancer = new elb.ApplicationLoadBalancer(this, "App-Loadbalancer", {
vpc: this.vpc,
internetFacing: true,
});
}
}

0 comments on commit 6e816e3

Please sign in to comment.