この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
概要
AWS CDK で既存のリソースから Construct を取得したい要件があると思います。例えば、すでにAWSに手動で構築してあるリソースや、別スタックでデプロイされているリソースなどです。CDK では便利な grant*
のメソッドがあり、これを使うことで面倒なIAMロール作成の手間を省くことができます。既存のリソースから grant*
のメソッドを使って、IAM ロールを作成したい要件もあるかと思います。 この記事では、別スタックでデプロイされている DynamoDB の ARN を取得し、別スタックから Lambda の環境変数にテーブル名を設定、さらに DynamoDB へのアクセス権限を付与する IAM ロールの設定を行うためのソースサンプルを記述します。
環境
cdk --version [cm-sato] 月 5/18 18:50:32 2020
1.39.0 (build 5d727c1)
DynamoDB スタック
以下のようなDynamoDBスタックを作成します。今回は sampleTable
というテーブルを作成しています。また、別のスタックで参照するために、ARN名をパラメーターストアに格納しています。
lin/dynamodb-stack.ts
import * as cdk from '@aws-cdk/core';
import { Table, BillingMode, AttributeType } from '@aws-cdk/aws-dynamodb';
import { StringParameter } from '@aws-cdk/aws-ssm';
export class DynamoDBStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
const sampleTable = new Table(this, 'sampleTable', {
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
type: AttributeType.STRING,
name: 'id',
},
});
// テーブルARNをパラメータストアに登録する
new StringParameter(this, 'SampleTableArn', {
parameterName: 'SampleTableArn',
stringValue: sampleTable.tableArn,
});
}
}
Lambda スタック
次に、Lambda 用のスタックを作成します。ここで、既存のリソースから Construct を取得します。CDK では既存のリソースから取得するために、from*Arn
メソッドが用意されています。 上記の DynamoDB スタックは先にデプロイされていることが前提となります。ここでは、パラメータストアから DynamoDB の Arn を取得し、そこから DynamoDB の Consturuct を取得しています。
lib/lambda-stack.ts
import * as cdk from '@aws-cdk/core';
import { Function, Code, Runtime } from '@aws-cdk/aws-lambda';
import { StringParameter } from '@aws-cdk/aws-ssm';
import { Table } from '@aws-cdk/aws-dynamodb';
export class LambdaStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// パラメータストアから値を取得する
const tableArn = StringParameter.valueForStringParameter(this, 'SampleTableArn');
// 既存のテーブルを取得する
const sampleTable = Table.fromTableArn(this, 'fromSampleTable', tableArn);
const sampleFn = new Function(this, 'SampleFn', {
code: Code.fromAsset('../handlers'),
handler: 'sample.handler',
runtime: Runtime.NODEJS_12_X,
environment: {
// 既存のテーブル情報からLambdaの環境変数にテーブル名を登録する
SampleTableName: sampleTable.tableName
}
});
// 既存のテーブル情報からIAMロールを作成しLambda関数に設定する
sampleTable.grantFullAccess(sampleFn);
}
}
デプロイ
bin/sample-stack.ts
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import { DynamoDBStack } from '../lib/dynamodb-stack';
import { LambdaStack } from '../lib/lambda-stack';
const app = new cdk.App();
new DynamoDBStack(app, 'DynamoDBStack');
new LambdaStack(app, 'LambdaStack');
cdk deploy DynamoDBStack
cdk deploy LambdaStack
まとめ
小ネタ的な記事でした。CDK でスタックを分割する場合に、クロススタック参照にしてしまうと、スタック間が密結合になってしまい、参照元のスタックを更新できなくなるなどの問題があります。その解決策としてパラメーターストアと from*Arn
のメソッドを使って、スタック間を疎結合にするというような用途で使えると思います。