概要
AWS Configを使えばリソースの設定がセキュリティポリシーに準拠しているかを継続的に監視できますが、非準拠リソースを検出した後の対応は手動で行う必要があります。運用チームが対応するまでの間、非準拠の状態が放置されるリスクがあります。
この問題を解決するのが、Config RulesとLambda関数を組み合わせた 自動修復(Auto Remediation) です。非準拠リソースを検出した時点でLambda関数が自動的に呼び出され、設定を修正します。
ただし、自動修復を構成する際には Lambda の実行ロールに適切な権限を付与する必要があり、権限不足によって修復が失敗するケースが頻繁に発生します。本記事では、S3バケットのサーバーアクセスログ設定を題材に、Config RulesとLambdaによる自動修復の仕組みと、IAMロールの権限設定のポイントを解説します。
AWS Configの基本的な使い方についてはAWS Configによるリソース設定の監視で解説しています。本記事ではその知識を前提に、自動修復にフォーカスします。

クラウドおさる非準拠を見つけたら、人の手を待たずに Lambda で直してしまう自動修復を確かめる記事でござる。ログ設定をわざと無効にして、勝手に元へ戻るところまで見届けるのでござるな。
この記事のメリット
- AWS Config Rulesの自動修復アーキテクチャ(SSM Automation方式とカスタムLambda方式)の違いを理解できる
- Lambda関数による自動修復を構築する際に必要なIAMロールの権限設計を習得できる
- Lambda実行ロールの信頼ポリシー(Trust Relationship)の設定方法を把握できる
- 「Lambdaが呼び出されたが修復に失敗する」というよくあるトラブルの原因と対処法を理解できる
- S3バケットのサーバーアクセスログ設定の自動修復をハンズオンで体験できる
- SCS試験の「Config Rulesによる自動修復」「Lambda実行ロールの権限」に関する問いに正確に答えられるようになる
執筆者とキャラクター紹介
執筆者:土肥(とひ)
株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。


クラウドおさる



はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。



基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。



猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。
技術解説
Config Rulesの自動修復方式
AWS Configで非準拠リソースを検出した後の修復方式は、大きく2つに分かれます。
| 方式 | 実装方法 | 特徴 | ユースケース |
|---|---|---|---|
| SSM Automation | Config Rulesの修復アクションとしてSSM Automationドキュメントを指定 | AWSが用意した修復ドキュメントを利用でき、実装が容易 | S3バケットのパブリックアクセスブロック有効化など、定型的な修復 |
| カスタムLambda | Config Rulesの変更トリガーでLambda関数を呼び出す | 複雑な修復ロジックや条件分岐が可能 | 修復前の条件判定、複数リソースにまたがる修復、通知との連携 |
SSM Automation方式は設定が簡単ですが、修復ロジックのカスタマイズには限界があります。カスタムLambda方式はコードを書く必要がありますが、修復前のチェックや例外処理など柔軟な対応が可能です。
マネージドルールとカスタムルール
Config Rulesには2種類あります。
| 種類 | 説明 | 例 |
|---|---|---|
| マネージドルール | AWSが提供する事前定義されたルール。設定パラメータを指定するだけで利用できる | s3-bucket-logging-enabled、s3-bucket-public-write-prohibited |
| カスタムルール | Lambda関数を使って独自の評価ロジックを実装するルール | 特定のタグが付与されているか、命名規則に準拠しているか等 |
本記事では、マネージドルール s3-bucket-logging-enabled を使ってS3バケットのサーバーアクセスログ設定を監視し、非準拠の場合にカスタムLambda関数で修復を行います。
カスタムLambdaによる自動修復のアーキテクチャ
カスタムLambdaによる自動修復は、以下の流れで動作します。
- S3バケットの設定が変更される
- AWS Configが設定変更を検出し、Config Ruleで評価する
- 評価結果が「非準拠(NON_COMPLIANT)」の場合、Amazon EventBridgeルールがトリガーされる
- EventBridgeルールのターゲットとして設定されたLambda関数が呼び出される
- Lambda関数がS3 APIを呼び出し、バケットのログ設定を修復する


Lambda実行ロールの権限設計
自動修復でよくある失敗パターンは、Lambda関数は正常に呼び出されるが、修復対象のAWSリソースに対する権限が不足しているケースです。
Lambda関数の実行ロールには、以下の3種類の権限が必要です。
| 権限の種類 | 内容 | 例 |
|---|---|---|
| Lambda基本実行権限 | CloudWatch Logsへのログ出力 | logs:CreateLogGroup、logs:CreateLogStream、logs:PutLogEvents |
| 修復対象リソースの操作権限 | 修復に必要なAPI呼び出し | s3:PutBucketLogging、s3:GetBucketLogging |
| Config への結果報告権限(任意) | 評価結果をConfigに報告 | config:PutEvaluations |
S3バケットのサーバーアクセスログを再有効化する場合、Lambda関数は s3:PutBucketLogging を呼び出してログ設定を書き込み、s3:GetBucketLogging で現在の設定を確認します。これらの権限がLambda実行ロールに付与されていないと、Lambda関数は実行されるもののAPI呼び出しが AccessDenied で失敗します。



Lambda が呼ばれているのに直らないときは、まず実行ロールの権限を疑うのでござる。s3:PutBucketLogging が無ければ、関数は動いても AccessDenied で止まるのでござるぞ。猿山でも、当番を起こしただけで倉庫の鍵を渡し忘れたら、バナナは一本も動かぬでござる。
Lambda実行ロールの信頼ポリシー
Lambda関数の実行ロールには、Lambdaサービスがそのロールを引き受けられるよう信頼ポリシー(Trust Relationship)を設定する必要があります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}この信頼ポリシーがないと、Lambda関数はロールを引き受けることができず、実行自体が失敗します。信頼ポリシーはロールが「誰に使わせるか」を定義するものであり、許可ポリシーが「何ができるか」を定義するのとは役割が異なります。
実践
前提条件
以下のリソースが作成済みであること。
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| S3バケット | config-remediation-target-bucket(任意の名前) | 修復対象のバケット |
| S3バケット | config-remediation-log-bucket(任意の名前) | アクセスログの保存先バケット |
| AWS Config | Configuration Recorder | リソースの設定記録(有効化済み) |
- リージョン:
ap-northeast-1(東京) - バケット名は全世界で一意である必要があるため、実際にはアカウントIDなどを付けた名前にします
- ログ保存先バケットには、S3サーバーアクセスログの配信を許可するバケットポリシー(プリンシパル
logging.s3.amazonaws.comにs3:PutObjectを許可)が設定済みであること - 修復対象バケットには、あらかじめサーバーアクセスのログ記録を有効にしておきます(準拠している状態から始めます)
- 修復対象バケットにタグ
Purpose = config-remediation-demoを付けておきます(Config Ruleの評価対象をこのバケットだけに絞るため)
重要:
s3-bucket-logging-enabledを絞り込みなしで作成すると、アカウント内のすべてのS3バケットが評価対象になります。この記事の構成では非準拠と判定されたバケットのログ設定をLambdaが自動的に書き換えるため、検証用でないバケットまで変更してしまいます。評価対象は必ずタグなどで絞り込んでください。
作成するリソース一覧
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| Config Rule | s3-bucket-logging-enabled | S3バケットのログ設定を評価するマネージドルール |
| IAMロール | ConfigRemediationLambdaRole | Lambda関数の実行ロール |
| IAMポリシー | ConfigRemediationLambdaPolicy | Lambda関数に必要な権限をまとめたポリシー |
| Lambda関数 | ConfigRemediateS3Logging | S3バケットのログ設定を修復する関数 |
| EventBridgeルール | config-s3-logging-noncompliant | Config Ruleの非準拠イベントをキャッチするルール |
ステップ1: Config Ruleの作成
S3バケットのサーバーアクセスログが有効になっているかを評価するマネージドルールを追加します。
- AWSマネジメントコンソールにログインし、リージョンが
ap-northeast-1(東京)であることを確認します - 上部の検索バーに
Configと入力し、表示された「Config」を選択します - 左側ナビゲーションの「ルール」を選択します
- 「ルールを追加」をクリックします
- 3ステップのウィザード(ルールタイプの指定 / ルールの設定 / 確認と作成)が開きます
- ステップ1で「AWS によって管理されるルールの追加」を選択します
- 検索ボックスに
loggingと入力してEnterを押し、ページを送ってs3-bucket-logging-enabledのラジオボタンを選択します
検索ボックスは1単語での絞り込みしかできません。
s3-bucket-logging-enabledのようにハイフンでつないだ名前をそのまま入力すると「一致が見つかりません」になります。loggingのような単語で絞り込み、ページ送りで目的のルールを探してください。


- 「次へ」をクリックします
- ステップ2「ルールの設定」で、「変更範囲」を「タグ」にして以下を入力します
- タグキー:
Purpose - タグの値:
config-remediation-demo - パラメータ(
targetBucket/targetPrefix)は空のままにします(空のままなら、ログ記録が有効かどうかだけを評価します) - 「次へ」をクリックし、確認画面で「保存」をクリックします





変更範囲をタグで絞ったのがここの肝でござる。絞らずに作ると、アカウント内のすべてのバケットが評価対象になり、検証用でないバケットのログ設定まで Lambda が書き換えてしまうのでござるな。
ステップ2: Lambda実行ロールの作成
Lambda関数がS3バケットのログ設定を修復するために必要なIAMロールを作成します。
- 上部の検索バーに
IAMと入力し、「IAM」を選択します - 左側ナビゲーションの「ポリシー」を選択します
- 「ポリシーの作成」をクリックします
- 「JSON」タブを選択し、以下のポリシーを入力します
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudWatchLogs",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Sid": "S3BucketLogging",
"Effect": "Allow",
"Action": [
"s3:GetBucketLogging",
"s3:PutBucketLogging"
],
"Resource": "arn:aws:s3:::config-remediation-target-bucket"
}
]
}

Resourceをワイルドカード(arn:aws:s3:::*)にすると、この関数はアカウント内のどのバケットのログ設定も書き換えられるようになります。修復対象のバケットに限定しておくのが安全です。
- 「次へ」をクリックします
- ポリシー名に
ConfigRemediationLambdaPolicyと入力します - 説明に
Permissions for the Config remediation Lambda functionと入力します
説明欄に日本語を入れると「無効な文字です。英数字と『+=,.@-』の文字を使用してください」というエラーになります。説明は英数字で書きます。
- 「ポリシーの作成」をクリックします
続いてIAMロールを作成します。
- 左側ナビゲーションの「ロール」を選択します
- 「ロールを作成」をクリックします
- 信頼されたエンティティタイプで「AWSのサービス」を選択します
- ユースケースで「Lambda」を選択します


- 「次へ」をクリックします
- 検索バーに
ConfigRemediationLambdaPolicyと入力し、表示されたポリシーにチェックを入れます - 「次へ」をクリックします
- ロール名に
ConfigRemediationLambdaRoleと入力します - 「ロールを作成」をクリックします


作成されたロールの信頼ポリシーを確認します。
- ロール一覧から
ConfigRemediationLambdaRoleをクリックします - 「信頼関係」タブを選択します
以下の信頼ポリシーが自動的に設定されていることを確認します。Lambdaをユースケースとして選択したため、lambda.amazonaws.comがプリンシパルに設定されています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}

ステップ3: Lambda関数の作成
S3バケットのサーバーアクセスログを再有効化するLambda関数を作成します。
- 上部の検索バーに
Lambdaと入力し、「Lambda」を選択します - 左側ナビゲーションの「関数」を選択します
- 「関数の作成」をクリックします
- 「一から作成」を選択します
- 以下を入力します
- 関数名:
ConfigRemediateS3Logging - ランタイム:
Python 3.13 - 「カスタム設定」の「その他の設定」を展開します
- 「全般」の「カスタム実行ロール」をオンにします
- 開いた「カスタム実行ロールを設定」で「既存のロールを選択」を選び、
ConfigRemediationLambdaRoleを選択して「保存」をクリックします


- 「関数の作成」をクリックします
関数が作成されたら、コードソースに以下のコードを入力します。
import json
import boto3
s3 = boto3.client('s3')
# ログの保存先バケット名を設定してください
LOG_BUCKET = 'config-remediation-log-bucket'
def lambda_handler(event, context):
print(json.dumps(event))
detail = event.get('detail', {})
resource_id = detail.get('resourceId', '')
compliance_type = detail.get('newEvaluationResult', {}).get('complianceType', '')
if compliance_type != 'NON_COMPLIANT':
print(f'Resource {resource_id} is {compliance_type}. No action needed.')
return
bucket_name = resource_id
print(f'Remediating S3 bucket logging for: {bucket_name}')
try:
s3.put_bucket_logging(
Bucket=bucket_name,
BucketLoggingStatus={
'LoggingEnabled': {
'TargetBucket': LOG_BUCKET,
'TargetPrefix': f'{bucket_name}/'
}
}
)
print(f'Successfully enabled logging for bucket: {bucket_name}')
except Exception as e:
print(f'Error enabling logging for bucket {bucket_name}: {str(e)}')
raise
return {
'statusCode': 200,
'body': json.dumps(f'Logging enabled for {bucket_name}')
}注意:
LOG_BUCKETの値は、ご自身のログ保存先バケット名に置き換えてください。


- 「Deploy」をクリックしてコードをデプロイします
ステップ4: EventBridgeルールの作成
Config Ruleが非準拠を検出した際にLambda関数を自動的に呼び出すEventBridgeルールを作成します。
- 上部の検索バーに
EventBridgeと入力し、「EventBridge」を選択します - 左側ナビゲーションの「ルール」を選択します
- 「ルールを作成」をクリックします
ルール作成画面には「強化ビルダー」(ドラッグアンドドロップのビジュアルビルダー)と「アドバンストビルダー」(ステップバイステップ)の2つのモードがあります。既定は強化ビルダーで、キャンバスにイベントとターゲットを置き、右側の「イベントパターン (フィルター)」のJSONエディタでパターンを直接書けます。
- 名前を
config-s3-logging-noncompliant、イベントバスをdefaultにします - イベントパターンに以下を入力します
{
"source": ["aws.config"],
"detail-type": ["Config Rules Compliance Change"],
"detail": {
"messageType": ["ComplianceChangeNotification"],
"configRuleName": ["s3-bucket-logging-enabled"],
"newEvaluationResult": {
"complianceType": ["NON_COMPLIANT"]
}
}
}

- ターゲットに「Lambda 関数」を選び、関数として
ConfigRemediateS3Loggingを指定します - 内容を確認して「作成」をクリックします
作成後、ルールの詳細画面の「ターゲット」タブで、Lambda関数がターゲットになっていることを確認します。


ステップ5: 動作確認(ログ設定の無効化と自動修復)
構成が正しく動作するかを確認します。対象バケットのサーバーアクセスログを手動で無効化し、自動的に再有効化されることを確認します。
ログ設定の無効化
- 上部の検索バーに
S3と入力し、「S3」を選択します - バケット一覧から
config-remediation-target-bucketをクリックします - 「プロパティ」タブを選択します
- 「サーバーアクセスのログ記録」セクションまでスクロールし、「編集」をクリックします
- 「サーバーアクセスのログ記録」を「無効にする」に変更します


- 「変更の保存」をクリックします
自動修復の確認
ログ設定の無効化後、AWS Configが設定変更を検出し、Config Ruleの評価が行われます。非準拠と判定されると、EventBridge経由でLambda関数が呼び出され、ログ設定が自動的に再有効化されます。
- 上部の検索バーに
Configと入力し、「Config」を選択します - 左側ナビゲーションの「ルール」を選択します
s3-bucket-logging-enabledをクリックします- 「対象範囲内のリソース」セクションで、対象バケットのコンプライアンスステータスが「非準拠」に変化することを確認します(このセクションは既定で「非準拠」だけを表示します)
注意: Config Ruleの評価には数分かかる場合があります。


Lambda関数の実行ログを確認します。
- 上部の検索バーに
CloudWatchと入力し、「CloudWatch」を選択します - 左側ナビゲーションの「ログ」→「ログ管理」を選択します
/aws/lambda/ConfigRemediateS3Loggingをクリックします- 最新のログストリームをクリックします
Successfully enabled logging for bucketというメッセージが出力されていることを確認します


最後に、S3バケットのログ設定が再有効化されていることを確認します。
- 上部の検索バーに
S3と入力し、「S3」を選択します - バケット一覧から
config-remediation-target-bucketをクリックします - 「プロパティ」タブを選択します
- 「サーバーアクセスのログ記録」セクションで、ログ記録が「有効」に戻っていることを確認します


権限不足による修復失敗のトラブルシューティング
Lambda実行ロールにs3:PutBucketLogging権限が付与されていない場合、CloudWatch Logsに以下のようなエラーが記録されます。
An error occurred (AccessDenied) when calling the PutBucketLogging operation: Access Deniedこの場合の対処手順は以下のとおりです。
- IAMコンソールで
ConfigRemediationLambdaRoleのポリシーを確認します ConfigRemediationLambdaPolicyにs3:PutBucketLoggingとs3:GetBucketLoggingが含まれていることを確認します- 権限が不足している場合はポリシーを編集して必要な権限を追加します
- Lambda関数を再度テスト実行し、修復が成功することを確認します



問われるのは、修復が失敗したときに信頼ポリシーと許可ポリシーのどちらが足りないのかを見分ける観点でござる。定型の修復なら SSM Automation、柔軟なロジックならカスタム Lambda、という使い分けも取り違えやすいところでござるな。
まとめ
本記事のポイントを整理します。
- Config Rulesの自動修復には2つの方式がある: SSM Automationは定型的な修復に適し、カスタムLambdaは柔軟な修復ロジックの実装に適しています
- カスタムLambda方式の構成: Config Rule → EventBridge → Lambda関数の流れで非準拠リソースを自動修復します
- Lambda実行ロールには修復対象の権限が必要: Lambda基本実行権限に加えて、修復に必要なAPI権限(
s3:PutBucketLogging等)を付与する必要があります - 信頼ポリシーの設定: Lambda実行ロールには
lambda.amazonaws.comをプリンシパルとする信頼ポリシーが必要です - よくある失敗パターン: Lambda関数は呼び出されるが、IAMロールの権限不足により修復APIの呼び出しが
AccessDeniedで失敗するケースに注意が必要です - マネージドルールとカスタムルール: マネージドルールはAWSが提供する定義済みルール、カスタムルールはLambda関数で独自の評価ロジックを実装するルールです
参照先
- AWS Config ルール – AWS Config
- AWS Config マネージドルール – AWS Config
- AWS Config ルールによる非準拠リソースの修復 – AWS Config
- s3-bucket-logging-enabled – AWS Config
- AWS Lambda 実行ロール – AWS Lambda
- Amazon S3 サーバーアクセスログの有効化 – Amazon S3
- Amazon EventBridge ルールの作成 – Amazon EventBridge










