(小ネタ)スクリプトを使い、複数アカウントでAWS Configの有効/無効をチェックしてみた

記事タイトルとURLをコピーする

エンタープライズクラウド部の山下(祐)です。

最近、200個くらいのアカウントでAWS Configが有効化されているか確認する必要があったため、 簡単なスクリプトを作って確認してみました。 本ブログでは、その内容についてご紹介します。

今回の環境

今回は、以下のような条件下で確認を行いました。

  • 踏み台アカウントから各アカウントへスイッチロールを行い、Config有効化を確認する
  • 各アカウントのスイッチロール先のロール名は同じ
  • 踏み台アカウントにはMFAが設定されている
  • 各アカウントはOrganizationsの組織に所属している
  • 確認するリージョンは1リージョンのみ(今回は東京リージョン)

下図のような動作イメージとなります。

事前準備

まずは事前準備として、以下を実施します。

  • アカウント一覧を取得する
  • 踏み台アカウントの一時認証情報を取得する
  • 「.aws/config」にprofileを追加する

アカウント一覧を取得する

以下コマンドを実行します。 profile には、Organizationsの管理アカウントの profile を指定します。

aws organizations list-accounts --query "Accounts[].[Id]" --output text --profile xxxxxx >>./account.txt

account.txtの中身は、以下のサンプルのような、1行につき1アカウントが記載されたリストとなります。

111111111111
222222222222
333333333333
444444444444
・
・
・

踏み台アカウントの一時認証情報を取得する

以下コマンドを実行し、踏み台アカウントの一時認証情報を取得します。 スクリプトで複数アカウントの確認を自動化する際に、MFAコードの手動入力を求められないようにするためです。

aws sts get-session-token --serial-number <MFAデバイスのARN> --token-code <MFAトークンコード>

以下のサンプルのような、一時認証情報が出力されます。 有効期限があるためご注意ください。(Expirationに記載の時刻まで利用可能)

{
  "Credentials": {
    "AccessKeyId": "ASIA574××××××××S5UOKBD",
    "SecretAccessKey": "Enqe7K7Oj2VKVM×××××××××××thvYSBf86AO/H",
    "SessionToken": "FwoGZXIvYXdzEKX//////////wEaDG4IBEijFDaVHbCUMiKGAYqcEoXb7SEIV7yf3LTu××××××××××××××××××××××××××××××××××××××p8sLWDg7lj1Ue8jQkWAmZ8/IEtcQDSL88kSY4lExWYBAmMmdbSzkvAeo5fX7np7gPG5O5TxaxFhBCnnI/vbmo7MHZWOo+EqulN0iRm60Y3gbVKJShyJoGMijoyK/mZ/jc2wP4Uoay72yNeJUJcOr5TdZ2uhyf7yTOZomLT9GsE3Xb"
    "Expiration": "2024-05-28T21:31:35+00:00"
  }
}

取得した情報を「.aws/credential」に追記します。

[bastion]
aws_access_key_id = ASIA574××××××××S5UOKBD
aws_secret_access_key = Enqe7K7Oj2VKVM×××××××××××thvYSBf86AO/H
aws_session_token = FwoGZXIvYXdzEKX//////////wEaDG4IBEijFDaVHbCUMiKGAYqcEoXb7SEIV7yf3LTu××××××××××××××××××××××××××××××××××××××p8sLWDg7lj1Ue8jQkWAmZ8/IEtcQDSL88kSY4lExWYBAmMmdbSzkvAeo5fX7np7gPG5O5TxaxFhBCnnI/vbmo7MHZWOo+EqulN0iRm60Y3gbVKJShyJoGMijoyK/mZ/jc2wP4Uoay72yNeJUJcOr5TdZ2uhyf7yTOZomLT9GsE3Xb

「.aws/config」にprofileを追加する

踏み台用、スイッチロール用のprofileを「.aws/config」に追記します。

[profile bastion]
region = ap-northeast-1
output = json

[profile xxxxxxxxxxxx]
region = ap-northeast-1
ourput = json
role_arn = arn:aws:iam::xxxxxxxxxxxx:role/SampleRole
source_profile = bastion

スクリプトを実行

事前準備が出来たら、スクリプトを実行します。

今回作成したスクリプト

今回作成したスクリプトは以下です。 「account.txt」と「.aws/config」はスクリプトファイルの相対パスで記載しています。 お手元の環境で実行される場合は、パスを環境に合わせて適宜修正ください。

#!/bin/bash

FILE_NAME=./account.txt
while read PROFILE
do
  sed -i ./.aws/config -e "s/xxxxxxxxxxxx/$PROFILE/g"
  sleep 1
  
  RECORDING=$(aws configservice describe-configuration-recorder-status --profile ${PROFILE} --query 'ConfigurationRecordersStatus[].recording' --output text)
  sleep 10

  if [ -z "$RECORDING" ]; then
    RECORDING="false"
  fi

  echo "${PROFILE},${RECORDING}" >> config.csv
  
  sed -i ./.aws/config -e "s/$PROFILE/xxxxxxxxxxxx/g"
  sleep 1
done < ${FILE_NAME}

スクリプトの細かい内容について以下で解説します。

繰り返し部分の処理

FILE_NAME=./account.txt
while read PROFILE
do
・
・
・
done < ${FILE_NAME}

「account.txt」から1行ずつアカウント番号を読み込みます。アカウントの数だけ処理を繰り返します。

profileの変換

 sed -i ./.aws/config -e "s/xxxxxxxxxxxx/$PROFILE/g"

「./.aws/config」のprofileのxxxxxxxxxxxxの部分を、「account.txt」のアカウント番号に変換します。

# 変換前
[profile xxxxxxxxxxxx]
region = ap-northeast-1
ourput = json
role_arn = arn:aws:iam::xxxxxxxxxxxx:role/SampleRole
source_profile = bastion

# 変換後
[profile 111111111111]
region = ap-northeast-1
ourput = json
role_arn = arn:aws:iam::111111111111:role/SampleRole
source_profile = bastion

スイッチロール先のロール名が全アカウントで共通の場合、アカウント番号を変換すれば、profileを使いまわすことが可能です。 予め全アカウント分のprofileを用意する必要がないため、アカウント数が多い場合は作業が効率的になります。

Config有効化の確認

  RECORDING=$(aws configservice describe-configuration-recorder-status --profile ${PROFILE} --query 'ConfigurationRecordersStatus[].recording' --output text)
  sleep 10

  if [ -z "$RECORDING" ]; then
    RECORDING="false"
  fi

AWS Configが有効化されているかどうか確認します。「aws configservice describe-configuration-recorder-status」の出力結果は、Configが有効化されている場合とされていない場合で、それぞれ以下のようになります。

# Configが有効化されている場合
{
  "ConfigurationRecordersStatus": [
    {
      "name": "configuration-recorder-ap-northeast-1",
      "lastStartTime": "2020-08-12T12:30:31.014000+09:00",
      "recording": true,
      "lastStatus": "SUCCESS",
      "lastStatusChangeTime": "2024-05-28T18:30:41.578000+09:00"
    }
  ]
}

# Configが有効化されていない場合
{
  "ConfigurationRecordersStatus": []
}

そのため、Configが有効化されている場合、上述の変数 RECORDING の値は「true」となり、Configが有効化されていない場合、RECORDING の値は null となります。 null だと少し分かりにくいので、以下の処理で、RECORDING の値が nullだった際には、「false」という値を代入しています。

  if [ -z "$RECORDING" ]; then
    RECORDING="false"
  fi

結果をCSVに書き込み

echo "${PROFILE},${RECORDING}" >> config.csv

PROFILE変数にはアカウント番号、RECORDING変数にはtrue か false の値が入っています。 そのため、CSVの中身は以下のようなイメージとなります。

111111111111,true
222222222222,false
333333333333,false
444444444444,true
・
・
・

profileを元に戻す

  sed -i ./.aws/config -e "s/$PROFILE/xxxxxxxxxxxx/g"

繰り返し処理のために、「.aws/config」のprofileのアカウント番号を、再度「xxxxxxxxxxxx」に戻します。

# 変換前
[profile 111111111111]
region = ap-northeast-1
ourput = json
role_arn = arn:aws:iam::111111111111:role/SampleRole
source_profile = bastion

# 変換後
[profile xxxxxxxxxxxx]
region = ap-northeast-1
ourput = json
role_arn = arn:aws:iam::xxxxxxxxxxxx:role/SampleRole
source_profile = bastion

ちょっと不格好ですが、そうしょっちゅう使うものでもないですし、シンプルな作りにしたかったので、これで良しとしました。



以上、複数アカウントのConfig有効化チェックでした。
AWSの利用期間が長くアカウント数も多い組織では、AWS Configが有効化されているアカウントとそうでないアカウントが入り混じって、確認が面倒なケースもあるかと思います。 そのような時に、本ブログがお役に立てば幸いです。

山下 祐樹(執筆記事の一覧)

2021年11月中途入社。前職では情シスとして社内ネットワークの更改や運用に携わっていました。 2023 Japan AWS All Certifications Engineers。