🤔

AWS CLIでこのAWSリソースってCloudFormationスタックで定義したやつだっけ・・を調べる方法

2021/06/28に公開

はじめに

不要なAWS環境を整理していて、とあるリソースを削除しようと思ったのですが、もしCloudFormationスタックで定義したものだったらドリフトが発生してしまう、定義したものだったかどうか覚えてない、削除したら戻すのが面倒、、、という状況になりました。

若干力技ですが、

  • 全スタックを一覧
  • 結果を出力
  • 出力結果から探す
    という方法をとりました。

前提

以下の環境に対して処理を行います

  • スタック数
    115つくらいあります
$ aws cloudformation list-stacks | jq .StackSummaries[].StackName | wc -l
     115

やってみたこと

CreateLambdaFunction という論理名のLambda関数を探してみます。

AWS SDK for JavaScriptを利用して、

  • listStacksで全スタックを取得
  • 取得したスタック一つ一つに対してlistStackResourcesを実行して全リソースを取得し、CreateLambdaFunction という論理名のLambda関数が無いかどうか確認
    を行いました。

サンプルコードは下記です。

app.js
const AWS = require("aws-sdk");
AWS.config.update({region:'ap-northeast-1'});
const CFn = new AWS.CloudFormation();

const main = async () => {
  const targetResource = "CreateLambdaFunction"; // 論理ID

  const targetStackList = await listTargetStacks();
  await findTargetResource(targetStackList, targetResource);
}

const listTargetStacks = async () => {
  let items = []
  let res;
  let params = {
    StackStatusFilter: [
      'CREATE_COMPLETE', 'UPDATE_COMPLETE'
    ]    
  }
  do {
    res = await CFn.listStacks(params).promise();
    items.push(...res.StackSummaries);
    params = { ...params, NextToken:res.NextToken }
  } while ( res.NextToken );

  return items.map( x => x.StackName );
}

const findTargetResource = async (stackNames , targetResource) => {
  let items = [];

  for (let index in stackNames) {
      let params = {
        StackName: stackNames[index],
      };
    try {
      do {
        await new Promise( resolve => setTimeout( () => { resolve();}, 1000)); // スロットリング回避用
        res = await CFn.listStackResources(params).promise();
        res.StackResourceSummaries.forEach( i => {
          if (i.LogicalResourceId === targetResource) {
            console.log(stackNames[index] + "のスタック内に存在します");
          }
          items.push(i.LogicalResourceId);
        })
        params = { ...params, NextToken:res.NextToken }
      } while ( res.NextToken );        
    } catch (e) {
      console.error(e);
    }      
  }
}

main();

実行結果は次のようになりました。

$ node app.js
hirobeltodoapp-devのスタック内に存在します
sample-app-devのスタック内に存在しま

マネコンで調べてみると・・ありました。

おわりに

115つスタックがあったので、115回API叩いてしまっている。。
もうちょっと効率がいい方法があれば知りたい。

急いで同じようなことしたい方は参考にしてみてください。

参考

Discussion