あなたのIaC、いまでも動きますか？

はじめまして。株式会社NTTデータ クラウド＆データセンタ事業部の奥村です。2023年からAWS Ambassadorsを務めています。  
所属組織でQiita Organizationsを新設しました！これから組織のメンバーでクラウドやデータセンタに関する記事を執筆していきたいと思いますので、どうぞよろしくお願いいたします！

# はじめに
昨今、AWSサービスを始めとしたインフラの設定をCloudFormationやCDK、Terraform等でIaC化するのは一般的になったかと思います。  
開発が頻繁に行われている時には、IaCを使ってじゃんじゃんデプロイしていたが、開発が落ち着き、久しぶりにIaCをデプロイしようとした際、本当に動作するかどうか少し不安に感じる方もいるのではないでしょうか。  

クラウドサービスベンダーの仕様変更によって、既存のIaCに変更があることってありますよね？  
+ [S3 Block Public Accessがデフォルト有効化](https://aws.amazon.com/jp/blogs/news/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/)
> お客様のアプリケーションがパブリックバケットや ACL を必要とする場合には、以下で説明する変更を加える必要があります (コード、スクリプト、AWS CloudFormation テンプレート、および他のオートメーションを必ず確認してください)。
+  [IAMのサービスプレフィックスやアクションの廃止](https://aws.amazon.com/jp/blogs/news/changes-to-aws-billing-cost-management-and-account-consoles-permissions/)
> aws-portalサービスプレフィックスとその配下にあるすべてのアクションは廃止されます。

これらの仕様変更がIaCに反映されていないと、久しぶりにIaCを実行した際にデプロイが失敗する可能性があります。

# 当社のIaC
NTTデータでは、最低限必要なセキュリティ設定が実施済みのAWSを払い出す[セキュリティアカウント発行サービス](https://dc.jp.nttdata.com/pcs/NTTD_PCSA/NTTD_PCSA.zip)（すみません、zipファイル内仕様書をご確認いただければと思います）を提供しています。払い出し時の初期設定ではIaCを使って実施しています。設定するセキュリティルールの関係でIaCとしては、[AWS SDK for Python (Boto3)](https://aws.amazon.com/jp/sdk-for-python/)を利用しています。  

## 課題
セキュリティアカウント発行サービスを安定的に提供するためには大きく2つの課題がありました。  
1. 多岐にわたるAWSサービスへの設定が必要であり、対象の全AWSサービスの全アップデートを追うことが難しい。気づかないうちに設定対象のサービス仕様が変わっており、IaCが動作しなくなる可能性があるのではないか？
1. ベースとしている[Security HubのAWS基礎セキュリティ・ベストプラクティス（FSBP）標準](https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/fsbp-standard.html)に頻繁に更新が入り、IaCの変更が頻発するため、動作しなくなる可能性があるのではないか？
※FSBPとは、AWS社から提供されているセキュリティベストプラクティスとなる設定のルールセットであり、新サービス追加や既存サービス仕様変更に素早く追従してくれるものです。多くの案件でFSBPはセキュリティ対策の一つとして採用されています。

## 対策
上述の課題への対応として、当社ではセキュリティアカウント発行サービスのIaCに対する継続的なテストを実施しています。  
しかし、IaCの対象がAWSアカウント全体であるため、例えば[localstack](https://github.com/localstack/localstack)のようなAWSサービスをエミュレートするツールではテストが困難でした。テストのたびに新規でAWSアカウントを払い出すのもなかなかハードルが高い状況であったため、当社では3つのAWSアカウントを駆使して、継続的なテストを実現しています。
1. テストの実行基盤のあるAWSアカウント
1. 単体テストの対象となるAWSアカウント
1. 結合テストの対象となるAWSアカウント

継続的なテストは、AWS CodeBuildとAWS Step Functionsの2つのサービスを組み合わせて実現しています。
+ AWS CodeBuild：AWSサービスごとの設定実施スクリプトの単体テスト
+ AWS Step Functions：依存関係を考慮した全スクリプトを通した結合テスト

これを図で表現すると下記となります。  
![IaCのCI環境.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965348/5a83fe67-d33b-4122-b828-2643f3d92020.jpeg)

テストは[pytest](https://pypi.org/project/pytest/)で実装しており、assertメソッドによって想定通りの値となっていることを確認しています。想定通りの値を定めるのは結構骨の折れる作業となっており、マネジメントコンソールなどで実際に設定を行ったうえで、describeなどの参照系処理を行い、一つ一つ丁寧に値を確認していきました。

この継続的テストには何点か工夫したポイントがありますので、紹介していこうと思います。

### 工夫ポイント1 ロールバック
上記の図を見てお気づきになった方もいるかもしれませんが、単体テストと結合テストの両方にロールバックの処理を入れています。テストごとにクリーンな状態のAWSアカウントを用意するのが難しいため、テスト完了時にロールバックを行い、毎回クリーンな状態を維持しています。
![ポイント1_ロールバック.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965348/0fdb5d30-1009-0805-d0a1-35ceac28d500.jpeg)
ロールバックでは各AWSサービスの設定値を可能な限り初期値に戻す処理を実施しています。


### 工夫ポイント2 単体テストの対象を限定
実はAWS CodeBuildを使った単体テストでは、セキュリティアカウント発行サービスで設定すべきすべてのAWSサービスをテスト対象にしていません。待機時間が必要な設定やロールバックに時間がかかる設定は単体テストの対象から除外し、単体テストの実行頻度を高く保つようにしています。テストの対象から除外しているものの具体例としては、AWS KMSのカスタマーマネージドキーの削除（ロールバック）などがあります。[KMSのカスタマーマネージドキーの削除は最短でも7日の待機時間が必要](https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/deleting-keys.html)となる仕様があるためです。

### 工夫ポイント3 結合テストの導入
単体テストだけでは確認できない依存関係がある設定（たとえばCloudTrailの証跡作成前にS3バケットを作っているなど）を含めて、セキュリティアカウント発行サービスとして必要な全体の流れを確認する結合テストをAWS Step Functionsを利用して実現しています。依存関係やロールバックの関係上、単体テストほどの頻度での実施は難しいですが、処理全体に問題がないかを確認するため、約2週間に1度程度の頻度で実施しています。

## 継続的テストの効果
ここまで紹介してきた継続的テストにより、セキュリティアカウント発行サービスはリリース後2年間を安定的にサービス提供ができています。  
この継続的テストの仕組み構築後、大きなサービス仕様変更がないため、単体テストが失敗することはほぼありませんが、スクリプト修正時のデグレードを確実に検知できるようになり、スクリプトの品質を維持できていると感じています。
また結合テストでは、Security HubのFSBPのスコアがほぼ満点となっていることを確認しているため、新たなコントロールが増えた際には、そのスコアが想定と異なるために、気付くことができています。

# おわりに
当社でのIaCの品質維持の取り組みを紹介させていただきました。意外とIaCを作ったらそのまま放置しているというケースもあるのではないかと思いますので、ぜひIaCも継続的なテストを組み入れていただければと思います！
今後もクラウドに限らず、さまざまな情報発信をしていく予定ですので、ぜひとも当Organizationの記事をご覧いただければ幸いです。

# 仲間募集中です！
NTTデータ クラウド&データセンタ事業部では、以下の職種を募集しています。
1. [プライベートクラウドコンサル/エンジニア](https://www.nttdata.com/global/ja/recruit/uptodata/articles/1268/)
2. [デジタルワークスペース構築／新規ソリューション開発におけるプロジェクトリーダー](https://www.nttdata.com/global/ja/recruit/uptodata/articles/1315/)
3. [IT基盤(パブリッククラウド、プライベートクラウド)エンジニア](https://www.nttdata.com/global/ja/recruit/uptodata/articles/4687/)
4. [パブリッククラウド/プライベートクラウドを用いた大規模プロジェクトをリードするインフラエンジニア](https://www.nttdata.com/global/ja/recruit/uptodata/articles/5104/)

# ソリューション紹介
1. [クラウドプロフェッショナルサービス/クラウドインテグレーションサービス/クラウドマネージドサービス/パートナークラウドサービス](https://dc.jp.nttdata.com/cloud/index/awssolutions.html)
2. [OpenCanvas](https://portal.opencanvas.ne.jp/)