本記事は
年度末の振り返りウィーク
2日目の記事です。
🌸
1日目
▶▶ 本記事 ▶▶
3日目
📅

はじめに
こんにちは!振り返りウィーク2日目担当の山本です!
みなさんアプリやウェブサイト構築にAmplifyを使ったことはあるでしょうか?
Amplifyは、GitHubやBitbucketなどのGitリポジトリと連携することで、 コードの変更をトリガーにビルドからデプロイまでを自動化できるフロントエンド向けのホスティングサービスです。 フロントエンドのCI/CD環境を比較的簡単に構築できるため、手軽に利用できるサービスの一つです。
今回、Amplifyを利用したフロントエンドのホスティング環境を構築するにあたり、インフラ構成をコードで管理する目的でCloudFormationを利用して環境を構築しました。
実際に構築を進めてみると、Amplify自体はシンプルに利用できるサービスである一方、CloudFormationで管理する場合にはいくつか意識しておきたいポイントがあることに気付きました。特に、サービスの内部構成や認証情報の管理方法などは、コンソールで設定する場合にはあまり意識しない部分でもあります。
この記事では振り返りとして、AmplifyをCloudFormationで構築する中で気を付けた点や意識した点をまとめます。
構築した構成
今回の構成では、フロントエンドのホスティング環境をAmplifyとBitbucketで連携するよう構築し、インフラリソースの管理にCloudFormationを使用しています。 これにより、環境の再現性を確保しつつ、設定変更もコードベースで管理できるようになります。

AmplifyはGitリポジトリと連携することで、コードの変更をトリガーにビルドとデプロイを自動で実行します。基本的な流れは次のようになります。
Gitリポジトリにコードをpush
Amplifyがビルドを実行
ビルド成果物をホスティング
CDN経由でコンテンツを配信
本稿では、このような構成をCloudFormationで管理する際に、実際に構築してみて意識したポイントについて紹介していきます。
ポイント①WAFの関連付けはus-east-1で作成する
まず前提として、Amplify Hostingは内部的にCloudFrontを利用してコンテンツを配信しています。 そのため、Amplifyに対してWAFを適用する場合はCloudFront用のWAFを利用することになります。 CloudFront用のWAFはグローバルリソースとして扱われるため、us-east-1(バージニア北部)リージョンで作成します。
ここでのポイントは、AmplifyのアプリケーションにWAFを関連付けるためには、 us-east-1リージョンのスタックに関連付け設定を記述する必要があるということです。
# AmplifyへのWAF関連付け設定
WafAssociationToAmplify:
Type: AWS::WAFv2::WebACLAssociation
Properties:
ResourceArn: {AmplifyアプリケーションのARN}
WebACLArn: {WAFのARN}
CloudFrontではWAFを関連付けるためのCloudFormationプロパティがありますが、AmplifyではそういったCloudFormationプロパティはサポートされていないため公式ドキュメントを参考に適切に関連付けの設定を行いましょう。
ポイント②リポジトリ接続時のアクセストークン
AmplifyをGitリポジトリと連携して利用する場合、リポジトリへのアクセスのためにアクセストークンをプロパティで設定する必要があります。
CloudFormationテンプレートでは、AWS::Amplify::Appリソースのプロパティで指定できます。
使用するGitサービスによって記述するプロパティが異なることに注意してください。
使用するプロパティの使い分けは以下の通りです。
※GitHubで組織アカウントを利用している場合は管理者によってPersonal access tokens(PAT)を利用したリソースへのアクセスが制限されている場合があります。
| Gitサービス | プロパティ名 | 発行者 |
|---|---|---|
| GitHub | AccessToken | 各ユーザ |
| Bitbucket・CodeCommit | OauthToken | ワークスペース管理者 |
ここでのポイントはBitbucketで使用するトークンの設定は"管理者権限を持ったユーザ"ではなく"管理者ユーザ"で行う必要があるという点です。
管理者権限を持ったユーザでは設定欄からトークンを有効化する項目が表示されないため私はここでハマりました。。。
また、テンプレートにトークンを直接記述する方法はあまり推奨されないため、 Secrets ManagerやSystems Manager Parameter Storeにトークンを保存し CloudFormationから参照する形にすることで、機密情報をテンプレートから分離して管理できます。 どうしてもパラメータで渡す場合は、プロパティでNoEchoを指定してマネジメントコンソールから閲覧できないようにしておきましょう。
ポイント③シークレットをビルドで使う
Amplifyではビルド処理の中でAPIキーや外部サービスのトークンなど、シークレット情報を利用するケースがあります。 このような情報を安全に扱うためには、Amplifyのシークレット機能を利用する方法が一般的です。 Amplifyではブランチごとにシークレットを設定でき、ビルド時には環境変数として参照できます。
ここでのポイントはAmplifyで設定したシークレットは以下の命名規則でSystems Manager Parameter Storeに保存されることです。
全てのブランチで共通な場合:/amplify/shared/<app-id>/<secret-key>
特定のブランチで利用する場合:/amplify/<app-id>/<branch-name>/<secret-key>
ただし、管理自体はAmplify側でマネージドに行われるためマネジメントコンソールから該当のリソースを直接参照することはできません。
ビルド設定ファイル(amplify.yml)では、次のようにCLIでコマンドを叩くことによって取得することができます。
version: 1
frontend:
phases:
preBuild:
commands:
# 共通のシークレット
- export COMMON_API_KEY=$(aws ssm get-parameter --name "/amplify/shared/${AWS_APP_ID}/COMMON_API_KEY" --with-decryption --query Parameter.Value --output text)
# 特定ブランチのシークレット
- export SPECIFIC_API_KEY=$(aws ssm get-parameter --name "/amplify/${AWS_APP_ID}/${AWS_BRANCH}/SPECIFIC_API_KEY" --with-decryption --query Parameter.Value --output text)
build:
commands:
- npm run build
artifacts:
baseDirectory: public
files:
- '**/*'
おわりに
AmplifyはGitリポジトリと連携するだけでビルドからデプロイまでを自動化できる非常に手軽なフロントエンド向けホスティングサービスです。
一方で、CloudFormationを使ってIaCとして管理する場合、コンソール操作ではあまり意識しなくてもよい前提や制約を理解しておく必要があると感じました。
今回構築を進める中で、WAFのリージョン制約やリポジトリ連携時の認証情報の扱い、ビルド時に利用するシークレットの管理方法など、設計段階で押さえておくべきポイントがいくつか見えてきました。これらは事前に把握していないと実装中に手戻りやハマりポイントになりやすい部分でもあります。
Amplifyは「簡単に使える」サービスだからこそ、CloudFormationで管理する場合には内部構成や仕組みを理解した上で設計することが重要だと感じました。
本記事を通して、AmplifyをCloudFormationで管理する際に押さえておきたいポイントを一緒にマスターしていきましょう。
執筆者 : 山本将望
食べることが生きがいのインフラエンジニア
執筆記事一覧 :
https://tech.nri-net.com/archive/author/m4-yamamoto