前提条件:
- VPC、サブネット、セキュリティグループは作成済み
- ECS,ECRを使用する際のIAMロールは作成済み
- 言語はtypescriptを使用
- ローカル環境で実行する
- クレデンシャルキーは発行済み
- Docker Desktopはインストール済み
ローカル環境構築:
#プロジェクト用にディレクトリを作成
mkdir my-ecs-project
#移動
cd my-ecs-project
#CDKプロジェクトの初期化
cdk init app --language typescript
#モジュールのインストール
npm install @aws-cdk/aws-ec2 @aws-cdk/aws-ecs @aws-cdk/aws-ecr @aws-cdk/aws-iam @aws-cdk/aws-ecr-assets
コーディング:
CDKスタックの定義
lib/my-ecs-project-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Stack, StackProps } from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as ecr from 'aws-cdk-lib/aws-ecr';
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';
import { Construct } from 'constructs';
export class MyEcsProjectStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// 既存のVPCを参照
const vpc = ec2.Vpc.fromLookup(this, 'MyExistingVpc', {
vpcId: 'vpc-XXXXXXXXXXX', // 既存のVPCのIDを指定
});
// 特定のサブネットを参照
const subnets = [
ec2.Subnet.fromSubnetId(this, 'Subnet1', 'subnet-XXXXXXXXXXX'),
// ec2.Subnet.fromSubnetId(this, 'Subnet2', 'subnet-XXXXXXXXXXXXX'), // 必要に応じて他のサブネットも追加
];
// ECS クラスター作成
const cluster = new ecs.Cluster(this, 'MyCluster', {
vpc,
clusterName: 'poc-Cluster', // クラスター名を指定
});
// ECR リポジトリ作成
const repository = new ecr.Repository(this, 'MyRepository', {
repositoryName: 'poc-repository', // リポジトリ名を指定
});
// CDKスタックのデプロイ完了後に実行される処理を定義
this.node.addDependency(repository);
// Docker イメージのビルドとプッシュ
const dockerImageAsset = new DockerImageAsset(this, 'MyDockerImage', {
directory: './', // Dockerfile が存在するディレクトリ
});
// 既存の IAM ロールを使用
const ecsTaskExecutionRole = iam.Role.fromRoleArn(this, 'EcsTaskExecutionRole', 'arn:aws:iam::533876055951:role/ec2-ssm-ecs-full');
// 既存のセキュリティグループを参照
const securityGroup = ec2.SecurityGroup.fromSecurityGroupId(this, 'ExistingSecurityGroup', 'sg-XXXXXXXXXXXX');
// ECS タスク定義作成
const taskDefinition = new ecs.FargateTaskDefinition(this, 'MyTaskDefinition', {
memoryLimitMiB: 512,
cpu: 256,
executionRole: ecsTaskExecutionRole,
family: 'poc-TaskDefinitionFamily' // タスク定義ファミリー名を指定
});
// コンテナ追加
const container = taskDefinition.addContainer('MyContainer', {
image: ecs.ContainerImage.fromDockerImageAsset(dockerImageAsset),
containerName: 'poc-Container', // コンテナ名を指定
memoryLimitMiB: 512,
cpu: 256,
});
container.addPortMappings({
containerPort: 80,
protocol: ecs.Protocol.TCP,
});
// ECS サービス作成
const service = new ecs.FargateService(this, 'MyService', {
cluster,
taskDefinition,
desiredCount: 1,
serviceName: 'poc-EcsService', // サービス名を指定
vpcSubnets: { subnets },
securityGroups: [securityGroup], // 既存のセキュリティグループを指定
});
}
}
CDKアプリのエントリーポイントの修正
bin/my-ecs-project.ts
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyEcsProjectStack } from '../lib/my-ecs-project-stack';
const app = new cdk.App();
new MyEcsProjectStack(app, 'MyEcsProjectStack', {
env: {
account: 'XXXXXXXXXXXX', #AWSマネジメントコンソールの右上の12桁
region: 'ap-northeast-1', #東京リージョン
},
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */
/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});
dockerファイルの作成:
Node.js をベースイメージとして使用して、Node.js アプリケーションを実行するための手順を定義
Dockerfile
# ベースイメージとしてNode.jsを使用
FROM node:14
# 作業ディレクトリを設定
WORKDIR /app
# プロジェクトの依存関係をコピー
COPY package.json package-lock.json ./
# 依存関係のインストール
RUN npm install
# ソースコードをコピー
COPY . .
# アプリケーションのビルド
RUN npm run build
# ポート番号の公開
EXPOSE 3000
# アプリケーションの実行
CMD [ "npm", "start" ]
デプロイ作業:
deployコマンド
cdk deploy
destroyコマンド
cdk destroy