Node.js でマルチアカウントの AWS リソース情報をファイル出力してみた
使用している AWS リソース情報を一覧で確認したいことってありますよね。
単一アカウントであれば、以下の方法があります。
今回は、上記の方法のうち 2 つ目の記事を参考に、マルチアカウントの AWS リソース情報を json ファイルとして出力する Node.js プログラムを作成してみました。
前提
・AWS マルチアカウント構成である
・各アカウントにはスイッチロールすることができる
・スイッチロールの権限は AdministratorAccess
・AWS CLI でスイッチロールができる状態である
・CLI からの呼び出しで MFA は使用していない
なお、今回はマルチリージョンでの出力は行っていませんのでご注意ください。
コード
Node.js でのスイッチロールは以下の記事のコードを流用しています。
const fs = require("fs");
const AWS = require("aws-sdk");
AWS.config.update({ region: "ap-northeast-1" });
AWS.config.apiVersions = {
sts: "2011-06-15",
resourcegroupstaggingapi: "2017-01-26",
};
const sts = new AWS.STS();
const main = async () => {
const ops = {
flag: "a",
};
const profiles = ["profile-name-1 ", "profile-name-2"];
const roles = [
"アカウント A の スイッチ用 IAM ロール ARN",
"アカウント B の スイッチ用 IAM ロール ARN",
];
const roleSessionNames = ["test1", "test2"];
for (let i = 0; i < profiles.length; i++) {
const credentials = new AWS.SharedIniFileCredentials({
profile: profiles[i],
});
AWS.config.credentials = credentials;
try {
const credentials = await assumeRole(roles[i], roleSessionNames[i]);
const options = {
accessKeyId: credentials.AccessKeyId,
secretAccessKey: credentials.SecretAccessKey,
sessionToken: credentials.SessionToken,
};
const resourcegroupstaggingapi = new AWS.ResourceGroupsTaggingAPI(
options
);
const result = await resourcegroupstaggingapi.getResources().promise();
const str = JSON.stringify(result);
fs.writeFile("resources.json", str, ops, (err) => {
if (err) {
console.log(err);
}
});
} catch (error) {
console.log(error);
}
}
};
main();
async function assumeRole(RoleArn, RoleSessionName) {
const params = {
RoleArn,
RoleSessionName,
};
try {
const result = await sts.assumeRole(params).promise();
return result.Credentials;
} catch (error) {
console.log(error);
}
}
コード内容
Node.js でのスイッチロール部分に関しては、先述の記事で説明しているので割愛します。
GetResources API
今回はリソース情報を取得するために、GetResources という API を使用しています。
GetResources
は ResourceGroupsTaggingAPI
というサービス API に含まれるので、以下の部分で STS とともに API バージョンを指定しています。
AWS.config.apiVersions = {
sts: "2011-06-15",
resourcegroupstaggingapi: "2017-01-26",
};
設定値のロード
以下の部分で config ファイルに記載されているスイッチロール用の各種 profile 情報をロードします。
(ロードではなくハードコーディングですが…)
const profiles = ["profile-name-1 ", "profile-name-2"];
const roles = [
"アカウント A の スイッチ用 IAM ロール ARN",
"アカウント B の スイッチ用 IAM ロール ARN",
];
const roleSessionNames = ["test1", "test2"];
本来はハードコーディングせずに config ファイルから直接ロードしたかったのですが、ロード方法がわからなかったので、ハードコーディングになりました。
config ファイルからロードする方法があればそちらの方が良いと思います。
ループでスイッチロール
各アカウントへのスイッチロール用の profile 分ループさせて、スイッチロールごとに GetResources
を呼び出しています。
取得した結果を文字列に変換してから、ファイルに追記モードで書き込んでいます。
for (let i = 0; i < profiles.length; i++) {
const credentials = new AWS.SharedIniFileCredentials({
profile: profiles[i],
});
AWS.config.credentials = credentials;
try {
const credentials = await assumeRole(roles[i], roleSessionNames[i]);
const options = {
accessKeyId: credentials.AccessKeyId,
secretAccessKey: credentials.SecretAccessKey,
sessionToken: credentials.SessionToken,
};
const resourcegroupstaggingapi = new AWS.ResourceGroupsTaggingAPI(
options
);
const result = await resourcegroupstaggingapi.getResources().promise();
const str = JSON.stringify(result);
fs.writeFile("resources.json", str, ops, (err) => {
if (err) {
console.log(err);
}
});
} catch (error) {
console.log(error);
}
}
追記モードに関しては、ループの中で毎回指定する必要はなかったので、処理の冒頭で以下のように指定しています。
const ops = {
flag: "a",
};
実行方法
aws-sdk
をインストールする必要があるので、以下のコマンドを実行します。
npm i aws-sdk
aws-sdk
をインストール後、以下のコマンドでプログラムを実行します。
node sample.js
実行後に resources.json
というファイルが生成され、各アカウントの東京リージョンのリソース情報が記載されているはずです。
整形
プログラム実行語に生成された json ファイルは不正な形式なので、フォーマットがうまくいかないと思います。
そのため、アカウントごとの切れ目を見つけて、別々の json ファイルにする必要があるのですが、切れ目の見つけ方は簡単です。
文字列検索で、PaginationToken
という単語がヒットするので、この直前の {
がアカウントの切れ目です。
なので、PaginationToken
直前の {
から始まる 1 ブロックごとに別々の json ファイルに分けると、うまく整形できるはずです。
そもそもプログラム側で書き込む時に、 1 つの json ファイルではなく、別々の json ファイルに分けるという方法もあると思いますので、適宜変更して下さい。
その他
マルチリージョンのリソース情報を取得する場合は、リージョン分ループかつアカウント分ループの 2 重ループでできるのではないかと思っています。
そのうち試してみようと思います。
また、シェルスクリプトでもできる気はしますが、僕はスクリプトよくわからないマンなので、きっと誰かが作ってくれるのではないかと願っています。
まとめ
今回はマルチアカウントの AWS リソース情報を json ファイルとして出力する Node.js プログラムを作成してみました。
改良の余地はありますが、参考になれば幸いです。
Discussion