Amazon Web Services ブログ
AWS Copilot CLI を使用した永続性を持つ AWS App Runner サービスの継続的ワークフローの実現
この記事は Enabling continuous workflows for AWS App Runner service with persistency using AWS Copilot CLI を翻訳したものです。
AWS は最近、AWS App Runner と呼ばれる新しいサービスを開始しました。これは、コンテナ化されたステートレスな Web アプリケーションを AWS でビルドして実行する最も簡単な方法です。App Runner は、ビルドパイプライン、ロードバランサー、スケールインとスケールアウト、そしてもちろんその基盤となるインフラストラクチャなど、コンテナを実行するために必要なすべてのリソースをプロビジョニングおよび管理します。
App Runner は Web 層の優れた抽象化レイヤーとして機能し、ステートレスな Web アプリケーションを最も簡単にデプロイして実行することができますが、外部の依存関係が必要になる場合があります。例えば、Web アプリケーションは、DynamoDB テーブルや S3 バケットなど、データ層として他の AWS リソースを必要とするかもしれません。
その必要なリソースをプロビジョニングして管理するには、どのような選択肢があるでしょうか?マネジメントコンソールや AWS CLI を使って作成しますか?それも一部のユーザーには有効ですが、一貫したデプロイメントのためには、より優れた方法が必要かもしれません。CloudFormation や Terraform のテンプレートをスクラッチから書くのはどうでしょうか?これにより、リソースを高度に構成管理することができ、継続的に管理できますが、明らかに簡単な作業ではありません。App Runner のベータ版ユーザーの一部からは、App Runner と同じくらいシンプルに依存するリソースを管理する方法を探しているというフィードバックがありました。
そこで Copilot の出番です。Copilot は AWS が作成したオープンソースのコマンドラインインターフェイスであり、もともとは開発者が Amazon ECS や AWS Fargate でプロダクションレディなコンテナワークロードを簡単に構築、リリース、および運用できるようにするために作成されました。Copilot では、わずかなコマンドで、アプリケーションの永続ストレージなどの外部の依存関係を作成することもできます。Copilot はバックグラウンドで CloudFormation を使用し、それらの依存関係を処理します。Copilot ユーザーが気にする必要があるのは、基盤となるインフラストラクチャについて考えたり管理することではなく、コンテナ化されたアプリケーションの「アーキテクチャ」だけです。
先に述べたように、App Runner はフルマネージドなビルドパイプラインを提供します。現在は、Node.js および Python アプリケーションにシームレスな “code-to-deploy” ワークフローを提供しますが、例えばユーザーによっては、コンテナをデプロイする前にユニットテストや統合テストを実行するといったより詳細な制御を行うために、マネージドなパイプラインではなく、独自のリリースパイプラインを持つことが重要な場合があります。Copilot はこのような場合にも役立ちます。いくつかのコマンドを実行するだけで、独自のカスタマイズ可能なパイプラインを作成できます。
AWS は App Runner の一般提供開始と同時に、App Runner をサポートする Copilot v1.7.0 をリリースしました。これにより、小規模な PoC アプリケーションから本番環境でのマルチリージョン、マルチアカウントのワークロードまで、Copilot を使ってコンテナ化されたアプリケーションを App Runner 上で実行できます。
これらがどのように連携して動作するのか、深く掘り下げてみましょう。このチュートリアルの最後には、以下の図のようなアーキテクチャができあがります。
ステップ 1 と 2 では、サンプルアプリケーションを実行するために、App Runner や DynamoDB など最低限必要なリソースをセットアップしてデプロイします。その後、ステップ 3 で AWS CodePipeline を使用してパイプラインを構成し、ステップ 4 で “push-to-deploy” を試して、すべての要素が期待どおりに連携することを確認します。チュートリアルでは、特に App Runner の使用と DynamoDB テーブルに対して料金が発生する場合があることに注意してください。
Copilot CLI を使用して App Runner で Next.js アプリケーションをビルドしてデプロイする
前提条件
- Copilot v1.7.1 以降 (必要に応じてインストールガイドを参照)
- Docker Desktop (または Linux 環境では Docker Engine)
jq
- “hello-app-runner-nodejs” GitHub リポジトリのフォーク
- このチュートリアルのステップ 4 で “push-to-deploy” を試すには、フォークした自分のリポジトリが必要になるため、Push が許可されているフォークしたリポジトリを使っていることを確認してください
0. フォークしたリポジトリをクローンする
1. Copilot の Application を作成する
Copilot のバイナリがない場合や古い場合は、Copilot のドキュメントに従ってインストールまたはアップデートしてください。
“test” Environment をプロビジョニングする
この時点で、 “test” Environment の作成に進むかどうかを尋ねられます。 “y” (Yes) を選択して次に進みます。
なお、Copilot は、最初に Copilot の Application の Service で共有するインフラストラクチャを保持するための Environment を作成します。App Runner は VPC や Amazon Elastic Container Service (Amazon ECS) クラスターを必要としませんが、Copilot はデフォルトでこれらの料金が発生しないリソースを作成します。これにより、コンピュートに選択した App Runner または Amazon ECS 間で、同じ Environment 内でシームレスなワークフローを実現することができます。
デプロイされたアプリを Web ブラウザで確認する
お好みの Web ブラウザで App Runner サービスのエンドポイントを開きます。エンドポイントの URL は、前のコマンドの出力の最後にあります (https://<ランダムな文字列>.<AWS リージョン>.awsapprunner.com という形式です) 。
開いてみると、アプリがデータの読み込みに失敗しているのがわかります。これは、この時点で DynamoDB テーブルがプロビジョニングされていないためです。
さて、それでは次のステップで DynamoDB テーブルをセットアップしましょう。
2. DynamoDB テーブルをセットアップする
先に進む前に、copilot storage init
コマンドは実際には AWS リソースをプロビジョニングせず、ローカルのワークスペースに構成ファイルを作成するだけであることを理解しておくとよいでしょう。具体的には、このケースでは ./copilot/my-svc/addons/Items.yml
を作成します。そのため、次のステップでは copilot deploy
コマンドを使用してプロビジョニングを行います。
上記のターミナル出力の最後で、Copilot が App Runner サービスに自動的に挿入する ITEMS_NAME
という名前の環境変数を介して、アプリケーションが DynamoDB テーブル名を参照できることに気付いたかもしれません。
次に、依存リソース (この場合は DynamoDB テーブルと IAM ロール) をプロビジョニングし、新しい環境変数 “ITEMS_NAME” を使用するようにサービスを更新しましょう。
初期データを DynamoDB テーブルにシードする
プロビジョニングされた DynamoDB テーブルはもちろんまだ空っぽなので、次のコマンドを実行してシードしましょう。
ワークスペースに npm
がない場合は、代わりに ./seed/seed.sh
を実行してください。なお、このスクリプトを正常に実行するには、jq
コマンドが必要です。
デプロイされたアプリを Web ブラウザで確認する (再度)
お好みの Web ブラウザアプリケーションで App Runner サービスのエンドポイントを開くか、前のステップで開いた Web ページをリロードします。前のステップで行ったように、ターミナルの出力から (またはもちろん App Runner マネジメントコンソールから) エンドポイント URL を取得することもできます。
おめでとうございます!これで今度は DynamoDB テーブルから読み込んだデータを使って、アプリが正常に動作するようになりました ?
最初の項目を開きましょう。 “Getting Started with App Runner using Copilot” です。
最初の項目では、このステップバイステップガイドでこれまでに完了したことを説明しています。
Copilot を使用していくつかのリソースを作成したので、次に進む前に、マネジメントコンソールで App Runner サービスという主要コンポーネントを少し詳しく見て、App Runner サービスがどのように見えるかを理解しましょう。
まず、Web ブラウザの新しいタブで AWS マネジメントコンソールの App Runner を開き、サービス名 “my-app-test-my-svc” をクリックして詳細を開きます。ご覧の通り、 “Default domain” として何度もアクセスしているエンドポイント、ECR リポジトリへのダイレクトリンク、そして Logs や Metrics、Custom domains などの複数のタブが表示されています。
“Logs” タブを見ると、複数のセクションがあります。1 つめは “Event log” です。これは、App Runner サービスの最新のライフサイクルイベントを表示します。次は “Deployment logs” で、デプロイメント毎に分離されたログストリームを表示します。最後は “Applocation logs” です。これは、App Runner 上で動作する Web アプリケーションからの実際のログです。この “Application logs” をクリックして開いてみましょう。
ログは CloudWatch Logs に保存され、コンソールにはインスタンスからの最新のログが結合されて 1 つのログストリームに表示されています。次のスクリーンショットでは、最初のインスタンスが “Missing required key ‘TableName’ in params” というエラーログを生成しています。これは、最初に DynamoDB テーブルなしでアプリケーションをデプロイしたため、その時点では TableName 変数がなかったためです。また、 “Using webpack 5. Reason: …” の行では、新しいインスタンスが起動していることがわかります。これらが、App Runner で現在実行しているインスタンスのログです。
この記事の冒頭で述べたように、Copilot はバックエンドとして CloudFormation を使用して AWS リソースをプロビジョニングおよび管理します。そこで、AWS マネジメントコンソールの CloudFormation セクションで、CloudFormation スタックを簡単に見てみましょう。CloudFormation を開いたら、 “Stacks” リストから “my-app-test-my-svc” スタックを選択します。
以下のページは “Template” タブから開くことができます。これはローカルのワークスペースにある ./copilot/my-svc/manifest.yml
から Copilot が生成した実際の CloudFormation テンプレートです。AWS::AppRunner::Service CloudFormation リソースの定義があり、リソース定義で “ITEMS_NAME” という名前の環境変数を見つけることができます。
上記の環境変数 “ITEMS_NAME” の値は他のスタックの出力、この場合は次のスクリーンショットに示すように “my-app-test-my-svc-AddonsStack-O2629IALDI8H” として表示されるネストされたスタックを参照しています。
アドオンスタックとその CloudFormation テンプレートも、Copilot が ./copilot/my-svc/addons/Items.yml
から作成したものです。YAML ファイルを参照して、前のステップで回答したいくつかの質問と “better by default” の原則で、Copilot が複雑なリソースをどのようにカバーし、抽象化しているかを知るのもよいでしょう。
さて、話を戻しましょう。
Web アプリの最初の項目のページがまだ Web ブラウザに表示されていると思います。それでは、 “Back to home” リンクをクリックしてトップページに戻り、2 番目の項目 “3. Set-up Release Pipeline” を開いて次のステップに進みましょう。
3. リリースパイプラインを設定する
開いた Web ページで説明されているように、2 つの Copilot コマンドを使用して CodePipeline でリリースパイプラインを作成します。
まず、copilot pipeline init
コマンドを実行して、構成ファイルを生成します。このファイルは、前のステップで簡単に確認した manifest.yml
に似ていますが、今回はパイプライン用です。
では、./copilot/pipeline.yml
ファイルを見てみましょう。
このチュートリアルではこのファイルを編集しませんが、例えば、いくつかのテストを追加したい場合には、ファイルの最後にある test_commands 行のコメントを解除できます。詳細な仕様については、Copilot のドキュメントを参照してください。
続いて、copilot pipeline update
を実行して、AWS アカウントに CodePipeline のパイプラインを作成します。
ここで、CodePipeline がリポジトリにアクセスできるようにするために、次のターミナル出力で説明されているように手動でアクションを実行する必要があります。
AWS アカウントにすでにサインインしている Web ブラウザの新しいタブで、コンソールの CodeSuite Connections を開きます。
接続名をクリックして詳細ビューに移動します。
“Update pending connection” ボタンをクリックすると、”Connect to GitHub” というタイトルのポップアップウィンドウが表示されます。
すでに GitHub Apps に接続している場合は、拡大鏡アイコンの横にある入力にフォーカスを当てると、既存の GitHub Apps がドロップダウンメニューで表示されます。
< リポジトリにアクセスできる既存の GitHub App がある場合 >
いずれかを選択し、 “Connect” をクリックします。少し下の “Copilot のステータスを確認する” セクションまで進んでください。
< リポジトリにアクセスできる既存の GitHub App がない場合 >
“Install a new app” ボタンをクリックすると、GitHub の Web ページが表示され、フォークしたリポジトリが属する GitHub ネームスペースを選択できます。
GitHub ネームスペースを選択したら、Web ページに従って GitHub App を作成または更新して、GitHub リポジトリへのアクセスを許可します。GitHub App ページの “Repository access” の項目で “Only select repositories” を選択した場合は、選択したリポジトリとして “hello-app-runner-nodejs” を選択する必要があります。
GitHub のページの “Save” ボタンをクリックすると、再び AWS マネジメントコンソールにリダイレクトされます。
これで入力に数値が入ったので、 “Connect” ボタンをクリックします。
Copilot のステータスを確認する
copilot pipeline update
を実行したターミナルに戻ると、以下のようにパイプラインの作成に成功したことが表示されているはずです。
CodePipeline でリリースパイプラインを作成したので、Web アプリケーション の Web ページの左下にある “Back to home” リンクをクリックします。
次のステップでは、作成したばかりのパイプラインを使用して “push-to-deploy” を試してみましょう。
4. “push-to-deploy” を試す
リポジトリ内の何かを編集し、それを Push してパイプラインを起動しましょう!
テキストを変更したら、それを保存し、ターミナルウィンドウで次のコマンドを実行します。
すべて完了です!Web ブラウザの新しいタブで、https://<AWS リージョン>.console.aws.amazon.com/codesuite/codepipeline/pipelines
にあるコンソールの CodePipeline にアクセスし、リストの中のパイプラインを開きます。以下のような表示になります。
パイプラインがすべてのステージを正常に完了するまで数分待ってから、Web アプリケーションの Web ページの左下にある “Back to home” リンクをクリックし、トップページに戻ります。
おめでとうございます ? ご覧のとおり、私たちが行った変更は、パイプラインを介して正常にデプロイされました!
これで、git push で呼び出すことができる構成可能な継続的デリバリーパイプラインができました。追加のコミットを Push して、サンプルアプリがどのように動作するかを確認することもできます。
5. お掃除する
これが最後の (オプションですが重要な) ステップです。予期せぬ課金を避けるために、プロビジョニングされたリソースをすべて削除することをお勧めします。
Copilot を使用すれば、このチュートリアルで AWS アカウントに作成したすべてを削除することも簡単です。これを行うには、次のコマンドを実行します。
おつかれさまでした!
さらに学ぶためのリソース
AWS App Runner や AWS Copilot CLI について学ぶためのリソースが他にもありますので、ぜひチェックしてみてください。
- Introducing AWS App Runner | Containers (日本語訳: AWS App Runner のご紹介)
- AWS Copilot ドキュメント
- AWS App Runner ドキュメント
- AWS App Runner Workshop
- ✨ AWS App Runner Public Roadmap at GitHub ✨ – 最新のロードマップアイテムを見たり、要望やフィードバックを App Runner チームに直接伝えることができます!
App Runner と Copilot で Happy Building! ?
翻訳はプロフェッショナルサービスの杉田が担当しました。