如何使用 Terraform 定义 cloundwatch 事件规则来触发 StepFunction 状态机

问题描述

我已经在terraform中定义了一个StepFunction状态机的创建,现在我想设置一个定时器来每天触发状态机,我想可能使用cloudwatch事件规则是一个不错的选择,我知道如何设置事件规则触发 Lambda:

resource "aws_cloudwatch_event_rule" "lambda_event_rule" {
  name                = xxx
  schedule_expression = xxx
  description         = xxx
}

resource "aws_cloudwatch_event_target" "lambda_event_target" {
  target_id = xxx
  rule      = aws_cloudwatch_event_rule.lambda_event_rule.name
  arn       = xxx
}

#I must setup the right permissions using 'aws_lambda_permission' 
#see: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target

resource "aws_lambda_permission" "lambda_event_permission" {
  statement_id  = xxx
  action        = "lambda:InvokeFunction"
  function_name = xxx
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.lambda_event_rule.name
}

但是如何设置触发状态机的权限部分?我找不到任何关于它的例子,我错过了什么吗?是因为我们不需要状态机的权限配置吗?有人可以帮忙吗?

以下是我到目前为止使用 cloudwatch 事件规则触发状态机的内容

resource "aws_cloudwatch_event_rule" "step_function_event_rule" {
  name                = xxx
  schedule_expression = xxx
  description         = xxx
}

resource "aws_cloudwatch_event_target" "step_function_event_target" {
  target_id = xxx
  rule      = aws_cloudwatch_event_rule.step_function_event_rule.name
  arn       = xxx
}


?????What else should I add here?

PS:我发现有人在问类似的问题 here,但还没有答案。

解决方法

我不太熟悉 terraform,但它似乎遵循与官方文档类似的模式。对于目标; https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutTargets.html >> 请参阅“添加 Step Functions 状态机作为目标”部分

for n in range(1,100):
   inputdata=h5py.File("Data/IN"+str(n),"r").get("Tree")[()].astype(np.float16)
   outputdata=h5py.File("Data/OUT"+str(n),"r").get("Tree")[()].astype(np.float16)

   phi.fit(inputdata,outputdata,epochs=2,batch_size=32)

   phi.save("trainedmodel_weights")
   del inputdata
   del outputdata

这告诉我你需要传递角色和 arn。以您为例,这是您可能需要填写的内容

{
    "Rule": "testrule","Targets": [
           {
        "RoleArn": "arn:aws:iam::123456789012:role/MyRoleToAccessStepFunctions"
        "Arn":"arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorld"
      }
    ]
}
,

    resource "aws_lambda_permission" "lambda_event_permission" {
     statement_id  = xxx
     action        = "lambda:InvokeFunction"
     function_name = xxx
     principal     = "events.amazonaws.com"
     source_arn    = aws_cloudwatch_event_rule.lambda_event_rule.name
    }

在您的情况下根本不需要部分,只需要“为了能够让 EventBridge 规则调用您的 AWS Lambda 函数或 SNS 主题”。

正如 blr 在他的回答中所述,您需要在 aws_cloudwatch_event_target 中添加 role_arn,使用授予访问权限的 assume_role_policy 设置角色到 states.amazonaws.com 和 events.amazonaws.com,并为该角色附加如下额外政策:

    data "aws_iam_policy_document" "CW2SF_allowexec" {
      statement {
        actions = [
          "sts:AssumeRole"
        ]

        principals {
          type = "Service"
          identifiers = [
            "states.amazonaws.com","events.amazonaws.com"
          ]
        }
      }
    }

    resource "aws_iam_role" "CW2SF_allowexec" {
      name               = "AWS_Events_Invoke-StepFunc"
      assume_role_policy = data.aws_iam_policy_document.CW2SF_allowexec.json
    }

    resource "aws_iam_role_policy" "state-execution" {
      name        = "CW2SF_allowexec"
      role   = aws_iam_role.CW2SF_allowexec.id

      policy = <<EOF
    {
      "Version": "2012-10-17","Statement": [
          {
              "Effect": "Allow","Action": [
                  "states:StartExecution"
              ],"Resource": [          
"arn:aws:states:${var.region}:${data.aws_caller_identity.current.account_id}:stateMachine:data-pipeline-incremental"
          ]
      }
  ]
}
EOF
} 

您需要使用 AssumeRole 建立 CloudWatch 和 StepFunctions 之间的信任,然后将内联或托管策略附加到该角色,专门允许该角色开始执行状态机。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...