HAPPY HACKING Oouchi's BLOG

PSE(ポンコツエンジニア)の技術ブログ

【AWS Organizations】メンバーアカウントを大量に作成する

f:id:ooooouchi:20200517021141p:plain

はじめに

先日のAWS CLI勉強会以来、AWS CLIにはまりました。
マネージメントコンソールを使用する作業は「CLIでできるかどうか」をまず考えるようになりました。

↓勉強会参加レポート

www.ooooouchi.info

今回は、実際に想定できるユースケースに沿ったCLIスクリプトを紹介します。

本題

やりたいこと

  • 指定した回数だけAWSアカウント作成コマンドを実行する
  • 作成中は処理が完了するまで待つ

前提

jqコマンドを使用しています。

qiita.com

実装

AWS_PROFILE_NAME=       # aws cliのプロファイル
CREATE_ACCOUNT_LENGTH=2 # 作成したいアカウント数
ROLE_NAME=              # デフォルトロールネーム
MAIL_NAME=              # メールアドレスのドメイン以前
MAIL_DOMAIN=            # メールアドレスのドメイン以降

echo "Start:create-account "
declare -a result=()
i=0
while :; do

    # ランダム文字列作成
    randomStr=$(cat /dev/urandom | tr -dc 'a-z0-9' | head -c 10)

    # プレフィクス付きメールアドレス作成
    accountName=${MAIL_NAME}+${randomStr}
    accountEmail=${accountName}${MAIL_DOMAIN}

    # アカウント作成
    account=$(
        aws organizations create-account \
            --profile ${AWS_PROFILE_NAME} \
            --email $accountEmail \
            --account-name $accountName \
            --role-name ${ROLE_NAME} \
            --iam-user-access-to-billing ALLOW |
            sed -e "s/[\r\n]\+//g"
    )

    # 作成ステータス確認
    while :; do
        requestId=$(echo $account |
            jq -r '.CreateAccountStatus.Id' |
            sed -e "s/[\r\n]\+//g")
        status=$(
            aws organizations describe-create-account-status \
                --profile ${AWS_PROFILE_NAME} \
                --create-account-request-id $requestId |
                sed -e "s/[\r\n]\+//g"
        )
        state=$(echo $status |
            jq -r '.CreateAccountStatus.State' |
            sed -e "s/[\r\n]\+//g")

        # 作成中の場合は3秒スリープして再試行
        if [ ${state} != "IN_PROGRESS" ]; then
            accountInfo=$(echo $status |
                jq -r '.CreateAccountStatus | { AccountName : .AccountName, AccountId : .AccountId }' |
                sed -e "s/[\r\n]\+//g")
            result[i]=$accountInfo
            let i++
            break
        fi
        sleep 3s
    done

    # 指定した数だけ作成が完了したら終了
    if [ ${CREATE_ACCOUNT_LENGTH} -eq ${i} ]; then
        break
    fi
done
echo "Created Account List =>"
for ((i = 0; i < ${#result[@]}; i++)); do
    echo "${result[i]}"
done
echo "finish."
:

解説

メインコマンドは↓の2つです。

  • aws organizations create-account
  • aws organizations describe-create-account-status

AWSアカウント作成

    # アカウント作成
    account=$(
        aws organizations create-account \
            --profile ${AWS_PROFILE_NAME} \
            --email $accountEmail \
            --account-name $accountName \
            --role-name ${ROLE_NAME} \
            --iam-user-access-to-billing ALLOW |
            sed -e "s/[\r\n]\+//g"
    )

AWSアカウントを作成するコマンドです。
コマンド実行前にメールアドレスとアカウント名、デフォルトロール名を定義しておきます。

余談ですが、メールアドレスとアカウント名は、

    # ランダム文字列作成
    randomStr=$(cat /dev/urandom | tr -dc 'a-z0-9' | head -c 10)

ここでランダム文字列をつけることで単一のメールアドレスで複数アカウントを作成できるような作りにしています。

アカウント作成ステータス確認

        status=$(
            aws organizations describe-create-account-status \
                --profile ${AWS_PROFILE_NAME} \
                --create-account-request-id $requestId |
                sed -e "s/[\r\n]\+//g"
        )

アカウント作成のステータスを取得するコマンドです。
AWSアカウントは同時作成数に制限があるため、基本的には都度作成ステータスを確認してあげる必要があります。

        state=$(echo $status |
            jq -r '.CreateAccountStatus.State' |
            sed -e "s/[\r\n]\+//g")

jqコマンドの使い所です。
先ほどのコマンドの返り値からステータス文字列をフィルタリングしています。

       # 作成中の場合は3秒スリープして再試行
        if [ ${state} != "IN_PROGRESS" ]; then
            accountInfo=$(echo $status |
                jq -r '.CreateAccountStatus | { AccountName : .AccountName, AccountId : .AccountId }' |
                sed -e "s/[\r\n]\+//g")
            result[i]=$accountInfo
            let i++
            break
        fi

作成ステータス確認部分です。
ステータスが作成中じゃなくなったら次のアカウント作成に移ります。

おわりに

CLIいいですね。
次は割と時間のかかるAWSリソースの洗い出しをサービス単位でちょくちょくやってみようかなと思います。