📝

Node.js の Lambda でマルチアカウントの AWS リソース情報を出力してみた

2025/01/29に公開

Node.js でマルチアカウントの AWS リソース情報をファイル出力してみた
上記を Lambda で実装してみました。

Lambda 関数設定

  • ランタイム: Node.js 22.x
  • タイムアウト: 30 秒
  • 実行ロールの権限: AdministratorAccess
  • 環境変数
    • role1: アカウント A の IAM ロール ARN
    • role2: アカウント B の IAM ロール ARN
    • role3: アカウント C の IAM ロール ARN

各アカウントの IAM ロールについて

別のアカウントでロールを引き受けるために Lambda 関数を設定する | AWS re:Post

  • AdministratorAccess 権限を付与
  • 信頼関係で Lambda 実行ロールからの AssumeRole を許可
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678901:role/my-lambda-execution-role"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

コード

index.js
index.js
const { STSClient, AssumeRoleCommand } = require("@aws-sdk/client-sts");
const {
  ResourceGroupsTaggingAPIClient,
  GetResourcesCommand,
} = require("@aws-sdk/client-resource-groups-tagging-api");
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3");
const fspromises = require("fs").promises;

exports.handler = async function (event, context) {
  const sts = new STSClient();
  const s3 = new S3Client();

  const roles = [process.env.role1, process.env.role2, process.env.role3];

  for (let i = 0; i < roles.length; i++) {
    const accountId = roles[i].substring(13, 25);

    const input = {
      RoleArn: roles[i],
      RoleSessionName: `role-${accountId}`,
    };

    try {
      const assumeRolecommand = new AssumeRoleCommand(input);
      const credentials = await sts.send(assumeRolecommand);

      const resourceGroupsTaggingAPI = new ResourceGroupsTaggingAPIClient({
        region: "ap-northeast-1",
        credentials: {
          accessKeyId: credentials.Credentials.AccessKeyId,
          secretAccessKey: credentials.Credentials.SecretAccessKey,
          sessionToken: credentials.Credentials.SessionToken,
        },
      });
      const getResourcescommand = new GetResourcesCommand();
      const response = await resourceGroupsTaggingAPI.send(getResourcescommand);
      const str = JSON.stringify(response);

      await fspromises.writeFile(`/tmp/resources-${accountId}.json`, str);
      await new Promise((resolve) => setTimeout(resolve, 3000));
      const buff = await fspromises.readFile(
        `/tmp/resources-${accountId}.json`
      );

      const param = {
        Body: buff,
        Bucket: "your-bucket-name",
        Key: `resources-${accountId}.json`,
      };
      const command = new PutObjectCommand(param);
      await s3.send(command);
    } catch (error) {
      console.log(error);
    }
  }
};

フロー

  1. 環境変数からアカウント ID および IAM ロール ARN を取得
  2. AssumeRole で各アカウントの IAM ロールの認証情報を取得
  3. GetResources API で各アカウントのリソース情報を取得
  4. 3 の情報を json ファイルとして Lambda のエフェメラルストレージに出力
  5. 4 で出力された json ファイルを読み取って S3 にアップロード

実行結果

S3 バケットに以下のような json ファイルがアップロードされていれば成功です。

  • resources-111111111111.json
  • resources-222222222222.json
  • resources-333333333333.json

まとめ

今回は Node.js の Lambda でマルチアカウントの AWS リソース情報を出力してみました。
どなたかの参考になれば幸いです。

参考資料

Discussion