はじめに
AWS CDK を使って OpenAPI 定義を API Gateway にインポートするとき、CDKを用いると、対応するLambdaの名称は動的かつユニークに生成される。ため、それがいつ使用されるか分からないという問題に直面する。今回は OpenAPI 定義の中のプレースホルダーを実際の値に置き換えるテンプレート手法を紹介する。
何もしない場合 Lambda の arn は以下のようになる。 {動的なユニークID} の部分が CDK で扱う上でちょっと厄介な部分だ。
arn:aws:lambda:{リージョン}:{アカウントID}:function:{スタック名}-{論理ID}-{動的なユニークID}
流れ
- OpenAPI 定義を用意する
- Lambda の Cfn 論理 ID を任意の名前に変更する
- OpenAPI 定義を API Gateway にがっちゃんこする
前提
- CDK バージョン 2.80
OpenAPI定義を用意
こちらのサンプル を使って OpenAPI 定義を編集する。以下のように Lambda Function の部分をまるっと ${ApiLambda.Arn}
で置き換えて、 Cfn 組み込み関数の Fn::Sub を使ってあとで置換できるようにしておく。
x-amazon-apigateway-integration:
uri:
+ Fn::Sub: 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ApiLambda.Arn}/invocations'
- arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:LambdaFunctionName/invocations
Lambda の Cfn 論理 ID を任意の名前に変更
ApiLambda
という名前で動的でユニークな ID を上書きする。
const apiLambda = new Function(this, 'Function', {
code: Code.fromAsset('../api/lambda'),
:
});
const cfnLambda = apiLambda.node.defaultChild as CfnFunction;
cfnLambda.overrideLogicalId('ApiLambda');
OpenAPI 定義を API Gateway にがっちゃんこ
Fn::Transform で AWS::Include
マクロを実行しプレースホルダーを実際の値に置換する。
// OpenAPI YAMLファイルからCfn Assetを定義
const openApiAsset = new Asset(this, 'openApiFile', {
path: 'openapi.yaml',
});
// AWS::Includeマクロの入力パラメータを作成
const transformMap = {
Location: openApiAsset.s3ObjectUrl,
};
// AWS::Include マクロを InlineApiDefinition で使えるようにする
// これでS3オブジェクトを参照している
const data: IResolvable = Fn.transform('AWS::Include', transformMap);
const apiDefinition: InlineApiDefinition = ApiDefinition.fromInline(data);
const specRestApi = new SpecRestApi(this, 'RestApi', {
apiDefinition: apiDefinition,
restApiName: 'tasks-api',
deployOptions: {
stageName: '',
loggingLevel: MethodLoggingLevel.INFO,
},
});
参考