AWS Config Rule 実装と運用してみた
AWS Config Ruleを使ったコンプライアンス監視の実装方法と運用のベストプラクティスをまとめました。
本記事では、AWS Config Ruleを使ったコンプライアンス監視の実装方法と、運用で得られた知見をまとめます。
AWS Config Rule とは
AWS Config Ruleは、AWSリソースの設定が組織のポリシーやベストプラクティスに準拠しているかを継続的に評価するサービスです。
主な用途
- セキュリティコンプライアンス: セキュリティグループの設定、暗号化の有効化など
- 運用ベストプラクティス: タグ付けルール、バックアップ設定など
- コスト最適化: 未使用リソースの検出
- カスタム要件: 組織固有のルールの実装
Config Rule の種類
1. マネージド Config Rule
AWSが提供する事前定義済みのルールです。一般的なコンプライアンス要件をカバーしています。
主なマネージドルール:
required-tags: 必須タグの存在確認encrypted-volumes: EBSボリュームの暗号化確認ec2-instance-managed-by-ssm: SSM管理下のEC2確認s3-bucket-public-read-prohibited: S3バケットのパブリック読み取り禁止rds-storage-encrypted: RDSストレージの暗号化確認
2. カスタム Config Rule
組織固有の要件に対応するため、独自のロジックを実装できます。実装方法は2つあります。
実装方法:
- Lambda関数: Pythonなどでカスタムロジックを実装
- Guard: ポリシーをコードとして記述(Policy as Code)
適用例:
- 特定のCloudWatchアラームの存在確認
- カスタムタグ命名規則の検証
- リソース間の依存関係チェック
- 特定の設定値の範囲チェック
カスタム Config Rule: GuardとLambdaの選び方
カスタムConfig Ruleを実装する際、GuardとLambdaの2つの方法があります。どちらを選ぶべきか、以下の基準で判断できます。
Guard vs Lambda 比較表
| 項目 | Guard | Lambda |
|---|---|---|
| 実装の難易度 | ⭐⭐⭐⭐⭐ 簡単 | ⭐⭐⭐ 中程度 |
| 学習コスト | 低い(DSL習得のみ) | 中程度(プログラミング知識必要) |
| チェック対象 | リソースの設定値のみ | 設定値 + 外部リソース |
| 複雑なロジック | ❌ 不可 | ✅ 可能 |
| 外部API呼び出し | ❌ 不可 | ✅ 可能 |
| ローカルテスト | ✅ 容易 | △ 環境構築が必要 |
| デバッグ | ⭐⭐⭐ 普通 | ⭐⭐⭐⭐ CloudWatch Logsで詳細確認可 |
| 保守性 | ⭐⭐⭐⭐⭐ 宣言的で読みやすい | ⭐⭐⭐ コードの品質に依存 |
| 実行コスト | 無料(Config料金のみ) | Lambda実行料金が発生 |
| パフォーマンス | ⭐⭐⭐⭐⭐ 高速 | ⭐⭐⭐⭐ 通常は十分 |
どちらを選ぶべきか?判断フロー
チェックしたい内容は? │ ├─ リソースの設定値のみをチェック │ (例:暗号化が有効か、タグが存在するか) │ │ │ └─ ✅ Guard を使用 │ - シンプルで保守しやすい │ - コストが低い │ - 実装が早い │ └─ 外部リソースの情報が必要 (例:CloudWatchアラームの存在、他のリソースとの関連) │ └─ ✅ Lambda を使用 - 柔軟な実装が可能 - 複雑なロジックに対応
Guard が適しているケース
✅ こんな時はGuardを選ぶ
-
設定値の単純なチェック
- S3バケットの暗号化が有効か
- EBSボリュームが暗号化されているか
- 必須タグが存在するか
- セキュリティグループのポート範囲チェック
-
複数の設定を組み合わせたチェック
- S3バケットが「暗号化 AND バージョニング AND パブリックアクセスブロック」全て有効か
- RDSが「暗号化 AND マルチAZ AND 自動バックアップ」全て有効か
-
設定値の範囲チェック
- RDSのバックアップ保持期間が7日以上か
- EC2インスタンスタイプが許可リストに含まれているか
Lambda が適しているケース
✅ こんな時はLambdaを選ぶ
-
外部リソースの存在確認
- EC2インスタンスに対応するCloudWatchアラームが存在するか
- VPCにVPCフローログが設定されているか
- S3バケットにライフサイクルポリシーが設定されているか
-
複雑な条件分岐
- 本番環境のリソースは厳しくチェック、開発環境は緩くチェック
- リソースタイプによって異なるルールを適用
- 時間帯や曜日によって評価基準を変更
-
動的な計算や集計
- 過去30日間のメトリクスを取得して評価
- 複数リソースの合計値をチェック
- コスト計算や使用率の算出
-
外部システムとの連携
- 社内CMDBとの照合
- 外部APIでの検証
- Slackへの通知(評価と同時に)
実際の選択例
ケース1: S3バケットのセキュリティチェック
要件: S3バケットが暗号化、バージョニング、パブリックアクセスブロックの全てが有効か
判断: ✅ Guard
- 理由: 全てS3バケット自体の設定値のチェック
- 外部リソースへのアクセス不要
ケース2: EC2インスタンスの監視設定チェック
要件: EC2インスタンスに対応するCloudWatchアラームが設定されているか
判断: ✅ Lambda
- 理由: CloudWatchアラーム(外部リソース)の存在確認が必要
- Guardではアラームの存在を確認できない
ケース3: RDSのバックアップ設定チェック
要件: RDSのバックアップ保持期間が7日以上か
判断: ✅ Guard
- 理由: RDS自体の設定値(BackupRetentionPeriod)のチェック
- シンプルな比較のみ
ケース4: VPCのフローログ設定チェック
要件: VPCにVPCフローログが設定されているか
判断: ✅ Lambda
- 理由: VPCフローログ(外部リソース)の存在確認が必要
describe_flow_logsAPIを呼び出す必要がある
両方を組み合わせる戦略
実際の運用では、GuardとLambdaを組み合わせて使うのが効果的です。
推奨アプローチ:
-
まずGuardで実装できるルールを洗い出す
- 80%のルールはGuardで実装可能
- シンプルで保守しやすい
-
Guardで実装できないものだけLambdaで実装
- 外部リソースチェックが必要なもの
- 複雑なロジックが必要なもの
-
定期的な見直し
- Guardの機能拡張により、Lambdaで実装していたものがGuardで実装可能になることも
まとめ:選択のポイント
| チェック内容 | 推奨方法 | 理由 |
|---|---|---|
| リソース自体の設定値 | Guard | シンプル、高速、低コスト |
| 外部リソースの存在確認 | Lambda | Guardでは不可能 |
| 複雑な条件分岐 | Lambda | 柔軟性が必要 |
| 動的な計算・集計 | Lambda | プログラミングが必要 |
| 外部API呼び出し | Lambda | Guardでは不可能 |
迷ったら: まずGuardで実装できないか検討し、無理ならLambdaを選択するのが良いアプローチです。
カスタム Config Rule の実装
方法1: Lambda関数を使った実装
Lambda関数を使うと、柔軟なロジックを実装できます。
方法2: AWS Config Guard を使った実装
AWS Config Guardは、ポリシーをコードとして記述できるドメイン固有言語(DSL)です。Lambda関数を書かずにルールを定義できます。
Guard の特徴
メリット:
- シンプル: Lambda関数を書く必要がない
- 宣言的: ポリシーを明確に記述できる
- テストが容易: ローカルでテスト可能
- バージョン管理: ポリシーファイルをGitで管理
デメリット:
- 複雑なロジックには不向き: 複雑な条件分岐や外部API呼び出しが必要な場合はLambdaが適している
Guard ルールの例
S3バケットの暗号化とバージョニングをチェックするルール:
# S3バケットの暗号化とバージョニングをチェック rule s3_bucket_compliance { # S3バケットのみを対象 AWS::S3::Bucket { # サーバーサイド暗号化が有効であること Properties.BucketEncryption exists Properties.BucketEncryption.ServerSideEncryptionConfiguration[*] { Rules[*].ServerSideEncryptionByDefault.SSEAlgorithm in ["AES256", "aws:kms"] } # バージョニングが有効であること Properties.VersioningConfiguration exists Properties.VersioningConfiguration.Status == "Enabled" # パブリックアクセスブロックが有効であること Properties.PublicAccessBlockConfiguration exists Properties.PublicAccessBlockConfiguration { BlockPublicAcls == true BlockPublicPolicy == true IgnorePublicAcls == true RestrictPublicBuckets == true } } }
Guard ルールのデプロイ
# Guardルールファイルをアップロード aws configservice put-config-rule --config-rule '{ "ConfigRuleName": "s3-bucket-compliance-guard", "Description": "S3バケットの暗号化とバージョニングをチェック", "Source": { "Owner": "CUSTOM_POLICY", "SourceDetails": [ { "EventSource": "aws.config", "MessageType": "ConfigurationItemChangeNotification" } ], "CustomPolicyDetails": { "PolicyRuntime": "guard-2.x.x", "PolicyText": "$(cat s3-bucket-compliance.guard)" } }, "Scope": { "ComplianceResourceTypes": ["AWS::S3::Bucket"] } }'
Guard のローカルテスト
# cfn-guardをインストール cargo install cfn-guard # ルールをテスト cfn-guard validate \ --rules s3-bucket-compliance.guard \ --data test-s3-bucket.json
適合パック(Conformance Packs)
適合パック(Conformance Packs)は、複数のConfig Ruleをテンプレートとしてまとめて管理できる機能です。
適合パックの特徴
- 一括管理: 複数のルールをYAMLテンプレートで定義
- 再利用性: テンプレートを複数のアカウント・リージョンに展開可能
- コンプライアンスフレームワーク対応: CIS、PCI-DSS、HIPAAなどのフレームワークに準拠したテンプレートが提供されている
- 修復アクション: Systems Manager Automation Documentと連携した自動修復
AWSが提供する適合パックテンプレート
- Operational Best Practices for CIS AWS Foundations Benchmark
- Operational Best Practices for PCI DSS 3.2.1
- Operational Best Practices for HIPAA Security
- Operational Best Practices for NIST 800-53 rev 5
適合パックの例
# conformance-pack-example.yaml Resources: # EC2インスタンスの暗号化チェック EC2VolumeEncryptionCheck: Type: AWS::Config::ConfigRule Properties: ConfigRuleName: ec2-volume-encryption-check Source: Owner: AWS SourceIdentifier: ENCRYPTED_VOLUMES Scope: ComplianceResourceTypes: - AWS::EC2::Volume # S3バケットのパブリックアクセスブロック S3BucketPublicReadProhibited: Type: AWS::Config::ConfigRule Properties: ConfigRuleName: s3-bucket-public-read-prohibited Source: Owner: AWS SourceIdentifier: S3_BUCKET_PUBLIC_READ_PROHIBITED Scope: ComplianceResourceTypes: - AWS::S3::Bucket # RDSの暗号化チェック RDSStorageEncrypted: Type: AWS::Config::ConfigRule Properties: ConfigRuleName: rds-storage-encrypted Source: Owner: AWS SourceIdentifier: RDS_STORAGE_ENCRYPTED Scope: ComplianceResourceTypes: - AWS::RDS::DBInstance Parameters: # パラメータを使って柔軟に設定可能 RequiredTagKey: Type: String Default: "Environment" Description: "必須タグのキー名"
適合パックのデプロイ
# 適合パックをデプロイ aws configservice put-conformance-pack \ --conformance-pack-name my-security-pack \ --template-body file://conformance-pack-example.yaml \ --delivery-s3-bucket my-config-bucket # デプロイ状況を確認 aws configservice describe-conformance-pack-status \ --conformance-pack-names my-security-pack
適合パックのメリット
- 一貫性: 全アカウントで同じルールセットを適用
- 効率性: 個別にルールを作成する手間を削減
- 監査対応: コンプライアンスフレームワークへの準拠を証明しやすい
- バージョン管理: テンプレートをGitで管理可能
アグリゲータ(Aggregator)
アグリゲータは、複数のアカウントやリージョンのConfig Ruleの評価結果を一元的に集約・表示する機能です。
アグリゲータの種類
1. アカウントアグリゲータ
特定のアカウントを指定して集約します。
aws configservice put-configuration-aggregator \ --configuration-aggregator-name my-account-aggregator \ --account-aggregation-sources '[ { "AccountIds": ["111111111111", "222222222222"], "AllAwsRegions": true } ]'
2. 組織アグリゲータ
AWS Organizations全体のアカウントを自動的に集約します。
aws configservice put-configuration-aggregator \ --configuration-aggregator-name my-org-aggregator \ --organization-aggregation-source '{ "RoleArn": "arn:aws:iam::123456789012:role/aws-service-role/organizations.amazonaws.com/AWSServiceRoleForOrganizations", "AllAwsRegions": true }'
アグリゲータの設定手順
1. 集約元アカウントでの設定
各アカウントで、集約を許可する設定を行います:
aws configservice put-aggregation-authorization \ --authorized-account-id 123456789012 \ --authorized-aws-region ap-northeast-1
2. 集約先アカウントでアグリゲータを作成
aws configservice put-configuration-aggregator \ --configuration-aggregator-name central-aggregator \ --account-aggregation-sources '[ { "AccountIds": ["111111111111", "222222222222", "333333333333"], "AllAwsRegions": true } ]'
3. コンプライアンス状況の確認
# 集約されたコンプライアンス状況を確認 aws configservice describe-aggregate-compliance-by-config-rules \ --configuration-aggregator-name central-aggregator \ --filters '{ "ComplianceType": "NON_COMPLIANT" }'
アグリゲータのメリット
- 一元管理: 複数アカウントのコンプライアンス状況を一箇所で確認
- 効率的な監査: 全体の準拠状況を素早く把握
- アラート統合: 非準拠リソースを集中的に監視
- レポーティング: 組織全体のコンプライアンスレポートを作成しやすい
アグリゲータの活用例
ダッシュボードでの可視化
CloudWatchダッシュボードと連携して、コンプライアンス状況を可視化:
import boto3 config_client = boto3.client('config') # 非準拠リソースの数を取得 response = config_client.get_aggregate_compliance_details_by_config_rule( ConfigurationAggregatorName='central-aggregator', ConfigRuleName='required-tags', ComplianceType='NON_COMPLIANT' ) non_compliant_count = len(response['AggregateEvaluationResults']) print(f'非準拠リソース数: {non_compliant_count}')
EventBridgeでの通知
非準拠リソースが検出されたら、Slackに通知:
{ "source": ["aws.config"], "detail-type": ["Config Rules Compliance Change"], "detail": { "configRuleName": ["required-tags"], "newEvaluationResult": { "complianceType": ["NON_COMPLIANT"] } } }
運用のベストプラクティス
1. 段階的な導入
初期フェーズ:
- まずはマネージドルールから導入
- 監視モードで運用開始し、誤検知を洗い出す
- 重要度の高いルールから優先的に適用
本格運用フェーズ:
- カスタムルールの追加
- 自動修復(Remediation)の検討
- アラート通知の設定
2. 適切なスコープ設定
リソースタイプやタグでスコープを絞り込み、評価対象を最適化:
{ "Scope": { "ComplianceResourceTypes": ["AWS::EC2::Instance"], "TagKey": "Environment", "TagValue": "Production" } }
3. コスト管理
- 評価頻度の最適化: 変更時のみ評価 vs 定期評価
- 対象リソースの絞り込み: タグやリソースタイプでフィルタリング
- 不要なルールの削除: 定期的な見直し
- 適合パックの活用: 個別ルールよりも効率的
4. 自動修復(Remediation)
Systems Manager Automation Documentを使った自動修復:
aws configservice put-remediation-configurations \ --remediation-configurations '[ { "ConfigRuleName": "s3-bucket-public-read-prohibited", "TargetType": "SSM_DOCUMENT", "TargetIdentifier": "AWS-PublishSNSNotification", "TargetVersion": "1", "Parameters": { "AutomationAssumeRole": { "StaticValue": { "Values": ["arn:aws:iam::123456789012:role/ConfigRemediationRole"] } }, "TopicArn": { "StaticValue": { "Values": ["arn:aws:sns:ap-northeast-1:123456789012:config-alerts"] } } }, "Automatic": true, "MaximumAutomaticAttempts": 3, "RetryAttemptSeconds": 60 } ]'
トラブルシューティング
よくある問題と対処法
1. Lambda関数がタイムアウトする
原因: 大量のリソースを評価する際に時間がかかる
対処法:
- タイムアウト時間を延長(最大15分)
- バッチ処理の実装
- 評価ロジックの最適化
2. 権限不足エラー
原因: Lambda関数やConfig Ruleに必要な権限が付与されていない
対処法:
- Lambda実行ロールに必要な権限を追加
config:PutEvaluations権限は必須
3. 評価結果が更新されない
原因: resultTokenの処理ミスや、評価結果の返却漏れ
対処法:
try: # 評価ロジック compliance_type = 'COMPLIANT' except Exception as e: compliance_type = 'NON_COMPLIANT' annotation = f'Error: {str(e)}' finally: # 必ず評価結果を返す config_client.put_evaluations( Evaluations=[...], ResultToken=event['resultToken'] )
4. アグリゲータでデータが表示されない
原因: 集約元アカウントで承認設定がされていない
対処法:
- 各アカウントで
put-aggregation-authorizationを実行 - IAMロールの権限を確認
コスト試算
料金体系(2025年12月時点)
- Config Rule評価: $0.001/評価
- 設定項目の記録: $0.003/設定項目/月
- 適合パック評価: $0.0011/評価
- Lambda実行: 実行時間とメモリに応じた従量課金
実例
環境: 100台のEC2インスタンス、10個のConfig Rule
月間コスト試算:
- Config Rule評価: 100インスタンス × 10ルール × 30日 × $0.001 = $30
- 設定項目記録: 100インスタンス × $0.003 = $0.30
- Lambda実行: 約$5(実行時間による)
合計: 約$35/月
まとめ
AWS Config Ruleは、AWSリソースのコンプライアンス管理を自動化する強力なツールです。
導入のポイント
- 小さく始める: まずはマネージドルールから導入
- 段階的に拡大: 運用に慣れてから対象を広げる
- 適合パックの活用: 複数ルールを効率的に管理
- アグリゲータで一元管理: マルチアカウント環境では必須
- 自動化を進める: 通知→修復の流れを構築
- 定期的な見直し: ルールの有効性を継続的に評価
Lambda vs Guard の使い分け
- Lambda: 複雑なロジック、外部API呼び出しが必要な場合
- Guard: シンプルな設定チェック、宣言的にポリシーを記述したい場合
次のステップ
- AWS Security Hubとの連携
- カスタムルールのライブラリ化
- CI/CDパイプラインへの組み込み
- 適合パックのカスタマイズ
適切に運用すれば、セキュリティとコンプライアンスの維持を大幅に効率化できます。