概要
Githubと連携させたAmplifyを使用したいが、WAFによるアクセス制限もしたい。
しかし、WAFがAmplifyをサポートしておらず苦戦したので、メモしておきます。
TL;DR
Amplify Consoleで構築したものに対してWAF適用しました。
構築内容
-
CloudFrontを前段に配置してWAFを適用する
-
OriginにAmplifyのEndpointを設定する
-
Amplify側への直アクセスも制御
-
ループ防止の設定をする
Amplifyに関して
Amplifyのメリット
SPA、静的コンテンツなどを新規サービスとして配信時、スピード感を持って構築できます。
-
例えば、S3に配置したい静的ファイルをGithubのコミットから直接更新出来る
-
複数の開発環境をブランチベースで用意することが出来て管理しやすい
-
認証機能がコンソールで実装できる
-
Amplify側のエラー処理やルーティング設定などをコンソールから開発者ができる
などのメリットがあります。
Amplify自体の構築パターン
Amplifyには構築方法が何パターンかあります。
- Amplify Console
マネジメントコンソールからの構築です。今回はこちらを使用しました。
理由は、開発者が最も容易に設定をいじれるという点に尽きます。
また、GitHubリポジトリとの連携やリダイレクト機能なども利用できます。
Basic 認証を付与することもコンソールからできるので非常に便利だと思います。
作成すると、デプロイされたAmplify環境のURLが発行されます。
尚、この構築方法ではAmplifyのインフラ部分が自動構築になるため
CloudFrontやS3がAWSコンソール上から見えないのですが、内部はCloudFront+S3などで出来ます。
WAFが使えないのであれば自分で前段においてしまおうというパターンをこの記事では記載します。
- Amplify CLI
npm install -g @aws-amplify/cli
でamplify cliから対話形式で構築内容を入力すると、CloudFormaitonが自動的に立ち上がり
CloudFrontやS3が構築されていきます。(amplify-***という名前のスタック)
この方法でCloudFront + S3を使用すると、GitHubリポジトリ連携が出来ません。
ただし、他のCICDツールを利用することでリポジトリのコードを更新した際に自動的にamplify publishコマンドが実行されるような仕組みを構築すれば、自動デプロイを実現することは可能みたいです。
構築例
amplify init
※環境によりこのあたり参考
-> amplify add hosting (CloudFront + S3でHTTPSパターンを選択)
-> amplify publish
Amplifyを使用するかはケースバイケース
大前提の話ですが、CodePipelineなどのCDツールを使用してデプロイする方法もあります。
Amplifyには制約があるので、この辺は手法によりそれぞれのメリットがあるため開発者で決める必要があります。
今回はあくまで「Amplifyを選んだがアクセス制限を基本機能に加えて実現したい場合」の手法です。
要件例
こんな要件のときに、今回の記事に記載する構築手法を用いられます。
・Githubリポジトリと連携がされており、自動デプロイ出来る
・WAFでアクセス制御が出来る
・CloudFrontは運用時のカスタマイズ性を考慮し、CloudFrontはマネジメントコンソールで管理出来る
・Amplifyの基本機能を使用したい=コンソールからリダイレクトや環境変数などの設定が出来る
アーキテクチャー例
Amplify Consoleで構築して前段にCloudFrontとWAFをおいた場合の部分構成図です。
Amplify側のアクセス制限
厳密にいうと、このアーキテクチャは穴があります。
AmplifyのエンドポイントはPublic状態であるため、もしEndpoint情報がさらされた場合は直接アクセスをされる可能性が大いにあります。せっかくの前段環境を通過される危険性があります。
CloudFront+S3をOAC/OAIなどで制限するような方法が、
CloudFront+Amplifyパターンにも無いのかという点ですが
代替案の一つとして、認証+ヘッダー制御の方法があります。
具体的には、Basic認証をAmplifyでかんたんに設定することができるため
あとは認証情報をCloudFrontのBehaviorで渡してあげます。
これでアクセスしたユーザはBasic認証情報を入力することなくサイト閲覧ができます。
設定方法
要点を重視した簡易手順です。
Amplifyアプリ作成
AWSマネジメントコンソールの、Amplify Consoleから作成。
Githubリポジトリ連携もします。
まずは単体での動作確認をします。
「ウェブアプリケーションをホスト」
->「リポジトリブランチの追加」ブランチ選択
-> 環境変数があれば設定後、次へ
-> 保存してデプロイ
待機し、デプロイまで完了したら
全般 -> 本番稼働ブランチURL にアクセスして、まずは単体で動作確認
前段のCloudFrontとWAFを作成
前段に置くCloudFrontを構築します。
管理化にできるリソースなのでTerraformで構築してもOKです。
構築に際しては特記事項はありません。
Amplifyを接続
CloudFrontディストリビューション構築後、AmplifyをOriginに登録します。
オリジン -> オリジンを作成 にて
「オリジンドメイン」項目にAmplifyの本番稼働ブランチURLを登録
Behavior設定でも*などでパス登録し、デプロイ後問題なくアクセスできることを確認します。
これでAmplifyアプリケーションの前段に、管理可能なCloudFrontとWAFを配置できました。
CloudFrontに対しては通常通りドメイン設定や別環境の連携も出来ます。
Amplifyに直接アクセスさせないように制御する場合
先に、AmplifyでBasic認証を設定します。
その後、Amplify単体で認証要求されること、アクセスできることを確認したら
先程のCloudFrontオリジン設定のカスタムヘッダー設定にて
先程の認証情報をBase64形式エンコードをした状態で付与します。
※ Authorization: Basic ${BASE64エンコード済のユーザ名:パスワード}
ディストリビューション側のデプロイタイムが終わったら再度アクセスして完了です。
これでIP制限やWAFRuleの適用ができるようになりました。
ループ防止
内部的に多段CloudFrontなので、以下の環境変数をAmplify側に入れて完了です。
_DISABLE_L2_CACHE: true