LoginSignup
2
2

More than 3 years have passed since last update.

Route53フェイルオーバ機能での夜間用Sorryページ切り替えをあきらめた話

Posted at

Route53のフェイルオーバ機能を利用した日中⇔夜間のページ切替を行おうとしたところ、社内プロキシの壁に阻まれた(と思われる)がために、代替手段を模索したお話です。

1.おおまかな要件

・日中のサービス時間帯のみウェブアプリケーションが稼働し、夜間はサーバを停止してコストカット
・夜間帯のサービスアウト時にはSorryページが表示される
・アプリケーションは特定多数のクライアント企業が使用し、クライアント証明が必要

2.やろうとしたこと

・サービスイン時のみEC2(ASG)でウェブアプリケーションが稼働し、サービスアウト時はASGの起動インスタンス数を0にする
・サービスアウト時にRoute53のフェイルオーバ機能が働き、S3に静的ホスティングしたSorryページを表示
・クライアント証明のためにALB不可のため、NLBを選択

構成図
※Bastionは運用/保守用の24H稼動インスタンス
処理フロー-ページ10.png

3.問題

ここで問題が発生しました。
Route53でドメインの向き先Aliasが切り替わった際、名前解決先は切り替わっているのに30分以上Web画面が切り替わらない状態に陥りました。
Resolve-DnsNameで確認しても、TTL(60秒)後にはちゃんと解決先が切り替わっていることが確認できます。

さらに確認を進めると、

・社内ネットワーク内の端末からのアクセス時には切り替わらない
・パブリックネットワーク上のEC2からのアクセス時にはちゃんと切り替わる

ということが分かりました。

ここから”社内プロキシがドメインの名前解決先をキャッシュしてしまっているのでは...?”と考えました。
しかし、社内プロキシ側の仕様はブラックボックスなため確実かどうかは判断できません。

4.対応

とはいうものの、開発もIT工程後半に差し掛かっており、どうにか早急に代替策を考えねばならない。
かつ、もし社内プロキシが原因だとすると、特定多数のクライアント企業側のプロキシ仕様によっては同様の事象が置き得るのでは?
という状態になりました。

そこで、代替策としてNLBのListenerをLambdaで操作し、リクエストのターゲット先を切り替える方針を検討、

・NLB利用のため、バックエンドにLambdaを置く方法はだめ
・ちょうど、運用/保守用のBastionインスタンスが24H稼動している

という前提を踏まえて以下の構成をとり、サービスアウト時にはBastionインスタンスに配置したSorryページを応答することにしました。

処理フロー-ページ11.png

NLBを切り替えるLambdaFunctionはシンプルにこんな感じで、サービスイン/アウトフラグをCloudWatchEventから受け取って切替処理を行います。

ChangeNlbTarget.py
import boto3
import os
import logger_formatter

logger = logger_formatter.setup_logging('ChangeNlbTarget')
client = boto3.client('elbv2')

def lambda_handler(event, context):
    logger.info('function start.')
    logger.info('event_param: %s', event)

    is_service_in = event['is_service_in']

    if not isinstance(is_service_in, bool):
        logger.error('error_message: %s is not boolean', is_service_in)
        raise Exception('Input Parameter is Invalid.')    

    if is_service_in == True:
        target = os.environ['TARGET_WEBAP_ARN']
    else:
        target = os.environ['TARGET_SORRY_ARN']

    try:
        res = client.modify_listener(
                ListenerArn = os.environ['LISTENER_ARN'],
                Port = 443,
                Protocol = 'TCP',
                DefaultActions = [
                        {
                            'Type' : 'forward',
                            'TargetGroupArn' : target
                        }
                    ]
            )
    except Exception as e:
        logger.error('error_message: %s', e)
        raise Exception('Change Nlb Target failed.')    


    logger.info('function end.')
    return{
        'statusCode': 200
    }

5.結果

しっかりTTL後には日中⇔夜間のページ切替が完了できるようになりました。
また、もともと24H稼動の必要がある別インスタンスを利用することで、コスト増も避けることができました。

想定する原因が本当に合っているのか、対応方法はベターか、というところはあるかと思います。
もし同じような状況に陥ったことがある方がいらっしゃれば、原因・対応方法等をコメントいただけると幸いです。

2
2
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
2
2