概要

CloudFormation Hooks は、CloudFormation がリソースをプロビジョニングする前にリソースの設定を検査し、組織のポリシーに準拠しているかチェックする機能

出典: What are CloudFormation Hooks?

CloudFormation Hooks is a feature that helps ensure that your CloudFormation resources, stacks, and change sets comply with your organization’s security, operational, and cost optimization best practices.

Hooks がない場合との比較

観点Hooks なしHooks あり
検出タイミングリソース作成後(事後)リソース作成前(事前)
対応コスト作成済みリソースの修正が必要作成前にブロックするため修正不要
自動化手動レビューまたは別ツールが必要CloudFormation に統合済み

類似サービスとの違い

サービス検査タイミング用途
CloudFormation Hooksプロビジョニング前リソース作成をブロック
AWS Config Rulesプロビジョニング後(継続的)既存リソースのコンプライアンス監視
Service Control Policies (SCP)API 呼び出し時Organizations レベルで API 自体を制限

Hook の適用範囲

Hook はアカウント・リージョン単位で有効化される。一度有効化すると、そのアカウント・リージョン内の全スタック操作に対して Hook が実行される。

出典: Hook configuration schema syntax reference

To enable your Hook to proactively inspect the configuration of your stack, set the HookInvocationStatus to ENABLED after the Hook has been registered and activated in your account.

特定のスタックだけに適用/除外したい場合は StackFilters で制御する:

StackFilters:
  FilteringCriteria: ALL
  StackNames:
    Include:
      - production-*    # production- で始まるスタックのみ対象
    Exclude:
      - test-*          # test- で始まるスタックは除外

Hook の実装方法

方法特徴
AWS Control Tower proactive controlsコードを書かずに AWS のベストプラクティスを適用
Guard Hook宣言的な DSL でポリシーを記述
Lambda Hook任意の言語で柔軟なロジックを実装可能
Custom HookCloudFormation CLI で独自の Hook を開発

Guard Hook

Guard Hook は AWS CloudFormation Guard という DSL(ドメイン固有言語)でポリシーを記述する方式

出典: Write Guard rules to evaluate resources for Guard Hooks

AWS CloudFormation Guard is an open-source and general purpose domain specific language (DSL) you can use to author policy-as-code.

Guard ルールの構文

let s3_buckets = Resources.*[ Type == 'AWS::S3::Bucket' ]
 
rule S3_BUCKET_ENCRYPTION_ENABLED when %s3_buckets !empty {
    %s3_buckets.Properties.BucketEncryption exists
    %s3_buckets.Properties.BucketEncryption.ServerSideEncryptionConfiguration[*].ServerSideEncryptionByDefault.SSEAlgorithm in ["aws:kms", "AES256"]
    <<
        Violation: S3バケットにはサーバーサイド暗号化を設定する必要があります
        Fix: SSEAlgorithm を "aws:kms" または "AES256" に設定してください
    >>
}
構文説明
let var = ...変数定義。Resources.*[ Type == '...' ] でリソースをフィルタリング
rule ... when ...条件付きルール。when 条件が真の場合のみ評価
existsプロパティが存在することを検証
in [...]値が許可リストに含まれることを検証
<< Violation: ... Fix: ... >>違反時のメッセージ

Guard Hook の構成要素

Guard Hook を動作させるには以下が必要:

  1. Guard ルールファイル(S3 に配置)
  2. IAM ロール(Hook が S3 からルールを読み取るため)
  3. Guard Hook リソース(AWS::CloudFormation::GuardHook

Guard Hook の主要プロパティ

プロパティ説明
AliasHook の識別名。Name1::Name2::Name3 形式。アカウント内で一意
ExecutionRoleS3 アクセス用 IAM ロールの ARN
FailureModeFAIL: 違反時にブロック、WARN: 警告のみで続行
HookStatusENABLED または DISABLED
RuleLocation.UriGuard ルールファイルの S3 URI
TargetOperations検査対象の操作タイプ
TargetFilters検査対象のリソースタイプとアクション
StackFilters対象/除外するスタック名

TargetOperations の種類

説明
RESOURCE個別リソース単位で検査
STACKテンプレート全体を検査
CHANGE_SET変更セット作成時に検査
CLOUD_CONTROLCloud Control API 経由の操作を検査

TargetFilters の設定

TargetFilters:
  TargetNames:
    - AWS::S3::Bucket       # 特定リソースタイプ
    - AWS::S3::*            # ワイルドカード可
  Actions:
    - CREATE
    - UPDATE
    - DELETE

参考資料

実際に試してみる