AWS CDKを使用してAmazon ECS の開始方法 - Amazon Elastic Container Service

AWS CDKを使用してAmazon ECS の開始方法

AWS Cloud Development Kit (AWS CDK) は、選択したプログラミング言語を使用して、AWS クラウドインフラストラクチャの定義に使用できる、Infrastructure as Code (IAC) フレームワークです。独自のクラウドインフラストラクチャを定義するには、最初に、(CDK でサポートされている言語のいずれかで) 1 つ以上のスタックが含まれるアプリケーションを記述します。次に、それを AWS CloudFormation テンプレートに合成して、AWS アカウント にリソースをデプロイします。このトピックのステップに従って、Amazon Elastic Container Service (Amazon ECS) と Fargate 上の AWS CDK で、コンテナ化されたウェブサーバーをデプロイしてください。

CDK に含まれる AWS 構成ライブラリは、AWS のサービス が提供するリソースのモデル化に使用できるモジュールを提供します。一般的なサービスでは、ライブラリが、スマートなデフォルトとベストプラクティスを持つ厳選された構成を提供します。これらのモジュールの 1 つである aws-ecs-patterns は、コンテナ化されたサービスと必要なすべてのサポートリソースをほんの数行のコードで定義するために使用できる、高レベルの抽象化を提供します。

このトピックでは、ApplicationLoadBalancedFargateService 構成を使用します。この構成は、Application Load Balancer の背後にある Fargate に Amazon ECS サービスをデプロイします。この aws-ecs-patterns モジュールには、Network Load Balancer を使用したり、Amazon EC2 で実行したりする構成も含まれています。

このタスクを開始する前に、AWS CDK 開発環境をセットアップし、次のコマンドを実行して AWS CDK をインストールします。AWS CDK 開発環境のセットアップ方法については、「Getting Started With the AWS CDK - Prerequisites」(AWS CDK の使用開始 - 前提条件) を参照してください。

npm install -g aws-cdk
注記

これらの手順は、AWS CDK v2 を使用していることを前提としています。

ステップ 1:AWS CDK プロジェクトを設定する

新しいAWS CDKアプリケーションのディレクトリを作成し、プロジェクトを初期化します。

TypeScript
mkdir hello-ecs cd hello-ecs cdk init --language typescript
JavaScript
mkdir hello-ecs cd hello-ecs cdk init --language javascript
Python
mkdir hello-ecs cd hello-ecs cdk init --language python

プロジェクトが開始されたら、プロジェクトの仮想環境をアクティブにし、AWS CDK のベースラインの依存関係をインストールします。

source .venv/bin/activate python -m pip install -r requirements.txt
Java
mkdir hello-ecs cd hello-ecs cdk init --language java

この Maven プロジェクトを Java IDE にインポートします。例えば Eclipse では、[File] (ファイル) > [Import] (インポート) > [Maven] > [Existing Maven Projects] (既存の Maven プロジェクト) を使用します。

C#
mkdir hello-ecs cd hello-ecs cdk init --language csharp
注記

AWS CDKアプリケーションテンプレートは、プロジェクトディレクトリの名前を使用し、ソースファイルとクラスの名前を生成します。この例では、ディレクトリ名は hello-ecs です。別のプロジェクトディレクトリ名を使用する場合、アプリケーションはこれらの指示と一致しません。

AWS CDK v2 は、aws-cdk-lib と呼ばれる単一パッケージですべての AWS のサービス の安定した構成を含んでいます。このパッケージは、プロジェクト開始時に依存関係としてインストールされます。特定のプログラミング言語で作業する場合、パッケージはプロジェクトを初めて構築するときにインストールされます。このトピックでは、Amazon ECS の使用時に高レベルの抽象化を提供する、Amazon ECS Patterns 構成の使用方法について説明します。このモジュールは、Amazon ECS 構成およびその他の構成に依存し、Amazon ECS アプリケーションに必要なリソースをプロビジョニングします。

これらのライブラリを CDK アプリケーションにインポートする際に使用する名前は、使用するプログラミング言語によって若干異なります。参考として、サポートされている各 CDK プログラミング言語で使用される名前を以下に示します。

TypeScript
aws-cdk-lib/aws-ecs aws-cdk-lib/aws-ecs-patterns
JavaScript
aws-cdk-lib/aws-ecs aws-cdk-lib/aws-ecs-patterns
Python
aws_cdk.aws_ecs aws_cdk.aws_ecs_patterns
Java
software.amazon.awscdk.services.ecs software.amazon.awscdk.services.ecs.patterns
C#
Amazon.CDK.AWS.ECS Amazon.CDK.AWS.ECS.Patterns

ステップ 2: AWS CDK を使用して、Fargate 上のコンテナ化されたウェブサーバーを定義する

DockerHub のコンテナイメージ amazon-ecs-sample を使用します。このイメージには、Amazon Linux 2 で実行される PHP ウェブアプリケーションが含まれています。

作成した AWS CDK プロジェクトで、スタック定義を含むファイルを次の例のいずれかと同様に編集します。

注記

スタックはデプロイの単位です。すべてのリソースがスタック内にある必要があり、スタック内のすべてのリソースは同時にデプロイされます。リソースのデプロイに失敗すると、既にデプロイされている他のリソースはロールバックされます。AWS CDK アプリケーションには複数のスタックを含めることができ、あるスタック内のリソースは別のスタック内のリソースを参照できます。

TypeScript

lib/hello-ecs-stack.ts を更新すると次のようになります。

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as ecs from 'aws-cdk-lib/aws-ecs'; import * as ecsp from 'aws-cdk-lib/aws-ecs-patterns'; export class HelloEcsStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new ecsp.ApplicationLoadBalancedFargateService(this, 'MyWebServer', { taskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), }, publicLoadBalancer: true }); } }
JavaScript

lib/hello-ecs-stack.js を更新すると次のようになります。

const cdk = require('aws-cdk-lib'); const { Construct } = require('constructs'); const ecs = require('aws-cdk-lib/aws-ecs'); const ecsp = require('aws-cdk-lib/aws-ecs-patterns'); class HelloEcsStack extends cdk.Stack { constructor(scope = Construct, id = string, props = cdk.StackProps) { super(scope, id, props); new ecsp.ApplicationLoadBalancedFargateService(this, 'MyWebServer', { taskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), }, publicLoadBalancer: true }); } } module.exports = { HelloEcsStack }
Python

hello-ecs/hello_ecs_stack.py を更新すると次のようになります。

import aws_cdk as cdk from constructs import Construct import aws_cdk.aws_ecs as ecs import aws_cdk.aws_ecs_patterns as ecsp class HelloEcsStack(cdk.Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) ecsp.ApplicationLoadBalancedFargateService(self, "MyWebServer", task_image_options=ecsp.ApplicationLoadBalancedTaskImageOptions( image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample")), public_load_balancer=True )
Java

src/main/java/com.myorg/HelloEcsStack.java を更新すると次のようになります。

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.ecs.ContainerImage; import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedFargateService; import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedTaskImageOptions; public class HelloEcsStack extends Stack { public HelloEcsStack(final Construct scope, final String id) { this(scope, id, null); } public HelloEcsStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); ApplicationLoadBalancedFargateService.Builder.create(this, "MyWebServer") .taskImageOptions(ApplicationLoadBalancedTaskImageOptions.builder() .image(ContainerImage.fromRegistry("amazon/amazon-ecs-sample")) .build()) .publicLoadBalancer(true) .build(); } }
C#

src/HelloEcs/HelloEcsStack.cs を更新すると次のようになります。

using Amazon.CDK; using Constructs; using Amazon.CDK.AWS.ECS; using Amazon.CDK.AWS.ECS.Patterns; namespace HelloEcs { public class HelloEcsStack : Stack { internal HelloEcsStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { new ApplicationLoadBalancedFargateService(this, "MyWebServer", new ApplicationLoadBalancedFargateServiceProps { TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions { Image = ContainerImage.FromRegistry("amazon/amazon-ecs-sample") }, PublicLoadBalancer = true }); } } }

前述の短いスニペットには次のものが含まれます。

  • サービスの論理名: MyWebServer

  • DockerHub から取得したコンテナイメージ: amazon/amazon-ecs-sample

  • ロードバランサーが公開アドレスを持ち、インターネットからアクセスできる事実といった、その他の関連情報。

AWS CDK は、次のリソースを含む、ウェブサーバーのデプロイに必要なすべてのリソースを作成します。この例では、これらのリソースは省略されています。

  • Amazon ECS クラスター

  • Amazon VPC と Amazon EC2 インスタンス

  • Auto Scaling グループ

  • Application Load Balancer

  • IAM ロールとポリシー

自動プロビジョニングされたリソースの一部は、スタックで定義されているすべての Amazon ECS サービスにより共有されます。

ソースファイルを保存し、アプリケーションのメインディレクトリで cdk synth コマンドを実行します。AWS CDK はアプリケーションを実行し、そのアプリケーションから AWS CloudFormation テンプレートを合成して、テンプレートを表示します。テンプレートは約 600 行の YAML ファイルです。ファイルの先頭は以下のとおりです。テンプレートはこの例と異なる場合があります。

Resources: MyWebServerLB3B5FD3AB: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: LoadBalancerAttributes: - Key: deletion_protection.enabled Value: "false" Scheme: internet-facing SecurityGroups: - Fn::GetAtt: - MyWebServerLBSecurityGroup01B285AA - GroupId Subnets: - Ref: EcsDefaultClusterMnL3mNNYNVpcPublicSubnet1Subnet3C273B99 - Ref: EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2Subnet95FF715A Type: application DependsOn: - EcsDefaultClusterMnL3mNNYNVpcPublicSubnet1DefaultRouteFF4E2178 - EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2DefaultRouteB1375520 Metadata: aws:cdk:path: HelloEcsStack/MyWebServer/LB/Resource MyWebServerLBSecurityGroup01B285AA: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Automatically created Security Group for ELB HelloEcsStackMyWebServerLB06757F57 SecurityGroupIngress: - CidrIp: 0.0.0.0/0 Description: Allow from anyone on port 80 FromPort: 80 IpProtocol: tcp ToPort: 80 VpcId: Ref: EcsDefaultClusterMnL3mNNYNVpc7788A521 Metadata: aws:cdk:path: HelloEcsStack/MyWebServer/LB/SecurityGroup/Resource # and so on for another few hundred lines

AWS アカウント でサービスをデプロイするには、cdk deploy コマンドをアプリケーションのメインディレクトリで実行します。AWS CDK が生成した IAM ポリシーを、承認するよう求められます。

デプロイには数分かかり、その間に AWS CDK は複数のリソースを作成します。デプロイからの出力の末尾数行に、ロードバランサーの公開ホスト名と、新しいウェブサーバーの URL が含まれます。その内容は次のとおりです。

Outputs: HelloEcsStack.MyWebServerLoadBalancerDNSXXXXXXX = Hello-MyWeb-ZZZZZZZZZZZZZ-ZZZZZZZZZZ.us-west-2.elb.amazonaws.com HelloEcsStack.MyWebServerServiceURLYYYYYYYY = http://Hello-MyWeb-ZZZZZZZZZZZZZ-ZZZZZZZZZZ.us-west-2.elb.amazonaws.com

ステップ 3: ウェブサーバーをテストする

デプロイ出力から URL をコピーし、ウェブブラウザに貼り付けます。ウェブサーバーからの次のウェルカムメッセージが表示されます。

ステップ 4: クリーンアップする

ウェブサーバーの使用が終了したら、CDK を使用して cdk destroy コマンドをアプリケーションのメインディレクトリで実行し、サービスを終了します。これにより、将来的に想定外の請求が発生するのを防げます。

次のステップ

AWS CDK を使用して AWS インフラストラクチャを開発する方法の詳細については、「AWS CDK デベロッパーガイド」を参照してください。

選択した言語で AWS CDK アプリケーションを記述する方法については、以下を参照してください。

TypeScript

TypeScript で AWS CDK を操作

JavaScript

JavaScript で AWS CDK を操作 

Python

Python で AWS CDK を捜査 

Java

Java で AWS CDK を操作

C#

C# で AWS CDK を操作

このトピックで使用する AWS 構成ライブラリモジュールの詳細は、以下の AWS CDK API リファレンスの概要を参照してください。