最近CDK使ってて出会した
端的に言えばCFnが悪いやつ(下はGithubのIssue)
ただまあ公式にも書いてあるこれをどうにかしてデプロイしたい
CreationPolicy、DeletionPolicy または UpdatePolicy 属性単独では更新できません。
更新できるのは、リソースを追加、変更、または削除する変更を含める場合だけです。
たとえば、リソースのメタデータ属性を追加または変更することはできます。
しかしながら一部変更を適用するのに、
いちいちリソースを変更まではしたくないなあと思って適当に回避策を思いついて試したらうまく動いたので残しとく
まずは適当にCDKのアプリケーションを作る(今回はTypeScriptだけど他の言語でも出来るはず)
cdk init app --language typescript # 作ると勝手にディレクトリ移動されるので今回はS3を使う npm install @aws-cdk/aws-s3
作ったらまずは適当にBucketを作る
import * as cdk from '@aws-cdk/core'; import * as s3 from '@aws-cdk/aws-s3'; export class CdkTestStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new s3.Bucket(this, 'TestBucket', { bucketName: 'ex-test-bucket-000000' }); } }
デプロイする
npm run cdk -- deploy
で、作ったあとにやっぱRemovalPolicyにDESTROYをつけたくなったとする
new s3.Bucket(this, 'TestBucket', { bucketName: 'ex-test-bucket-000000', removalPolicy: cdk.RemovalPolicy.DESTROY, });
diffが出る(元々デフォルトでRetainがついてるので)
npm run cdk -- diff > cdk-test@0.1.0 cdk > cdk "diff" Stack CdkTestStack Resources [~] AWS::S3::Bucket TestBucket TestBucket560B80BC ├─ [~] DeletionPolicy │ ├─ [-] Retain │ └─ [+] Delete └─ [~] UpdateReplacePolicy ├─ [-] Retain └─ [+] Delete
デプロイするとNo changes!!!!😇
npm run cdk -- deploy > cdk-test@0.1.0 cdk > cdk "deploy" CdkTestStack: deploying... CdkTestStack: creating CloudFormation changeset... ✅ CdkTestStack (no changes)
というわけで↓を新たに入れておく
new cdk.CfnOutput(this, 'UpdateTime', { description: 'UpdateTime', value: new Date().toLocaleString(), })
diffが増える
npm run cdk -- diff > cdk-test@0.1.0 cdk > cdk "diff" Stack CdkTestStack Resources [~] AWS::S3::Bucket TestBucket TestBucket560B80BC ├─ [~] DeletionPolicy │ ├─ [-] Retain │ └─ [+] Delete └─ [~] UpdateReplacePolicy ├─ [-] Retain └─ [+] Delete Outputs [+] Output UpdateTime UpdateTime: {"Description":"UpdateTime","Value":"2021/7/22 16:51:32"}
デプロイをする
今回はリソースを追加したので当たり前だが成功する
npm run cdk -- deploy > cdk-test@0.1.0 cdk > cdk "deploy" CdkTestStack: deploying... CdkTestStack: creating CloudFormation changeset... ✅ CdkTestStack Outputs: CdkTestStack.UpdateTime = 2021/7/22 16:52:02
今度はRemovalPolicyをRETAINに戻したくなったとする
new s3.Bucket(this, 'TestBucket', { bucketName: 'ex-test-bucket-000000', // removalPolicy: cdk.RemovalPolicy.DESTROY, これを削除する });
diffを見る
(ぱっと見、上で失敗したときのパターンに見える)
npm run cdk -- diff > cdk-test@0.1.0 cdk > cdk "diff" Stack CdkTestStack Resources [~] AWS::S3::Bucket TestBucket TestBucket560B80BC ├─ [~] DeletionPolicy │ ├─ [-] Delete │ └─ [+] Retain └─ [~] UpdateReplacePolicy ├─ [-] Delete └─ [+] Retain
これをdeployするとOutputsのUpdateTimeが変わる為、CDK(CFn)はちゃんとデプロイしてくれる
npm run cdk -- deploy > cdk-test@0.1.0 cdk > cdk "deploy" CdkTestStack: deploying... CdkTestStack: creating CloudFormation changeset... ✅ CdkTestStack Outputs: CdkTestStack.UpdateTime = 2021/7/22 16:56:21
再度diffを叩くと何も変更なしになる
(リソースへの変更は適用された為)
npm run cdk -- diff > cdk-test@0.1.0 cdk > cdk "diff" Stack CdkTestStack There were no differences
この状態でdeployするとUpdateTimeに対しての変更がかかる
npm run cdk -- deploy > cdk-test@0.1.0 cdk > cdk "deploy" CdkTestStack: deploying... CdkTestStack: creating CloudFormation changeset... ✅ CdkTestStack Outputs: CdkTestStack.UpdateTime = 2021/7/22 16:58:23
とまあこんな感じでOutputsにUpdateTimeとかを設定しておけば、
管理したいリソースに対して変更を加えずともOutputsに変更を加えて半強制的にデプロイをすることが出来て便利という小技