はじめに
個人でAWS上でWEBサイトを運営していますが、アクセスに応じてスケールするサービスを使っているので、月の利用料金が怖いです。
ということで、今回は設定した利用料金を超えたら、サイトをクローズする設定を導入しました。
設計
概要
サービスクローズの方法は、Route53に設定したサービスのAレコードを上書きし、URLのアクセス先をS3バケットに保存したメンテナンスページに向けることで実現する。
AWS利用料監視にはCloudWatchのEstimatedChargesメトリクスを使用し、このメトリクスの閾値超過をトリガーに、Route53のレコードが上書きされるLambdaを実行する。
構成図
AWS利用料が閾値を超えてからサービスクローズまでのイメージを以下に示します。
機能設計
- CloudWatch
AWS利用料を監視する。利用料のメトリクスであるEstimatedChargesに閾値を設定し、それを超えると発砲されるアラームを作成する。 - SNS
CloudWatchアラームをEメール配信するために利用する。トピックに紐づいたサブスクリプションには管理者のEメールアドレスを設定する。 - EventBridge
CloudWatchアラームの状態が「ALARM」になるイベントを検知した際に、Lambdaを呼び出すために利用する。 - Lambda
Route53に設定したレコード情報を上書きするAPIを実行するために利用する。
設定
CloudWatch、SNSのアラート設定は、以下の記事が参考になりますので割愛します。
CloudWatchで請求アラームを作成する
S3
まずは、メンテナンスページを格納するS3バケットを作成します。
バケットは以下の点に注意して作成します。
- レコード名とバケット名を同一にする。
- バケットの静的ウェブサイトホスティング設定を有効にする。
- バケットのパブリックアクセスを許可する。
EventBridge
- イベントパターン
イベントパターンに以下を指定すると、作成したCloudWatchアラームの状態が「OK」→「ALARM」に変化した際に設定したターゲットが実行されます。
{
"source": ["aws.cloudwatch"],
"detail-type": ["CloudWatch Alarm State Change"],
"detail": {
"alarmName": ["CloudWatchアラームの名前"],
"state": {
"value": ["ALARM"]
}
}
}
- ターゲット
ここでは後の紹介で作成するLambdaを指定します。
EventBridgeからLambdaの実行は非同期のため、再試行回数や、デッドレターキューの使用などの設定も行います。
※参考
Amazon EventBridge (CloudWatch Events) でAWS Lambdaを使用する
Lambda
コードは以下です。
pythonのAWS SDKで、Route53に登録されているレコードを編集するAPIを実行しています。
import json
import boto3
client = boto3.client('route53')
def lambda_handler(event, context):
client.change_resource_record_sets(
HostedZoneId='Route53のホストゾーンID',
ChangeBatch={
'Changes': [
{
'Action': 'UPSERT',
'ResourceRecordSet': {
'Name': 'レコード名(WEBサイトのURL)',
'Type': 'A',
'AliasTarget': {
'HostedZoneId': 'Z2M4EHUR26P7ZW',
'DNSName': 's3-website-ap-northeast-1.amazonaws.com.',
'EvaluateTargetHealth': True
},
}
},
]
}
)
※以下はS3東京リージョンのウェブサイトエンドポイントのホストゾーンIDで、固有の値です。
Amazon Simple Storage Service エンドポイントとクォータ
'HostedZoneId': 'Z2M4EHUR26P7ZW',
- 権限
権限まわりの設定は、LambdaがRoute53のリソースにアクセスするため、実行ロールに許可を与える必要があります。特にRoute53側のリソースを絞らない場合は、以下のポリシーでOK です。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:ListResourceRecordSets"
],
"Resource": "*"
}
]
}
Lambdaへのアクセス権限は、EventBridgeで関数をターゲットに指定した際に、自動で設定されます。(※AWSコンソール操作の場合)
おわりに
今回は月のAWS利用料に応じて、サイトのURLをS3に保存したメンテナンスページにアクセスするよう変更する設定を行いました。
このおかげで、AWSサービスのオートスケール機能の恩恵を受けつつ、安心してWEBサイトの運用ができそうです。
おまけ
本記事の機能は以下のサービスで利用されています。
観た映画を登録、管理できるサービス MyMovie
サービスURL : mymovie.jp
紹介記事 : 【個人開発】みた映画を管理/共有するアプリを作りました。