AWS でのプロジェクト

モダンウェブアプリケーションを構築する

ウェブアプリケーションのデプロイ、データベースへの接続、ユーザー動作の分析

モジュール 2: ウェブサーバーでのアプリケーションのホスト

このモジュールでは、AWS Fargate を使用してホストされる新しいマイクロサービスを作成します。 

概要

このモジュールでは、AWS Fargate を使用してホストされる新しいマイクロサービスを作成し、Mythical Mysfits ウェブサイトをアプリケーションバックエンドと統合できるようにします。

AWS FargateAmazon Elastic Container Service (ECS) のデプロイオプションです。このサービスを使用すると、クラスターやサーバーを管理することなくコンテナをデプロイできます。Mythical Mysfits バックエンドには Python を使用して、Network Load Balancer の後ろに配置される Docker コンテナに Flask アプリケーションを作成します。これは、フロントエンドのウェブサイトに対応するマイクロサービスバックエンドとして動作します。

Fargate を選択した理由

ここで Fargate を選択した理由は、Fargate がウェブ、モバイル、PaaS などのプラットフォーム向けマイクロサービスバックエンドのような、長時間実行されるプロセスに最適であるためです。Fargate を使用すると、コンテナを管理できるようになり、実行のタイミングを柔軟に選択できます。サーバーのプロビジョニングやスケールについて心配する必要はありません。Fargate により、ネットワーク、セキュリティ、およびサービス間通信を完全に制御できるようになります。また、Fargate は、セキュリティ、ネットワーク、アクセスコントロール、開発者ツール、モニタリング、ログ取得用の AWS のサービスとネイティブに統合されています。

Fargate に加えて、コンピューティングニーズを満たすために AWS Lambda を使用することもできます。Lambda は、Fargate と同じサーバーレスの利点を提供します。また、データの変更、システム状態の変化、ユーザーによるアクションにリアルタイムに応答する必要があるデータ駆動型アプリケーションに最適です。Lambda についてはモジュール 5 で詳しく説明します。モジュール 5 では、Lambda を使用してサイトでのお客様の行動を分析します。

実装手順

以下に示すステップごとの詳細な手順に従い、AWS Fargate サービスを作成します。このモジュールは規模が大きいため、3 つのサブモジュールに分割しています。モジュール 2A では、サービスをデプロイするための準備として、コアインフラストラクチャをセットアップします。モジュール 2B では、AWS Fargate を使用してサービスをデプロイします。最後に、モジュール 2C では、AWS のコードサービスを使用して自動デプロイをセットアップします。

モジュール 2A: コアインフラストラクチャのセットアップ

サービスを作成する前に、Amazon VPC のネットワークインフラストラクチャや AWS Identity and Access Management のロールなど、サービスで使用するコアインフラストラクチャ環境を作成する必要があります。AWS IAM のロールは、ECS や独自のコンテナに対して AWS での権限を定義するものです。

コアインフラストラクチャのセットアップには、AWS CloudFormation を使用します。AWS CloudFormation は、AWS のリソースを CloudFormation テンプレートと呼ばれる JSON または YAML ファイル内で定義し、プログラムを使用してプロビジョニングできるサービスです。これにより、Infrastructure as Code の一般的なベストプラクティスを実現できます。 

  • 必要なすべてのネットワークとセキュリティのリソースを作成するために、/module-2/cfn/core.yml に CloudFormation テンプレートを用意しています。このテンプレートにより、以下のリソースが作成されます。

    • Amazon VPC – 10.0.0.0/16 のプライベート IP 空間に 4 つのサブネット (パブリックとプライベートを 2 つずつ) を配置したネットワーク環境と、必要なすべてのルートテーブル設定。このネットワークのサブネットは別々の AWS アベイラビリティーゾーン (AZ) で作成され、AWS リージョン内の複数の物理的な施設全体で高可用性を実現できます。AZ で高可用性を実現する方法の詳細をご覧ください。
    • 2 つの NAT ゲートウェイ (各パブリックサブネットに 1 つ) – 最終的にプライベートサブネットにデプロイするコンテナがインターネットと通信して、必要なパッケージなどをダウンロードできるようにします。
    • DynamoDB VPC エンドポイント – マイクロサービスバックエンドは、永続性を実現するため、最終的に Amazon DynamoDB と統合します (モジュール 3 で実施)。
    • セキュリティグループ – Docker コンテナが、Network Load Balancer を経由してポート 8080 でインターネットからのトラフィックを受信できるようにします。
    • IAM ロール – Identity and Access Management ロールが作成されます。ロールは、AWS のサービスや作成するリソースが他の AWS のサービス (DynamoDB、S3 など) にアクセスできるようにするために、ワークショップ全体を通じて使用します。

    Cloud9 ターミナルで以下のコマンドを実行して、これらのリソースを作成します (スタックの作成には最大 10 分ほどかかります)。

    aws cloudformation create-stack --stack-name MythicalMysfitsCoreStack --capabilities CAPABILITY_NAMED_IAM --template-body file://~/environment/aws-modern-application-workshop/module-2/cfn/core.yml

    AWS コンソールを使用するか、以下のコマンドを実行することで、スタックの作成状況を確認できます。

    aws cloudformation describe-stacks --stack-name MythicalMysfitsCoreStack

    定期的に describe-stacks コマンドを実行して、"StackStatus" というステータスが "CREATE_COMPLETE" になっているか確認します。

    describe-stacks コマンド

    (クリックして拡大)

    このレスポンスは、CloudFormation で上記の主要なネットワークリソースとセキュリティリソースのプロビジョニングが完了し、手順を続行できることを意味します。上記のスタックで "CREATE_COMPLETE" と表示されるまで待ってから次に進んでください。

    残りのワークショップ全体で、このコマンドで出力される値を使用します。以下のコマンドを実行すると、上記の describe-stacks コマンドを直接 IDE 内の新しいファイルに出力できます。このファイルは cloudformation-core-output.json として保存されます。

    aws cloudformation describe-stacks --stack-name MythicalMysfitsCoreStack > ~/environment/cloudformation-core-output.json

モジュール 2B: AWS Fargate を使用したサービスのデプロイ

次に、Docker コンテナイメージを作成します。コンテナイメージには、Flask で作成したマイクロサービス API を提供する Mythical Mysfits バックエンドを実行するために必要なコードと設定をすべて含めます。Docker コンテナイメージを Cloud 9 内でビルドして Amazon Elastic Container Registry にプッシュすることで、Fargate を使用するサービスを作成する際に、イメージをここからプルできるようになります。

アーキテクチャ図

ブラウザ ->ロードバランサー -> Fargate
  • A: Docker イメージをビルドする

    サービスバックエンドを実行するために必要なコードはすべて、Cloud9 IDE 内にクローンしたリポジトリの /module-2/app/ ディレクトリに保存されています。Flask を使用してサービス API を作成する Python コードを確認するには、/module-2/app/service/mythicalMysfitsService.py ファイルを参照します。

    先ほど作成した Cloud9 IDE には、Docker が既にインストールされているため、Cloud9 ターミナルで以下の 2 つのコマンドを実行すれば、Docker イメージをローカルでビルドできます。  

    最初に、~/environment/module-2/app にディレクトリを変更します。

    cd ~/environment/aws-modern-application-workshop/module-2/app

    先ほどの CloudFormation **describe-stacks の出力からアカウント ID とデフォルトのリージョンを取得できます。

    以下のコマンドで、REPLACE_ME_ACCOUNT_ID をアカウント ID に、REPLACE_ME_REGION をデフォルトのリージョンに置き換えると、Dockerfile ファイルを使用して Docker イメージをビルドできます。Dockerfile ファイルには Docker の手順が記述されています。コマンドで -t オプションを使用すると、Docker イメージにタグが付けられます。特定のタグ形式にすることで、後でイメージを Amazon Elastic Container Registry サービスにプッシュできます。

    アカウント ID を取得したら、Docker イメージをビルドできます。

    docker build . -t REPLACE_ME_AWS_ACCOUNT_ID.dkr.ecr.REPLACE_ME_REGION.amazonaws.com/mythicalmysfits/service:latest

    Docker によってアプリケーションに必要なすべての依存関係パッケージのダウンロードとインストールが実行され、ビルドイメージのタグが出力されることを確認できますイメージタグは、後で参照できるようにコピーしておきますタグは以下に示したように、111111111111.dkr.ecr.us-east-1.amazonaws.com/mythicalmysfits/service:latest のような形式になります。

    Successfully built 8bxxxxxxxxab
    Successfully tagged 111111111111.dkr.ecr.us-east-1.amazonaws.com/mythicalmysfits/service:latest
    B: サービスをローカルでテストする

    Cloud9 内でローカルにイメージをテストして、すべて期待通りに動作しているか確認します。前のコマンドの結果でコピーしたイメージタグを貼り付け以下のコマンドを実行して「ローカルで」コンテナをデプロイします (これは実際に、AWS の中にある Cloud9 IDE 内で行われます)。

    docker run -p 8080:8080 REPLACE_ME_WITH_DOCKER_IMAGE_TAG

    これにより、コンテナがローカルで稼働中であることが Docker によってレポートされます。

     * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)

    ローカルリクエストを使用してサービスをテストするには、Cloud9 の IDE 内でビルトインウェブブラウザを開きます。これは、IDE インスタンスで実行されているアプリケーションをプレビューするために使用できます。

    Cloud9 メニューバーで [Preview]、[Preview Running Application] の順に選択して、プレビュー用のウェブブラウザを開きます。

    preview-menu

     

    これにより、IDE でウェブブラウザが別のパネルで開きます。プレビューブラウザのアドレスバーで URI の末尾に /mysfits を追加しENTER キーを押します

    address-bar

    成功した場合、サービスからのレスポンスとして、`/aws-modern-application-workshop/module-2/app/service/mysfits-response.json` に保存されている JSON ドキュメントが返されます。

    サービスのテストが完了したら、PC または Mac で Ctrl + C キーを押すことで終了できます。

    C: Docker イメージを Amazon ECR にプッシュする

    ローカルでサービスのテストが正常に終了したら、Amazon Elastic Container Registry (Amazon ECR) でコンテナイメージリポジトリを作成し、イメージをプッシュできます。レジストリを作成するために以下のコマンドを実行します。これにより、アカウントに作成されたデフォルトの AWS ECR レジストリに新しいリポジトリが作成されます。

    aws ecr create-repository --repository-name mythicalmysfits/service

    このコマンドのレスポンスには、作成されたリポジトリに関する詳細なメタデータが含まれます。新しいリポジトリにコンテナイメージをプッシュするには、Docker クライアントをリポジトリで認証するための認証情報を取得する必要があります。

    以下のコマンドを実行すると、Docker クライアントの認証情報を取得するためのログインコマンドが返され、それが自動的に実行されます (以下の $ を含めたコマンド全体を指定してください)。コマンドが成功すると「Login Succeeded」と表示されます。

    $(aws ecr get-login --no-include-email)

    次に、先の手順でコピーしたタグを使用して、作成されたイメージを ECR リポジトリにプッシュします。このコマンドを使用すると、イメージおよびそれに依存するすべてのイメージが Docker によって Amazon ECR にプッシュされます。

    docker push REPLACE_ME_WITH_DOCKER_IMAGE_TAG

    以下のコマンドを実行すると、 プッシュされ、ECR リポジトリ内に保存された、新しい Docker イメージを確認できます。

    aws ecr describe-images --repository-name mythicalmysfits/service
  • A: AWS Fargate クラスターを作成する

    ECR でイメージが利用できるようになったため、AWS Fargate を使用して Amazon ECS でホストされるサービスに、このイメージをデプロイできます。前のモジュールで Cloud9 ターミナルを使用してローカルでテストしたものと同じサービスをクラウド内でデプロイし、Network Load Balancer の背後で公開できます。

    最初に、Amazon Elastic Container Service (ECS)でクラスターを作成します。これは、サービスコンテナのデプロイ先となる「サーバー」のクラスターを意味します。「サーバー」は実際には AWS Fargate を使用します。Fargate を使用すると、サーバーのプロビジョニングや管理を自分で実際に行うことなく、コンテナをクラスターにデプロイするよう指定できます。

    以下のコマンドを実行して、ECS で新しいクラスターを作成します。

    aws ecs create-cluster --cluster-name MythicalMysfits-Cluster
    B: AWS CloudWatch Logs グループを作成する

    次に、AWS CloudWatch Logs で新しいロググループを作成します。AWS CloudWatch Logs は、ログの収集と分析を行うサービスです。コンテナが自動生成するログは、このロググループに属するものとして CloudWatch Logs にプッシュされます。コンテナを実行しているサーバーインフラストラクチャにはアクセスできないため、AWS Fargate を使用する場合はこのことが特に重要になります。

    以下のコマンドを実行して、CloudWatch Logs で新しいロググループを作成します。

    aws logs create-log-group --log-group-name mythicalmysfits-logs
    C: ECS のタスク定義を登録する

    クラスターを作成し、コンテナログのプッシュ先となるロググループを定義したため、ECS のタスク定義を登録できます。ECS のタスクは、同時にスケジュールされる必要があるコンテナイメージのセットです。タスク定義では、コンテナのセットと、それらのコンテナに必要なリソースおよび設定を定義します。AWS CLI を使用して新しいタスク定義を作成し、先ほど作成した ECS クラスターに対する新しいコンテナイメージのスケジュール設定を定義します。

    CLI コマンドへの入力として指定する JSON ファイルはあらかじめ用意されています。

    IDE で ~/environment/aws-modern-application-workshop/module-2/aws-cli/task-definition.json を開きます。

    作成したリソースの適切な値を使用して、指定されている値を置き換えます

    これらの値は、先ほどコピーした CloudFormation のレスポンスと、ECR にプッシュした Docker イメージのタグです。例: REPLACE_ME_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/mythicalmysfits/service:latest

    task-defintion.json の値を置き換え、ファイルを保存したら、以下のコマンドを実行して、ECS で新しいタスク定義を登録します。

    aws ecs register-task-definition --cli-input-json file://~/environment/aws-modern-application-workshop/module-2/aws-cli/task-definition.json
  • A: Network Load Balancer を作成する

    新しいタスク定義を登録したら、サービススタックに必要なインフラストラクチャをプロビジョニングします。サービスをインターネットに直接公開するのではなく、Network Load Balancer (NLB) をプロビジョニングしてサービス層の前面に配置します。これにより、フロントエンドのウェブサイトのコードが通信を行う対象は単一の DNS 名のみになります。一方、バックエンドのサービスでは、需要に応じて、またはエラーが発生したり新しいコンテナのプロビジョニングが必要になったりした場合に、伸縮自在にスケールインとスケールアウトが実行されるようになります。

    新しい NLB をプロビジョニングするには、Cloud9 ターミナルで以下の CLI コマンドを実行します (保存してある CloudFormation の出力からサブネット ID を取得します)。

    aws elbv2 create-load-balancer --name mysfits-nlb --scheme internet-facing --type network --subnets REPLACE_ME_PUBLIC_SUBNET_ONE REPLACE_ME_PUBLIC_SUBNET_TWO > ~/environment/nlb-output.json

    このコマンドが正常に完了すると、nlb-output.json という新しいファイルが IDE に作成されます。DNSName、VpcId、LoadBalancerArn はこの後のステップで使用します。

    B: ロードバランサーのターゲットグループを作成する

    次に、CLI を使用して NLB ターゲットグループを作成します。ターゲットグループでは、ロードバランサーが受信したリクエストを転送するターゲットとして、AWS リソースを登録できます。サービスコンテナはこのターゲットに自動的に登録されるため、プロビジョニングされると NLB からトラフィックを受信できます。このコマンドでは vpc-id の値を置き換える必要があります。前のステップで保存した、CloudFormation から返された MythicalMysfitsCoreStack の出力に含まれる値を使用します。

    aws elbv2 create-target-group --name MythicalMysfits-TargetGroup --port 8080 --protocol TCP --target-type ip --vpc-id REPLACE_ME_VPC_ID --health-check-interval-seconds 10 --health-check-path / --health-check-protocol HTTP --healthy-threshold-count 3 --unhealthy-threshold-count 3 > ~/environment/target-group-output.json

    このコマンドが完了すると、IDE 内の target-group-output.json に出力が保存されます。TargetGroupArn の値はこの後のステップで参照します。

    C: ロードバランサーのリスナーを作成する

    次に、CLI を使用して NLB ロードバランサーのリスナーを作成します。このリスナーは、特定のポートで受信したリクエストについて、それらのリクエストが前述のターゲットグループに登録されているターゲットに転送される必要があるということを、ロードバランサーに通知します。指示された 2 つの値を、ターゲットグループの ARN と前のステップで保存した NLB の ARN で置き換えてください。

    aws elbv2 create-listener --default-actions TargetGroupArn=REPLACE_ME_NLB_TARGET_GROUP_ARN,Type=forward --load-balancer-arn REPLACE_ME_NLB_ARN --port 80 --protocol TCP
  • A: ECS のサービスにリンクされたロールを作成する

    これまでに ECS を使用したことがある場合は、このステップを省略し、次のステップに進むことができます。ECS を使用したことがない場合は、IAM で**サービスにリンクされたロール**を作成する必要があります。このロールにより、アカウント内で ECS API リクエストを作成するための権限が ECS サービス自体に付与されます。これが必要となる理由は、ECS にサービスが作成されると、このサービスがアカウント内で API を呼び出し、Docker イメージのプルやタスクの新規作成といったアクションを実行するためです。

    ロールを作成しないと、必要なアクションを実行する権限が ECS サービスに付与されません。ターミナルで以下のコマンドを実行し、ロールを作成します。  

    aws iam create-service-linked-role --aws-service-name ecs.amazonaws.com

    上記のコマンドで、ロールが既に存在しているというエラーが返された場合は無視してください。これは、過去にアカウント内でこのロールが自動的に作成されたことを意味します。

    B: サービスを作成する

    NLB の作成と設定が完了し、ECS サービスに適切な権限を付与したら、ECS で実際の**サービス**を作成できます。作成したサービスでは、コンテナの実行とコンテナのロードバランサーへの登録を行い、トラフィックを受信します。CLI コマンドへの入力として指定する JSON ファイルはあらかじめ `~/environment/aws-modern-application-workshop/module-2/aws-cli/service-definition.json` に用意されています。このファイルには、作成されるサービスに関する設定の詳細がすべて含められています。例えば、このサービスは **AWS Fargate** を使用して起動される必要あることが示されており、これは、ターゲットのクラスター内でサーバーをプロビジョニングする必要がないことを意味しています。コンテナはこのサービスで使用するタスクの一部としてスケジュールされ、AWS で完全に管理されるクラスター上で実行されます。

    IDE で ~/environment/aws-modern-application-workshop/module-2/aws-cli/service-definition.json を開き、REPLACE_ME と指示されている値を置き換えます。保存したら、以下のコマンドを使用してサービスを作成します。

    aws ecs create-service --cli-input-json file://~/environment/aws-modern-application-workshop/module-2/aws-cli/service-definition.json
    B: サービスをテストする

    NLB を作成したときに保存した DNS 名をコピーし、Cloud9 のプレビューブラウザで開きます (今回はサービスがインターネット上で利用可能なため、任意のウェブブラウザを使ってテストすることもできます)。以下のように指定して、Mysfits リソースにリクエストを送信します。

    http://mysfits-nlb-123456789-abc123456.elb.us-east-1.amazonaws.com/mysfits

    表示されたレスポンスが、前のステップで Docker コンテナを Cloud9 でローカルにテストしたときに受信した JSON のレスポンスと同じであれば、Flask API が AWS Fargate で稼働していることを示しています。

    注: この Network Load Balancer は、SSL/TLS 証明書がインストールされていないため、HTTP (http://) リクエストのみをサポートします。このチュートリアルでは、http:// のみを使用してリクエストを送信してください。https:// のリクエストは正常に動作しません。

  • A: API エンドポイントを置き換える

    次に、ウェブサイトを新しい API バックエンドと統合する必要があります。あらかじめ S3 にアップロードされているハードコードされたデータは使用しません。NLB と同じ URL を API コールにも使用するには、/module-2/web/index.html ファイルを更新する必要があります (パスに /mysfits は含めないようにします)。

    Cloud9 でファイルを開き、下記の反転表示されている引用符間を、NLB URL に置き換えます。

    before-replace

    貼り付けた後の状態は、以下のようになるはずです。

    after-replace
    B: S3 にアップロードする

    このファイルを S3 でホストされたウェブサイトにアップロードするため、モジュール 1 で作成したバケット名を再度使用して以下のコマンドを実行します

    aws s3 cp ~/environment/aws-modern-application-workshop/module-2/web/index.html s3://INSERT-YOUR-BUCKET-NAME/index.html

    モジュール 1 の最後で使用したものと同じ URL を使用してウェブサイトを開き、新しい Mythical Mysfits ウェブサイトを表示します。このウェブサイトは、AWS Fargate にデプロイされた Docker コンテナ内で実行されている Flask API から JSON データを取得します。

モジュール 2C: AWS のコードサービスを使用したデプロイの自動化

無事にサービスが稼働するようになりました。しかし、コードに変更を加えて Flask サービスに反映させたい場合があります。サービスに新しい機能をデプロイするたびに上記と同じステップをすべて実行しなければならないとなると、デプロイにかかる時間がボトルネックとなります。ここで、継続的インテグレーションと継続的デリバリー、つまり CI/CD の出番です。

このモジュールでは、完全マネージド型の CI/CD スタックを作成します。これにより、コードベースに対して行うすべてのコード変更が、前のモジュールで作成したサービスに自動的に配信されるようになります。

アーキテクチャ図

動的なウェブサイトアーキテクチャを構築する – Cloud9 -> コードツール -> Fargate
  • A: パイプラインアーティファクト用の S3 バケットを作成する

    CI/CD パイプラインの実行過程で作成される一時的なアーティファクトを保存するために、別の S3 バケットを作成する必要があります。これらのアーティファクト用の新しいバケット名を決めて、以下の CLI コマンドを使用してバケットを作成します

    aws s3 mb s3://REPLACE_ME_CHOOSE_ARTIFACTS_BUCKET_NAME

    次に、このバケットには、バケット内に保存されるデータに対する権限を定義するためのバケットポリシーが必要です。ただし、ウェブサイトバケットのようにすべての人にアクセスを許可するのではなく、CI/CD パイプラインにのみ、このバケットへのアクセス権を付与する必要があります。このポリシーを設定するために必要な JSON ファイルはあらかじめ ~/environment/aws-modern-application-workshop/module-2/aws-cli/artifacts-bucket-policy.json に用意されています。

    ファイルを開き、いくつかの文字列を置き換える必要があります。置き換える必要があるのは、前のステップで作成された MythicalMysfitsCoreStack の ARN と、新しく決めた CI/CD アーティファクト用のバケット名です。

    ファイルを修正して保存したら、以下のコマンドを実行して、バケットへのアクセス権を CI/CD パイプラインに付与します。

    aws s3api put-bucket-policy --bucket REPLACE_ME_ARTIFACTS_BUCKET_NAME --policy file://~/environment/aws-modern-application-workshop/module-2/aws-cli/artifacts-bucket-policy.json
    B:CodeCommit リポジトリを作成する

    コードをプッシュして保存する場所が必要です。これには、CLI を使用して **AWS CodeCommit リポジトリ**を作成します。

    aws codecommit create-repository --repository-name MythicalMysfitsService-Repository
    C: CodeBuild プロジェクトを作成する

    コードを保存するリポジトリと、CI/CD アーティファクト用の S3 バケットを指定して、サービスビルドを作成するためのステップを CI/CD スタックに追加してみましょう。これは、AWS CodeBuild プロジェクトを作成することで実現できます。ビルドの実行がトリガーされるたびに、AWS CodeBuild では、ビルドサーバーを使用中の構成に対して自動的にプロビジョニングし、Docker イメージをビルドして、作成した ECR リポジトリにそのイメージの新しいバージョンをプッシュするために必要なステップを実行します (その後、ビルドが完了すると、サーバーを停止します)。

    ビルドのためのステップ (Python コードをパッケージ化して Docker コンテナをビルド/プッシュする) は、~/environment/aws-modern-application-workshop/module-2/app/buildspec.yml ファイルに含まれています。buildspec.yml ファイルは、CodeBuild プロジェクト内でのビルドの実行に必要なステップを CodeBuild に指示するために作成するものです。

    CodeBuild プロジェクトを作成するには、CLI 用の別の入力ファイルが必要です。このファイルを、リソース固有のパラメータを使用して更新する必要があります。これは、~/environment/aws-modern-application-workshop/module-2/aws-cli/code-build-project.json に用意されています。前回の MythicalMysfitsCoreStackOutput のときと同じように、このファイル内の値を置き換えます。保存したら、CLI で以下を実行し、プロジェクトを作成します。

    aws codebuild create-project --cli-input-json file://~/environment/aws-modern-application-workshop/module-2/aws-cli/code-build-project.json
    D: CodePipeline のパイプラインを作成する

    最終的に、CodeBuild プロジェクトを使用して CodeCommit リポジトリを継続的に統合するための方法が必要です。これにより、コードの変更がリポジトリにプッシュされたときに自動的にビルドを作成できます。次に、新しくビルドされたアーティファクトを ECS のサービスに継続的に提供する方法が必要です。AWS CodePipeline は、これから作成するパイプラインでこれらのアクションをまとめて実行するサービスです。

    CodePipeline のパイプラインによって、上で説明したことがまさに実行されます。CodePipeline では、コードの変更が CodeCommit リポジトリにプッシュされるたびに、最新のコードを AWS CodeBuild プロジェクトに配信し、ビルドを作成します。CodeBuild によるビルドが成功すると、CodePipeline では、CodeBuild の実行によって ECR にプッシュされた最新のコンテナイメージを使用して、ECS に対するデプロイを実行します。

    これらのステップはすべて、パイプラインの作成時に AWS CLI への入力として使用する JSON ファイルで定義します。このファイルは、~/environment/aws-modern-application-workshop/module-2/aws-cli/code-pipeline.json に用意されています。ファイルを開いて必要な属性を置き換え、保存してください。

    保存したら、以下のコマンドを使用して CodePipeline でパイプラインを作成します

    aws codepipeline create-pipeline --cli-input-json file://~/environment/aws-modern-application-workshop/module-2/aws-cli/code-pipeline.json
    E: ECR イメージリポジトリへの自動アクセスを有効にする

    CI/CD パイプラインがエンドツーエンドで正常に実行されるために必要な最後のステップが残っています。CI/CD パイプラインを配置したら、コンテナイメージを ECR に手動でプッシュすることはできなくなります。そこで、今後は CodeBuild を使用して新しいイメージをプッシュします。

    ECR リポジトリポリシーを使用して、イメージリポジトリに対してアクションを実行するための権限を CodeBuild に付与する必要があります。ポリシードキュメントを更新して、指定された ARN を、MythicalMysfitsCoreStack によって作成された CodeBuild ロールのものに置き換える必要があります。ポリシードキュメントは ~/environment/aws-modern-application-workshop/module-2/aws-cli/ecr-policy.json に用意されています。

    このファイルを更新して保存し、以下のコマンドを実行してポリシーを作成します

    aws ecr set-repository-policy --repository-name mythicalmysfits/service --policy-text file://~/environment/aws-modern-application-workshop/module-2/aws-cli/ecr-policy.json

    ポリシーが正常に作成されると、ECS のサービスに対してコードの変更を自動的に配信するための、エンドツーエンドの CI/CD パイプラインが機能するようになります。

  • A: AWS CodeCommit で Git を使用する

    新しいパイプラインをテストするには、Cloud9 IDE で git を設定して CodeCommit リポジトリに統合する必要があります。

    AWS CodeCommit では git 用の認証情報ヘルパーが提供されており、これを使用することで簡単に統合できます。

    以下のコマンドをターミナルで連続して実行し、AWS CodeCommit で git を使用できるよう設定します (成功しても、いずれのコマンドからもレスポンスは返されません)。

    git config --global user.name "REPLACE_ME_WITH_YOUR_NAME"
    git config --global user.email REPLACE_ME_WITH_YOUR_EMAIL@example.com
    git config --global credential.helper '!aws codecommit credential-helper $@'
    git config --global credential.UseHttpPath true

    次に、ターミナルで以下のコマンドを実行して IDE のディレクトリを environment ディレクトリに変更します。

    cd ~/environment/

    これで、以下のターミナルコマンドを使用してリポジトリをクローンする準備ができました。

    git clone https://git-codecommit.REPLACE_REGION.amazonaws.com/v1/repos/MythicalMysfitsService-Repository

    コマンドの結果は、リポジトリが空であることを示しています。 以下のコマンドを使用してリポジトリのディレクトリにアプリケーションファイルをコピーし、これを解決します。

    cp -r ~/environment/aws-modern-application-workshop/module-2/app/* ~/environment/MythicalMysfitsService-Repository/
    B: コードの変更をプッシュする

    モジュール 2 で Fargate サービスを作成するために使用したサービスの完全なコードが、AWS CodeCommit から先ほどクローンしたローカルリポジトリに保存されています。変更をコミットする前に Flask サービスに変更を加え、先ほど作成した CI/CD パイプラインが機能しているか検証してみましょう。Cloud9 で、~/environment/MythicalMysfitsService-Repository/service/mysfits-response.json という名前で保存されているファイルを開き、Mysfit のいずれかの年齢を別の値に変更してファイルを保存します。

    ファイルを保存したら、以下のコマンドを実行して、新しいリポジトリのディレクトリに移動します

    cd ~/environment/MythicalMysfitsService-Repository/

    次に、以下の git コマンドを実行してコードの変更をプッシュします。

    git add .
    git commit -m "I changed the age of one of the mysfits."
    git push

    変更がリポジトリにプッシュされたら、AWS コンソールで CodePipeline サービスを開き、変更の履歴を見て、CI/CD パイプライン経由で処理が実行されていることを確認します。コードの変更をコミットした後、Fargate で実行されている本番サービスに変更がデプロイされるまでには 5~10 分ほどかかります。

    その間、AWS CodePipeline は、CodeCommit リポジトリに変更がチェックインされるとパイプライン実行のトリガーを編成し、CodeBuild プロジェクトをトリガーして新しいビルドを開始します。その後、CodeBuild によって ECR にプッシュされた Docker イメージを取得し、サービス内で実行されている既存のコンテナの接続ドレインに対して自動の ECS 更新サービスのアクションを実行して、新しくビルドされたイメージと置き換えます。ブラウザで Mythical Mysfits ウェブサイトをリロードし、変更が反映されていることを確認します。

    こちらの AWS CodePipeline コンソールでコード変更の進行状況を確認できます (操作は不要です。自動で処理が行われるのを確認してください)。

    これでモジュール 2 は終了です。

次は、Mysfit データの保存です。