4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

あなたはAWS Configで損をしている!? ~ AWS提供サンプルテンプレートの罠 ~

Posted at

はじめに

結論から言います。

AWSが提供している CloudFormation StackSets サンプルテンプレートを用いて、AWS Config を有効化している場合、余分なコストが発生している可能性があります。

対象読者

  • AWSが提供している CloudFormation StackSets サンプルテンプレートを用いて、 AWS Config を有効化している方(または、これから有効化しようと考えている方)
  • AWS Config をすべてのリージョンで有効化していない方
  • AWS Config のベストプラクティスに興味のある方

CloudFormation StackSets とは

複数のアカウントとリージョンに対して、同じ CloudFormation スタックを作成する機能です。

マルチアカウントの印象が強いかもしれませんが、対象アカウントを一つにすることにより、同一アカウント内の複数リージョンのみを対象とすることも可能です。

本記事では、同一アカウントの複数リージョンを対象とします。
また、CloudFormation StackSets では長いので、以降は StackSets と略します。

image.png

引用: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 を有効にする テンプレートも含まれています。

image.png

引用:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-sampletemplates.html

なお、マネジメントコンソールから StackSet を作成する際にもサンプルテンプレートを選ぶことができます。

CloudFormation > StackSets > StackSet の作成

image.png

なにが問題なのか?

問題は、このサンプルテンプレートをそのまま使うと、すべてのリージョンでグローバルリソースの記録が有効になってしまうこと です。

グローバルリソースとは 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)がすべてのリージョンに反映されます。
これが原因です。

EnableAWSConfig.yml(オリジナル抜粋)
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 にする です。

具体的な方法を解説していきます。

  1. グローバルリソースの記録を有効にするリージョンをパラメータとして追加します。
    Parameter: HomeRegion

  2. 疑似パラメータの AWS::Region を用いて、スタックを作成するリージョンが HomeRegion か否かを判定する Condition を作成します。
    Condition: IsHomeRegion

  3. 条件式を用いて、IsHomeRegion が真 = スタックを作成するリージョンが HomeRegion と一致した場合に限り、IncludeGlobalResourceTypes の値を True に設定します。

  4. 元々あった IncludeGlobalResourceTypes パラメータは不要なので、削除します。

EnableAWSConfig.yml(改善版抜粋)
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月以降はグローバルリソースの扱いが変わっている!?

ここまでサンプルテンプレートの問題点と改善方法を解説してきましたが、最後に重要なお知らせがあります。

なんと、公式ドキュメントに以下の記載がありました。

image.png

引用:https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/select-resources.html

2022 年 2 月以前にオンボードされたものは変更されず、今後も AWS Config で有効化されているすべてのリージョン内の設定項目を配信します。この変更は、2022 年 2 月以降にオンボードされた新しいグローバルリソースタイプのみに影響します。

この記載によると、2022 年 2 月以降はグローバルリソースの扱いが変わっているそうです。

ただし、私が 2022/03/21 時点で動作を確認した限りでは、従来動作からの差異は確認できませんでした。

■確認手順

  1. 既存の AWS Config 関連リソース(AWS::Config::ConfigurationRecorder および AWS::Config::DeliveryChannel)を削除。
  2. 新しい AWS Config 関連リソース(AWS::Config::ConfigurationRecorder および AWS::Config::DeliveryChannel)を作成。
    IncludeGlobalResourceTypes は東京リージョン(ap-northeast-1)のみ True とし、他リージョンは False とした。
  3. 新しい IAM リソース(AWS::IAM::Group)を作成。

■確認結果

  • 東京リージョン(ap-northeast-1)の AWS Config に新たに作成した IAM リソース(AWS::IAM::Group)が表示された。
  • バージニア北部リージョン(us-east-1)の AWS Config には新たに作成した IAM リソース(AWS::IAM::Group)が表示されなかった。

また、念のため、API リファレンスも確認してみましたが、動作変更に関する記載はありませんでした。

時間が取れたらさらに検証してみようと思いますが、AWS サポートに確認した方が確実かつ早いかもしれません。
もし、詳細をご存じの方がいらっしゃいましたら教えてください。

おわりに

本記事では、サンプルテンプレートの問題点を指摘・改善しましたが、サンプルの提供元を批判する意図は一切ありません。
サンプルの提供元に関わらず、利用者が内容を理解した上で利用することと、ベストプラクティスの理解が重要と考えます。

最後まで読んでいただき、ありがとうございます。
本記事が少しでも役に立てば幸いです。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?