0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

id変換表を参照して URL リダイレクトさせるシステムをサーバレスで構築する

Last updated at Posted at 2019-12-29

#とある業務で「id変換表を参照して URL をリダイレクト」させる必要があったので、サーバレスで実現できるか検証をした際の備忘録

1. 要件

  • サイトA:https://example-A.com をクローズする。ただし、サイトAの一部のページはサイトB:https://example-B.com へ移植して、サイトAクローズ後も閲覧できるようにする(ここではページの移植作業については割愛)。

  • サイトAの移植対象ページのURLは、サイトAクローズ後も生かしておく。そのURLへアクセスすると、サイトBの移植後のURLへリダイレクトさせる。

  • サイトAの移植対象ページのURLの例

    https://example-A.com/before/demo.php?id=100002
  • サイトBの移植先ページのURLの例

    https://example-B.com/after/10100002
  • 移植先のサイトBの id は移植元のサイトAの id と異なるものになってしまうため、id 変換表を用意する。

  • id変換表の例


before	after	
100000	10100000
100001	10100001
100002	10100002
100003	10100003
100004	10100004
100005	10100005

2. システム概要

2.1 id変換表作成

  • CSV形式のデータを DynamoDB へインポートする。ただし、CSV形式のデータは、そのままのフォーマットでは DynamoDB へインポートできないため、インポート用のフォーマットに整形する必要がある。

  • S3, AWS Data Pipeline を使う。

  • DynamoDB インポート形式のファイルを S3 バケットへアップロードする。Data Pipeline で S3 バケットファイルのデータを DynamoDB のテーブルへインポートする。
    image.png

2.2 リダイレクト設定

  • Route53, ALB, Lambda(ALBのターゲット), DynamoDB を使う。

  • 元の構成
    image.png

  • リダイレクト構成案1

  • 今回は、この方法で構築した。

  • リダイレクト用ALBを用意する。

  • リダイレクト開始は、Route 53 で サイトA の Aエイリアスレコードを サイトA の ALB から リダイレクト用 ALB へ変更する。
    image.png

  • リダイレクト構成案2

  • サイトAのALBを使用する。

  • リダイレクト開始は、サイトA の ALB のターゲットグループを、リダイレクト用Lambdaを設定したターゲットグループへ変更する。
    image.png

3. システム構築

3.1 id変換表を作成

  • DynamoDB テーブルを作成する

  • テーブル名: id-mapping
    プライマリキー: before (文字列)
    image.png

    image.png

  • CSVファイルを作成する

  • 作業PCで次のような csv ファイルを作成する。
    id-mapping.csv

    
    before,after
    s,s
    100000,10100000
    100001,10100001
    100002,10100002
    100003,10100003
    100004,10100004
    100005,10100005
    

$ python3 csv2json.py
CSVのパスを入力:id-mpping.csv

$ cat id-mapping.json
{"before": {"s": "100000"}, "after": {"s": "10100000"}}
{"before": {"s": "100001"}, "after": {"s": "10100001"}}
{"before": {"s": "100002"}, "after": {"s": "10100002"}}
{"before": {"s": "100003"}, "after": {"s": "10100003"}}
{"before": {"s": "100004"}, "after": {"s": "10100004"}}
{"before": {"s": "100005"}, "after": {"s": "10100005"}}
  • 整形された id-mapping.json ファイルを置く S3バケットを作成する

  • S3バケット名を 「dynamodb-datapipeline-************ 」 とする ( "************" はユニークな文字列)。

  • S3バケット 「dynamodb-datapipeline-************」 に「csv」というフォルダを作成する。

    image.png

  • Data Pipeline を作成する

  • Name: import dynamodb from s3
    Source: Import DynamoDB backup data from S3

  • Input S3 folder: s3://dynamodb-datapipeline-************/csv/
    Target DynamoDB table name: id-mapping
    Region of the DynamoDB table: ap-northeast-1

  • IAM roles: default
    【参考】AWS Data Pipeline の IAM ロール
    image.png

  • Data Pipeline を Activate する
    image.png

  • Data Pipeline の裏で、EMRクラスターとEC2が作成されている。それらのプロビジョニングが完了するまで、Data Pipeline のステータスは「WAITING_FOR_RUNNER」になっている。
    image.png

  • EMR クラスターのステータス
    image.png

  • EMR クラスターのプロビジョニングが終わると、Data Pipeline の DynamoDB インポート処理が実行される。完了すると、ステータスは「FINISHED」となる。
    image.png

  • EMR クラスターは終了済となり、EMPクラスターやEC2が削除される。
    image.png

  • DynamoDB 「id-mapping」 テーブルにデータがインポートされていることを確認する。
    image.png

3.2 リダイレクト設定 - リダイレクト構成案1 のシステムを構築する

  • リダイレクト用 ALB 作成

  • ALB 名を 「redirect」 とする。

  • Lambda にアタッチする IAM ロールを作成する

  • ロールを使用するサービスで 「lambda」 を選択
    image.png

  • 次のポリシーをアタッチする(今回は検証なので、FullAccessにしている)。
    AmazonDynamoDBFullAccess
    AWSLambdaBasicExecutionRole

  • ロール名を 「lambda_redirect」 とする。

  • Lambda作成

  • 一から作成
    関数名: redirect
    ランタイム: Python 3.7
    実行ロール: lambda_redirect
    image.png

  • トリガーを追加

    image.png

  • トリガーの設定
    Application Load Balancer: redirect
    リスナー: HTTPS:443
    ホスト: example-A.com
    パス: * (ワイルドカード)

    image.png

  • トリガーの設定が完了すると、ALB redirect のリスナーとターゲットグループに Lambda の設定が自動的に反映される。

  • HTTPS:443 のリスナーのルール設定
    image.png

  • ターゲットグループ: lambda-25bxlPn0KCbRK4JVO3Ii
    image.png

  • ターゲットグループ: lambda-25bxlPn0KCbRK4JVO3Ii のヘルスチェック設定

  • ヘルスチェックの編集
    image.png

  • 有効化
    パス: /healthcheck
    image.png

  • Lambda関数作成(これがこのシステムの肝)

  • 関数コード
    image.png

  • 実際のコード

import boto3
from botocore.exceptions import ClientError
from boto3.dynamodb.conditions import Key
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
    logger.info(event)
    for key, value in event["queryStringParameters"].items():
        if key == "id":
            table = boto3.resource("dynamodb").Table("id-mapping")
            item = table.get_item(Key={"before":value})
            if ("Item" in item):
                after_id = table.get_item(Key={"before":value})["Item"]["after"]
                location = "https://example-B.com/after/" + after_id
                response = {
                    "statusCode": 302,
                    "isBase64Encoded": False,
                    "headers": {
                        "Location": location
                    }
                }
                return response
            else:
                response = {
                    "statusCode": 302,
                    "isBase64Encoded": False,
                    "headers": {
                        "Location": "https://example-B.com"
                    }
                }
                return response
        else:
            response = {
                "statusCode": 302,
                "isBase64Encoded": False,
                "headers": {
                    "Location": "https://example-B.com"
                }
            }
            return response
    if ( event["path"] == "/healthcheck" ):
        response = {
            "statusCode": 200,
            "isBase64Encoded": False,
            "headers": {
                "Content-Type": "text/html; charset=utf-8"
            }
        }
        return response
    else:
        response = {
            "statusCode": 302,
            "isBase64Encoded": False,
            "headers": {
                "Location": "https://example-B.com"
            }
        }
        return response
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?