maybe daily dev notes

私の開発日誌

CDK Tips: Step Functionsで別リージョンのAWS APIを呼び出す

AWS CDK Tipsシリーズです。

先日久々にAWS CDKの新機能をマージしてもらえたので、その宣伝をさせてください。Step Functionsで別リージョンのAWS APIを呼び出すためのコンストラクトです。

github.com

TL;DR

以下のコードで、Step FunctionsからクロスリージョンのAWS APIコールを行うSFnタスクを実装できます (CDK v2.148.0〜)。

// 例: us-west-2のS3バケットからgetObjectするSFnタスク
const getObject = new tasks.CallAwsServiceCrossRegion(this, 'GetObject', {
  region: 'us-west-2',  // ここでリージョンを指定
  service: 's3',
  action: 'getObject',
  parameters: {
    Bucket: myBucket.bucketName,
    Key: sfn.JsonPath.stringAt('$.key')
  },
  iamResources: [myBucket.arnForObjects('*')],
});

ドキュメントはこちら: aws-cdk-lib.aws_stepfunctions_tasks module · AWS CDK

モチベーション

AWS Step Functionsでは、ステートマシン内でAWS APIを呼び出す機能が提供されています: AWS SDK Integrations

200以上のAWSサービスとの連携が可能

しかしながら、この機能では、ステートマシンと同一のリージョンのAWS APIを呼ぶことしかできません。

Currently, cross-Region AWS SDK integration and cross-Region AWS resource access aren't available in Step Functions. https://docs.aws.amazon.com/step-functions/latest/dg/concepts-access-cross-acct-resources.html

クロスリージョンでもAWS APIを呼びたいですよね?これを可能にするのが今回紹介する機能です。

使い方

AWS CDKでStep Functionsを使ったことがある方なら簡単です。上記のAWS SDK統合機能は、 CallAwsService コンストラクト を使って定義することができましたね。

クロスリージョンの場合は、CallAwsServiceCrossRegion コンストラクトを使うことができます。

使い方は既存のCallAwsService コンストラクトとほぼ同じですが、追加で region プロパティを指定できます。このプロパティで指定したリージョンのAWS APIが呼び出されます。

コード例は下記です:

import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';

declare const table: ITable;

// 基本的にはCallAwsServiceコンストラクトのAPIを踏襲
const deleteTable = new tasks.CallAwsServiceCrossRegion(this, 'DeleteTable', {
  service: 'dynamodb',
  action: 'deleteTable',
  parameters: {
    TableName: table.tableName,
  },
  iamResources: [table.tableArn],
  // 追加引数: ここでリージョンを指定
  region: 'us-east-2',
});

new sfn.StateMachine(this, 'StateMachine', {
  definition: deleteTable,
});

注意点として、CallAwsService コンストラクトのプロパティと完全な互換性はありません。serviceparametersAWS SDK for JavaScript v3スタイルで指定する必要があるため、適宜APIリファレンスをご参照ください。また、CDK v2.148.0以降でのみ利用できることにもご注意ください。

仕組み

仕組みは非常にシンプルで、Lambda関数 (Node.jsランタイム) を利用してAWS APIを呼び出しています。SDK初期化時のregionプロパティを指定することで、任意リージョンのAPIを呼び出すことができます。

Step Functionsの入力から、Lamba内で必要なAWS SDKのサービスとそのメソッドを動的に選択して、引数付きで呼び出します。

同様の機能をセルフ開発することも難しくはないですが、Lambdaのコード管理などを自前でするのはやや億劫でしょう。このコンストラクトを使うことで、諸々の責務をaws-cdk-libに任せることができ、ユーザーはただCDKのバージョンを最新に保つことだけを意識していれば十分となります。

ユースケース

本機能のユースケースをいくつか紹介します。

レジリエンシーのためのクロスリージョン

リージョンをまたいでAWSサービスを使うというのは、かつては一部のヘビーユーザーだけが踏み入れる秘境でした [要出典]。例えばBLEA FSIでは、主に金融業界に向けてクロスリージョン構成による高レジリエンシーの実現を提案しています

aws.amazon.com

上記の実装サンプルでは、クロスリージョンのフェイルオーバーを自動化するために、Step Functionsを活用しています。この中でクロスリージョンのAPIコールが必要でした (各リージョンの持つパラメータの書き換えなど)。Route53 Application Recovery Controllerの呼び出しにも、冗長化されたエンドポイントの指定やAPIコールのために*1、今回の仕組みが役立っています。*2

Bedrockのためのクロスリージョン

今日では、クロスリージョン設計はレジリエンシーの文脈だけには留まりません。特にAmazon Bedrockでは、USリージョンが機能追加の早さやクォータなどの面で優遇されがちなため、クロスリージョンの実装がありふれたものになりつつあります。(例: アプリの主要部は東京・Bedrock関連のみオレゴンなど)

Bedrockにおける「おま国」の様子

例えばbedrock-claude-chatでは、東京のステートマシンから、オレゴンのBedrock Knowledge Baseへのデータ投入を開始するために、本機能を利用しています

その他にも、意外と身近に応用先があるかもしれません。見つけたらぜひご活用ください。

まとめ

AWS CDKを使ってStep FunctionsでのクロスリージョンAWS APIコールを簡単に実装する方法を紹介しました。 コード管理もaws-cdk-libの責務と見なせるため、Lambdaを使うとは言えど運用負荷は軽めと思います。 用途があればぜひ試してみてください。

今月のもなちゃん

余白を大事にするタイプのもなちゃんです。

お腹の羽毛の分かれ目に入りたいですね。

*1:複数のリージョンに分散された専用のエンドポイントを、いずれか指定して呼び出す必要があります。AWSの中では非常に独特なサービスだと思います。

*2:実装のタイミングの都合で、今回紹介したコンストラクト自体は利用していないのですが、同じ仕組みを使っています。