CloudFrontに複数オリジン(API GatewayオリジンとS3オリジン)の設定

  • 0
    いいね
  • 0
    コメント

    概要

    API Gatewayを使うとき手が届かないむずかゆいところがたくさんあります(HTTPSのみしか受け付けないとか、前段にWAFおけないとか)。
    そのときに使われるのがCloudFrontになりますが(もちろん、API Gateway内部にCloudFrontが暗黙的に使われており、多段CloudFrontになるため遅延が大きいというのは承知)、API Gatewayの前段用にCloudFront使うのもなんなのでS3オリジンの配信もやっちゃいたい、という内容です。

    • CloudFront + API Gateway + S3
    • S3はOAI(Object Access Identity)でアクセス制限
    • API Gatewayはカスタムオリジンヘッダによるアクセス制限はしない
      • めんどいので
    • API Gatewayはキャッシュしない
    • Route53で取得したドメインを利用
    • ACMで取得した証明書をHTTPS通信に利用

    アーキテクチャ構成

    arch.png

    手順

    Route53の設定(その1)

    CloudFrontのエンドポイントを覚えやすいドメイン名にするため、Route53でドメイン名を取得して設定する必要があります。

    1. Domain Resigtration
      • 独自ドメインをRoute53から取得します。[Domain Registration]->[Resigter Domain]を選択し、ドメイン(xxxxxx.comなど)を取得してください。
      • メインを取得すると、ダッシュボードが下記になります register.png

    ACM(Amazon Certificate Manager)で証明書作成

    独自ドメインに対してhttpsアクセスするために証明書を作成します。

    1. ACM画面
      top.png 

    2. 登録画面 
      Route53で取得したドメインを登録します。
      regist.png 

    3. 確定画面 
      設定を確認し、確定します。確定するとドメインに関連付けられているメールアドレスにValidationメールが送付されます。
      confirm.png 

    4. 仮登録完了画面
      pre_done.png  

    5. バリデーション画面
      送付されてきたメールリンクを押下すると下記画面となります。承認を押して確定してください。
      validation.png 

    6. 完了画面
      success.png 

    7. ダッシュボード
      完了までするとステータスが発行済みとなり、使用中でないことを確認してください。以後、これを使ってHTTPS通信における証明をします。
      result.png 

    API Gatewayの設定

    詳細は割愛しますが、下記手順で実施します。完了後にAPI Gatewayのデプロイ完了画面が表示されるはずです。下記画像の通り、各リソースごと(メソッドごと)にURLエンドポイントが発行されています。

    1. API作成
    2. リソース作成
    3. メソッドの作成
    4. APIをステージへデプロイ

    apiurl.png

    ここで使うのはURLの、https://XXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod」
    までの部分です。

    CloudFrontの設定(その1)

    CloudFrontの設定に入ります。その1としているのは後でS3の設定が入るからです。
    注意として、CloudFrontのデプロイにはめちゃくちゃ時間がかかる(20分くらい)ので、あせらず実施してください。時間のあるときにやってください。

    1. CloudFrontを開くと下記画面が表示されるので、Distributionを作成します。
      dashboard.png 

    2. webを選択します。
      web.png 

    3. Origin Settingsの設定
      origin.png 

    4. Behavior Settingsの設定

    • 注意点としては、HOSTヘッダーはForwardさせてはいけない。なぜかというとAPI Gateway自体がSNI前提のバーチャルホスト構成なのでHOSTが切り替えられなくなってしまうため。
    • 見切れている下記オプションについて
      • Smooth Streaming:動画配信でないため「No」
      • Restrict Viewer Access:今回は「No」
      • Compress Objects Automatically:Gzip圧縮しないので「No」
      • Lambda Function Associations:S3オリジンにファイルが入ってInvalidationAPIたたいたりする設定。今回は「設定しない」  behavior.png 
    1. Distribution Settingsの設定
      見切れているオプションは特に変更せずデフォルトのままにする。
      distribution.png 

    2. 作成!
      progress.png 

    • ダッシュボードに戻り、Statusが「In Progress」になります。ここから20分ほど、ぐつぐつ煮込んでください)
    • StateがEnabledになったら無事完了です。

    Route53の設定(その2)

    CloudFrontの代替名を独自ドメインにしたのでRoute53の設定が必要です。

    • 上記で取得したドメインをCloudFrontへルーティングするためにDNSリソースレコードを追加する必要があります。[DNS management]->[Domain Name]を選ぶと作成したDNSリソースが記載された画面に移動します。
    • [Create Record Set]を選択
      • Record setを下記の通り設定します。
      • Name:ZoneApexを指定のため何も入力しない
      • Type:Aレコード
      • Alias:Yes
      • Alias Target:CloudFrontDistribution名(xxxx.cloudfront.net.)
      • Routing policy: Simple
      • Evaluate Target Health: No
    • リソースレコードの登録が完了です。 dns.png

    中間CP

    いったん、ここまでの設定が動作確認してみます。

    • API Gatewayは単純にSuccessと返すだけのMockエンドポイントを用意し、prodステージにデプロイしました。
      • リソース名:success
    • ブラウザから動作確認

      • アドレスバーに下記を入力して実行
      • https://xxxxxx.com/success cp.png 
      • 補足)CloudFrontのDistribution設定でACMで取得した証明書を設定していない場合は下記のエラーになります。 sslerror.png 

    CloudFrontの設定(その2)

    現在の設定ではAPI Gatewayに対してのパスしかないので、S3オリジンとパスを追加します。

    1. オリジンを追加するために、[Create Origin]を押下
      s3_add_origin.png 

    2. S3オリジンの設定
      s3_origin.png 

    3. S3オリジン設定完了
      s3_origin_result.png 

    4. S3オリジンへのリクエストを受けるためのレスポンスを追加するために[Create Behavior]を押下
      s3_add_behavior.png 

    5. S3 Behaviorの設定
      見切れているオプションについてはデフォルトのままで問題ありません。
      s3_behavior.png 

    6. S3 Behaviorの設定完了
      s3_behavior._result.png 

    S3のバケットプロパティの確認

    CloudFrontからコンテンツ配信するために下記設定を確認してください。

    • Static website hosting:Enabledとなっていること
    • バケットポリシーはOAIのみAllowとなっていること

      • 例えば以前にS3からStatic website hostingしていた場合、下記の設定が残っていることがあります。
      bucket.json
          {
            "Version": "2008-10-17",
            "Id": "test",
            "Statement": [
                {
                    "Sid": "1",
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "*"
                    },
                    "Action": "s3:GetObject",
                    "Resource": "arn:aws:s3:::bucket-name/*"
                }
            ]
          }
      
      
      • 上記の場合、CloudFrontからのアクセス+S3への直接アクセスも許可していることになり、OAIで絞り込んでいる意味がないため削除し、プリンシパルがCloudFrontのみのアクセスだけ残してください。 
      bucket.json
          {
              "Version": "2008-10-17",
              "Id": "PolicyForCloudFrontPrivateContent",
              "Statement": [
                  {
                      "Sid": "1",
                      "Effect": "Allow",
                      "Principal": {
                          "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXXX"
                      },
                      "Action": "s3:GetObject",
                      "Resource": "arn:aws:s3:::bucket-name/*"
                  }
              ]
          }
      

    結果

    長かったですが、ここまでの設定内容を確認したら完了です。

    1. Route53で取得したドメイン名でAPIコールが出来ること
    2. Route53で取得したドメイン名でS3コンテンツを取得できること
    3. S3のドメイン名でS3コンテンツを取得できないこと

    まとめ

    • CloudFront経由でAPI GatewayとS3を配信する構成を作成できました。
    • CloudFrontの設定が多く結構手こずりました。
      • Blackbeltの資料など読んで各設定が何を意味しているか頭にいれておくとよいです。