Skip to content

Instantly share code, notes, and snippets.

@SharpCoder
Created October 28, 2023 16:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SharpCoder/281822c3ed3139c9de1c7ed2fd4aa593 to your computer and use it in GitHub Desktop.
Save SharpCoder/281822c3ed3139c9de1c7ed2fd4aa593 to your computer and use it in GitHub Desktop.
Express server in fargate with cdk
const {
aws_route53: route53,
aws_certificatemanager: acm,
aws_ecs: ecs,
aws_ec2: ec2,
aws_ecr_assets: ecr_assets,
aws_elasticloadbalancingv2: elbv2,
Stack,
CfnOutput,
IgnoreMode,
Duration,
} = require('aws-cdk-lib');
const { AwsLogDriver } = require('aws-cdk-lib/aws-ecs');
const {
ApplicationProtocol,
Protocol,
} = require('aws-cdk-lib/aws-elasticloadbalancingv2');
const { RetentionDays } = require('aws-cdk-lib/aws-logs');
const { LoadBalancerTarget } = require('aws-cdk-lib/aws-route53-targets');
// const sqs = require('aws-cdk-lib/aws-sqs');
class InfraStack extends Stack {
/**
*
* @param {Construct} scope
* @param {string} id
* @param {StackProps=} props
*/
constructor(scope, id, props) {
super(scope, id, props);
// The code that defines your stack goes here
const siteDomain = 'hopefullynominal.net';
const hostedZoneId = "your-hosted-zone-id";
const dockerFileLocation = "../../";
const hostedZone = route53.HostedZone.fromHostedZoneAttributes(
this,
'HostedZone',
{
zoneName: siteDomain,
hostedZoneId,
}
);
/**
* EC2 Stuff
*/
const vpc = new ec2.Vpc(this, 'HopefullyNominalVpc', { maxAzs: 2 });
const ecsCluster = new ecs.Cluster(this, 'HopefullyNominalCluster', {
vpc: vpc,
clusterName: 'HopefullyNominalCluster',
});
const dockerAsset = new ecr_assets.DockerImageAsset(
this,
'HopefullyNominalImage',
{
directory: dockerFileLocation,
asset_name: 'Dockerfile',
ignoreMode: IgnoreMode.DOCKER,
}
);
const taskDef = new ecs.FargateTaskDefinition(
this,
'HopefullyNominalTaskDefinition',
{
cpu: 256,
memoryLimitMiB: 512,
networkMode: ecs.NetworkMode.AWS_VPC,
}
);
const container = taskDef.addContainer(
'HopefullyNominalContainerImage',
{
image: ecs.ContainerImage.fromDockerImageAsset(dockerAsset),
logging: new AwsLogDriver({
streamPrefix: 'hopefullynominal',
logRetention: RetentionDays.FIVE_DAYS,
}),
healthCheck: {
command: [
'CMD-SHELL',
'curl -f http://localhost:3000/healthcheck || exit 0',
],
interval: Duration.seconds(30),
timeout: Duration.seconds(10),
retries: 5,
},
}
);
container.addPortMappings({
containerPort: 3000,
hostPort: 3000,
protocol: ecs.Protocol.TCP,
});
const fargateService = new ecs.FargateService(
this,
'HopefullyNominalFargateService',
{
cluster: ecsCluster,
taskDefinition: taskDef,
serviceName: 'HopefullyNominalService',
desiredCount: 1,
}
);
// TLS certificate
const apiCertificate = new acm.Certificate(this, 'ApiCertificate', {
domainName: 'api.' + siteDomain,
validation: acm.CertificateValidation.fromDns(hostedZone),
});
new CfnOutput(this, 'ApiCertificateOutput', {
value: apiCertificate.certificateArn,
});
const alb = new elbv2.ApplicationLoadBalancer(
this,
'HopefullyNominalAlb',
{
vpc: vpc,
internetFacing: true,
loadBalancerName: 'HopefullyNominalLB',
}
);
new route53.ARecord(this, 'HopefullyNominalApiDnsRecord', {
recordName: 'api.' + siteDomain,
zone: hostedZone,
target: route53.RecordTarget.fromAlias(new LoadBalancerTarget(alb)),
});
const listener = alb.addListener('listener', {
open: true,
port: 443,
certificates: [apiCertificate],
protocol: ApplicationProtocol.HTTPS,
});
listener.addTargets('service1', {
targetGroupName: 'Service1Target',
port: 3000,
protocol: Protocol.HTTP,
targets: [fargateService],
});
}
}
module.exports = { InfraStack };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment