📝

AWS Configの全アカウント全リージョン有効化の良い方法を考えてみた

2021/08/06に公開

AWS Configの全アカウント全リージョン有効化において、個人的にたどり着いた設定方法を紹介します。個人的かつ発展途上なので、これが公式の最良というわけではない点にご注意ください。

Configとは

AWS Config は、AWS リソースの設定を評価、監査、審査できるサービスです。
AWS Config

リソース設定の変更履歴を残したり、ルールに準拠しているかどうかを評価してくれます。
AWS Config ベストプラクティスでは、全アカウント全リージョンで有効化することが推奨されています。

1.すべてのアカウントとリージョンで AWS Config を有効にします。
これは、 Center for Internet Security (CIS) が推奨する業界のベストプラクティスです。AWS Config を使用すると、AWS リソースの設定を監査し、設定のベストプラクティスに確実に準拠することができます。 AWS CloudFormation StackSets を使用すると、共通の CloudFormation テンプレートを使用して、複数のアカウントとリージョンで AWS Config を有効にできます。

上記の通り、CloudFormation StackSetsを利用すればマスターアカウント以外のアカウントでは一括で有効化できます。そのためのテンプレートもAWS側で用意されているので、有効化自体は簡単にできます。

一括有効化してもいいけど・・・

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

  • 記録用S3バケットが各アカウントに作成される
  • グローバルリソースの記録が全リージョンで有効化される

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

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

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

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

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

こちらもデフォルト設定のまま展開すると、全アカウントの全リージョンでグローバルリソースの記録が有効化されます。
AWS Config ベストプラクティスでは、

1 つのリージョンでのみグローバルリソース (IAM リソースなど) を記録します。

と記載されており、全リージョンで有効化する必要はありません。

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

ちなみに、グローバルリソースを全リージョンで有効化するとこんなことになるよ!という記事が超面白くて超勉強になるのでぜひご覧下さい!
IAM ロールを 1000 個作って遊んでいたら AWS 利用費が 50 ドルを超えていた話を JAWS-UG 初心者支部で LT しました

とりあえず簡単に中央ロギングしたいだけなんだけど

サンプルテンプレートでは、SNSトピックの作成などもしてくれますが、僕はとりあえず全アカウント全リージョンを有効化し、ログ用アカウントのS3バケットにConfigログを集約できればよかったので、以下のように展開しました。

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

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

先述のテンプレートで東京リージョンのみに展開してもよかったのですが、マスターアカウントを含めて4アカウントだけだったので、東京リージョンのみ手っ取り早くマネジメントコンソール上で有効化しました。

まず、東京リージョンでのみグローバルリソースの記録を有効化しました。

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

残りのアカウントでの有効化時に、上記のバケットを指定しました。こうすることで、ある程度はConfig用のバケットポリシーが生成された状態からスタートでき、修正するのはアカウントIDの箇所ぐらいで済みます。

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

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

3. StackSetsを使用して、各アカウントの残りのリージョンでConfigを有効化

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

EnableConfig.json
{
  "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を有効化できました!
グローバルリソースは東京リージョンでのみ記録、ログは単一のS3バケットに集約させることもできました。
SNSトピックやその他の細かい設定はしていませんが、とりあえず有効化するだけなら十分かなと思っています。

せっかくならアグリゲーターでデータ収集も

GuardDutyやSecurity Hubように、ConfigでもOrganizationsの「委任管理者」を指定することができるということで、以下の記事を参考にやってみました。割と簡単にできたので、参考までにリンクを貼っておきます。
[アップデート] 委任したメンバーアカウントで AWS Config アグリゲーターを使った Organizations 組織レベルのデータ収集が可能になりました

料金にはご注意を!

Configは全アカウント全リージョンで有効化することが推奨されているとはいえ、無料ではないので、料金には注意しましょう!
仮に各リージョンのConfig利用料が1USDだとしても、先述の無効化されている4リージョンを除けば17リージョンあります。それが4アカウント分だと、
1USD × 17リージョン × 4アカウント = 68USD
になります。

僕の場合、1日で10USDを超えてAWS Budgetsで設定していたアラートが来たので、結局ほとんどのアカウントとリージョンで無効化しました。
プライベートアカウントでやるにはちょっと荷が重すぎたかなと思っています・・・。

まとめ

今回はAWS Configの全アカウント全リージョン有効化において、個人的にたどり着いた設定方法を紹介しました。
マネジメントコンソールとStackSetsの併用という方法なので、これがよいのかどうかはわかりませんが、僕はひとまず自分なりの答えにたどり着いたので現時点での検証としては満足しました。

もちろんスクリプトを使用したり、テンプレートを改造すればもっと簡単にできるようになるかもしれないので、そのへんは乞うご期待ということで!

個人的な設定方法でしたが、参考になれば幸いです。
余は満足じゃあ~。

Discussion