はじめに
結論から言います。
AWSが提供している CloudFormation StackSets サンプルテンプレートを用いて、AWS Config を有効化している場合、余分なコストが発生している可能性があります。
対象読者
- AWSが提供している CloudFormation StackSets サンプルテンプレートを用いて、 AWS Config を有効化している方(または、これから有効化しようと考えている方)
- AWS Config をすべてのリージョンで有効化していない方
- AWS Config のベストプラクティスに興味のある方
CloudFormation StackSets とは
複数のアカウントとリージョンに対して、同じ CloudFormation スタックを作成する機能です。
マルチアカウントの印象が強いかもしれませんが、対象アカウントを一つにすることにより、同一アカウント内の複数リージョンのみを対象とすることも可能です。
本記事では、同一アカウントの複数リージョンを対象とします。
また、CloudFormation StackSets では長いので、以降は StackSets と略します。
引用:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html
StackSets の使いどころ
StackSets は複数リージョンに対して、同じリソースを作成したい場合に効果を発揮します。
例えば、AWS アカウントの初期設定 です。
本記事のテーマである AWS Config だけでなく、 CloudTrail, GuardDuty, Security Hub などのサービスは、すべてのリージョンで有効化することが推奨されています。
しかし、これらのサービスをマネジメントコンソールからすべてのリージョンで有効化するのは大変です。
このような場合に StackSets を使うと、すべてのリージョンで一括設定することが可能です。
AWSが提供しているサンプルテンプレートの問題点
本題に入りましょう。
AWS は、いくつかの StackSets サンプルテンプレートを提供しています。
この中には AWS Config を有効にする テンプレートも含まれています。
引用:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-sampletemplates.html
なお、マネジメントコンソールから StackSet を作成する際にもサンプルテンプレートを選ぶことができます。
CloudFormation > StackSets > StackSet の作成
なにが問題なのか?
問題は、このサンプルテンプレートをそのまま使うと、すべてのリージョンでグローバルリソースの記録が有効になってしまうこと です。
グローバルリソースとは IAM などのグローバルサービスのリソースのことです。
AWS Config では、各リージョンの記録にグローバルリソースを含めるか否かを選択することができます。
すべてのリージョンでグローバルリソースの記録が有効にした場合、以下の問題が発生します。
AWS Config の料金が増える
AWS Config はルールの評価件数に応じて課金されるため、各リージョンでグローバルリソースを重複して記録している場合、余分な料金が発生します。
グローバルリソースに関する通知が重複する
ルールの評価結果に対して通知を設定している場合、各リージョンでグローバルリソースに関するチェックが実行されるため、通知も重複します。
通知の重複については、以下のブログで検証されています。
AWS Config のベストプラクティス
ここで AWS Config のベストプラクティスを見てみましょう。
実は、グローバルリソースの記録は1つのリージョンのみで有効としたほうがよい、という話は AWS Config のベストプラクティスにも書かれています。
3.1 つのリージョンでのみグローバルリソース (IAM リソースなど) を記録します。
これにより、IAM 設定アイテムの冗長コピーをすべてのリージョンで取得することがなくなります。それは費用の節約にもなります。
引用:https://aws.amazon.com/jp/blogs/news/aws-config-best-practices/
しかし、残念ながら提供されているサンプルテンプレートは、このベストプラクティスに準拠していません。
改善しよう
問題点ばかり指摘しても仕方がないので、サンプルテンプレートを改善してみましょう。
サンプルテンプレートの分析
グローバルリソースを記録するか否かは AWS::Config::ConfigurationRecorder リソースの IncludeGlobalResourceTypes プロパティで指定します。
サンプルテンプレートでは、このプロパティの値をパラメータで指定する形になっています。
StackSets は、指定したリージョンに対して、同じテンプレートからスタックを作成するため、パラメータで指定した値(True または False)がすべてのリージョンに反映されます。
これが原因です。
Parameters:
IncludeGlobalResourceTypes:
Type: String
Default: False
Description: Indicates whether AWS Config records all supported global resource types.
AllowedValues:
- True
- False
(中略)
Resources:
ConfigRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn:
- ConfigBucketPolicy
Properties:
RoleARN: !GetAtt ConfigRecorderRole.Arn
RecordingGroup:
AllSupported: !Ref AllSupported
IncludeGlobalResourceTypes: !Ref IncludeGlobalResourceTypes
ResourceTypes: !If
- IsAllSupported
- !Ref AWS::NoValue
- !Ref ResourceTypes
改善版テンプレート
では、どのように改善したらよいか?
答えは、特定のリージョンの場合に限り IncludeGlobalResourceTypes を True にする です。
具体的な方法を解説していきます。
-
グローバルリソースの記録を有効にするリージョンをパラメータとして追加します。
Parameter: HomeRegion -
疑似パラメータの AWS::Region を用いて、スタックを作成するリージョンが HomeRegion か否かを判定する Condition を作成します。
Condition: IsHomeRegion -
条件式を用いて、IsHomeRegion が真 = スタックを作成するリージョンが HomeRegion と一致した場合に限り、IncludeGlobalResourceTypes の値を True に設定します。
-
元々あった IncludeGlobalResourceTypes パラメータは不要なので、削除します。
Parameters:
HomeRegion:
Type: String
(中略)
Conditions:
IsHomeRegion: !Equals [!Ref AWS::Region, !Ref HomeRegion]
(中略)
Resources:
ConfigRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn:
- ConfigBucketPolicy
Properties:
RoleARN: !GetAtt ConfigRecorderRole.Arn
RecordingGroup:
AllSupported: !Ref AllSupported
IncludeGlobalResourceTypes: !If
- IsHomeRegion
- True
- False
ResourceTypes: !If
- IsAllSupported
- !Ref AWS::NoValue
- !Ref ResourceTypes
これで HomeRegion パラメータで指定したリージョンに限り、グローバルリソースを記録することができました。
【要検証】2022年2月以降はグローバルリソースの扱いが変わっている!?
ここまでサンプルテンプレートの問題点と改善方法を解説してきましたが、最後に重要なお知らせがあります。
なんと、公式ドキュメントに以下の記載がありました。
引用:https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/select-resources.html
2022 年 2 月以前にオンボードされたものは変更されず、今後も AWS Config で有効化されているすべてのリージョン内の設定項目を配信します。この変更は、2022 年 2 月以降にオンボードされた新しいグローバルリソースタイプのみに影響します。
この記載によると、2022 年 2 月以降はグローバルリソースの扱いが変わっているそうです。
ただし、私が 2022/03/21 時点で動作を確認した限りでは、従来動作からの差異は確認できませんでした。
■確認手順
- 既存の AWS Config 関連リソース(AWS::Config::ConfigurationRecorder および AWS::Config::DeliveryChannel)を削除。
- 新しい AWS Config 関連リソース(AWS::Config::ConfigurationRecorder および AWS::Config::DeliveryChannel)を作成。
IncludeGlobalResourceTypes は東京リージョン(ap-northeast-1)のみ True とし、他リージョンは False とした。 - 新しい IAM リソース(AWS::IAM::Group)を作成。
■確認結果
- 東京リージョン(ap-northeast-1)の AWS Config に新たに作成した IAM リソース(AWS::IAM::Group)が表示された。
- バージニア北部リージョン(us-east-1)の AWS Config には新たに作成した IAM リソース(AWS::IAM::Group)が表示されなかった。
また、念のため、API リファレンスも確認してみましたが、動作変更に関する記載はありませんでした。
時間が取れたらさらに検証してみようと思いますが、AWS サポートに確認した方が確実かつ早いかもしれません。
もし、詳細をご存じの方がいらっしゃいましたら教えてください。
おわりに
本記事では、サンプルテンプレートの問題点を指摘・改善しましたが、サンプルの提供元を批判する意図は一切ありません。
サンプルの提供元に関わらず、利用者が内容を理解した上で利用することと、ベストプラクティスの理解が重要と考えます。
最後まで読んでいただき、ありがとうございます。
本記事が少しでも役に立てば幸いです。