Amazon Web Services ブログ

ECS Blueprints で Amazon ECS ベースのワークロードを加速しよう

はじめに

Amazon Elastic Container Service (Amazon ECS) でコンテナワークロードを簡単かつ素早くビルド可能にする、ECS Blueprints for AWS Cloud Development Kit (AWS CDK) をご紹介いたします。ECS Blueprints は、Amazon ECS クラスター上でコンテナワークロードを設定しデプロイするのに役立つ、Infrastructure as Code (IaC) のオープンソースモジュールの集まりです。ECS Blueprints は、お客様が Amazon ECS への移行を開始する際だけでなく、既存のクラスターに Application Load Balancer (ALB) によるフロントエンドサービスなど特定のワークロードを構築する際にも使用できます。また、ECS Blueprints は各シナリオのベストプラクティスを示し、リファレンスアーキテクチャとソリューションパターンを提供します。ECS Blueprints は、特定シナリオのエンドツーエンドの要件に対応しているため、お客様は Amazon ECS ワークロードの構築をスピードアップすることができます。さらに、ECS Blueprints テンプレートをユースケースに合わせて簡単にカスタマイズすることも可能です。これについてはこの記事で詳しく説明します。

AWS CDK は、使い慣れたプログラミング言語を使用してクラウドインフラストラクチャをモデル化およびプロビジョニングするオープンソースのソフトウェア開発フレームワークです。そのため、開発者は TypeScript、Python、Java などの使い慣れた言語を使用して、インフラストラクチャのプロビジョニングとビジネスロジックの構築を同時に行うことができます。さらに、AWS CDK の組み込みコンポーネントは 1 つ以上の AWS リソースで構成される高レベルの抽象化であるため、お客様は AWS CDK コンストラクトによって定義されたパラメータのカスタム値を使用して、複数の環境を素早く設定しデプロイできます。

この記事では AWS CDK を使用した ECS Blueprints に焦点を当てていますが、Terraform を使用した ECS Blueprints も同じリポジトリにあり、Terraform でも同様の概念を実装しています。

モチベーション

コンテナは、アプリケーションのパッケージングとデプロイのデファクトスタンダードです。コンテナにはアプリケーションの依存関係がすべて含まれており、開発者のラップトップから本番環境まで、あらゆるマシンで一貫して起動します。コンテナの移植性により、お客様はエンドツーエンドの自動化されたソフトウェアデリバリーパイプラインを構築でき、ソフトウェアを頻繁かつ迅速にリリースできます。しかし、多くの新規顧客にとって、これらのメリットを得るために必要な学習曲線とスキルは非常に厳しい場合があります。コンテナイメージの構築方法を学び、Amazon ECS などのコンテナオーケストレーションを理解し、デプロイアーティファクトを作成し、オブザーバビリティとセキュリティのための仕組みを作成し、継続的インテグレーション (CI) と継続的デプロイ (CD) パイプラインを設定する必要があります。Amazon ECS や AWS Fargate によって手間のかかる作業を大幅に省くことができますが、それでも新規ユーザーが高めるべきスキルは、かなり多岐にわたります。

ECS Blueprints によって、新規ユーザーがコンテナベースのモダナイゼーションによって得られるメリットを、数か月ではなく数時間で実現できるようにしたいと考えています。ブループリントは、新規ユーザーがすぐに始めることができ、実践を通じて学習できるようにすることを目的としています。ECS Blueprints では、ベストプラクティスと適切に設計されたアーキテクチャパターンを体系化し、CI/CD、オブザーバビリティ、セキュリティ、コスト効率に対応するエンドツーエンドのソリューションを提供することを目指しています。この投稿では、コンピューティングとしてサーバーレスコンテナエンジンである AWS Fargate を使用し、Infrastructure as Code として AWS CDK を使用する ECS Blueprints について詳しく説明します。

ECS Blueprints の構造理解

AWS CDK 開発のベストプラクティスの 1 つは、「コンストラクトによるモデリングとスタックによるデプロイ」です。つまり、複数の AWS リソースからアプリケーションの上位論理ユニットのコンストラクトを構築します。このベストプラクティスガイドラインに従い、コンポーネントディレクトリを複数のシナリオで再利用できるようにカスタムコンストラクトで構成しました。この記事の執筆時点では、コンポーネントディレクトリにはコアインフラストラクチャと CI/CD パイプラインの 2 つのコンストラクトがあります。

コアインフラストラクチャのコンストラクトは、Amazon VPC (Amazon Virtual Private Cloud)、Amazon ECS クラスター、プライベート DNS 名前空間などで構成されています。Amazon ECS への移行を開始するために必要な、基本的な AWS リソースの集まりです。 CI/CD のコンストラクトは、AWS CodeBuildAmazon Elastic Container Registry (Amazon ECR)AWS CodePipeline、および関連する AWS IAM ロールからなります。この 2 つのコンストラクトを各 ECS Blueprints テンプレートに埋め込む代わりに、カスタムコンストラクトにしました。この設計の利点は、お客様が繰り返し使用するソースコードを減らせることです。お客様はこのコンストラクトをプログラミング言語の関数として、複数の ECS Blueprints テンプレートに簡単に挿入できます。

図 1. AWS CDK のための ECS Blueprints の一部

コンポーネントディレクトリと同じ階層の各ディレクトリには、Amazon ECS ワークロードの名前が付けられています。そして、そのディレクトリ配下の各テンプレートは、以下に示したものと同じ階層構造に従います。

└── <workload name>
    ├── lib
    │   ├── __init__.py 
    │   ├── <workload name>_stack.py
    │   ├── <workload name>_stack_props.py                
    ├── README.md                 
    ├── __init__.py              
    ├── app.py
    ├── cdk.json
    ├── sample.env
  • lib/<workload name>_stack.py – このブループリントアプリケーションのメインスタックのコンストラクトが定義されているファイル。
  • lib/<workload name>_stack_props.py – アプリケーションのメインスタックに必要な変数で構成されているファイル。
  • README.md – この ECS Blueprints の使用方法を説明するファイル。
  • __init__.py – ディレクトリを Python パッケージとして扱うために使用されるファイル。
  • app.py – この Amazon ECS アプリケーションを実行するためのエントリーポイント。
  • cdk.json – CDK コンストラクトツリーを生成するために、実行する必要がある実行可能な CDK を定義している AWS CDK の設定ファイル。
  • sample.env – この ECS Blueprints テンプレートの実行に必要な、変数のサンプルコレクション。

AWS CDK スタックはデプロイの単位であるため、スタックのスコープ内で定義されるすべての AWS リソースのライフサイクルは同じです。この特性に基づいて、各機能を異なるテンプレートに分割しました。

ウォークスルー

このウォークスルーでは、ECS Blueprints テンプレートを使用して Amazon ECS クラスターに簡単なウェブアプリケーションをデプロイします。最も一般的なワークロードであるこのアプリケーションでは、エンドユーザーが アプリケーションロードバランサー のエンドポイント経由でサービスにアクセスできます。ALB を経由するトラフィックはフロントエンドサービスによって処理され、フロントエンドサービスはサービスディスカバリーを通じてバックエンドサービスと通信します。

図 2. AWS CDK を通じてデプロイされたフルスタックアプリケーションのアーキテクチャ

前提条件

ECS Blueprints で Amazon ECS ワークロードを簡単に設定できることを示すために、フルスタックアプリケーションのプロビジョニングに 2 つの ECS Blueprints テンプレートを使用します。このウォークスルーには、以下の準備が必要です。

ウォークスルーする場所で AWS 認証情報を設定します。始めに、ECS Blueprints Github リポジトリをクローンします。

git clone https://github.com/aws-ia/ecs-blueprints.git

Step 1: コアインフラストラクチャとバックエンドサービスをデプロイ

バックエンドサービスのブループリントは、次のステップでデプロイするフロントエンドアプリケーションのトラフィックを処理する Node.js バックエンド API をデプロイします。このバックエンドサービスには、AWS Cloud Map に登録されたサービスディスカバリー名を持っています。この Amazon ECS クラスターで実行されている他のサービスは、バックエンドサービスのディスカバリー名を使用してバックエンドサービスにアクセスできます。

cd ecs-blueprints/cdk/examples/backend_service/

ご自身の環境に合わせて AWS アカウントと AWS リージョンの環境変数を設定します。この投稿では、例としてオレゴンリージョン (us-west-2) を使用します。次に、AWS CDK テンプレートで使用する .env ファイルを生成します。バックエンドサービスのデプロイ時に、.env ファイル内の変数が取得されます。

export AWS_ACCOUNT=$(aws sts get-caller-identity --query 'Account' --output text)
export AWS_REGION=${AWS_REGION:=us-west-2}

sed -e "s/<ACCOUNT_NUMBER>/$AWS_ACCOUNT/g" \
  -e "s/<REGION>/$AWS_REGION/g" sample.env > .env

Python の仮想環境を作成して、Python のインストールと関連する pip パッケージをローカル環境から分離します。その後、必要なパッケージをインストールします。

# manually create a virtual environment: 
python3 -m venv .venv

# activate your virtual environment:
source .venv/bin/activate

# install the required dependencies: 
python -m pip install -r ../../requirements.txt

.env ファイルの各値を詳しく見てみましょう。

  1. deploy_core_stack – VPC や Amazon ECS クラスターなどのコアインフラストラクチャを事前にプロビジョニングしていないため、コアインフラストラクチャとバックエンドサービスの両方をデプロイしました。そのため、この値を True に設定しています。
  2. Essential Props – これには、AWS CDK スタックのデプロイ時に不可欠な要素である AWS アカウント ID と AWS リージョンが含まれます。
  3. Core Stack Props – コアインフラストラクチャを構成するコンポーネントの名前を指定します。
  4. Backend Service Props – コンテナイメージ URI、コンテナ名、コンテナポート、Amazon ECS タスクに割り当てられるリソース量など、バックエンドサービスの詳細情報を設定します。
  5. ECS cluster Props と Service discovery Props – コアインフラストラクチャのプロビジョニング中にこれらの値は自動的に出力されるため、両方の prop 値をデフォルト設定のままにします。

初めて CDK を使用してインフラストラクチャを作成する場合は、CDK をブートストラップします。

cdk bootstrap aws://${AWS_ACCOUNT}/${AWS_REGION}

バックエンドサービスのスタックをデプロイする前に、次の AWS CDK コマンドを使用してこのアプリケーションの AWS CDK スタックを調べてください。CoreInfraStack と BackendService という名前の 2 つのスタックが表示されます。

cdk ls

下記のコマンドを使用して AWS CDK スタックをデプロイします。

cdk deploy --all --require-approval never --outputs-file output.json

Step 2: ロードバランサーとフロントエンドサービスをデプロイする

フロントエンドサービスのテンプレートに移動します。このブループリントは、ウェブ向けの負荷分散された Amazon ECS サービスを作成します。

cd ../lb_service

再び、ご使用の環境に合わせて AWS アカウントと AWS リージョンの環境変数を設定します。AWS CDK テンプレートで使用する .env ファイルを生成します。フロントエンドサービスのデプロイ中に .env ファイル内の変数が取得されます。

export AWS_ACCOUNT=$(aws sts get-caller-identity --query 'Account' --output text)
export AWS_REGION=us-west-2

sed -e "s/<ACCOUNT_NUMBER>/$AWS_ACCOUNT/g" \
  -e "s/<REGION>/$AWS_REGION/g" sample.env > .env

ただし、バックエンドサービスをデプロイする場合とは異なり、一部の値は調整が必要です。まず、コアインフラストラクチャはすでにプロビジョニングされているため、その Amazon ECS クラスターをフロントエンドサービスに使用します。deploy_core_stack の値を False に変更してください。次に、前のステップでプロビジョニングしたコアインフラストラクチャ情報を参照して、ECS タスク実行ロール ARN と名前空間の値を指定します。必要な情報は、バックエンドサービスのディレクトリ内の output.json ファイルから取得できます。

訳注:下記の {ECS_TASK_EXECUTION_ROLE_ARN}{NAMESPACE_ARN}, {NAMESPACE_ID} を置き換えてください。

deploy_core_stack="False"

# Essential Props
account_number="${AWS_ACCOUNT}"
aws_region="${AWS_REGION}"

# Core Stack Props
vpc_cidr="10.0.0.0/16"
ecs_cluster_name="ecs-blueprint-infra"
namespaces="default"
enable_nat_gw="True"
az_count="3"

# Frontend Service Props
backend_svc_endpoint="http://ecsdemo-backend.default.ecs-blueprint-infra.local:3000"
container_image="public.ecr.aws/aws-containers/ecsdemo-frontend"
container_name="ecsdemo-frontend"
container_port="3000"
task_cpu="256"
task_memory="512"
desired_count="3"
service_name="ecsdemo-frontend"

## Enter the values below by referring to the backend_service/output.json

# ECS cluster Props
ecs_task_execution_role_arn="{ECS_TASK_EXECUTION_ROLE_ARN}"
vpc_name="ecs-blueprint-infra-vpc"

# Service discovery Props
namespace_name="default.ecs-blueprint-infra.local"
namespace_arn="{NAMESPACE_ARN}"
namespace_id="{NAMESPACE_ID}"

下記のコマンドを使用して AWS CDK スタックをデプロイします。

cdk deploy FrontendService --require-approval never

2 つの ECS Blueprints テンプレートを使用して Amazon ECS クラスターを構築し、その上にフロントエンドサービスとバックエンドサービスをプロビジョニングしました。デプロイを確認するには、AWS CDK 出力情報の最後の部分に記載されているロードバランサーエンドポイントをウェブブラウザにコピーしてアクセスします。次のような画像が表示されます。

図 3. バックエンドとフロントエンドの CDK スタックをデプロイした結果

ECS Blueprints を好みに合わせてカスタマイズ

図 4. 1 つのワークロードディレクトリ内のファイル間の相関関係

ECS Blueprints が目的のワークロードに合わない可能性もあります。その場合は、ECS Blueprints をカスタマイズして、お客様のワークロードに合わせたテンプレートに簡単に変換できます。ブループリントテンプレートをカスタマイズするには、提供されている AWS CDK コードをより深く理解する必要があります。

前述のとおり、各 Amazon ECS ワークロードの設定ロジックは stack.py ファイルにあります。また、stack_props.py ファイルに列挙されている変数は、stack.py ファイル内の各リソースを設定する際のパラメータとして使用されます。つまり、このファイルはスタックのプロパティを定義するために使用されるインターフェースです。さらに、お客様はこれらのプロパティの値を .env ファイルで指定できます。そのため、お客様は必要なパラメータを変数に変換することで、1 つのテンプレートからパラメータの異なる複数のサービスを生成できます。たとえば、お客様が Amazon ECS サービスの自動スケーリングの設定にタスクの最大値と最小値を直接指定したい場合、それらを環境変数および状態変数として stack_props.py ファイルに抽出できます。最後のステップとして、これらの値を stack.py ファイルの環境変数に置き換えます。

加えて、各 Amazon ECS ワークロードシナリオはそれぞれ異なるディレクトリに配置され、独自のデプロイライフサイクルを有しています。お客様は、既存のディレクトリ構造を使用して、Amazon ECS ワークロードのロジックを含む ECS Blueprints テンプレートを簡単に作成できます。任意でお客様がテンプレートのロジックに少し変更を加えることで、同じ目標を達成できます。

クリーンアップ

AWS CloudFormation コンソールか、フロントエンドサービスのテンプレートの場所で AWS CDK コマンドを使用することでスタックを削除できます。

cdk destroy

フロントエンドサービスを削除したら、バックエンドサービスのテンプレートに移動し、AWS CDK コマンドをもう一度使用してください。これで、バックエンドサービスとコアインフラストラクチャが削除されます。

cd ../backend_service
cdk destroy --all --force

まとめ

この投稿では、ECS Blueprints とは何か、そしてどのように使用するか、どのようにカスタマイズできるかを紹介しました。ECS Blueprints をお客様のワークロードに使用する方法を学んだばかりなので、今すぐ ECS Blueprints を始められます!ECS Blueprints の詳細については、ECS Blueprints ワークショップ公式 GitHub リポジトリをご覧ください。ECS Blueprints は無料で使用でき、お支払いいただくのはデプロイしたリソースの分だけです。

ECS Blueprints は、一般的な Amazon ECS ワークロードシナリオをカバーすることを目的としています。そのため、ECS Blueprints をどのように発展できるかについてのフィードバックをお待ちしています。フィードバックにご興味がおありでしたら、ECS Blueprints リポジトリへ GitHub Issue をオープンしてください。

本記事は Accelerate Amazon ECS-based workloads with ECS Blueprints (2023 年 7 月 24 日公開) を翻訳したものです。翻訳は、ソリューションアーキテクトの吉田が担当しました。