はじめに
ご覧いただき、ありがとうございます。
AWS CDK で S3 クロスリージョンレプリケーションを設定する AWS CDK Advanced Workshop をやってみました。
設定自体はこのワークショップに沿って簡単にできましたが
その過程で気になったことを書き残したいと思います。
気になったところ
S3 バケット暗号化用 KMS キーを作成する必要がある
2023 年 1 月 5 日 から全ての S3 バケットの暗号化が必須になっています。
単にバケットを使用するだけであれば、デフォルトでキーの作成や設定は自動的にやってくれるため、特に問題はありません。
しかしながら、レプリケーションを設定する際は、レプリケーション先の S3 バケットで使用するキーを明示的に指定する必要があります。
そのため、予めレプリケーション先で新規にキーを作成しておいて、それを指定するようにします。
レプリケーション元からレプリケーション先の KMS キーを参照する方法
先述のとおり、レプリケーションを設定する際は、レプリケーション先の KMS キーを指定する必要があるため
レプリケーション元から KMS キーを参照できるようにする必要があります。
しかし、CloudFormation はネイティブでリージョン間の参照を行えません。
そこで、キーを SSM パラメータに格納し、SSM 経由で参照できるようにします。
export class MultiRegionS3CrrKmsCmkTarget extends Construct {
// プロパティを定義する
public readonly targetBucket: s3.Bucket;
public readonly targetKeyIdSsmParameterName: string;
constructor(scope: Construct, id: string) {
(中略)
// キーを SSM パラメータに格納する
const stack = cdk.Stack.of(this);
const parameterName = `${stack.stackName}.MyTargetKeyId`;
new ssm.StringParameter(this, 'MyTargetKeyIdSSMParam', {
parameterName: parameterName,
description: 'The KMS Key Id for the target stack',
stringValue: targetKmsKey.keyArn
});
// 値を設定する
this.targetBucket = targetBucket;
this.targetKeyIdSsmParameterName = parameterName;
}
}
SSM に格納したターゲット KMS キーは、カスタムリソースを使用して取得します。
カスタムリソースは簡単に説明すると、CloudFormation で提供されていない処理を、ユーザ自身が作成できる仕組みになります。
異なるリージョンの SSM パラメータはインポートできないため、このような機能を利用する必要があります。
ちなみに、同じリージョンであれば、ssm.StringParameter.valueFromLookup() メソッドで対応できます。
const targetKeyLookupCR = new cr.AwsCustomResource(this, 'TargetKeyLookup', {
// 今回はスタック作成、もしくは更新時に実行されてほしいため、`onUpdate` プロパティで設定しています。
// (`onUpdate` は作成時も実行されます。)
onUpdate: {
service: 'SSM',
action: 'getParameter',
parameters: {
Name: props.targetKeyIdSsmParameterName
},
region: props.targetRegion,
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString())
},
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({resources: [parameterArn]})
});
この物理リソース ID(physicalResourceId プロパティ)に、現在時間(Date.now())を含めることで
デプロイされるたびに値は変化し、スタックが更新されることになります。
このような設定をしている理由は、CDK(CloudFormation)で作成されるリソースのうち、物理名が付与されているものについては
例えば、イミュータブルなプロパティの変更、つまり、リソースの置き換えが必要になった際に
物理名を変更するか、もしくはスタックを 1 度削除しなければならないからです。
すなわち、キーが変更された際も、自動的に新しいキーがインポートされるようになるということです。
- Resources – AWS Cloud Development Kit (AWS CDK) v2 – Physical names
- Update a CloudFormation stack when a custom-named resource requires replacing | AWS re:Post
最後の policy プロパティでは、カスタムリソースを実行するための権限を付与しています。
SSM パラメータの ARN を指定し、ポリシーを設定します。
なお、内部的には Lambda 関数及びそのための IAM ポリシーが作成され、実行されることになります。
終わりに
やはりクロスリージョン参照がやや複雑であると感じました。
一発で設定できる crossRegionReferences プロパティというものもありますが、本記事を投稿した時点では experimental であるようなので、ご注意ください。
それ以外の方法としては、サードパーティのパッケージを利用するという手もあります。
最後までご覧いただき、ありがとうございました。