1
3

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 1 year has passed since last update.

WebページのSorryページをALBとLambdaのみで自動切替できるようにしてみた

Last updated at Posted at 2023-08-15

目的

  • ALB配下のEC2が全停止したらSorryページを表示

上記を実装するにあたり色々調べたが一か所に集約されていなかったため
記事にまとめてみようと思う。

前提

  • 既に運用中のWebサイトがある
  • WebサイトをAWSで構築している

利用するサービス

  • ALB
  • Lambda
  • CloudWatch

実装方法

  • ALB

まずALBのリスナールールに通常のWebサイトを
ターゲットとするルールに加えて、メンテナンスページ用のルールを
追加する。

①リスナールールの作成
 →条件に「パス」=「*」
 →「固定レスポンスを返す」を選択
 →レスポンスコード:503
 →メッセージの形式:text/html
 →レスポンス本文:以下参照

<html>
  <head>
    <title>Sorry Page</title>
  </head>
  <body>
    <h1>Webサイト名を入力</h1>
    <p>現在、メンテナンス中です。以下の時間帯ではサービスがご利用いただけません<br />
    (毎日18:00~08:00)</p>
  </body>
</html>

以上で、ALBのリスナールールが追加された。

  • Lambda

Lamndaに付与するIAMロールも念のため作成しておく。
IAMポリシーから以下のポリシーを選択して適当な名前でロール作成
・CloudWatchReadOnlyAccess
・CloudWatchLogsFullAccess
・AmazonEC2FullAccess

上記のポリシーを付与したIAMロールを作成したら
Lambda関数の作成に取り掛かる。

import boto3

def lambda_handler(event, context):
    client = boto3.client('elbv2')

    #リスナールールの優先順位切替。(メンテナンスページ→通常ページへ切替)
    responce = client.set_rule_priorities(
        RulePriorities=[
            {
                'RuleArn': 'メンテナンスページ用のリスナールールのArn',
                #優先度に指定する値は通常のWebサイトよりも小さい値に設定する。
                #通常のWebページ用の優先度が100の場合は90などに設定
                'Priority': 90
            },
        ]
    )
    
    # 変更後の設定を表示
    result = client.describe_rules(
        ListenerArn='ALBリスナーのArn',
    )
        
    return result

同様に、Sorryページからの戻しのルールも作成するが
変更箇所は「Priority」の値のみ。
メンテナンス用ページの優先度を通常のWebページよりも大きい値に変更する。

※Lambdaの他の設定はすべてデフォルトのままでOK

以上でLambdaの設定が完了。

  • CloudWatch
    実はここが一番ハマった・・・。(どうでもいい)

【やりたいこと】
CloudWatchのルール(=EventBridge)を利用して
特定のイベントが発生したらLambdaを呼び出して
ALBのリスナールールの優先度を変更したい。

結論としては以下で実装可能
まずはメンテナンスページへ移行する場合のルール

{
  "source": ["aws.ec2"],
  "detail-type": ["EC2 Instance State-change Notification"],
  "detail": {
    "state": ["stopped", "stopping"],
    "instance-id": ["EC2のインスタンスID","EC2のインスタンスID",・・・]
  }
}

※stoppedとstoppingを両方しているのは、
 計画的に停止した場合と障害等でザクっと落ちた場合を考慮。

次に通常ページに戻す場合のルールは以下

{
  "source": ["aws.ec2"],
  "detail-type": ["EC2 Instance State-change Notification"],
  "detail": {
    "state": ["running"],
  }
}

インスタンスIDを指定していないのは任意のインスタンスが起動すれば
Webサイトは運用可能という考え方。

動作確認

マネコンよりEC2を停止してみる。
すると、「stopping」のルールに反応して
503ページを表示することなく、指定したメンテナンスページを表示することができた。

また、起動時は、EC2のステータスが「running」になるまで
メンテナンスページを表示し続けてくれ、runningになったタイミングで
Webページを表示することができた。

まとめ

今回、WebページのSorryページを作りたいとのご要望で
ALBの機能で簡単に実装することができた。
https(SSL)のサイトにも対応した手順となっているため
実運用でも活用できる内容ではないでしょうか?
ご参考になれば幸いです。

コメントやいいねをいただけると励みになりますのでお願いいたします。

1
3
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
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?