AWS Organizations配下の複数アカウント、全リージョンにAWS Configのマネージドルールを一括で展開してみる

# AWS Organizations配下の全アカウントにAWS Configのルールを適用したい。

当初はポチポチでイケるもんだと思ってたら、マネージドコンソールから親アカウントを有効化しても子アカウントに自動的に適用されるもんでもないらしい。。。

# やりたいこと

- Organizations 組織内のすべてのアカウント全体でAWS Configルールを一元的に作成、更新、削除する。

- すべてのアカウント感で共通のAWS Configルールセットをデプロイし、AWS Configルールを作成しないアカウントを指定する。

- AWS Configルールをカスタムする気はなく、デフォルトのマネージドルールを使用する。

# AWS CloudFormationテンプレートを使用したAWS Configマネージドルールの作成

AWS Configマネージドルールについては、AWS CloudFormationテンプレートを使用してアカウント用に作成するか、既存のAWS Cloudformationスタックを更新することで適用することが出来る。
※テンプレートを使用してスタックを起動すると、AWS Configマネージドルールが自動的に作成される。テンプレートで作成されるのは「ルールのみ」で、追加のAWSリソースは作成されない。

# 手順

※AWS Organizationsで各アカウントとの信頼されたアクセスの有効化をしておく。

1. CloudFormationのStacksetsの作成をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/190aec88-c8af-6496-8c0f-ba3a4a1dc368.png)

2. サービスマネージドアクセス許可->サンプルテンプレートを使用->サンプルテンプレートの選択から「AWS Config」の有効化を選択する。（次へをクリック）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/e2195a60-319e-9292-a7e7-2acd295bf4ab.png)

3. Stackset名を記入し、パラメータを設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/114c15f0-c747-df01-7304-8c6061b972c8.png)


4.デプロイオプションを設定する。新しいスタックのデプロイ->組織へのデプロイ->自動デプロイオプションは基本デフォルト->リージョンはAllリージョン指定（次へをクリック）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/719b31ce-838a-df9b-3d8f-963fb6760482.png)

5. AWS CloudFormationによってIAMリソースが作成される場合があることを承認します。をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/aec21e86-9f12-8580-b6c3-8c1ca55f882b.png)



##一括有効化してみた結果。。。

用意されたテンプレートをそのまま使用して、全アカウント全リージョンに展開すると以下になる。

・記録用S3バケットが各アカウントに作成される

・グローバルリソースの記録が全リージョンで有効化される

## 記録用S3バケットが各アカウントに作成される

Configを有効化する際、リソースの設定履歴などを保存するためにS3バケットを作成or指定する必要があります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/1d91e98e-fe6d-afb0-1914-65d852f40a09.png)

デフォルト設定のままテンプレートを展開すると、各アカウントにS3バケットが作成されます。個人的にはログはログ用アカウントに集約したいので、各アカウントにS3バケットを作りたくはないのです。

その場合は、「集中ロギングでAWS Configを有効にする」のテンプレートを使用して、ログ用アカウントのS3バケットを指定すれば回避できる。（※手動でバケットポリシーを修正する必要あり）

## グローバルリソースの記録が全リージョンで有効化される

デフォルト設定のまま展開すると、全アカウントの全リージョンでグローバルリソースの記録が有効化されます。

回避策としては、東京リージョンのみグローバルリージョンの記録がONになるように、東京リージョンのみに展開するStackSetsを作成してテンプレートを展開します。残りのリージョンでは、同じテンプレートを別のStackSetsで展開し、グローバルリソースのパラメータをfalseにします。

# とりあえず、中央ロギングしたい

サンプルテンプレートではSNSトピックの作成などもしてくれますが、とりあえず、全アカウント全リージョンで有効化し、ログ用アカウントのS3バケットにConfigログを集約したいので、以下の方針を取ることとする。

１，各アカウントの東京リージョンのマネジメントコンソールでConfigを有効化
２，ログ用S3バケットのバケットポリシーを修正
３，StackSetsを使用して、各アカウントの残りのリージョンでConfigを有効化
４，マスターアカウントの残りのリージョンでConfigを有効化

## １，各アカウントの東京リージョンのマネジメントコンソール上でConfigを有効化

マスターアカウントを含めて25アカウントの東京リージョンのみをマネジメントコンソール上で有効化した上で、グローバルリソースの記録を有効化する


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/0336eb0c-3e89-a9f9-e852-32236938e65f.png)

S3バケットについては、最初にログ用アカウントでConfigを有効化する際にバケットを作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/fbea8468-2b14-f96b-778f-fc737eb0c2dd.png)

残りのアカウントでの有効時に上記のバケットを指定し、ある程度はConfig用のバケットポリシーが生成された状態からスタート出来ます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/862034f3-1d05-a8c3-c6dc-3b3f5b3ed6d0.png)


## 2、ログ用S3バケットのバケットポリシーを修正

1の手順で、ログ用アカウントに作成されたS3バケットには、ログ用アカウントからのアクセスしかできないようなバケットポリシーが設定されています。

```
{
    "Sid": "AWSConfigBucketDelivery",
    "Effect": "Allow",
    "Principal": {
	"Service": "config.amazonaws.com"
    },
    "Action": "s3:PutObject",
    "Resource":　"arn:aws:s3:::bucket name/AWSLogs/Account ID/Config/*", ←ここ
    "Condition": {
	"StringEquals": {
	    "s3:x-amz-acl": "bucket-owner-full-control"
	}
    }
}
```


上記のポリシーを修正し、別アカウントからのアクセスも許可します。
公式ドキュメントを参考に、以下のように修正しました。

```
{
    "Sid": "AWSConfigBucketDelivery",
    "Effect": "Allow",
    "Principal": {
	"Service": "config.amazonaws.com"
    },
    "Action": "s3:PutObject",
    "Resource": [
	"arn:aws:s3:::bucket name/AWSLogs/Account ID1/Config/*",
	"arn:aws:s3:::bucket name/AWSLogs/Account ID2/Config/*",
	"arn:aws:s3:::bucket name/AWSLogs/Account ID3/Config/*",
	"arn:aws:s3:::bucket name/AWSLogs/Account ID4/Config/*"
    ],
    "Condition": {
	"StringEquals": {
	    "s3:x-amz-acl": "bucket-owner-full-control"
	}
    }
}
```
Resourceを配列形式に変更し、Account IDを各アカウントのIDに設定します。
もともとConfigでのS3バケット指定時に、各アカウントIDとリージョンが設定されたプレフィックス配下にログが記録されるようになっています。

```
/AWSLogs/Account ID/Config/region
```

このプレフィックスをResourceで指定しないと、プレフィックスが作成できないため、バケットポリシーを上記のように修正しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/d8709759-5f67-9b47-591e-72ed9705e0ce.png)

なお、バケットポリシーでリージョンまで指定してしまうと、全リージョン分のResourceを追記する必要があるため、Config以下は*となっています。

##3,Stacksetsを利用して、各アカウントの残りのリージョンでConfigを有効化

1、2で核となる設定は終わったので、あとは単純にStackSetsで東京リージョン以外のリージョンのConfigを有効化します。
やることは、
・Configの有効化(ただしグローバルリソースは記録しない)
・ログ用S3バケットにログを集約
なので、以下のようなテンプレートを作成しました。

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Enable Config",
  "Resources": {
    "ConfigConfigurationRecorder": {
      "Type": "AWS::Config::ConfigurationRecorder",
      "Properties": {
        "Name": "default",
        "RecordingGroup": {
          "AllSupported": true,
          "IncludeGlobalResourceTypes": false ←グローバルリソースは記録しない
        },
        "RoleARN": {
          "Fn::Sub": "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig"
        }
      }
    },
    "ConfigDeliveryChannel": {
      "Type": "AWS::Config::DeliveryChannel",
      "Properties": {
        "Name": "default",
        "S3BucketName": "ログ用S3バケット名" ←ログ用S3バケットの指定
      }
    }
  }
}
```

上記テンプレートを展開しますが、デフォルトで無効になっている以下の4リージョンは外しました。
・アフリカ
・香港
・ミラノ
・バーレーン

特にパラメーターはないので、展開するだけでOKです。

## 4, マスターアカウントの残りのリージョンでConfigを有効化

StackSetsではマスターアカウントに一括展開はできないので、面倒でしたがコンソール上で全リージョンを有効化しました。スクリプトでCLIを使用して一括有効化もできるとは思いますが、今回は手動作業にて実施しました。

## Configアグリゲータを組んで管理アカウントを委任する

GuardDutyやSecurityHubと同じく、ConfigでもOrganizationsの「委任管理者」を指定することができるので、管理アカウントにてConfigのアグリゲータを設定しました。

参考：https://dev.classmethod.jp/articles/config-aggregator-in-organization-member-account/


## まとめ

AWS Configの全アカウントを全リージョンで有効化することにより、委任されたメンバーアカウントで一括管理できるように設定しました。

マネジメントコンソールとStacksetsの併用という方式にはなりましたが、手法は今後検討洗練していきたいと思います。


Organizations及びConfigルールを有効化することにより、マルチアカウントのリソース把握・セキュリティ統制に活用していければと思います。。