Amazon ECS でコンテナ・ウェブアプリケーションをデプロイする
入門ガイド
モジュール 2: インフラストラクチャの作成とアプリケーションのデプロイ
このモジュールで、ECS クラスターを作成し CDK でアプリケーションをデプロイする
はじめに
このモジュールでは、ECS クラスターをセットアップするために必要な全てのインフラストラクチャを作成する AWS CDK アプリケーションを作成し、サンプルコンテナをデプロイします。
学習内容
- シンプルな CDK アプリケーションを作成する
- 容量用 Fargate での ECS クラスターを作成する
- タスク定義を作成してアプリケーションをデプロイするためのサービス
所要時間
15 分
モジュールの前提条件
- 管理者レベルのアクセス権を持つ AWS アカウント**
- 推奨ブラウザ: Chrome または Firefox の最新バージョン
[**] 過去 24 時間以内に作成されたアカウントは、このチュートリアルに必要なサービスへのアクセス権限がまだ付与されていない可能性があります。
実装
CDK アプリケーションの作成
はじめに、CDK がインストールされていることを確認します。インストールされていない場合、「AWS CDK の入門」ガイドに従います。
cdk --version
TypeScript を選択した言語として使用し、スケルトン CDK アプリケーションを作成します。ターミナルで次のコマンドを実行します。
mkdir cdk-ecs-infra
cd cdk-ecs-infra
cdk init app --language typescript
これにより以下が行われます。
Applying project template app for typescript
# Welcome to your CDK TypeScript project!
This is a blank project for TypeScript development with CDK.
The `cdk.json` file tells the CDK Toolkit how to execute your app.
## Useful commands
* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
Executing npm install...
✅ All done!
リソーススタックのコードを作成する
/lib/cdk-ecs-infra-stack.tsのファイルへ移動します。ここに、これから作成するリソーススタックのコードを書き込みます。
リソーススタックは、特定のアカウントへプロビジョンされる、クラウドインフラストラクチャリソースのセットです (これらが全て AWS リソースになる特別なケースもあり)。これらのリソースがプロビジョンされるアカウント/リージョンは、スタック内 (「AWS CDK の入門」ガイドで設定される場合もあります。
このリソーススタックでは、以下のリソースを作成することになります。
- IAM ロール: このロールはコンテナに割り当てられ他の AWS のサービスを呼び出す許可を付与します。
- ECS タスク定義: コンテナを起動する際に使用する固有のパラメータのこと。
- Fargate ロードバランスサービスの ECS パターン: クラスター、ロードバランス、サービスの構築に必要な全てのコンポーネントの複雑さを抽象化し、全てが連携した動きになるよう設定します。
ECS クラスターの作成
ECS クラスターを作成するには、まず正しいモジュールをインポートする必要があります。
npm i @aws-cdk/aws-s3-assets
続いて、lib/cdk-eb-infra-stack.tsファイルの最初に依存関係を追加します。
npm i @aws-cdk/aws-ec2 @aws-cdk/aws-ecs @aws-cdk/aws-ecs-patterns @aws-cdk/aws-iam
その後、lib/cdk-eb-infra-stack.tsファイルを編集し、このファイルの最初に依存関係を追加します。
import ecs = require('@aws-cdk/aws-ecs'); // Allows working with ECS resources
import ec2 = require('@aws-cdk/aws-ec2'); // Allows working with EC2 and VPC resources
import iam = require('@aws-cdk/aws-iam'); // Allows working with IAM resources
import ecsPatterns = require('@aws-cdk/aws-ecs-patterns') // Helper to create ECS services with loadbalancers, and configure them
これらのモジュールは、ウェブアプリケーションをデプロイするために必要な全てのコンポーネントへのアクセスを提供します。最初のステップは、以下のコードを追加することによりアカウント内の既存のデフォルト VPC を検索することです。
// Look up the default VPC
const vpc = ec2.Vpc.fromLookup(this, "VPC", {
isDefault: true
});
次に、どのコンテナを使用するか、設定をどのようにするかを定義する必要があります。これは、コンテナポートや必要な cpu やメモリの量、使用のコンテナイメージを満たすタスク定義を作成することで行われます。このガイドで、SampleAppフォルダのサンプルアプリケーションにコンテナイメージを構築し、CDK でコンテナの構築、アップロードやデプロイを管理します。今後のガイドのためにも、タスク定義に添付する空の IAM ロールを作成します。
タスク定義や IAM ロールを作成し、次のコードを追加します。
const taskIamRole = new iam.Role(this, "AppRole", {
roleName: "AppRole",
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
const taskDefinition = new ecs.FargateTaskDefinition(this, 'Task', {
taskRole: taskIamRole,
});
taskDefinition.addContainer('MyContainer', {
image: ecs.ContainerImage.fromAsset('../SampleApp'),
portMappings: [{ containerPort: 80 }],
memoryReservationMiB: 256,
cpu : 256,
});
上記のコードでは、FargateTaskDefintion を使用して Fargate にデプロイするタスク定義タイプを指定し、ContainerImage.fromAsset を使用していることが確認できます。CDK は SampleApp ディレクトリの Dockerfile を使用し、コンテナイメージを構築します。
次に、ECS クラスターのセットアップ、サービスの定義、ロードバランサーの作成、サービスに接続するための設定、必要なセキュリティグループルールのセットアップが必要です。ECS のサービスは、必要なコピー数やデプロイ戦略、その他の設定を指定し、タスク定義を起動するために使用されます。この例では、コンテナの 1 コピーだけを起動します。セキュリティグループは、インスタンスの仮想ファイアウォールとして機能し、インバウンドやアウトバウンドトラフィックをコントロールしますが、その設定を使用している ECS Pattern が行うため、設定の必要はありません。
プロジェクトのタスク定義の下に、次のコードを追加します。
new ecsPatterns.ApplicationLoadBalancedFargateService(this, "MyApp", {
vpc: vpc,
taskDefinition: taskDefinition,
desiredCount: 1,
serviceName: 'MyWebApp',
assignPublicIp: true,
publicLoadBalancer: true,
})
以前検索したすべてのリソースの作成場所を指定する vpc オブジェクトと、どのコンテナイメージをデプロイするかを定義するためのタスク定義を学んでいます。必要なコピー数の desiredCount、必要なサービスを呼ぶ serviceName と、publicLoadBalancer はインターネットでアクセスできるよう true に設定されています。 ここでは、プライベートサブネットがないデフォルト VPC を使用している例なので、assignPublicIp を true にするライン設定が重要です。ベストプラクティスで、プライベートサブネットのサービスを始めることをおすすめしていますが、このガイドでは範囲外です。
ウェブアプリケーションをデプロイする準備ができましたが、まずはじめに、デプロイするアカウントに CDK をセットアップする必要があります。
bin/cdk-ecs-infra.tsファイルを編集し、14 行目のコメントを解除します。
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
これは、AWS CLI で設定されたアカウント ID とリージョンを使用します。CDK を使用する前に、ブートストラップする必要があります。これにより、CDK がアカウントのインフラストラクチャを管理するために必要なインフラストラクチャが作成されます。CDK をブートストラップするには、cdk bootstrapを実行します。次のような出力が表示されます。
cdk bootstrap
#output
⏳ Bootstrapping environment aws://0123456789012/<region>...
✅ Environment aws://0123456789012/<region> bootstrapped
これで、お使いのアカウントで必要なインフラストラクチャを管理するためのインフラストラクチャが CDK で作成されます。CDK アプリケーションのセットアップに不慣れな場合は、「AWS CDK の入門」ガイドの参照をおすすめします。
ブートストラップが完了したら、cdk deployを実行してコンテナやクラスターおよび全てのインフラストラクチャのデプロイが必要です。次のような出力が表示されます。

CDK は、(このケースでは IAM ロールとセキュリティグループを作成することによって) セキュリティ設定を変更するインフラストラクチャを作成しようとしているため、インフラストラクチャを作成する前にプロンプトを表示します。yを押してから、Enter を押してデプロイします。これで、CDK は定義したすべてのインフラストラクチャをセットアップします。完了するまでに数分かかります。
実行中、このような更新内容が表示されます。

この手順が完了すると、サービスにアクセスできる公開 URL リンクの出力が、次のように表示されます。

全コードサンプル
import * as cdk from '@aws-cdk/core';
import ecs = require('@aws-cdk/aws-ecs');
import ec2 = require('@aws-cdk/aws-ec2');
import iam = require('@aws-cdk/aws-iam');
import ecsPatterns = require('@aws-cdk/aws-ecs-patterns')
export class CdkEcsInfraStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Look up the default VPC
const vpc = ec2.Vpc.fromLookup(this, "VPC", {
isDefault: true
});
const taskIamRole = new iam.Role(this, "AppRole", {
roleName: "AppRole",
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
const taskDefinition = new ecs.FargateTaskDefinition(this, 'Task', {
taskRole: taskIamRole,
});
taskDefinition.addContainer('MyContainer', {
image: ecs.ContainerImage.fromAsset('../SampleApp'),
portMappings: [{ containerPort: 80 }],
memoryReservationMiB: 256,
cpu : 256,
});
new ecsPatterns.ApplicationLoadBalancedFargateService(this, "MyApp", {
vpc: vpc,
taskDefinition: taskDefinition,
desiredCount: 1,
serviceName: 'MyWebApp',
assignPublicIp: true,
publicLoadBalancer: true,
})
}
}
まとめ
このモジュールでは、Fargate で CDK による ECS パターンを使用して、実行中のコンテナにトラフィックを提供するロードバランサーで、どのように ECS クラスターを作成するかを学習しました。次のモジュールでは、このガイドで作成された全てのリソースをクリーンアップします。
次回: リソースをクリーンアップする