LoginSignup
10
3

More than 3 years have passed since last update.

【AWS】SAMでStep Functionsを利用してCloudWatch Logsにログ出力する際、sam deploy時にエラーが発生するケースがある【SAM】

Last updated at Posted at 2020-12-29

はじめに

AWS SAMがStep Functionsをサポートするようになりましたが、CloudWatch Logsへのログ出力設定に不具合があり、ハマりましたので、その内容と対処方法をのこしておきます。

事象内容

SAMでStep Functionsを含むアプリケーションを作成し、 「$ sam deploy」 によるCloudFormation Stackの更新の際に以下のエラーが表示されることがあります。

The state machine IAM Role is not authorized to access the Log Destination (Service: AWSStepFunctions; Status Code: 400; Error Code: AccessDeniedException; Request ID: 4598526e-a9b6-4745-880d-1dd24f47f500; Proxy: null)

2021-01-01_14h41_24.png

具体的には、CloudWatch Logsへのログ出力を有効にしたState Machineを作成する、ログ出力を行っていないState Machineをログ出力するよう変更する、といった更新の際に発生する可能性があります。

これはIAM Role の権限不足のケースだけではなく、CloudWatchLogs自体のResource based policyの権限不足によるケースもあります。
この場合、当該のStep Functions State Machineに付与するIAM Roleの定義をいくら見直しても解決できません。

下記のフォーラムの内容と同等のものとなります。

原因/調査方法

Step FunctionsのState MachineからCloudWatch Logsへログを出力する場合、大きく、State MachineのIAM Roleと、CloudWatch LogsのResource based policyの2つのPermissionsが必要となります。

どちらか一方のPermissionsが不足していた場合、State Machine作成/更新時に前述のエラーが発生するようです。どちらのケースであっても、発生するエラーメッセージは変わらないようです。

単純いState MachineそのものにCloudWatch Logsのログ出力用のIAM Permissionsを付与すればよいだけではないようで、中で少し複雑なことを行っているようですが、詳細は未確認です。

State Machineに付与するIAM Role

まず、State Machineに付与するIAM Roleに、CloudWatch Logsに関する権限(具体的には以下のIAM Permissions)が必要なようです。
このIAM Permissionsは、AWS Management ConsoleのStep Functions Consoleにて、IAM Roleを作成し、且つログを有効にしてState Machineを作成する際に付与されるものと同等です。下記公式ドキュメントにも記載があるものです。

Logging using CloudWatch Logs - AWS Step Functions
https://docs.aws.amazon.com/step-functions/latest/dg/cw-logs.html#cloudwatch-iam-policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogDelivery",
                "logs:GetLogDelivery",
                "logs:UpdateLogDelivery",
                "logs:DeleteLogDelivery",
                "logs:ListLogDeliveries",
                "logs:PutResourcePolicy",
                "logs:DescribeResourcePolicies",
                "logs:DescribeLogGroups"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

CloudWatch LogsのResource based policy

CloudWatch Logsには、それ自体で権限制御するためのResource based policyが備わっています。(このResource based policyは、Log GroupやLog Streamごとではなく、リージョンごとに1つずつという単位で存在している模様)

このCloudWatch LogsのResource based policyにはサイズ上限があり、SAMによりこの上限を超える変更をしようとする場合に発生します。

通常、AWSサービスからCloudWatch Logsにログ出力する際には、出力する側のIAM Entity(≒主体)にIAM Permissionsを付与して権限制御します。
このCloudWatch Logs側のResource based policyの目的は大きく以下の2つあるようですが、Step Functionsは前者に該当するため、これが用いられているものと推測できます。

  • 一部のサービスで出力する側のIAM EntityにIAM Roleを付与できない場合
  • AWSアカウントをまたいでCloudWatch Logsにログを出力する場合

Step Functionsの挙動

SAMでStep Functions State Machineを作る場合、SAMとしてのCloudFormation template内の定義を元に、自動でCloudWatchLogsのResource based policyを生成し、付与しようとします。
しかしこの際、CloudWatchLogsのResource based policyサイズは5120バイトが上限値であるため、きめ細かな制御を行おうとするとサイズが足りず、必要な権限を付与できないようです。

またStep Functions側の挙動として、CloudWatchLogsへの出力を有効にする設定でState Machine定義を作成・更新する際、CloudWatch LogsのResource based policyに必要な権限があるかチェックしているようです。
Step Functionsとして必要な権限が不足していると判断すると、前述のエラーを発生させ、State Machine定義の作成・更新は失敗します。

以下のコマンドで、設定済みのCloudWatch LogsのResource based policyを参照可能です。

$ aws logs describe-resource-policies
{
    "resourcePolicies": [
        {
            "policyName": "AWSLogDeliveryWrite20150319",
            "policyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"AWSLogDeliveryWrite\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"delivery.logs.amazonaws.com\"},\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\"],\"Resource\":[\"arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/HelloWorld-Logs:log-stream:*\",\"arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/InputOutputStateMachine-GrBZXWGHTyuW-Logs:log-stream:*\",\"arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/InputOutput-Logs:log-stream:*\",\"arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/InputOutputStateMachine-Logs:log-stream:*\"]}]}",
            "lastUpdatedTime": 1609057420992
        }
    ]
}

SAMのCFn template側でログ出力設定をいろいろ変えながら試していると、下記のように「Resource」がどんどん追加されていく状況になります。

$ aws logs describe-resource-policies | jq ".resourcePolicies[0].policyDocument | fromjson"
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AWSLogDeliveryWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/HelloWorld-Logs:log-stream:*",
        "arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/InputOutputStateMachine-GrBZXWGHTyuW-Logs:log-stream:*",
        "arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/InputOutput-Logs:log-stream:*",
        "arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/InputOutputStateMachine-Logs:log-stream:*"
      ]
    }
  ]
}

対応方法

AWSフォーラムの回答に記載の通り、CloudWatchLogsのResource based policyを手動で更新し、「Resource」の範囲を緩くすることで対処可能です。

手順は以下のとおりです。

cloudwatchlogs-resourcebased-policy.json
### 更新用のPolicy documentを作る
$ vi cloudwatchlogs-resourcebased-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AWSLogDeliveryWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/*:*"
      ]
    }
  ]
}
aws logs put-resource-policy
### CloudWatchLogsのResource based policyを、上述のPolicy documentで上書きする
$ aws logs put-resource-policy --policy-name AWSLogDeliveryWrite20150319 --policy-document file://cloudwatchlogs-resourcebased-policy.json
{
    "resourcePolicy": {
        "policyName": "AWSLogDeliveryWrite20150319",
        "policyDocument": "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"AWSLogDeliveryWrite\",\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"Service\": \"delivery.logs.amazonaws.com\"\n      },\n      \"Action\": [\n        \"logs:CreateLogStream\",\n        \"logs:PutLogEvents\"\n      ],\n      \"Resource\": [\n        \"arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/*:*\"\n      ]\n    }\n  ]\n}\n",
        "lastUpdatedTime": 1609077195669
    }
}
aws logs describe-resource-policies
### 更新後のCloudWatchLogs Resource based policyを確認する
$ aws logs describe-resource-policies | jq ".resourcePolicies[0].policyDocument | fromjson"
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AWSLogDeliveryWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:us-west-2:123456789012:log-group:/aws/vendedlogs/states/*:*"
    }
  ]
}

Furthermore

Step Functions State Machineからのログ出力が誰の権限によって行われるか、当該State Machineに付与したIAM Roleの権限で行われるのか、Step Functionsサービス自体の権限で行われるのか、不明確であるため引き続き確認したいと思います。

→検証しました。CloudWatch Logsへのログ出力操作は、当該State Machineに付与したIAM Roleの権限とは無関係でした。
【AWS】Step FunctionsからCloudWatch Logsへのログ出力時の権限を確認する【Step Functions】

参照した情報/関連情報

AWS Developer Forums: Bug with LoggingConfiguration ...
https://forums.aws.amazon.com/thread.jspa?threadID=321488

Amazon CloudWatch Logs resource policy size restrictions - AWS Step Functions
https://docs.aws.amazon.com/step-functions/latest/dg/bp-cwl.html

Enabling Logging from Certain AWS Services - Amazon CloudWatch Logs
https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AWS-logs-and-resource-policy.html

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3