AWS Control Towerで設定されたAWS Configの料金が高騰したのでどうにかした話

# AWS Control Tower とは

[AWS Control Tower](https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide/what-is-control-tower.html) は、AWS のマルチアカウント環境を簡単にセットアップしてくれるサービスです。

マルチアカウント化の考え方や AWS Control Tower を利用するメリットについては、こちらの記事が非常に参考になります。  
[スタートアップにおけるマルチアカウントの考え方と AWS Control Tower のすゝめ](https://aws.amazon.com/jp/blogs/startup/multi-accounts-and-control-tower/)  
スタートアップ向けに書かれた記事ですが、内容は AWS を運用している方なら誰でも参考になると思います。

AWS Control Tower の特徴の１つにガードレールがあります。あらかじめルールを設定しておくことで、

- 望まない操作を禁止する（予防的ガードレール）
- 望まない設定変更があった場合、それを検出する（検出的ガードレール）

ことが出来るようになります。

![Xnip2022-05-15_19-30-05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98903/39f5b733-bf46-6cda-6274-07ec57f75b9c.jpeg)

このうち予防的ガードレールは SCP で、検出的ガードレールは **AWS Config** によって実装されます。  

# AWS Config の料金高騰

[AWS Config](https://aws.amazon.com/jp/config/) は、AWS リソースに対して行った設定を継続的に監視します。これにより、望まない設定変更があった場合に検出することができます。  

非常に便利なサービスではあるのですが、開発チームでこの AWS Config にかかる料金の高騰が問題になりました。  
[AWS Config の料金](https://aws.amazon.com/jp/config/pricing/)
AWS Config では記録された設定項目あたり 0.003USD がかかります（2022/05/15 現在、東京リージョン）。１項目あたりの料金は大したことがないように見えても、積み重なると簡単に高騰します。  

どのリソースが原因かを調査する方法は以下の記事が非常に詳しく参考になります。
[AWS Config の料金がなぜこんなに高い？ Amazon Athena でどのリソースが Config の記録対象になっているか調べてみた](https://dev.classmethod.jp/articles/aws-config-amazon-athena/)

自分たちのチームでは原因は明らかで、１回のデプロイで数十の Lambda が更新されるようになっていましたが、特に検証環境では構築した CI/CD パイプラインにより１日に数回〜数十回もデプロイが走るため、頻繁に設定の変更が記録されていました。  
このためアプリケーションのワークロードにかかる料金よりも AWS Config の料金の方が高い、などという事態が発生してしまっていました。

# AWS Control Tower で設定された AWS Config 固有の課題

[前述の記事](https://dev.classmethod.jp/articles/aws-config-amazon-athena/)で記録対象を絞る方法が紹介されており AWS Config 単体で利用している場合は有効なのですが、**AWS Control Tower を利用しているとうまくいきません**。
AWS Config は AWS Control Tower の検出的ガードレールが動くために必須なサービスなので、**AWS Config 自体の設定変更を禁止する予防的ガードレールが存在し、これらは必須となっています。**  

![Xnip2022-05-15_20-14-12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98903/b27b6a93-3830-aae6-c92f-6c6c80aaed6a.jpeg)

この予防的ガードレールは [SCP](https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide/mandatory-guardrails.html#config-disallow-changes) として設定されているため、**たとえ root アカウントであっても、変更する権限がありません。**  
実際に変更しようとすると、以下のようなエラーが発生します。

![Xnip2022-05-15_21-00-37.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98903/f92b9e37-e482-c4d8-6579-f1988d0881b7.jpeg)

# 対処方法

AWS Control Tower を利用する以上 AWS Config の設定は書き換えられないので

- AWS Control Tower の利用をやめる
- AWS Config の料金を抑えるようにデプロイ方法を最適化する

などを考えましたが、前者は料金のためだけに AWS Control Tower のメリットを享受出来ないのはあまりにもったいないですし、後者は時間がかかります。  
試行錯誤の末、以下の方法で対処することが出来たので紹介します。

### 注意事項

先に注意事項を挙げておきます。

**公式に紹介されている方法ではない**

ややトリッキーな方法で AWS Config の記録対象を変更しますが、公式に紹介されている方法ではないことを留意してください。  
念のため AWS のサポートエンジニアに相談したところ、現状 AWS Control Tower で AWS Config の設定をいじる方法は無いが、以下で紹介する方法は良いテクニックで有効だというご回答をいただいています。　　
同様の悩みを抱えている方も多いとのことなので、設定を変更できるようになる公式のアップデートを待つのも１つの手段だと思います。

**むやみに設定はいじらない**

そもそも AWS Control Tower を導入する目的の１つにセキュリティ・ガバナンスの強化があるはずなので、本来は全てのリソースが記録対象に入ることが望ましいです。  
その前提で、リスクやコストと相談しながら設定の変更を考えましょう。  
自分たちのチームでも、検証環境の特定のリソースのみを記録対象外としつつ、そうしなくて済むようデプロイ方法の最適化を並行して進めることにしました。

**Management アカウントへのアクセスが必要**
AWS Organizations の Management アカウントでの操作が必要になります。

**コスト監視はきちんとする**
AWS Config の設定を書き換えることになりますが、Landing Zone のバージョンアップなどで設定が元に戻る可能性もあります。  
AWS Budgets や Cost Explorer を活用して、料金高騰に早く気づけるような仕組みを作っておきましょう。

### 設定変更方法
AWS コンソールを開き、CloudFormation > StackSets と開きます。

StackSets のなかに `AWSControlTowerBP-BASELINE-CONFIG` があるので、これを開きます。この StackSet によって、組織内の各アカウントに AWS Config のリソースが作成されています。

![Xnip2022-05-15_22-10-54.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98903/158e320f-ff5a-dc61-cda2-2a55f164d7e0.jpeg)

パラメータタブで、以下の設定になっていることが確認できます。

- AllSupported: true
- IncludeGlobalResourceTypes： true
- ResourceTypes: （指定なし）

これらのパラメータは、AWS Config の記録対象を指定します。パラメータの詳細は [AWS::Config::ConfigurationRecorder RecordingGroup](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-config-configurationrecorder-recordinggroup.html) を参照してください。  
デフォルトで、全リソースを記録する設定になっています。

![Xnip2022-05-15_22-37-10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98903/a368cf82-e7ab-50da-be36-f59f673766a1.jpeg)

アクションタブから「StackSet のパラメータを上書き」を選択し、その後の設定画面で、AWS Config の設定を変更したいアカウントとリージョンを指定します。デプロイオプションは適宜設定してください。  
続いてパラメータの上書きを指定する画面で、以下の値で StackSet 値の上書きを行います。

- AllSupported: false
- IncludeGlobalResourceTypes： false
- ResourceTypes: （記録対象リソースをカンマ区切りで指定）

ResourceTypes についてはホワイトリスト方式でしか登録できないのが面倒ですが、除外したいリソース**以外**をカンマ区切りで指定します。　　
AWS Config がサポートするリソース一覧は[こちら](https://docs.aws.amazon.com/config/latest/developerguide/resource-config-reference.html)です。

```text
AWS::EC2::Volume,AWS::EC2::Host,AWS::EC2::EIP
```


最後のレビュー画面で更新したいアカウントやパラメータが正しいことを確認したら、「送信」ボタンを押すことで、各アカウントに反映されます。　　
対象アカウントの CloudFormation でスタック更新が無事行われたことを確認できれば、設定完了です。

# さいごに

再度の注意になりますがもし上記の方法を実行する場合は、しっかりと変更内容の意味を理解した上で、コストとリスクの兼ね合いを考えた上で行うようにしてください。　　
あくまで対症療法的なものだと考え、その他の根本的な解決策（リソースの最適化など）を模索した方が良いと思います。

AWS Control Tower はワンストップで基本的なセキュリティやガバナンスのベースを作成してくれる素晴らしいサービスです。  
コストの一側面だけで利用を諦めてしまいその他のメリットを享受出来なくなるのは非常にもったいないと思い、こちらの記事を起こしました。

もっと他に良い方法をご存知の方がいれば、教えていただけますと幸いです。