How to use Terraform to define cloundwatch event rules to trigger StepFunction statemachine
O

2

6

I have defined the creation of a StepFunction state machine in Terraform, now I want to set a timer to trigger the state machine everyday, I think probably using cloudwatch event rules is a good choice, I know how to set event rule to trigger a 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
}

but how can I setup the permission part for triggerring a state machine? I couldn't find any examples about it, am I missing anything? Is it because we don't need a permission config for state machine? Can someone help please?

Below is what I got to use cloudwatch event rules to trigger state machine so far:

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: I found someone else was asking about a similar question here, but no answers yet.

Orman answered 5/1, 2021 at 14:19 Comment(0)
G
5

I'm not well versed with terraform but it seems to follow a similar pattern to the official documentation. For targets; https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutTargets.html >> See section "Adds a Step Functions state machine as a target"

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

This tells me that you need to pass the role and arn. So taking your example, here's the thing you probably need to fill

resource "aws_cloudwatch_event_rule" "step_function_event_rule" {
  name                = <something unique>
  schedule_expression = <syntax described in https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html>
  description         = <something descriptive>
}

resource "aws_cloudwatch_event_target" "step_function_event_target" {
  target_id = <something unique>
  rule      = aws_cloudwatch_event_rule.step_function_event_rule.name
  arn       = <step function arn>
  role_arn  = <role that allows eventbridge to start execution on your behalf>
}
Gavette answered 5/1, 2021 at 15:21 Comment(5)
is this target_id = <something unique> a required field?Orman
I just checked the doc, it's optinal, I included it anyway, thanksOrman
Based on docs.aws.amazon.com/eventbridge/latest/APIReference/…, seems to be required. Perhaps terraform creates one for you if you don't set it.Gavette
when I try 'terraform plan', it shows an extra field for the event rule ` + event_bus_name = "default"`, I assume this is better be included in the script otherwise it'll be set to default.Orman
Yes. It'll be set to default.Gavette
R
4

The

    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
    }

part is not needed at all in your case, only needed as stated "In order to be able to have your AWS Lambda function or SNS topic invoked by an EventBridge rule".

As blr stated in his answer, you need to add the role_arn in the aws_cloudwatch_event_target, set up a role with assume_role_policy which grants access to states.amazonaws.com and events.amazonaws.com, and attach to this role an extra policy as follows:

    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
} 

You need to establish the trust between CloudWatch and StepFunctions with the AssumeRole, and then attach an inline or managed policy to the role that specifically allows this role to StartExecution of the state machine.

Rootstock answered 26/3, 2021 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.