Amazon Web Services ブログ
AWS AmplifyでのフルスタックアプリケーションのCI/CDパイプラインの構築
この記事は、Complete guide to full-stack CI/CD workflows with AWS Amplifyを翻訳したものです。
AWS Amplify は、1) 条件付きバックエンドデプロイ、2) ビルド時のaws-exports.js の自動生成、3) 異なるAmplify アプリケーション間でのバックエンドの共有といった3つの新しい機能をAmplify のCI/CD ワークフローに追加しました。これらの機能を使用することで、より柔軟にフルスタックアプリケーションをデプロイすることが可能です。
AWS Amplify は、フルマネージドな CI/CD およびホスティングサービスを提供し、開発者は Git リポジトリを接続するだけで、シングルページアプリケーション(SPA)またはサーバーサイドレンダリング(SSR)のフロントエンドアプリケーションをデプロイすることができます。また、自動的にビルドされたウェブアプリケーションはCloudFrontを利用することで、グローバルに配置されたエッジローケーションにデプロイされます。さらに、Amplify は認証、リアルタイムデータ、ファイルストレージ、AI/ML等のAWSのサービスを簡単に構築し、接続することができます。AmplifyのCI/CD ワークフローは、機能・デプロイステージ毎にブランチを分割することで、それぞれのブランチ毎に環境を完全に分割することができます。また、Amplifyアプリケーションはフロントエンドとバックエンド(任意)を同一のリポジトリで管理することができるので、同一ライフサイクルでデプロイすることができます。
サンプルアプリケーション(React)のデプロイ
このブログではcreate-react-app
を使用して作成したシンプルなReactアプリケーションのサンプルを以下のボタンをクリックし、Amplify Consoleでデプロイします。
上のボタンをクリックすると、Amplify Consoleの画面に遷移するので、画面の指示に従って、GitHubアカウントとの連携及び、Service Roleを作成し、[Save and deploy]を選択します。すると、自動的にReactのサンプルアプリケーションが自身のGitHubアカウントにフォークされ、自動でビルド・デプロイが実行されます。
これだけで、上図のように CI/CD パイプラインがトリガーされ、数分でフォークしてきたリポジトリのメインブランチが amplifyapp.com
のドメインでホストされます。
続いて、Admin UI で、[Data] タブに移動し、GraphQLのスキーマを構築します。この例では、description
というフィールドを持つ Todo
という名前のデータモデルを作成します。[Save and deploy] を押すと、データにアクセスするための AWS AppSync GraphQL API や 定義したTodo アイテムを保存するための Amazon DynamoDB テーブルなど、バックエンドに必要な AWS リソースがすべて自動的に作成されます。Amplify は 透過的にCloudFormation を使用し、バックエンドの定義をInfrastructure-as-Code(IaC)として管理・デプロイします。
フロントエンドアプリケーションからバックエンドと接続する
Admin UIで作成したバックエンドにフロントエンドアプリケーションから接続するには、Amplify CLI をインストールし、amplify pull —appID XXX —envName staging
を実行して、バックエンド定義をプロジェクトに取り込む必用があります。これだけで、フロントエンドからバックエンドへ接続するための設定が完了します。続いて、Amplify が提供する DataStore という、リアルタイムおよびオフラインサポートが組み込まれた、クライアントライブラリを使用して、DynamoDBとデータのやり取りをしてみましょう。DataStoreを使用することで、GraphQLのQueryを書くことなく、直感的な APIでDynamoDBとデータのやり取りをすることが可能です。 DataStoreについて更に詳細を知りたいという方はこちら を参照ください。DataStoreを使用したサンプルアプリケーションのコードは、フォークしたリポジトリのsrc/App.js
から確認することができます。(フォーク元のコードはこちら)
CI/CD パイプライン外からデプロイされたブランチをバックエンドに接続する (aws-exports.js の自動生成)
続いて、アプリケーションを更新してみましょう。git push
を実行して、Amplify コンソールのビルドトリガーを確認するとCannot find file './aws-exports' in ./src
というエラーが発生し、ビルドが失敗していることが確認できます。これは、Amplifyの設定ファイル である aws-exports.js
がビルドに使用するソースに含まれていないためです。Amplify CLI はプロジェクトを作成した段階で aws-exports.js
を.gitignore
に自動的に追加し、生成されたファイルに関連するコンフリクトを防止します。
新しいアップデートによってこの問題は解決することができます。aws-exports.js
を.gitignore
に追加していても、 Amplify Consoleでのビルド時 に aws-exports.js
を自動生成してくれるようになりました。Amplify Consoleの[Frontend environments]タブのブランチ名の下にある [Edit] を押して、staging
バックエンドに接続してみましょう。
これにより、ターゲットバックエンドに接続するように求めるモーダルが開きます。現在の設定では staging
環境をサンドボックス環境として使用し、バックエンドは手動でプッシュすることによって更新する設定となっています(バックエンドの更新は、1) Admin UI 、 2) CLIから amplify push
を実行すの2つの選択肢があります)。まずはフルスタック CI/CD を有効にするチェックボックスをオフにします。そうすることで、ビルド時に自動的にバックエンドの更新が行われなくなり、 aws-exports.js
が自動生成されます。[Save] を押す前に、Amplify がバックエンド設定にアクセスするために必要なサービスロールの設定をするための手順が確認できるので、指示にしたがってサービスロールをセットアップします。
IAM のコンソールにてロールの作成が完了したら、[App settings] > [General] > [Edit] に移動し、ドロップダウンから作成したサービスロールを選択します。
続いて、CI/CDパイプラインをトリガーさせるために、コードをpush、もしくはビルドの詳細ページで [Redeploy this version] を選択して、新しいビルドをトリガーします。このビルドではバックエンドに更新が発生しないため、エラーは発生しないはずです。次に、フロントエンドアプリケーションにアクセスしてデータを作成してみてください。データがブラウザとAdmin UI の [Content] タブに正常に表示されるはずです。
本番環境のデプロイパイプラインの設定
ここまでで、staging
ブランチを正常にデプロイし、データベースをセットアップし、CI/CDパイプラインを使用せずに手動でデプロイしたフロントエンドのブランチ(main
)にバックエンド環境(staging
)を接続しました。staging
環境に対しても、 Admin UI からデータモデルの変更や、認証等の新しい機能の追加を簡単に追加することができます。しかし、本番環境において必要なワークフローでは話が変わってきます。例えば、Admin UIから手動でデータモデルを変更することで、本番環境で動作するアプリケーションに直接的に影響してしまうことも考えられます。そのため、本番環境へのデプロイは常に CI/CD パイプラインを介してデプロイされ、アプリケーションに直接的に影響を与える可能性があるバックエンド環境の変更は、安全のため、本番環境とは独立した環境でテストすることが望ましいです。
Amplifyを使用することで、そういった本番環境用のデプロイフローに関しても簡単に作成することができます。まず、ステージング環境のクローンを作成し、prod
という名前を付けます。クローンすることで、内部で(独自の CloudFormation スタックを使用して)まったく新しいアプリケーションのバックエンドを作成するため、多少時間がかかります。
デプロイが完了すると、本番環境用の、prod
環境に独立した、新しいデータベースとGraphQL API が作成されているのが確認できます。
続いて、本番用フロントエンドブランチをセットアップしてみましょう。git リポジトリに prod
という名前のブランチを作成し、Amplify コンソールから prod
ブランチを接続します。今回は、フルスタック用の CI/CD 設定をオンのままにして prod
ブランチを prod
バックエンド環境に紐付けます。これにより、/amplify
フォルダー 内で変更が検知された場合、Amplify Consoleにそれらの変更をデプロイする権限が与えられます。
これで、本番環境を管理するためのセットアップが完了し、最終的に、本番環境に新しい変更を加えるためのワークフローは以下の様になります。
staging
環境でデータモデルに新しいフィールドを追加するamplify pull
をローカルのmain
ブランチで実行してmain
ブランチのAmplifyプロジェクトのバックエンド設定を更新するmain
ブランチにコードをプッシュする — アプリのバックエンド設定を変更すると、新しいフィールドへの参照を含む/amplify
フォルダ配下の増分フォルダーに対しても更新が適用されます。- プルリクエストを送信して
main
ブランチの変更をprod
ブランチにマージします。 プルリクエスト をレビューし、新しく変更した部分に問題がないかを確認します。この際、ユニットテストだけでなく、バックエンド環境との統合部分のテストを含めた、エンドツーエンドでのテストが実施されることが理想的です。 - 変更を
prod
にマージします。 これにより Amplify Consoleの CI/CD のビルドがトリガーされます。これで、新しいフィールドがprod
データモデルにも表示されるようになります。
条件付きバックエンドビルド
Amplify では全ブランチにおいて、条件付きバックエンドビルドを有効化することが可能です。この機能は現在、環境変数 AMPLIFY_DIFF_BACKEND
を true
にすることでオプトインすることができます。Amplify CI/CD ビルドシステムはビルド時にバックエンドの変更を検知し、変更が検出されない場合はバックエンドのビルドをスキップします。これにより、フロントエンドにのみ変更が加えられる様なビルドをスピードアップすることができます。
では実際に試して見ましょう。 App.js
をエディターで開き、フロントエンドのコードを少し変更してみます。
変更を Git リポジトリにコミットして、新しいビルドをトリガーします。すると、バックエンドのビルドがスキップされたというログが確認できるはずです。
複数のフロントエンドで同じバックエンドリソースを共有する
Amplifyでは、複数のフロントエンドで同一のバックエンドを再利用することが可能です。一般的なユースケースとしては、マイクロフロントエンドを構築するチーム、あるフレームワークから別のフレームワークへ のWeb アプリケーションの移行、モノリポでの作業等です。このワークフローをテストするために、別のリポジトリを接続してアプリケーションをデプロイしてみます(バックエンドなし)。デプロイを実行したら、以前と同様に [Edit] ボタンを選択し、モーダル内の [backend environment from a different app] を選択します。このように、別のクライアントアプリから同一のバックエンド環境に接続する場合は、フルスタック CI/CD 機能を有効にしないことが推奨されます。
参考リンク
翻訳は Solutions Architect の鈴木が担当しました。原文はこちらです。