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

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

このトピックでは、Amazon Elastic Container Service と Fargate上 の AWS Cloud Development Kit (AWS CDK) で、コンテナ化された Web サーバーをデプロイする方法を紹介します。AWS CDKは、本格的なプログラミング言語を使用して、AWSインフラストラクチャを定義することができるコードとしてのInfrastructure as Code (IAC) フレームワークです。CDK でサポートされている言語の 1 つでアプリケーションを書き、1 つ以上のスタックを含み、それをAWS CloudFormationテンプレートに合成し、リソースをAWSアカウントにデプロイします。

CDKに含まれるAWS構成ライブラリは、すべてのAWSサービスに提供されるリソースをモデル化するAPIを提供しています。最も一般的なサービスでは、スマートなデフォルトを提供し、必要なパラメータを減らしてベストプラクティスを実装できるよう、ライブラリは厳選された構成を提供します。これらのモジュールの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 をインストールします。

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ではファイル >インポート >Maven >既存の Maven プロジェクト).

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

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

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-/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 上のコンテナ化されたWebサーバーを定義します

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

作成したAWS CDKプロジェクトで、スタックの定義を含むファイルを編集して、以下のコードのようにします。ApplicationLoadBalancedFargateServiceコンストラクトのインスタンス化―または少なくともその名前を認識できます。

注記

スタックとは何でしょう? スタックはデプロイの単位です:すべてのリソースがスタック内にある必要があり、スタック内のすべてのリソースが一緒にデプロイされます。リソースのデプロイに失敗すると、すでにデプロイされている他のリソースはロールバックされます。AnAWS CDKアプリケーションには複数のスタックを含めることができ、1 つのスタック内のリソースは別のスタック内のリソースを参照することができます。

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..

  • ロードバランサーが公開アドレスを持ち、インターネットからアクセスできるということ。

ここですでに説明したので省略していますが、Amazon ECS クラスター、基盤となる Amazon Virtual Private Cloud と Amazon EC2 インスタンス、Auto Scaling グループ、Application Load Balancer、必要な IAM ロールとポリシー、その他のAWSリソースを Web サーバーのデプロイに必要な場合、AWS CDKは、これらのリソースも作成します。自動プロビジョニングされたリソースの一部は、スタックで定義されているすべての 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が、かなりの数の リソースを作成するのが確認できます。デプロイからの出力の最後の数行に、ロードバランサーの公開ホスト名と、新しい Web サーバーの HTTP 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 をコピーし、Web ブラウザに貼り付けます。Web サーバーからのウェルカムメッセージが表示が確認できます。

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

これで、Web サーバーの使用が完了しました ([おめでとう] メッセージを表示する以外に何もしません)。CDK を使用して、サービスを停止することができます。問題cdk destroyをアプリケーションのメインディレクトリでを発行します。これを行うことで、意図しないAWS課金を防ぐことができます。

次のステップ

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 リファレンスの概要」を参照してください。