💸

AWS Control Tower環境下でのConfig 費用を70% 抑制した話

2024/06/04に公開

はじめに

Septeni Japan株式会社でインフラ業務を担当している中川と申します。
当社では、Control TowerやSecurityHub などのAWSサービスを組み合わせることで、40以上のAWSアカウントで予防的統制・発見的統制を実現しています。

https://zenn.dev/septeni_japan/articles/a11b9e2decb5e2

発生した問題

Control Tower 導入後に AWS Config の費用の高騰を確認しました。原因を調べていくと、毎時のバッチ処理のためにEC2を都度立ち上げているインフラ構成を採用しているアカウントの影響であることがわかりました。

Control Tower導入前後でのAWS Config の費用推移Control Tower導入前後でのAWS Config の費用推移

  • 費用がスパイクしている日はControl Tower 導入によるものなので問題なし。
  • 赤色と青色のアカウントで継続的にコストが発生している。

課題

AWS Config は記録頻度を日時に変更したり、特定のリソースタイプを除外することで費用を抑制することが可能です。しかし当社の場合、Control Tower を導入しているため、SCP(Service Control Policy) の制限により、Administrator 権限であってもメンバーアカウントのAWS Config の設定変更はできませんでした。

※参考:
https://zenn.dev/septeni_japan/articles/b4ff22cfad3b9e#予防的コントロール

解決策の概要

様々な手法の検討(後述)を行った結果、こちらのAWS公式ブログの手法を「応用」することにより、AWS Config の費用を抑制できることが分かりました。具体的には、 マネジメントアカウント経由で指定したメンバーアカウントに対して、特定のリソースタイプを記録対象から除外する設定を上書きする というものです。

「応用」と書いたのは、ブログの手法をそのまま利用すると、リソースタイプの除外設定を行わないアカウントを全てCloud Formation Stackのパラメータで指定する必要があったからです。そのため当社では、リソースタイプの除外設定を行うアカウントは最小限にしたかったので、リソースタイプの除外設定を行う対象アカウントを指定できる方式へと改修を行いました。

解決策の詳細

除外するリソースタイプの決定

AWS Config ダッシュボードの 「リソースのインベントリ」の最下部にある「リソース設定データに対して、高度なクエリを実行します」というリンクから遷移する画面で、以下の「調査用のクエリ」を実行します。これで、リソースタイプ毎のAWS Configの記録数が分かるレポートを入手できます。より詳細にログを確認をしたい場合は Athena を利用ください。

調査用のクエリ
SELECT
  resourceType,
  COUNT(*)

GROUP BY
  resourceType

ORDER BY
  COUNT(*) DESC

アーキテクチャ と処理の概要

Cloud Formation Stack を作成することで、以下構成のリソースが展開されます。

展開されるリソースの構成図

  1. アカウント追加・OU再登録・ランディングゾーン更新などのControlTower の変更イベントを、EventBridgeで検出してProducer Lambda を起動
  2. Producer Lambda が設定変更の対象となるアカウントを抽出してSQSに Queを追加
  3. SQS が Consumer Lambdaを起動
  4. Consumer Lambda が、各アカウント(x リージョン)毎に API リクエストを実行してAWS Config の設定を変更(リソースタイプの除外)

ソリューションのデプロイ方法

公式ブログの場合は、template.yamlをCloud Formationに適用すればソリューションが組み上がりますが、今回はコードを改修しているため、LambdaのソースコードのzipファイルをS3に格納する必要があります。

ソースコードを入手

https://github.com/septeni/infra-aws-control-tower-config-customization/releases/tag/2024-05-31

ローカルでzipファイルを作成

ct_configrecorder_override_consumer_v2ct_configrecorder_override_producer のディレクトリ2つをそれぞれ圧縮して以下2つのzipファイルを作成します。私の環境ではGUIでzipを作成するとうまく行かなかったので、zip コマンドで圧縮したらうまくいきました。

  • ct_configrecorder_override_consumer_v2.zip
  • ct_configrecorder_override_producer.zip

Zipファイルを マネジメントアカウント の s3 にアップロード

  • バケット名は任意でOK
  • 作成したバケット配下に /config のディレクトリを作成
  • /config ディレクトリ配下にZipを2つ格納

最終的に以下のような構成になっていればOKです。

hogebucket
  ∟ config
    ∟ ct_configrecorder_override_consumer_v2.zip
    ∟ ct_configrecorder_override_producer.zip

マネジメントアカウントで CloudFormation Stack を作成

ステップ1:スタックの作成
- 既存のテンプレートを選択 => テンプレートファイルのアップロード
- template.yaml を 指定

ステップ2:スタックの詳細を指定
- スタック名: 任意
- パラメータ:
    - ConfigRecorderExcludedResourceTypes:除外対象のリソースタイプをカンマ区切りで記載
    - LambdaSourceCodeS3Bucket: アップロードしたS3バケット名を記載
    - TargetAccounts: 除外対象のアカウントを配列で記載

ステップ3:スタックオプションの設定
- 何も入力せずに「次へ」

ステップ4:確認して作成
- 「送信」を押すと各種リソースが展開される
- 続いて ProducerLambda、ConsumerLambda が 実行される

ステップ2 の設定例

まとめ

上記ソリューションを導入することにより、無事 AWS Config の費用を抑制することができました。

解決策導入後のAWS Config の費用推移

また、今回のソリューションを導入していくうえで、以下のような注意点も見えてきました。皆様の環境で導入を検討される際はメリット・デメリットをしっかりと認識したうえで慎重に導入判断をして頂けると幸いです。

Appendix:検討・調査した手法

今回、調査・検証にかなり苦戦したので、試してみて断念した手法も含めて記録として残しておきます。

手法1:Cloud Formation StackSetsでAWS Config の記録対象リソースを指定

AWSControlTowerBP-BASELINE-CONFIG のパラメータResourceTypesで記録対象のリソースを指定する方法を検討しました。しかし、全アカウントに設定が適用されてしまうことで、全アカウントで対象外としたリソースタイプに関連するSecurityHub の検出が上がらなくなり、発見的統制が弱まるため断念しました。

手法2:Cloud Formation StackSets でAWS Config の記録頻度を指定

手法1と同じく、AWSControlTowerBP-BASELINE-CONFIG のパラメータFrequency の設定を変更する手法を検討しました。しかし、このパラメータで指定する値は AWS Config Snapshot の配信頻度の設定となるため、今回抑制したいAWS Config の記録回数ではないという点で断念しました。

AWSControlTowerBP-BASELINE-CONFIG のパラメータ設定画面

手法3:CfCT(Customizations for Control Tower)を利用して AWS Config の設定を上書き

CfCT で 各メンバーアカウントのConfig設定を上書きする StackSets を作成しようとしました。しかし、CfCTの実行過程で AWSControlTowerBP-BASELINE-CONFIG と設定がバッティングするエラーが発生してしまい断念しました。

※参考:CfCT の仕組み
https://dev.classmethod.jp/articles/customizations-for-control-tower/

Discussion