📚

AWS Organizationsを利用して複数のAWSアカウントを作成・管理する

2022/03/02に公開

はじめに

AWS Organizationsは複数のAWSアカウントを管理するためのAWSサービスです。このサービスを利用することで複数のアカウントへの料金請求をまとめたり、アカウント内での特定の操作に対して制限を課す等の管理が行えるようになります。

また管理アカウントからAWSアカウントを簡単に作成できるようになるため、複数のAWSアカウントを作成する際の作業コストも抑えることができます。

この記事ではAWS OrganizationsのセットアップやAWSアカウントの作成を行い、アカウントの操作制限ができる状態にするまでの手順を紹介します。

組織の構成要素

手順を説明する前に、AWS Organizationsにおける組織を構成する各要素について説明します。組織は主にOrganization Unit(以下OU)/Root/AWSアカウント/Service Control Policy(以下SCP)の4つの要素から構成されており、これらを組み合わせることでAWSアカウントの統制管理を実現しています。

aws organization model
AWS ORganizationsの用語と概念から引用

Organization Unit(OU)

OUは組織に所属するAWSアカウントを管理する為のAWS Organizations独自の単位を指します。OUは親となるOUまたはRootを必ず一つ持ち、複数のOUやアカウントを子として持つことができます。これは木構造であり、これによって組織の階層構造を表すことができます。

OUにはSCPと呼ばれるアクセス制御ポリシーを設定する事ができます。設定されたポリシーは所属する下位のOUやアカウントに反映されるため、OUとSCPを組み合わせることで階層的なアクセス制限を記述することができます。

Root

Rootは木構造の根にあたる特殊なOUのことを指します。すべてのOUやアカウントはRootに所属するため、Rootに対してSCPを設定することで全体に制限を課すことができます。

AWSアカウント

AWSアカウントは管理用アカウントメンバーアカウントの二種類があります。

管理用アカウントはOUやメンバーアカウントの作成、ポリシーの設定など組織の管理を行うためのAWSアカウントを指します。組織ごとに1つしか所属できず、組織を作成したアカウントが自動的に管理アカウントとなります。また全アカウントの利用料金は管理アカウントにまとめられ、請求が発生します

メンバーアカウントは管理用アカウントではないAWSアカウントを指します。メンバーアカウントの利用費は管理用アカウントにまとめて請求され、また組織による統制管理の対象となります。

OUと同様、AWSアカウントに対して直接SCPを設定し、制限を課すことも可能です。OU単位ではなく特定アカウントに対して特別な制限を課す場合に有効です。

Service Control Policy(SCP)

OUやアカウントに対してService Control Policy(以下SCP)を設定することで、利用できるサービスや操作を制限することができるようになります

SCPとIAM Policyと類似していますが、IAM Policyが操作が許可されたアクションを直接示している一方、SCPはIAM Policyで許可することが可能なアクションのセットを示しているという違いがあります。SCPで許可されていないアクションは例えIAM Policyで許可されていたとしても実行することができません。

事前準備

AWSアカウントの作成を行う前に、まずは事前準備として組織の作成と必要な機能の有効化を行なっていきます。

組織の作成

はじめに、以下のコマンドを実行して組織の作成を行います。

$ aws organizations create-organization
{
    "Organization": {
        "Id": "o-aa111bb222",
        "Arn": "arn:aws:organizations::123456789012:organization/o-aa111bb222",
        "FeatureSet": "ALL",
        "MasterAccountArn": "arn:aws:organizations::123456789012:account/o-aa111bb222/123456789012",
        "MasterAccountId": "123456789012",
        "MasterAccountEmail": "admin@example.com"
    }
}

組織を作成した場合、管理用アカウントに登録されているメールアドレスに対して検証メールが送られます。AWSアカウントを作成する場合はメールアドレスの検証は不要ですが、外部のAWSアカウントを組織に招待する場合などにメールアドレスが検証されている必要があるため、事前に検証は済ませておくことをお勧めします。

SCPを有効化

組織が作成された直後はデフォルトでSCPの機能が無効化されているため、組織を作成したタイミングでSCPを有効にしておきます。

はじめに組織を作成した際に自動的に作成されたRootのIDを確認します。

$ aws organizations list-roots
{
    "Roots": [
        {
            "Id": "r-a1b2",
            "Arn": "arn:aws:organizations::123456789012:root/o-aa111bb222/r-a1b2",
            "Name": "Root",
            "PolicyTypes": []
        }
    ]
}

次に、確認できたRoot ID(r-a1b2)を指定し、SCPを有効にします。

$ aws organizations enable-policy-type --root-id r-a1b2 --policy-type SERVICE_CONTROL_POLICY
{
    "Root": {
        "Id": "r-a1b2",
        "Arn": "arn:aws:organizations::123456789012:root/o-aa111bb222/r-a1b2",
        "Name": "Root",
        "PolicyTypes": []
    }
}

再度list-rootsを実行すると、PolicyTypesSERVICE_CONTROL_POLICYが追加され有効となっていることが確認できます。

$ aws organizations list-roots
{
    "Roots": [
        {
            "Id": "r-a1b2",
            "Arn": "arn:aws:organizations::123456789012:root/o-aa111bb222/r-a1b2",
            "Name": "Root",
            "PolicyTypes": [
                {
                    "Type": "SERVICE_CONTROL_POLICY",
                    "Status": "ENABLED"
                }
            ]
        }
    ]
}

メンバーアカウントの作成

つづいてAWSアカウントの作成を行なっていきます。

AWSアカウントの作成には、アカウントの名称連絡先メールアドレスを指定する必要があります。連絡先は既存のAWSアカウントに紐づいていないメールアドレスを指定する必要があります。

アカウント作成は下記のコマンドでリクエストすることができます。通常のAWSアカウント作成と異なり、連絡先メールアドレスの検証や支払い方法の登録などを行う必要はありません。

$ aws organizations create-account --email susan@example.com --account-name "test account"
{
        "CreateAccountStatus": {
                "State": "IN_PROGRESS",
                "Id": "car-examplecreateaccountrequestid111"
        }
}

AWSアカウントの進捗状況は作成時に発行される、car-から始まるRequest IDで確認することができます。

$ aws organizations describe-create-account-status --create-account-request-id car-examplecreateaccountrequestid111
{
  "CreateAccountStatus": {
    "State": "SUCCEEDED",
    "AccountId": "555555555555",
    "AccountName": "test account",
    "RequestedTimestamp": 1470684478.687,
    "CompletedTimestamp": 1470684532.472,
    "Id": "car-examplecreateaccountrequestid111"
  }
}

メンバーアカウント(555555555555)が作成されていることがわかります。StateSUCCEEDEDになればAWSアカウントの作成は完了です。

メンバーアカウント向けユーザーの作成

つづいて、メンバーアカウントにログインできるIAMユーザーを作成していきます。

AWS OrganizationsからAWSアカウントを作成した場合、デフォルトでOrganizationAccountAccessRoleというロールがアカウント内に作成されます。
管理アカウントからスイッチできるため、ユーザーの作成などの初期作業はこのロールを通して行います。

.aws/credentialsを編集し、AWS CLIからprofileを通してメンバーアカウント(555555555555)にアクセスできるようにしておきます。

$ cat ~/.aws/credentials
[management-acc]
aws_access_key_id = XXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXX

[member-acc]
role_arn = arn:aws:iam::555555555555:role/OrganizationAccountAccessRole
source_profile = management-acc

OrganizationAccountAccessRoleにスイッチできることを確認し、メンバーアカウント向けのユーザー(test)を作成していきます。メンバーアカウントにはひとまず管理者権限を追加しておきます。

$ #ユーザー作成
$ aws --profile sf-masuwo3 iam create-user --user-name test
{
    "User": {
        "UserName": "test",
        "Path": "/",
        "CreateDate": "2013-06-08T03:20:41.270Z",
        "UserId": "AIDAIOSFODNN7EXAMPLE",
        "Arn": "arn:aws:iam::555555555555:user/test"
    }
}

$ #管理者権限を付与
$ aws --profile member-acc iam attach-user-policy --user-name test --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

$ #パスワードを設定
$ aws --profile member-acc iam create-login-profile --user-name test --password 'pa$$w0rd' --password-reset-required
{
    "LoginProfile": {
        "UserName": "test",
        "CreateDate": "2022-03-02T06:37:58+00:00",
        "PasswordResetRequired": true
    }
}

webのログイン画面から登録したパスワードを入力し、ログインやAWSの操作が確認できればユーザーの作成作業は完了です。

SCPの設定

次に、メンバーアカウントをOUに所属させた上でSCPによる操作制限を行います。

まずはメンバーアカウントが所属するOUを作成します。

$ aws organizations create-organizational-unit --parent-id r-a1b2 --name ou-test
{
        "OrganizationalUnit": {
                "Id": "ou-examplerootid111-exampleouid111",
                "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111",
                "Name": "ou-test"
        }
}

続いてメンバーアカウントを作成したOUに移動させます。

$ aws organizations move-account --account-id 555555555555 --source-parent-id r-a1b2 --destination-parent-id ou-examplerootid111-exampleouid111

最後にOUに対して全てのAWSに関する操作を制限するSCPを設定します。

$ #全ての操作を拒否するSCPを作成する
$ cat deny_all.json
{    
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*"
    }
  ]
}

$ aws organizations create-policy --content file://deny_all.json --description 'deny all.' --name deny_all --type SERVICE_CONTROL_POLICY
{
    "Policy": {
        "PolicySummary": {
            "Id": "p-examplepolicyid111",
            "Arn": "arn:aws:organizations::o-exampleorgid:policy/service_control_policy/p-examplepolicyid111",
            "Name": "deny_all",
            "Description": "deny all.",
            "Type": "SERVICE_CONTROL_POLICY",
            "AwsManaged": false
        },
        "Content": ...(snip)...
    }
}

$ #OUにSCPを設定
$ aws organizations attach-policy --policy-id p-examplepolicyid111 --target-id ou-examplerootid111-exampleouid111

再度ユーザー(test)にログインし、AWSの操作を行なってみると、ユーザーの権限が変更されていないにもかかわらず操作ができなくなっていることがわかります。

これでOUへのSCPの設定を通して、メンバーアカウントに操作制限ができるようになりました。

参考

Discussion