2025年2月6日に AWS CloudFormation の新機能「Stack Refactoring(スタックリファクタリング)」がリリースされた👏
運用中の AWS CloudFormation スタックでリソースの論理 ID を変更したり,リソースを別の AWS CloudFormation スタックに移動できる.ある程度の規模になると AWS CloudFormation スタックのリソースを見直したいな〜という場面もあって,今までだと「諦める」or「DeletionPolicy: Retain
で紐付きを解除してからインポートする」という選択肢があったりした.
今回はまず「同じ AWS CloudFormation スタックでリソースの論理 ID を変更する」を試す \( 'ω')/
準備
👾 template.yaml
まずは Amazon CloudWatch Logs ロググループを定義する.このとき論理 ID は Logs
にしておく👌
AWSTemplateFormatVersion: 2010-09-09 Resources:Logs:Type: AWS::Logs::LogGroup Properties:LogGroupName: cfn-stack-refactoring-logical-id
そして aws cloudformation deploy
コマンドを使って AWS CloudFormation スタックをデプロイする.
$ aws cloudformation deploy \--stack-name cfn-stack-refactoring-logical-id \--template-file ./template.yaml
リファクタリング
👾 template.yaml
スタックリファクタリングではリファクタリング後の AWS CloudFormation テンプレートも必要になる.以下のように論理 ID を AwesomeLogs
に変更した.今までだと,論理 ID を変更するとリソースの置換になってしまっていた🔥
AWSTemplateFormatVersion: 2010-09-09 Resources:AwesomeLogs:Type: AWS::Logs::LogGroup Properties:LogGroupName: cfn-stack-refactoring-logical-id
👾 refactor.json
次にリファクタリングの対象を指定する refactor.json
を作る.今回は同じ AWS CloudFormation スタックになるため StackName
は cfn-stack-refactoring-logical-id
で,LogicalResourceId
を Source(リファクタリング前)
と Destination(リファクタリング後)
で変更している👌
[{"Source": {"StackName": "cfn-stack-refactoring-logical-id", "LogicalResourceId": "Logs" }, "Destination": {"StackName": "cfn-stack-refactoring-logical-id", "LogicalResourceId": "AwesomeLogs" }}]
実行する
スタックリファクタリングを実行する前に,まず aws cloudformation create-stack-refactor
コマンドを使ってスタックリファクタリング ID を採番する.オプションとしては大きく3つ指定した👌
--stack-definitions
: スタック名と AWS CloudFormation テンプレート名(修正後)を指定する--no-enable-stack-creation
: 新しく AWS CloudFormation スタックは作らない--resource-mappings
: 作成したrefactor.json
を指定する
$ aws cloudformation create-stack-refactor \--stack-definitionsStackName=cfn-stack-refactoring-logical-id,TemplateBody@=file://template.yaml \--no-enable-stack-creation\--resource-mappings file://refactor.json {"StackRefactorId": "1da7a9b6-bf69-4f7e-9e16-cb52eca39250"}
次は aws cloudformation describe-stack-refactor
コマンドを使ってステータスを確認する.問題なければ以下のようになる.AWS CloudFormation テンプレートや refactor.json
に誤りがあると ExecutionStatus: UNAVAILABLE
/ Status: CREATE_FAILED
と表示される💨 エラー原因は StatusReason
を参考に直していく.
$ aws cloudformation describe-stack-refactor \--stack-refactor-id 1da7a9b6-bf69-4f7e-9e16-cb52eca39250 {"StackRefactorId": "1da7a9b6-bf69-4f7e-9e16-cb52eca39250", "StackIds": ["arn:aws:cloudformation:ap-northeast-1:000000000000:stack/cfn-stack-refactoring-logical-id/7a806480-e6f7-11ef-86d1-0e4a804155dd"], "ExecutionStatus": "AVAILABLE", "Status": "CREATE_COMPLETE"}
最後は aws cloudformation execute-stack-refactor
コマンドを使ってスタックリファクタリングを実行すれば完了👌
$ aws cloudformation execute-stack-refactor \--stack-refactor-id 1da7a9b6-bf69-4f7e-9e16-cb52eca39250
実行結果を確認する
おおお〜 \( 'ω')/
参考: AWS SAM x スタックリファクタリング
AWS CloudFormation でスタックリファクタリングを試した後に AWS SAM でも試してみたところ Resource ${LogicalId} in stack ${ARN} does not match the destination resource's properties.
というエラーが出てしまった.sam package
コマンドで生成された .aws-sam/build/template.yaml
には自動的に SamResourceId
というメタデータが付くため,差分をなくすために削除もしてみたけどエラーは解消できなかった.あと AWS::Serverless::Function
で自動生成する IAM Role のようなリソースがある場合も問題がありそうだった.今度再挑戦しよう〜💪