kakakakakku blog

Weekly Tech Blog: Keep on Learning!

CloudFormation スタックリファクタリング: リソースの論理 ID を変更しよう

2025年2月6日に AWS CloudFormation の新機能「Stack Refactoring(スタックリファクタリング)」がリリースされた👏

運用中の AWS CloudFormation スタックでリソースの論理 ID を変更したり,リソースを別の AWS CloudFormation スタックに移動できる.ある程度の規模になると AWS CloudFormation スタックのリソースを見直したいな〜という場面もあって,今までだと「諦める」or「DeletionPolicy: Retain で紐付きを解除してからインポートする」という選択肢があったりした.

aws.amazon.com

今回はまず「同じ 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 スタックになるため StackNamecfn-stack-refactoring-logical-id で,LogicalResourceIdSource(リファクタリング前)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-definitions StackName=cfn-stack-refactoring-logical-id,TemplateBody@=file://template.yaml \
    --no-enable-stack-creation \
    --resource-mappings file://refactor.json
{
    "StackRefactorId": "1da7a9b6-bf69-4f7e-9e16-cb52eca39250"
}

awscli.amazonaws.com

次は 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"
}

awscli.amazonaws.com

最後は aws cloudformation execute-stack-refactor コマンドを使ってスタックリファクタリングを実行すれば完了👌

$ aws cloudformation execute-stack-refactor \
    --stack-refactor-id 1da7a9b6-bf69-4f7e-9e16-cb52eca39250

awscli.amazonaws.com

実行結果を確認する

おおお〜 \( 'ω')/

参考: 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 のようなリソースがある場合も問題がありそうだった.今度再挑戦しよう〜💪

関連記事

aws.amazon.com