AWS CloudWatchでのPutLogEventsによるAccessDeniedExceptionの修正

intermediate☁️ AWS2026-03-31| AWS SDK (Python, Node.js, Go)、AWS CLI、IAMロールを使用するEC2、Lambda、またはECS。

Error Message

An error occurred (AccessDeniedException) when calling the PutLogEvents operation: User: arn:aws:sts::123456789012:assumed-role/MyAppRole is not authorized to perform: logs:PutLogEvents on resource: arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/my-func:*
#aws#cloudwatch#iam#トラブルシューティング#devops

シナリオ

新しいマイクロサービスやLambda関数をデプロイしたばかりだとしましょう。すべて順調に見えますが、ログを確認すると状況が一変します。アプリケーションデータが表示される代わりに、大量のAccessDeniedExceptionエラーが発生しています。アプリケーションはCloudWatchにデータをプッシュしようとしていますが、AWSによって拒否されている状態です。

An error occurred (AccessDeniedException) when calling the PutLogEvents operation: User: arn:aws:sts::123456789012:assumed-role/MyRole is not authorized to perform: logs:PutLogEvents on resource

このエラーは、十分な権限を付与したつもりでも発生することが多いため、非常に厄介です。たとえCloudWatchLogsFullAccessをアタッチしていたとしても、リソースレベルでの細かな制限やKMS権限の不足により、ロギングパイプラインが停止してしまうことがあります。

なぜこのエラーが発生するのか?

PutLogEventsアクションは、他の多くのAWS操作よりも制約が厳格です。主な原因は以下の通りです。

  • ヘルパーアクションの不足: Python用のBoto3などの多くのSDKは、単にPutLogEventsを呼び出すだけではありません。通常、まずDescribeLogStreamsを使用してストリームの存在を確認します。このアクションの権限が不足していると、プロセス全体が失敗します。
  • 末尾のワイルドカード: よくある間違いは、IAMポリシーで:*を付けずにロググループのARNを指定してしまうことです。このワイルドカードがないと、ポリシーはグループに対しては権限を付与しますが、その中の「ストリーム」に対しては権限を付与しません。
  • KMS暗号化: カスタマー管理キー(CMK)を使用してログを暗号化している場合、IAMロールにはログの権限だけでなく、その特定のキーを使用するための権限も必要になります。
  • 組織のガードレール: 多くの企業のAWSアカウントでは、サービスコントロールポリシー(SCP)がマスターオーバーライドとして機能します。SCPでlogs:*が拒否されている場合、ローカルのIAMポリシーの設定に関わらず拒否されます。

ステップバイステップの修正方法

1. 正確なリソースARNを特定する

問題が発生している特定のロググループを特定します。CloudWatchコンソールを開き、ロググループに移動します。ロググループの詳細タブからARNを取得します。形式は以下のようになります。

arn:aws:logs:us-east-1:123456789012:log-group:my-app-logs

2. IAMポリシーを洗練させる

エラーメッセージに記載されているIAMロールを開きます。広範な権限を使用する代わりに、以下のターゲットを絞ったポリシーを適用してください。これには、最新のSDKがスムーズに動作するために必要なDescribeおよびCreateアクションが含まれています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:DescribeLogStreams",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:123456789012:log-group:my-app-logs:*"
            ]
        }
    ]
}

プロのヒント: リソース文字列の末尾にある:*に注目してください。PutLogEventsにおいてこれは必須です。なぜなら、このアクションは技術的にはロググループの子要素であるログ「ストリーム」に対して実行されるからです。

3. KMSキーの権限を確認する

ログはカスタムキーで暗号化されていますか?その場合、IAMロールを「キーユーザー」にする必要があります。ロールのポリシーに以下のステートメントを追加して、ログデータを即座に暗号化できるようにします。

{
    "Effect": "Allow",
    "Action": [
                "kms:Decrypt",
                "kms:GenerateDataKey*"
            ],
    "Resource": "arn:aws:kms:us-east-1:123456789012:key/your-key-id"
}

修正のテスト

IAMの変更は通常数秒で反映されますが、反映までに最大1分ほどかかる場合もあります。ローカルマシンのAWS CLIを使用して、接続をすぐにテストできます(同じ権限を持っていることが前提です)。

1. テストストリームを作成する:

aws logs create-log-stream --log-group-name my-app-logs --log-stream-name manual-test

2. ダミーイベントを送信する:

aws logs put-log-events \
    --log-group-name my-app-logs \
    --log-stream-name manual-test \
    --log-events timestamp=$(date +%s000),message="Permission test success"

If the CLI returns a nextSequenceToken, you are back in business.

ベストプラクティスのまとめ

  • 最小権限の原則: Resource: "*"を使用しないでください。これはセキュリティリスクになります。アプリケーションが実際に使用する特定のロググループにのみアクセスを制限してください。
  • Infrastructure as Code (IaC): これらの権限はTerraformやAWS CDKで定義しましょう。コンソールでの手動変更は追跡が難しく、ステージング環境から本番環境へ移行する際の再現も困難です。
  • スロットリングの監視: 権限を修正してもログが表示されない場合は、ThrottlingExceptionを確認してください。ストリームあたりのPutLogEventsの制限である、毎秒5トランザクション(TPS)に達している可能性があります。

Related Error Notes