はじめに
ご覧いただき、ありがとうございます。
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 であるようなので、ご注意ください。
それ以外の方法としては、サードパーティのパッケージを利用するという手もあります。
最後までご覧いただき、ありがとうございました。