デプロイ前のコンプライアンスチェック!CloudFormation Guardを試してみた

CloudFormation Guard を使うことで、CloudFormation をデプロイ前にコンプライアンスチェックでき、より安全なデプロイをできるようになります。
2020.10.31

CloudFormation テンプレート(以下、CFn テンプレート)が、ポリシーガイドラインに準拠しているか確認できるコマンドラインツールとして、CloudFormation Guard (以下、CFn Guard)が公開されました。
CFn Guard は、2020年10月1日から一般提供されています。

これまで、Security Hub のセキュリティ標準や Config 適合パックを用いて、AWS環境がコンプライアンスに準拠しているか調べられます。
CFn Guard では、CFnテンプレートが定義したルールを満たしているかをチェックでき、デプロイする前にコンプライアンスに準拠しているかチェックできます。 デプロイ前にCFn Guard でチェックすることによって、より安全なデプロイを実現できます。

やってみた

実際に使いながら何をできるか確認していきます。まずは GitHub の手順に従って、ローカルで CFn Guard を試します。

0. インストール

Mac で実行する場合は、Homebrew からインストールできます。

brew install cloudformation-guard

他の OS 実行環境でのインストール方法については、こちらを参照ください。

1. ローカルで実行

以下のような EBS ボリュームを作成する CFn テンプレートを作成します。

ebs.yml

AWSTemplateFormatVersion: "2010-09-09"
Description: EBS Volume Stack
Resources:
  NewVolume:
    Type: AWS::EC2::Volume
    Properties:
      Size: 500
      Encrypted: false
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region
  NewVolume2:
    Type: AWS::EC2::Volume
    Properties:
      Size: 50
      Encrypted: false
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region

続いて、以下のルールセットのファイルを作成します。

ebs_volume_template.ruleset

let encryption_flag = true

AWS::EC2::Volume Encrypted == %encryption_flag
AWS::EC2::Volume Size <= 100

1 行目は let 変数名 = 値 のフォーマッットで変数を定義しています。
3,4 行目では リソースタイプ プロパティ 演算子 値 のフォーマットで CloudFormation リソースタイプのプロパティに期待する値を指定しています。これが CFn Guard における基本的なルールの書き方になります。
ルールの書き方の詳細につきましては、こちらを参照ください。

見てのとおりではありますが、ここでは

  • EBSボリュームで暗号化がされていること
  • ボリュームサイズが100GB以下であること

を定義しています。

テンプレートとルールができたので、cfn-guard check コマンドでチェックしています。

$ cfn-guard check --template ebs.yml --rule_set ebs_volume_template.ruleset
[NewVolume2] failed because [Encrypted] is [false] and the permitted value is [true]
[NewVolume] failed because [Encrypted] is [false] and the permitted value is [true]
[NewVolume] failed because [Size] is [500] and the permitted value is [<= 100]
Number of failures: 3

NewVolume と NewVolume2 は暗号化してなかっため、エラーとなってます。
また、NewVolume はボリュームサイズが100GBを超えているため、エラーとなっています。

では、エラーとなった箇所を以下の通り修正します。

ebs.yml

AWSTemplateFormatVersion: "2010-09-09"
Description: EBS Volume Stack
Resources:
  NewVolume:
    Type: AWS::EC2::Volume
    Properties:
      Size: 50
      Encrypted: true
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region
  NewVolume2:
    Type: AWS::EC2::Volume
    Properties:
      Size: 50
      Encrypted: true
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref AWS::Region

cfn-guard check コマンドを再度実行します。

$ cfn-guard check --template ebs.yml --rule_set ebs_volume_template.ruleset

エラーなく、CFn Guard が完了しました! ルールセットは、サンプルでいくつか用意されておりますので、お試しで使っていただければと思います。

2. 自動ルールの生成

CFn Guard では、cfn-guard rulegen コマンドを使うことにより、既存の CFn テンプレートからルールを自動生成できます。

$ cfn-guard rulegen ebs.yml
AWS::EC2::Volume AvailabilityZone == [0,{"Fn::GetAZs":"AWS::Region"}]
AWS::EC2::Volume Encrypted == true
AWS::EC2::Volume Size == 50

ルールが生成されましたら、必要に応じでルールの追加や削除をして、チェックで使用するルールができあがります。

さいごに

デプロイ前にコンプライアンスチェックできる CloudFormation Guard を試してみました。
組織に合わせたルールを一度定義しデプロイフローに組み込むことで、より安全なデプロイが可能になります。今回はローカルで試しましたが、実運用を想定して CI/CD パイプラインに組み込む構成も試したいです。

CloudForamtion を使っている環境で、ぜひ使いたいツールだと思います。
プロダクト環境で使うには、rule-setの運用をどうするか、ルールセットを無視したい場合どうすといいのかは検討必要そうです。内部統制と開発者の職務分離するためにも、コードとrule-setを管理するリポジトリは分けて権限を絞ると良さそうな気はしてます。統制側で例外ルールを管理できると良さそうですがが、どうするといいのか私にはいいアイデアが思いつきませんでした。(そもそも例外となるルールはあってはいけないと考えるべきかもしれませんが)案ある方いましたらコメントいただけますと幸いです。

参考