【AWS】Cloudfront使用時のedge Lambdaを使ったindex.html省略

1. 使用するサービス

(AWS)

  • Cloudformation
  • Cloudfront
  • edge Lambda

2. 概要

CloudfrontとS3を用いたWebサイトのURLがパスを区切った時にindex.htmlを指定しないと、見たいパスが表示されない現象を、Cloudfrontへのアクセスをedge Lambdaで受け取り、パスを変換してくれる構成を説明します。

3. 実装

3-1. Cloudfrontの設定

Cloudformationのテンプレート載せます。パラメータとかは適宜調整してください。
LambdaFunctionAssociationsの部分が今回の対象です。

Cloudfrontnet:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Aliases:
          - !Sub "${S3DomainName}.${HostedZoneName}"
        Enabled: true
        PriceClass: PriceClass_All
        DefaultCacheBehavior:
          TargetOriginId: !Sub "S3-${WebContentsBucketBaseName}-${Project}-${Stage}/*"
          ViewerProtocolPolicy: redirect-to-https
          MinTTL: 0
          AllowedMethods:
            - HEAD
            - GET
            - OPTIONS
          CachedMethods:
            - HEAD
            - GET
          ForwardedValues:
            Headers:
              - Authorization
              - Origin
              - Access-Control-Request-Method
              - Access-Control-Request-Headers
            Cookies:
              Forward: none
            QueryString: false
          LambdaFunctionAssociations:
            - EventType: origin-request
    #3-2で作成するLambdaのArn:version
              LambdaFunctionARN: !Sub "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:urlReplaceFunction:2"

3-2. Lambdaの実装

まず、リージョンをus-east-1にします。Lambdaを通常通りに作成し、triggerにCloudfrontを選択します。すると、下記のようにedge@Lambdaにするか聞かれるので、Deployを選択します。

edge_lambda_deploy
edge@Lambdaデプロイ

実装内容としてはnodejsで以下のようになります。

exports.handler = (event, context, callback) => 
{
   const request = event.Records[0].cf.request;
   const olduri = request.uri;

   const newuri = olduri.replace(/\$/, '\/index.html');

   request.uri = newuri;

   return callback(null, request);
}

4. 以上で、URLのパスだけでアクセス出来るようになります。index.htmlを打ち込む必要がなくなります。