- 公開日
- 最終更新日
Step Functionsを使ったLambdaのDR構成 HTTPレスポンスで東京/大阪に自動切替
この記事を共有する
目次
皆さんこんにちは、サービスGの山内です。
現在の業務では DR構成を検討しており、今回はAWS Step Functionsを使った構成を紹介します。
概要と構成図
東京リージョンでAmazon EventBridgeにて定期的に実行されるAWS Lambdaの処理を、東京リージョンに障害が発生した場合に、
大阪リージョンへ自動的に切り替えるDR構成です。
構成のポイント
- 東京・大阪の両リージョンに AWS Step Functions を配置し、同じスケジュールで起動します。
- バージニアリージョンに配置した Amazon API Gateway + AWS Lambda が、Amazon CloudWatch Alarm の状態を確認し、どちらのリージョンで処理を実行すべきかを返します。
- 各リージョンの AWS Step Functions は、このレスポンスに基づいて自リージョンの AWS Lambda を実行するか、何もせず終了するかを判断します。
なぜバージニアリージョンに Amazon API Gateway を置くのか
東京・大阪のどちらに障害が起きても影響を受けない第三のリージョンに判定ロジックを配置することで、判定自体の可用性を確保しています。
処理の流れ
- AWS Step Functions を起動する Amazon EventBridgeが起動
- バージニアリージョンのAmazon API Gatewayを呼び出すStepが起動
- Amazon API Gateway から起動された AWS Lambda が Amazon CloudWatch Alarmの状態を確認
- 正常時はTokyo、アラート時はOsakaをAWS Lambdaが返却
- レスポンスがTokyoの場合は東京リージョンのAWS Lambdaが起動、レスポンスがOsakaの場合は大阪リージョンのAWS Lambdaが起動
構成図は以下の通りです。

各リソースについて
Amazon CloudWatch Alarmを確認するAWS Lambda
AWS Lambdaのコードはシンプルです。
対象のAmazon CloudWatch Alarmを確認し、アラーム状態によってレスポンスを分けています。
AWS Lambdaの環境変数にて、Amazon CloudWatch Alarm名を渡しています。

ここを押すと展開します
import os
import json
import boto3
from botocore.exceptions import ClientError
cloudwatch = boto3.client("cloudwatch")
ALARM_NAME = os.getenv("ALARM_NAME")
def lambda_handler(event, context):
try:
response = cloudwatch.describe_alarms(
AlarmNames=[ALARM_NAME]
)
if not response['MetricAlarms']:
return {
'statusCode': 404,
'body': json.dumps({'message': f'Alarm {ALARM_NAME} not found'})
}
state_value = response['MetricAlarms'][0]['StateValue']
location = 'Osaka' if state_value == 'ALARM' else "Tokyo"
return{
'statusCode': 200,
'headers': {
'Content-Type': 'application/json; charset=utf-8'
},
'body': json.dumps({'location': location, 'state': state_value}, ensure_ascii=False)
}
except Exception as e:
print(f"Error: {e}")
return {
'statusCode': 500,
'body': json.dumps({'message': 'Internal Server Error'})
}
Amazon API Gateway
Amazon API Gatewayの設定もシンプルです。
リージョンタイプの REST API とし、AWS Lambda プロキシ統合を有効化しています。

Amazon EventBridge Connections
Amazon EventBridge Connections は、AWS Step Functions の「Call HTTPS APIs」ステップで外部の HTTPS エンドポイントを呼び出す際に、認証方法や接続情報を管理するためのリソースです。
今回の構成では、各リージョンの AWS Step Functions からバージニアリージョンの Amazon API Gateway を呼び出すために使用しています。
以下の手順で作成していきます。
Amazon EventBridge の左ペイン>統合>接続から「接続を作成」をクリックします。

接続名を記載します。
説明の記載は不要です。

呼び出し設定は「パブリック」とします。

「認証を設定」では、カスタム設定、「認証タイプ」ではAPIを選択します。
今回の構成はデモのためAPIキーを使用しません。
そのため「APIキー名」と「値」は、任意の値を設定してください。

暗号化の設定はしません。
すべての設定が完了したら、「作成」をクリックします。

AWS Step Functions
東京リージョンで作成したAWS Step Functionsと、大阪リージョンで作成したAWS Step Functionsはそれぞれ以下の通りです。
アカウントIDとAmazon API Gateway IDはマスクしています。
「Call HTTPS APIs」ステップにて、レスポンスのステータスコード200以外だった場合は、
- 東京リージョンでは AWS Lambda を実行
- 大阪リージョンでは AWS Step Functions を終了
という処理となります。 また、Amazon EventBridge Connectionの名前は「test」を前提にしています。
東京リージョンのAWS Step Functions
ここを押すと展開します
{
"Comment": "A description of my state machine",
"StartAt": "Call HTTPS APIs",
"States": {
"Call HTTPS APIs": {
"Type": "Task",
"Resource": "arn:aws:states:::http:invoke",
"Parameters": {
"ApiEndpoint": "https://xxxxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/",
"Method": "GET",
"Authentication": {
"ConnectionArn": "arn:aws:events:ap-northeast-1:xxxxxxxxxxxx:connection/test/5a7c61aa-84f5-44b0-9b0c-3d1967f19539"
}
},
"Retry": [
{
"ErrorEquals": [
"States.Http.StatusCode.429",
"States.Http.StatusCode.503",
"States.Timeout"
],
"BackoffRate": 2,
"IntervalSeconds": 2,
"MaxAttempts": 3
}
],
"Next": "Evaluate the alarm status.",
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "Lambda Invoke"
}
]
},
"Lambda Invoke": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"OutputPath": "$.Payload",
"Parameters": {
"Payload.$": "$",
"FunctionName": "arn:aws:lambda:ap-northeast-1:xxxxxxxx:function:getlambda:$LATEST"
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2,
"JitterStrategy": "FULL"
}
],
"End": true
},
"Evaluate the alarm status.": {
"Type": "Choice",
"Choices": [
{
"Next": "Stop Workflow",
"Variable": "$.ResponseBody.location",
"StringEquals": "Osaka"
}
],
"Default": "Lambda Invoke"
},
"Stop Workflow": {
"Type": "Succeed"
}
},
"QueryLanguage": "JSONPath"
}

大阪リージョンのAWS Step Functions
ここを押すと展開します
{
"Comment": "A description of my state machine",
"StartAt": "Call HTTPS APIs",
"States": {
"Call HTTPS APIs": {
"Type": "Task",
"Resource": "arn:aws:states:::http:invoke",
"Parameters": {
"ApiEndpoint": "https://xxxxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/",
"Method": "GET",
"Authentication": {
"ConnectionArn": "arn:aws:events:ap-northeast-3:xxxxxxxxxxxx:connection/osaka-connection/01ba4523-77fa-4f28-8436-4421e86f256a"
}
},
"Retry": [
{
"ErrorEquals": [
"States.Http.StatusCode.429",
"States.Http.StatusCode.503",
"States.Timeout"
],
"BackoffRate": 2,
"IntervalSeconds": 2,
"MaxAttempts": 3
}
],
"Next": "Evaluate the alarm status.",
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "Stop Workflow"
}
]
},
"Lambda Invoke": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"OutputPath": "$.Payload",
"Parameters": {
"Payload.$": "$",
"FunctionName": "arn:aws:lambda:ap-northeast-3:xxxxxxxxxxxx:function:getlambda:$LATEST"
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2,
"JitterStrategy": "FULL"
}
],
"End": true
},
"Evaluate the alarm status.": {
"Type": "Choice",
"Choices": [
{
"Next": "Lambda Invoke",
"Variable": "$.ResponseBody.location",
"StringEquals": "Osaka"
}
],
"Default": "Stop Workflow"
},
"Stop Workflow": {
"Type": "Succeed"
}
},
"QueryLanguage": "JSONPath"
}

動作確認
実際に Amazon CloudWatch Alarm の状態を切り替えて、期待通りにリージョンが切り替わるか確認します。
アラームが正常な場合の動作
正常時(東京リージョンで処理を実行すべき状態)の動作を確認します。

東京リージョンでは、AWS Lambdaが起動しました。

大阪リージョンでは、AWS Lambdaを起動せずに終了しました。

アラームが異常な場合の動作
異常時(大阪リージョンへ切り替えるべき状態)の動作を確認します。

東京リージョンでは、AWS Lambdaを起動せずに終了しました。

大阪リージョンでは、AWS Lambdaが起動しました。

まとめ
今回は、AWS Step Functions を活用して東京・大阪リージョン間で AWS Lambda の実行を自動切り替えする DR 構成を紹介しました。
この構成のポイントをまとめると以下の通りです。
- 第三のリージョン(バージニア)に判定ロジックを置くことで、東京・大阪どちらの障害にも対応可能
- Amazon CloudWatch Alarm の状態に基づいて、実行リージョンを動的に切り替え
- 各リージョンの AWS Step Functions が自律的に判断するため、手動での切り替え操作が不要
なお、今回はデモのため Amazon API Gateway の認証(API キー)を省略しています。本番環境で利用する際は、適切な認証設定を行ってください。
初めてAWS Step Functionsを使った構成だったため、構築に時間がかかりましたが、正常にAWS Step Functionsが起動したときはとても嬉しかったです。
機会があればほかの構成についても紹介したいと思います。
この記事は私が書きました
山内 宏紀
記事一覧CloudFormationが好きです。 使っているギターはSGです。