![[AWS CDK]ECS FargateでNestJSで作成したRESTfull APIデプロイ](/images/thumbnail/nest-logo.png)
[AWS CDK]ECS FargateでNestJSで作成したRESTfull APIデプロイ
2022-05-2415 min read
目次
概要
NestJSで作成したRESTfull APIアプリケーションをECS Fargateで起動するスタックを、AWS CDKを利用して構築・デプロイした際のメモです。
プロジェクト作成
作業ディレクトリを作成しCDKプロジェクトとして初期化します。
mkdir ecs-fargate
npx cdk init app --language=typescript
cd ecs-fargate
Stack実装
Stackを次のコードのように実装します。
ポイントは以下となります。
- VPC構築を構築しALBをパブリックサブネットに配置
- ECS Fargate を構築しALBからのリクエストを受け付ける
- ACMを作成しALBで利用
- Route53の設定でALBに対してAレコードを設定
lib/ecs-fargate.ts
import {
aws_certificatemanager as acm,
aws_ec2 as ec2,
aws_ecs as ecs,
aws_elasticloadbalancingv2 as elbv2,
aws_logs as log,
aws_route53 as route53,
aws_route53_targets as route53Targets,
Stack,
StackProps,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
// todo:
// example.com は置き換えること
const domainName = `example.com`;
export class CdkEcsFargateStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const vpc = new ec2.Vpc(this, 'VPC', {
cidr: '10.1.0.0/16',
enableDnsHostnames: true,
enableDnsSupport: true,
subnetConfiguration: [
{
cidrMask: 24,
name: 'PublicSubnet',
subnetType: ec2.SubnetType.PUBLIC,
},
{
cidrMask: 24,
name: 'PrivateIsolatedSubnet',
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
],
});
// SecurityGroup
const securityGroupELB = new ec2.SecurityGroup(this, 'SecurityGroupELB', {
vpc,
});
securityGroupELB.addIngressRule(
ec2.Peer.ipv4('0.0.0.0/0'),
ec2.Port.tcp(443),
);
const securityGroupApp = new ec2.SecurityGroup(this, 'SecurityGroupApp', {
vpc,
});
const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', {
domainName: domainName,
});
const cert = new acm.DnsValidatedCertificate(this, 'Certificate', {
domainName: domainName,
hostedZone,
// region: "us-east-1",
region: 'ap-northeast-1', // ALBと同じリージョンに配置
});
// ALB
const alb = new elbv2.ApplicationLoadBalancer(this, 'ALB', {
vpc,
securityGroup: securityGroupELB,
internetFacing: true,
});
const listenerHTTP = alb.addListener('ListenerHTTP', {
port: 443,
certificates: [
{
certificateArn: cert.certificateArn,
},
],
});
// Target Group
const targetGroup = new elbv2.ApplicationTargetGroup(this, 'TargetGroup', {
vpc: vpc,
port: 3000,
protocol: elbv2.ApplicationProtocol.HTTP,
targetType: elbv2.TargetType.IP,
healthCheck: {
path: '/',
healthyHttpCodes: '200',
},
});
listenerHTTP.addTargetGroups('DefaultHTTPSResponse', {
targetGroups: [targetGroup],
});
// ECS Cluster
const cluster = new ecs.Cluster(this, 'Cluster', {
vpc,
});
// Fargate
const fargateTaskDefinition = new ecs.FargateTaskDefinition(
this,
'TaskDef',
{
memoryLimitMiB: 1024,
cpu: 512,
},
);
const container = fargateTaskDefinition.addContainer('AppContainer', {
image: ecs.ContainerImage.fromAsset('src/ecs/app'),
logging: ecs.LogDrivers.awsLogs({
streamPrefix: 'nest-app',
logRetention: log.RetentionDays.ONE_MONTH,
}),
});
container.addPortMappings({
containerPort: 3000,
hostPort: 3000,
});
const service = new ecs.FargateService(this, 'Service', {
cluster,
taskDefinition: fargateTaskDefinition,
desiredCount: 1,
assignPublicIp: true,
securityGroups: [securityGroupApp],
});
service.attachToApplicationTargetGroup(targetGroup);
new route53.ARecord(this, `AliasRecord`, {
zone: hostedZone,
recordName: `ecs.${domainName}`,
target: route53.RecordTarget.fromAlias(
new route53Targets.LoadBalancerTarget(alb),
),
});
}
}
NestJSアプリケーションの実装
NestJSでRESTfullAPIアプリケーションを実装していきます。
プロジェクト作成
mkdir -p src/ecr
cd src/ecr
nest new app
cd app
サンプルAPI作成
デフォルトで作成されるcontroller・serviceを次のように実装します。
src/app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello() {
return this.appService.getHello();
}
}
src/app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello() {
return {
message: 'Hello World!',
};
}
}
npm run start
を実行して http://localhost:3000 で { "message": "Hello World!" }
のレスポンスが返ってくることを確認します。
またビルドするためのDockerfileも作成します。
Dockerfile
FROM node:16-alpine
WORKDIR /app
COPY . /app
RUN npm install && \
npm run build
ENV HOST 0.0.0.0
EXPOSE 3000
CMD ["npm", "run", "start:prod"]
デプロイ
cdk deploy
を実行しAWS環境へデプロイを行います。
https://ecs.example.com (自分が設定したFQDNに置き換える) に接続しレスポンスが正しいことを確認します。
参考にしたサイト
Recommends
New Posts
Hot posts!
Date
Tags
Author