[JAWS-UG CLI] AWS Organizations 入門 (3) Policyの作成およびOUへの適用

# この記事について

[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. Policyの作成

Rootを含むOUに対してどのようなアクセス制限を設けるかを定義します。

## 1.1. Service Control Policies (SCPs)の有効化

### Service Control Policies (SCPs)の有効化

Organizationにおいて、「利用可能なサービスを制限する機能」を有効化します。

```bash:コマンド
aws organizations enable-all-features
```

```json:結果
{
    "Handshake": {
        "Id": "h-012d6c64482e4b77866c3c4a768f50f2",
        "State": "REQUESTED",
        "Resources": [
            {
                "Type": "ORGANIZATION",
                "Value": "o-0vapyd2tob"
            }
        ],
        "Parties": [
            {
                "Type": "ORGANIZATION",
                "Id": "0vapyd2tob"
            }
        ],
        "Action": "ENABLE_ALL_FEATURES",
        "RequestedTimestamp": 1493022115.954,
        "ExpirationTimestamp": 1500798115.954,
        "Arn": "arn:aws:organizations::************:handshake/o-0vapyd2tob/enable_all_features/h-012d6c64482e4b77866c3c4a768f50f2"
    }
}
```

### Service Control Policies (SCPs)の有効化処理のステータスを確認する

```bash:コマンド
aws organizations list-handshakes-for-organization
```

```json:結果
{
    "Handshakes": [
        {
            "Id": "h-012d6c64482e4b77866c3c4a768f50f2",
            "State": "OPEN",
            "Resources": [
                {
                    "Type": "ORGANIZATION",
                    "Value": "o-0vapyd2tob"
                }
            ],
            "Parties": [
                {
                    "Type": "ORGANIZATION",
                    "Id": "0vapyd2tob"
                }
            ],
            "Action": "ENABLE_ALL_FEATURES",
            "RequestedTimestamp": 1493022115.954,
            "ExpirationTimestamp": 1500798115.954,
            "Arn": "arn:aws:organizations::275049440191:handshake/o-0vapyd2tob/enable_all_features/h-012d6c64482e4b77866c3c4a768f50f2"
        }
    ]
}
```

### Service Control Policies (SCPs)の有効化を承認する

```bash:コマンド
HANDSHAKE_ID=$(aws organizations list-handshakes-for-organization \
    --query "Handshakes[?Action==\`ENABLE_ALL_FEATURES\`].Id" \
    --output text) \
    && echo ${HANDSHAKE_ID}
```

```bash:コマンド
aws organizations accept-handshake \
    --handshake-id ${HANDSHAKE_ID}
```

```json:結果
{
    "Handshake": {
        "Id": "h-012d6c64482e4b77866c3c4a768f50f2",
        "State": "ACCEPTED",
        "Resources": [
            {
                "Type": "ORGANIZATION",
                "Value": "o-0vapyd2tob"
            }
        ],
        "Parties": [
            {
                "Type": "ORGANIZATION",
                "Id": "0vapyd2tob"
            }
        ],
        "Action": "ENABLE_ALL_FEATURES",
        "RequestedTimestamp": 1493022115.954,
        "ExpirationTimestamp": 1500798115.954,
        "Arn": "arn:aws:organizations::************:handshake/o-0vapyd2tob/enable_all_features/h-012d6c64482e4b77866c3c4a768f50f2"
    }
}
```

### Service Control Policies (SCPs)が有効化されたことを確認

"FeatureSet"が"ALL"になっていることを確認します。

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

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

## 1.2. Policyの作成

### Policy Documentのファイル名を指定

```bash:コマンド
POLICY_FILE_NAME="scp.json"
```

### Policy Documentの生成

現時点ではサービスコントロールポリシーでアクセス制御できることには制限があります。（「グローバルサービスを除き、特定のリージョン以外を利用できないようにしたい」といったことが現時点では実現できません。）

[Service Control Policy Syntax](http://docs.aws.amazon.com/organizations/latest/userguide/orgs_reference_scp-syntax.html)

```bash:コマンド
REGION="ap-northeast-1"
```

```bash:コマンド
AWS_ID=$(aws sts get-caller-identity \
    --query "Account" \
    --output text) \
    && echo ${AWS_ID}
```

```bash:コマンド
cat << EOF > ${POLICY_FILE_NAME}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:*",
                "sts:*",
                "cloudtrail:*",
                "aws-portal:*",
                "budgets:*",
                "s3:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
EOF
```

### Policy Documentの確認

```bash:コマンド
cat ${POLICY_FILE_NAME}
```

### Policy Documentの検証

```bash:コマンド
jsonlint -q ${POLICY_FILE_NAME}
```

### Policy名の指定

```bash:コマンド
POLICY_NAME="test-policy"
POLICY_DESCRIPTION="This is test policy."
```

### 変数の確認

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

    POLICY_FILE_NAME: ${POLICY_FILE_NAME}
    POLICY_NAME: ${POLICY_NAME}
    POLICY_DESCRIPTION: ${POLICY_DESCRIPTION}

ETX
```

```text:結果

    POLICY_FILE_NAME: scp.json
    POLICY_NAME: test-policy
    POLICY_DESCRIPTION: This is test policy.

```

### Policyの作成

```bash:コマンド
aws organizations create-policy \
    --content file://${POLICY_FILE_NAME} \
    --description "${POLICY_DESCRIPTION}" \
    --name ${POLICY_NAME} \
    --type SERVICE_CONTROL_POLICY
```

```json:結果
{
    "Policy": {
        "Content": "{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"iam:*\",\n                \"sts:*\",\n                \"cloudtrail:*\",\n                \"aws-portal:*\",\n                \"budgets:*\",\n                \"s3:*\"\n            ],\n            \"Resource\": [\n                \"*\"\n            ]\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"ec2:*\"\n            ],\n            \"Resource\": [\n                \"*\"\n            ]\n        }\n    ]\n}\n",
        "PolicySummary": {
            "AwsManaged": false,
            "Description": "This is test policy.",
            "Type": "SERVICE_CONTROL_POLICY",
            "Id": "p-kg35mxnv",
            "Arn": "arn:aws:organizations::************:policy/o-0vapyd2tob/service_control_policy/p-kg35mxnv",
            "Name": "test-policy"
        }
    }
}
```

## 1.3. Policyの確認

### Policyの一覧

```bash:コマンド
aws organizations list-policies \
    --filter SERVICE_CONTROL_POLICY
```

```json:結果
{
    "Policies": [
        {
            "AwsManaged": true,
            "Description": "Allows access to every operation",
            "Type": "SERVICE_CONTROL_POLICY",
            "Id": "p-FullAWSAccess",
            "Arn": "arn:aws:organizations::aws:policy/service_control_policy/p-FullAWSAccess",
            "Name": "FullAWSAccess"
        },
        {
            "AwsManaged": false,
            "Description": "This is test policy.",
            "Type": "SERVICE_CONTROL_POLICY",
            "Id": "p-kg35mxnv",
            "Arn": "arn:aws:organizations::************:policy/o-0vapyd2tob/service_control_policy/p-kg35mxnv",
            "Name": "test-policy"
        }
    ]
}
```

### Policyの詳細を表示

```bash:コマンド
POLICY_ID=$(aws organizations list-policies \
    --filter SERVICE_CONTROL_POLICY \
    --query Policies[?Name==\`${POLICY_NAME}\`].Id \
    --output text) \
    && echo ${POLICY_ID}
```

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

```json:結果
{
    "Policy": {
        "Content": "{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"iam:*\",\n                \"sts:*\",\n                \"cloudtrail:*\",\n                \"aws-portal:*\",\n                \"budgets:*\",\n                \"s3:*\"\n            ],\n            \"Resource\": [\n                \"*\"\n            ]\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"ec2:*\"\n            ],\n            \"Resource\": [\n                \"*\"\n            ]\n        }\n    ]\n}\n",
        "PolicySummary": {
            "AwsManaged": false,
            "Description": "This is test policy.",
            "Type": "SERVICE_CONTROL_POLICY",
            "Id": "p-kg35mxnv",
            "Arn": "arn:aws:organizations::************:policy/o-0vapyd2tob/service_control_policy/p-kg35mxnv",
            "Name": "test-policy"
        }
    }
}
```

# 2. Policyの適用

## 2.1. Policyの適用

### Policy Typeの有効化

（解説）

```bash:コマンド
aws organizations enable-policy-type \
    --root-id ${ROOT_ID} \
    --policy-type SERVICE_CONTROL_POLICY
```

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

### アタッチされているPolicyを確認

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

```bash:コマンド
aws organizations list-policies-for-target \
    --target-id ${OU_ID} \
    --filter SERVICE_CONTROL_POLICY
```

```json:結果
{
    "Policies": [
        {
            "AwsManaged": true,
            "Description": "Allows access to every operation",
            "Type": "SERVICE_CONTROL_POLICY",
            "Id": "p-FullAWSAccess",
            "Arn": "arn:aws:organizations::aws:policy/service_control_policy/p-FullAWSAccess",
            "Name": "FullAWSAccess"
        }
    ]
}
```

### PolicyをOUにアタッチ

```bash:コマンド
aws organizations attach-policy \
    --policy-id ${POLICY_ID} \
    --target-id ${OU_ID}
```

```text:結果
（返値無し）
```

### Policyがアタッチされたことを確認

```bash:コマンド
aws organizations list-policies-for-target \
    --target-id ${OU_ID} \
    --filter SERVICE_CONTROL_POLICY
```

```json:結果
{
    "Policies": [
        {
            "AwsManaged": false,
            "Description": "This is test policy.",
            "Type": "SERVICE_CONTROL_POLICY",
            "Id": "p-kg35mxnv",
            "Arn": "arn:aws:organizations::************:policy/o-0vapyd2tob/service_control_policy/p-kg35mxnv",
            "Name": "test-policy"
        },
        {
            "AwsManaged": true,
            "Description": "Allows access to every operation",
            "Type": "SERVICE_CONTROL_POLICY",
            "Id": "p-FullAWSAccess",
            "Arn": "arn:aws:organizations::aws:policy/service_control_policy/p-FullAWSAccess",
            "Name": "FullAWSAccess"
        }
    ]
}
```

## 2.1. 既存のPolicyのデタッチ

### 既存のPolicyのデタッチ

```bash:コマンド
aws organizations detach-policy \
    --policy-id "p-FullAWSAccess" \
    --target-id ${OU_ID}
```

```text:result
（返値無し）
```


### Policyがデタッチされたことを確認

```bash:コマンド
aws organizations list-policies-for-target \
    --target-id ${OU_ID} \
    --filter SERVICE_CONTROL_POLICY
```

```json:結果
{
    "Policies": [
        {
            "AwsManaged": false,
            "Description": "This is test policy.",
            "Type": "SERVICE_CONTROL_POLICY",
            "Id": "p-kg35mxnv",
            "Arn": "arn:aws:organizations::************:policy/o-0vapyd2tob/service_control_policy/p-kg35mxnv",
            "Name": "test-policy"
        }
    ]
}
```

以上