■AWS Organizationsをawscliで使ってみる。 マネージメントコンソールなら以下を参照する。 チュートリアル: 組織の作成と設定 https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_tutorials_basic.html AWS組織を作成 Consolidated Billing verification complete」の通知メールを確認する。 SCPのポリシータイプを有効化 OUを作成する。 OUに移動する。 既存のスタンドアロンアカウントをメンバーとして招待する。 待された側のアカウントで承認する。 マネージメントコンソールからロールの切り替えで、 Idとロール名を使ってログインしてみる。 新規メンバーアカウントを作成する。 ロールとポリシーを関連付ける。 マネージメントコンソールからロールの切り替えで、 Idとロール名を使ってログインしてみる ■「leave-organization」は親組織からメンバーアカウントを削除するために、 退会したいアカウントによって実行するコマンド。 指定されたアカウントを組織から削除するのは「remove-account-from-organization」 メンバーから抜けると、スタンドアロンアカウントとして 請求情報を登録する必要があるので注意。 awscliのすべてのコマンドとサブコマンドを一覧してみる。 https://labunix.hateblo.jp/entry/20210117/1610827122 $ awk '/aws organizations [a-z]*-organization$/' aws/subcmd/aws-allsubcmd.txt aws organizations create-organization aws organizations delete-organization aws organizations describe-organization aws organizations leave-organization ■招待する側もされる側もrootアカウントを適切に設定し、 以下2つのAWS管理ポリシーが適用されたIAMユーザで作業出来る。 AdministratorAccess SystemAdministrator ■まずはAWS組織を作成 マネージメントコンソールでの「組織の作成」と同じ。 「ALL」か請求情報に限定した「CONSOLIDATED_BILLING」のどちらかを選択。 $ aws organizations create-organization --feature-set ALL ...[describe-organizationと同じ出力]... ■AWS組織の作成確認 $ aws organizations describe-organization { "Organization": { "Id": "o-yyyyyyyyyy", "Arn": "arn:aws:organizations::XXXXXXXXXXXX:organization/o-yyyyyyyyyy", "FeatureSet": "ALL", "MasterAccountArn": "arn:aws:organizations::XXXXXXXXXXXX:account/o-yyyyyyyyyy/XXXXXXXXXXXX", "MasterAccountId": "XXXXXXXXXXXX", "MasterAccountEmail": "labunix@example.jp", "AvailablePolicyTypes": [ { "Type": "SERVICE_CONTROL_POLICY", "Status": "ENABLED" } ] } } $ aws organizations list-accounts | jq -r '.Accounts[].Status' ACTIVE ■Consolidated Billing verification complete」の通知メールを確認する。 メールのリンクからマネージメントコンソールにログインすると確認したことになる。 ■既存のスタンドアロンアカウントをメンバーとして招待する。 $ aws organizations invite-account-to-organization \ --target '{"Type": "EMAIL", "Id": "labunix-sub@example.jp"}' \ --notes "This is a request for labunix-sub account to join labunix organization." ...[list-handshakes-for-organizationと同じ出力]... $ aws organizations list-handshakes-for-organization | jq -r '.Handshakes[].State' OPEN ■招待された側のアカウントで承認する。 $ aws organizations list-handshakes-for-account ...[招待した側のlist-handshakes-for-organizationと同じ出力]... $ aws organizations accept-handshake \ --handshake-id $(aws organizations list-handshakes-for-account | jq -r '.Handshakes[].Id') ■招待した側のアカウントで承認状況を確認する。 $ aws organizations list-handshakes-for-organization | jq -r '.Handshakes[].State' ACCEPTED ■SCPのデフォルトポリシーを確認する。 ※既存はあるが有効にはなっていない。 $ aws organizations list-policies --filter SERVICE_CONTROL_POLICY | \ jq -r -c '.Policies[] | [ .Name, .Description ]' ["FullAWSAccess","Allows access to every operation"] ■SCPのポリシータイプを有効化 $ awk '/aws organizations/&&/type/' aws/subcmd/aws-allsubcmd.txt aws organizations disable-policy-type aws organizations enable-policy-type $ aws organizations enable-policy-type \ --root-id $(aws organizations list-roots | jq -r '.Roots[].Id') \ --policy-type SERVICE_CONTROL_POLICY ■OUを作成する。 $ awk '/aws organizations/&&/unit/' aws/subcmd/aws-allsubcmd.txt aws organizations create-organizational-unit aws organizations delete-organizational-unit aws organizations describe-organizational-unit aws organizations list-organizational-units-for-parent aws organizations update-organizational-unit $ aws organizations create-organizational-unit \ --parent-id $(aws organizations list-roots | jq -r '.Roots[].Id') \ --name develop { "OrganizationalUnit": { "Id": "ou-XXXX-XXXXXXXX", "Arn": "arn:aws:organizations::XXXXXXXXXXXX:ou/o-XXXXXXXXX/ou-XXXX-XXXXXXXX", "Name": "develop" } } ■OUに移動する。 OU=Root直下の招待したアカウントをdevelop配下に移動する。 招待したアカウントの名前が「labunix」を検索してそのIDを取得している。 $ awk '/aws organizations/&&/account/&&/move/&& !/remove/' aws/subcmd/aws-allsubcmd.txt aws organizations move-account $ aws organizations move-account \ --account-id $(aws organizations list-accounts | jq -r '.Accounts[] | select (.Name | test ("labunix")) | .Id') \ --source-parent-id $(aws organizations list-roots | jq -r '.Roots[].Id') \ --destination-parent-id $(aws organizations list-organizational-units-for-parent --parent-id $(aws organizations list-roots | jq -r '.Roots[].Id') | jq -r '.OrganizationalUnits[].Id') ■Root OUのIDからOUのIDを引いて、そのOUに所属するアカウントの名前を表示 ※招待された側のアカウント $ aws organizations list-accounts-for-parent \ --parent-id $(aws organizations list-organizational-units-for-parent --parent-id $(aws organizations list-roots | jq -r '.Roots[].Id') | jq -r '.OrganizationalUnits[].Id') | \ jq -r '.Accounts[].Name' labunix ■Root OUのIDに所属するアカウントの名前を表示 ※招待した側のアカウント $ aws organizations list-accounts-for-parent \ --parent-id $(aws organizations list-roots | jq -r '.Roots[].Id') | jq -r '.Accounts[].Name' labunix@example.jp ■マネージメントコンソールからロールの切り替えで、 Idとロール名を使ってログインしてみる。 ※デフォルトのロール名は「OrganizationAccountAccessRole」 $ aws organizations list-accounts-for-parent \ --parent-id $(aws organizations list-roots | jq -r '.Roots[].Id') | jq -r '.Accounts[] | select (.Email | test( "labunix-sub@example.jp")) | .Id' XXXXXXXXXXXX ■新規メンバーアカウントを作成する。 $ awk '/aws organizations/&&/create-account/' aws/subcmd/aws-allsubcmd.txt aws organizations create-account aws organizations describe-create-account-status aws organizations list-create-account-status $ aws organizations create-account \ --email labunix-sub2@example.jp \ --account-name "product" { "CreateAccountStatus": { "Id": "car-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "AccountName": "product", "State": "IN_PROGRESS", "RequestedTimestamp": "2021-04-16T22:40:12.972000+09:00" } } $ aws organizations list-create-account-status | jq -r '.CreateAccountStatuses[].State' SUCCEEDED $ aws organizations describe-create-account-status \ --create-account-request-id \ $(aws organizations list-create-account-status | jq -r '.CreateAccountStatuses[-1].Id') | \ jq -r '.CreateAccountStatus.State' SUCCEEDED ■マネージメントコンソールからロールの切り替えで、 Idとロール名を使ってログインしてみる。 ※デフォルトのロール名は「OrganizationAccountAccessRole」 $ awk '/aws iam/&& $3 ~ /-role$/&& $3 !~ /instance|service|tag/' aws/subcmd/aws-allsubcmd.txt aws iam create-role aws iam delete-role aws iam get-role aws iam update-role $ aws iam list-roles | jq -r '.Roles[] | select( .RoleName | test( "OrganizationAccountAccessRole" ))' | \ jq -r '.AssumeRolePolicyDocument.Statement' | jq -r '.[].Principal.AWS' arn:aws:iam::XXXXXXXXXXXX:root $ aws iam list-roles | jq -r '.Roles[] | select( .RoleName | test( "OrganizationAccountAccessRole" ))' { "Path": "/", "RoleName": "OrganizationAccountAccessRole", "RoleId": "XXXXXXXXXXXXXXXXXXXXX", "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/OrganizationAccountAccessRole", "CreateDate": "2021-04-16T14:50:29+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::XXXXXXXXXXXX:root" }, "Action": "sts:AssumeRole", "Condition": {} } ] }, "MaxSessionDuration": 3600 } $ aws iam list-attached-role-policies --role-name OrganizationAccountAccessRole { "AttachedPolicies": [ { "PolicyName": "AdministratorAccess", "PolicyArn": "arn:aws:iam::aws:policy/AdministratorAccess" } ] } $ aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess | jq -r . { "PolicyGroups": [ { "GroupName": "Admins", "GroupId": "XXXXXXXXXXXXXXXXXXXXX" } ], "PolicyUsers": [], "PolicyRoles": [ { "RoleName": "OrganizationAccountAccessRole", "RoleId": "XXXXXXXXXXXXXXXXXXXXX" } ] }