My Note

自己理解のためのブログ

CloudFrontとLambda@Edge(Python3)とS3でリダイレクト設定をする

はじめに

今回はCloudFrontとLambda@Edgeでリダイレクトを設定しました。 CloudFront、Lambda@Edge、IAMに関しては下記の前回の記事を参照ください。

yhidetoshi.hatenablog.com

構成

f:id:yhidetoshi:20211209130510p:plain

リダイレクト元と先のサイトをそれぞれ簡易な静的ページをCloudFrontとS3で用意しました。 S3のバケットにそれぞれ以下のパスで用意。*) hoge, fugaは記事用に修正したものです。

  • サイトA
    • CloudFrontA
      • hoge.cloudfront.net
    • S3(Origin)
      • hoge-cloudfront-net
    • Lambda@Edge(リダイレクト用)
  • サイトB
    • CloudFrontB
      • fuga.cloudfront.net/
    • S3(Origin)
      • fuga-cloudfront-net

それぞれのS3バケットのパス

hoge-cloudfront-net /
      index.html
      /v1/index.html
      /v2/index.html

fuga-cloudfront-net /
      index.html
      /v1/index.html
      /v2/index.html

リダイレクト設定(Lambda@Edge)

パターン1: すべてのリクエストを別ホストにリダイレクト

REDIRECT_TARGET_HOST = 'fuga.cloudfront.net'


def lambda_handler(event, context):
    redirect_response = {
        'status': '301',
        'statusDescription': 'Moved Permanently',
        'headers': {
            'location': [
                {
                    'key': 'Location',
                    'value': f'http://{REDIRECT_TARGET_HOST}'
                }
            ]
        }
    }
    return redirect_response

パターン2: 特定のパス配下のアクセスを同じホストの別パスにリダイレクト

- hoge.cloudfront.net/v1/index.html --> hoge.cloudfront.net/v2/index.html
import re

PATH_PATTERN = '^\/v1\/'


def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']

    host = headers['host'][0]['value']
    uri = request['uri']

    if (re.match(PATH_PATTERN, uri)):
        redirect_response = {
            'status': '301',
            'statusDescription': 'Moved Permanently',
            'headers': {
                'location': [
                    {
                        'key': 'Location',
                        'value': f'http://{host}/v2/index.html'
                    }
                ]
            }
        }
        return redirect_response
    return request

パターン3: 特定のパス配下のアクセスを別ホストにリダイレクト(同じパス)

- hoge.cloudfront.net/index.html --> hoge.cloudfront.net/index.html
- hoge.cloudfront.net/v1/index.html --> fuga.cloudfront.net/v1/index.html
- hoge.cloudfront.net/v2/index.html --> fuga.cloudfront.net/v2/index.html
import re

PATH_PATTERN = '^\/v1\/|^\/v2\/'
REDIRECT_TARGET_HOST = 'fuga.cloudfront.net'


def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    uri = request['uri']

    if (re.match(PATH_PATTERN, uri)):
        redirect_response = {
            'status': '301',
            'statusDescription': 'Moved Permanently',
            'headers': {
                'location': [
                    {
                        'key': 'Location',
                        'value': f'http://{REDIRECT_TARGET_HOST}{uri}'
                    }
                ]
            }
        }
        return redirect_response
    return request

パターン4: ホスト名指定の場合はリダイレクトしない(同じパス)

- hoge.cloudfront.net --> hoge.cloudfront.net
- hoge.cloudfront.net/index.html --> fuga.cloudfront.net/index.html
REDIRECT_TARGET_HOST = 'fuga.cloudfront.net'

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']

    if headers['host'][0]['value'] == REDIRECT_TARGET_HOST:
        return request

    uri = request['uri']

    redirect_response = {
        'status': '301',
        'statusDescription': 'Moved Permanently',
        'headers': {
            'location': [
                {
                    'key': 'Location',
                    'value': f'http://{REDIRECT_TARGET_HOST}{uri}'
                }
            ]
        }
    }

    return redirect_response[]

ソースコードは下記のGitHubにあります。

github.com