s3+cloudFront+LambdaでBasic認証

タイトル通り、s3+cloudFront+LambdaでBasic認証を設定したのでそのログ。 なおソース管理はGithubで、Pushでs3へ自動デプロイも行う。

s3+cloudFront+LambdaでBasic認証

参考: https://medium.com/crunchtimer/aws-s3-cloudfront-lambda-edge%E3%81%A7%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%83%AC%E3%82%B9basic%E8%AA%8D%E8%A8%BC-be7d416ed82c https://qiita.com/coinlockerbaby/items/ce228975d6b13b103517

s3

https://s3.console.aws.amazon.com/s3/home

バケット新規作成

基本的に、設定はデフォルトでOK。

名前とリージョン

バケット名 - 任意
リージョン - アジア・パシフィック

オプションの設定

デフォルト通り。次へ。

アクセス許可の設定

Block all public access にチェックを入れる。 ※多分デフォルトで入っている。

以上で、作成完了。

Static website hostingを有効にする

S3の一覧から、作成したパケットを選択する。 「プロパティ」タブの、Static website hostingを有効化する。 そして以下の設定を行う。

「このバケットを使用してウェブサイトをホストする」を選択。
インデックスドキュメント - index.html 
エラードキュメント - error.html

この時点でindx.htmlをアップすると、確認可能となる。

以上で一旦S3は完了。

CloudFront

https://console.aws.amazon.com/cloudfront/home

Create Distribution

Create Distribution する。 WEBの、Get startを選択。 以下、設定。

Origin Settings

Origin Domain Name

先程作ったs3バケット名から始まるものを選択

Restrict Bucket Access

Yes

Origin Access Identity

Create a New Identity

Grant Read Permission on Bucket

Yes, Update Bucket Policy ※この設定をすることで、CloudFrontを通してs3が見れるようになる。

Default Cache Behavior Settings

Viewer Protocol Policy

Redirect HTTP to HTTPS ※https化したいのであれば

Object Caching

Customize とし、各TTL値は0 ※プレビュー環境なのでキャッシュ不要なので。キャッシュさせる場合は不要。

Distribution Settings

Default Root Object

index.html

以上で、Create Distribution する。 一覧に戻ると、作成したものが追加され、In Progressとなっていることが確認できる。

Error Pages

デフォルトでエラーキャッシュを回避するため、無効にする設定 作成したDistributionを選択し、Error Pagesタブを選択。

Create Custom Error Responseを選択し、HTTP Error Codeを403とする。 このときのTTLを0にしておく。 SPAであれば、customize error responseを設定する。 設定したら、Create。

以上で一旦ClondFrontは終わり。

※2020/5 追記

Nodeバージョンが10.xのみ選択になったことで、少し様子が変わったかも。

Origin Access IdentityをCreate a New Identity
Grant Read Permissions on BucketをYes, Update Bucket Policy

で様子を見てみる。

https://dev.classmethod.jp/articles/s3-cloudfront-redirect/

これによると、

・s3のリージョン

・24時間以内のアクセス

により、s3に転送されちゃうことがあるみたい。

回避策も書いているので試してみる。

Lambda Edge

https://console.aws.amazon.com/lambda/

Basic認証のためのLambdaファンクションを作成する。 リージョンはバージニア北部を選択する。 ※東京だとARN設定のときエラーになる

関数の作成

「1から作成」を選択。

名前

任意。

ランタイム

Node.js 10.x

アクセス制限

実行ロールで、「基本的なLambdaアクセス権限で新しいロールを作成」を選択

以上で、関数を作成する。 次のページに進む。

設定

関数コード

'use strict';
exports.handler = (event, context, callback) => {

    // Get request and request headers
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    // Configure authentication
    const authUser = 'user';
    const authPass = 'pass';

    // Construct the Basic Auth string
    const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64');

    // Require Basic authentication
    if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
        const body = 'Unauthorized';
        const response = {
            status: '401',
            statusDescription: 'Unauthorized',
            body: body,
            headers: {
                'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
            },
        };
        callback(null, response);
    }

    // Continue request processing if authentication passed
    callback(null, request);
};

実行ロール

IAM コンソールで xxxxxxxxxxxxxx-role-bwrjj5bt ロールを表示します。をクリック。 IAMが開く。 アクセス権限に、

AWSLambdaBasicExecutionRole-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

とあるか確認。

そして「信頼関係」タブの「信頼関係の編集」で、サービスを追加

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": {
            "Service": [
               "lambda.amazonaws.com",
               "edgelambda.amazonaws.com"
            ]
         },
         "Action": "sts:AssumeRole"
      }
   ]
}

以上で、IAMでのロール設定は終了。

バージョンアップ

Lambda設定画面へ戻り、右上「アクション」より「新しいバージョンを発行」する

ARNが更新されるのでコピー。(末尾が :1 のようにバージョンがつく)

以上でLamdbaは終了。

CloudFront

CloudFrontのDirstibutionへ戻り、 Behaviuorsを選択。 チェックを入れて編集。

Lambda Function Associations

Select Event Typeで「Viewer Request」を選択 「Lambda Function ARN」にコピーしたファンクションのARNをペースト 以上で更新完了。 するとStatusがIn Progressとなるので、DeployedとなったらOK.

Githubからs3へのデプロイ

CodePipelineを使うのが手っ取り早い。 ビルドが必要なブロジェクトの場合は、CodeBuild。 今回はCodePipeLineの場合の説明を。

CodePipeline

https://console.aws.amazon.com/codesuite/codepipeline/pipelines?region=us-east-1

超簡単。 注意点はs3とリージョンをあわせることくらい。

パイプラインの作成

パイプライン名は似にで New service roleを選択

Allow AWS CodePipeline to create a service role so it can be used with this new pipeline にチェックをいれ

デフォルトの場所を選択。

そしてgithubへ接続し、レポジトリ・ブランチを指定。

今回はビルドはスキップ。

デプロイプロバイダにS3を指定し、 上で作ったパケットを指定。

デプロイする前にファイルを展開する はチェックを入れる

確認して、パイプラインの作成を行う。