Step Function with EventBridge 任务`"NotAuthorizedForSourceException"`

Step Function with EventBridge task `"NotAuthorizedForSourceException"`

背景

我正在创建一个 Step Function 状态机,一旦定义的 AWS CodePipeline 的执行状态为 SUCCEED,它就会启动 AWS CodeBuild。我在 Step Function 中使用 .waitForTaskToken 功能来等待 CodePipeline 通过 CloudWatch 事件成功。管道成功后,事件将令牌发送回步骤函数并运行 CodeBuild。

阶梯函数定义如下:

{
  "StartAt": "PollCP",
  "States": {
    "PollCP": {
      "Next": "UpdateCP",
      "Parameters": {
        "Entries": [
          {
            "Detail": {
              "Pipeline": [
                "bar-pipeline"
              ],
              "State": [
                "SUCCEEDED"
              ],
              "TaskToken.$": "$$.Task.Token"
            },
            "DetailType": "CodePipeline Pipeline Execution State Change",
            "Source": "aws.codepipeline"
          }
        ]
      },
      "Resource": "arn:aws:states:::events:putEvents.waitForTaskToken",
      "Type": "Task"
    },
    "UpdateCP": {
      "End": true,
      "Parameters": {
        "ProjectName": "foo-project"
      },
      "Resource": "arn:aws:states:::codebuild:startBuild.sync",
      "Type": "Task"
    }
  }
}

step函数的权限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "codebuild:StartBuild",
            "Resource": "*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "codepipeline:*",
            "Resource": "*"
        }
    ]
}

arn:aws:iam::aws:policy/CloudWatchEventsFullAccess

问题

步函数内的cloudwatch事件returns错误:

Error

EventBridge.FailedEntry
Cause

{
  "Entries": [
    {
      "ErrorCode": "NotAuthorizedForSourceException",
      "ErrorMessage": "Not authorized for the source."
    }
  ],
  "FailedEntryCount": 1
}

尝试次数:

  1. 修改关联的 Codepipeline 和 Codebuild 角色,使其具有发送任务状态的步骤功能权限。具体权限为:
{
            "Effect": "Allow",
            "Action": [
                "states:SendTaskSuccess",
                "states:SendTaskFailure",
                "states:SendTaskHeartbeat"
            ],
            "Resource": "*"
}

得到与上述相同的原始错误。

  1. 修改关联的 Step Function 机器的权限,使其拥有对所有 Step Function 操作和资源的完全访问权限。得到了上面提到的相同的原始错误。

  2. 使用默认的 AWS EventBridge 总线测试 PollCP 步骤函数任务中指定的事件规则。事件是:

{
  "version": "0",
  "detail-type": "CodePipeline Pipeline Execution State Change",
  "source": "aws.codepipeline",
  "account": "123456789012",
  "time": "2021-06-14T00:44:41Z",
  "region": "us-west-2",
  "resources": [],
  "detail": {
    "pipeline": "<pipeline-arn>",
    "state": "SUCCEED"
  }
}

事件输出与上述相同的错误。这可能意味着错误与上面代码片段中提到的事件条目严格相关。

您的 CodeBuild 服务角色将需要使用文档中的 states:SendTask*SuccessFailureHeartbeatactions so that it can notify the state machine. This page 的权限有更多详情。

您是否尝试在 CodePipeline 管道 completes/succeeds 时使用 CloudWatch 事件触发您的状态机?

如果是这样,则无法在状态机中定义触发器。 与 EventBridge 的集成并不是为了让状态机可以被事件触发。而是将事件从您的状态机或工作流发布到事件总线。

在此处阅读更多内容:https://aws.amazon.com/blogs/compute/introducing-the-amazon-eventbridge-service-integration-for-aws-step-functions/

所以我建议您创建一个 CloudWatch 规则并改为针对您的状态机。

如果你想使用 waitForTaskToken 模式。您将必须通过 send_task_success API 调用显式 return 该令牌(下面的 python/boto3 示例)。

sfn.send_task_success(
    taskToken=task_token,
    output=json.dumps(some_optional_payload)
)

这意味着,当步骤执行时,它会将事件发布到 EventBridge 总线。您必须在状态机外部检测此事件,最有可能使用 CloudWatch 事件规则。然后从规则中触发 lambda 函数。 lambda 函数执行 send_task_success API 调用,restarts/continues 你的 workflow/state 机器。

在我看来,这是没有必要的。就像我说的,您可以使用 CW 事件规则简单地观察管道执行状态的变化,触发您的状态机,您的状态机从 CodeBuild 阶段开始。

旁注:很高兴看到人们将 Step Functions 用于 CI/CD 管道。它只是具有更大的灵活性和执行复杂分支策略的能力。可能会很快就此写一篇博客 post。