[JAWS-UG CLI] AWS Organizations 入門 (2) OrganizatonおよびOU（Organization Unit）の作成

# この記事について

[JAWS-UG CLI専門支部 #83 Organizations入門](https://jawsug-cli.doorkeeper.jp/events/57578)で実施するハンズオン用の手順書です。


# 前提条件

## 必要な権限

- Organizationsのフルコントロール権限
- Identity and Access Managementのフルコントロール権限
- Security Token Serviceのフルコントロール権限

## 必要なリソース

**本日のハンズオンは、親アカウントの作成と削除も含めて実施します**

- メールアドレス × 2（親アカウントおよび子アカウント用）
- クレジットカード情報
- 通話可能な電話番号（個人認証用）

# 0. 準備

## 0.1. リージョンを指定

AWS Organizatonsのリージョンは、バージニアリージョンのみで提供されています。

```bash:コマンド
export AWS_DEFAULT_REGION="us-east-1"
```

## 0.2. 資格情報を確認

```bash:コマンド
aws configure list
```

```text:結果（例）
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                  aws-org           manual    --profile
access_key     ****************6TOQ shared-credentials-file
secret_key     ****************EtJQ shared-credentials-file
    region                us-east-1              env    AWS_DEFAULT_REGION
```

## 0.3. バージョン確認

```bash:コマンド
aws --version
```

```text:結果
aws-cli/1.11.80 Python/2.7.12 Linux/4.9.20-10.30.amzn1.x86_64 botocore/1.5.43
```

## 0.4. バージョンアップ（必要に応じて）

```bash:コマンド
sudo pip install -U awscli
```


# 1. Organizationの作成

## 現在操作しているAWSアカウントを確認

AWS IDが、操作しようとしているAWSアカウントのものと一致しているか確認します。

```bash:コマンド
aws sts get-caller-identity
```

```json:結果
{
    "Account": "************",
    "UserId": "A********************",
    "Arn": "arn:aws:iam::************:user/CLI"
}
```

アカウントエイリアスを設定している場合、こちらでも確認可能です。

```bash:コマンド
aws iam list-account-aliases
```

```json:結果（アカウントエイリアス未設定の場合）
{
    "AccountAliases": []
}
```

## Organizationが存在しないことを確認

```bash:コマンド
aws organizations describe-organization
```

```text:結果
An error occurred (AWSOrganizationsNotInUseException) when calling the DescribeOrganization operation: Your account is not a member of an organization.
```

## Organizationの作成

Organizaton（複数のアカウントを管理するためのリソース）を作成します。
（この時点では、Consolidated Billingのみ有効な状態で作成します。）

```bash:コマンド
aws organizations create-organization \
    --feature-set CONSOLIDATED_BILLING
```

```json:結果
{
    "Organization": {
        "AvailablePolicyTypes": [],
        "MasterAccountId": "************",
        "MasterAccountArn": "arn:aws:organizations::************:account/o-0vapyd2tob/************",
        "FeatureSet": "CONSOLIDATED_BILLING",
        "MasterAccountEmail": "************@outlook.jp",
        "Id": "o-0vapyd2tob",
        "Arn": "arn:aws:organizations::************:organization/o-0vapyd2tob"
    }
}
```

## Organizationが作成されたことを確認

```bash:コマンド
aws organizations describe-organization
```

```json:結果
{
    "Organization": {
        "AvailablePolicyTypes": [],
        "MasterAccountId": "************",
        "MasterAccountArn": "arn:aws:organizations::************:account/o-0vapyd2tob/************",
        "FeatureSet": "CONSOLIDATED_BILLING",
        "MasterAccountEmail": "***********@outlook.jp",
        "Id": "o-0vapyd2tob",
        "Arn": "arn:aws:organizations::************:organization/o-0vapyd2tob"
    }
}
```

## Root Accountの確認

```bash:コマンド
aws organizations list-roots
```

```json:結果
{
    "Roots": [
        {
            "PolicyTypes": [],
            "Id": "r-e2uv",
            "Arn": "arn:aws:organizations::************:root/o-0vapyd2tob/r-e2uv",
            "Name": "Root"
        }
    ]
}
```

## アカウントの一覧を確認

```bash:コマンド
aws organizations list-accounts
```

```json:結果
{
    "Accounts": [
        {
            "Status": "ACTIVE",
            "Name": "Nobuhiro Nakayama",
            "JoinedMethod": "INVITED",
            "JoinedTimestamp": 1493008453.5,
            "Id": "************",
            "Arn": "arn:aws:organizations::************:account/o-0vapyd2tob/************"
        }
    ]
}
```

## アカウントの詳細を確認

```bash:コマンド
ACCOUNT_ID=$(aws organizations list-accounts \
    --query "Accounts[0].Id" \
    --output text) \
    && echo ${ACCOUNT_ID}
```

```text:結果
************
```

```bash:コマンド
aws organizations describe-account \
    --account-id ${ACCOUNT_ID}
```

```json:結果
{
    "Account": {
        "Status": "ACTIVE",
        "Name": "Nobuhiro Nakayama",
        "JoinedMethod": "INVITED",
        "JoinedTimestamp": 1493008453.5,
        "Id": "************",
        "Arn": "arn:aws:organizations::************:account/o-0vapyd2tob/************"
    }
}
```


# 2. Organization Unitの作成

## 2.1. Organization Unitの作成

### OUが存在しないことを確認

```bash:コマンド
ROOT_ID=$(aws organizations list-roots \
    --query Roots[].Id \
    --output text) \
    && echo ${ROOT_ID}
```

```text:結果
r-e2uv
```

```bash:コマンド
aws organizations list-organizational-units-for-parent \
    --parent-id ${ROOT_ID}
```

```json:結果
{
    "OrganizationalUnits": []
}
```

### OU名の指定

```bash:コマンド
OU_NAME="test-ou"
```

### 変数の確認

```bash:コマンド
cat << ETX

    ROOT_ID: ${ROOT_ID}
    OU_NAME: ${OU_NAME}

ETX
```

```text:結果

    ROOT_ID: r-e2uv
    OU_NAME: test-ou

```

### OUの作成

```bash:コマンド
aws organizations create-organizational-unit \
    --parent-id ${ROOT_ID} \
    --name ${OU_NAME}
```

```json:結果
{
    "OrganizationalUnit": {
        "Id": "ou-e2uv-0w028u9k",
        "Arn": "arn:aws:organizations::************:ou/o-0vapyd2tob/ou-e2uv-0w028u9k",
        "Name": "test-ou"
    }
}
```

## OUの確認

### Root配下のOUを確認

```bash:コマンド
aws organizations list-organizational-units-for-parent \
    --parent-id ${ROOT_ID}
```

```json:結果
{
    "OrganizationalUnits": [
        {
            "Id": "ou-e2uv-0w028u9k",
            "Arn": "arn:aws:organizations::************:ou/o-0vapyd2tob/ou-e2uv-0w028u9k",
            "Name": "test-ou"
        }
    ]
}
```

### OUのIDを取得

```bash:コマンド
OU_ID=$(aws organizations list-organizational-units-for-parent \
    --parent-id ${ROOT_ID} \
    --query OrganizationalUnits[0].Id \
    --output text) \
    && echo ${OU_ID}
```

```text:結果
ou-e2uv-0w028u9k
```


### OUの確認

```bash:コマンド
aws organizations describe-organizational-unit \
    --organizational-unit-id ${OU_ID}
```

```json:結果
{
    "OrganizationalUnit": {
        "Id": "ou-e2uv-0w028u9k",
        "Arn": "arn:aws:organizations::************:ou/o-0vapyd2tob/ou-e2uv-0w028u9k",
        "Name": "test-ou"
    }
}
```

以上