0

I want to create a step function that runs a lambda function. These are the policies I have attached to my state machine and role for now:

resource "aws_iam_role_policy" "sfn_policy" {
  policy = jsonencode(
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
       "Resource": "*"
    },
    {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction",
                "lambda:InvokeAsync"
            ],
            "Resource": "*"
    },
    {
            "Effect": "Allow",
             "Action": [ "states:StartExecution" ],
            "Resource": "*"
        }
  ]
}
  )
  role = aws_iam_role.processing_lambda_role.id
}


resource "aws_sfn_state_machine" "sfn_state_machine_zip_files" {
  name     = local.zip_files_step_function_name
  role_arn = aws_iam_role.processing_lambda_role.arn

  definition = <<EOF
{
  "Comment": "Process Incoming Zip Files",
  "StartAt": "ProcessIncomingZipFiles",
  "States": {
    "ProcessIncomingZipFiles": {
      "Type": "Task",
      "Resource": "${aws_lambda_function.process_zip_files_lambda.arn}",
      "ResultPath": "$.Output",
      "End": true
    }
  }
}
EOF
}
resource "aws_iam_role" "processing_lambda_role" {
  name = local.name
  path = "/service-role/"

  assume_role_policy = jsonencode({
    Version   = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = { Service = "lambda.amazonaws.com" }
        Action    = "sts:AssumeRole"
      }
    ]
  })
}

resource "aws_iam_role_policy" "lambda" {
  name = local.processing_lambda_permission_name
  role = aws_iam_role.processing_lambda_role.id

  policy = jsonencode({
    Version   = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = [
          "s3:ListBucket",
          "s3:HeadObject",
          "s3:GetObject",
          "s3:GetObjectVersion",
          "s3:PutObject"
        ]
        Resource = [
          aws_s3_bucket.ingest.arn,
          "${aws_s3_bucket.ingest.arn}/*",
          aws_s3_bucket.dwh.arn,
          "${aws_s3_bucket.dwh.arn}/*",
        ]
      },
      {
        Effect   = "Allow"
        Action   = [
          "s3:DeleteObject"
        ]
        Resource = ["${aws_s3_bucket.ingest.arn}/*"]
      },
      {
        Effect   = "Allow"
        Action   = [
          "kms:Decrypt",
          "kms:GenerateDataKey",
        ]
        # If it breaks because of permission to the s3 buckets, look here
        Resource = "*"
        #Resource = [aws_kms_key.dwh.arn, aws_kms_key.ingest.arn]
      },
    ]
  })
}

Are there any missing policies? Currently, I get this error:

"Neither the global service principal states.amazonaws.com, nor the regional one is authorized to assume the provided role."

I know that the step function does start because I see that it enters the TaskStateEntered. However, it fails when it comes to running the lambda function.

x89
  • 2,798
  • 5
  • 46
  • 110

1 Answers1

0

The AssumeRole action is not used like that. It is used for another identity(read: resource) - not a principle - to assume that role. (ie you really should never use * for resources in AssumeRole ever). For example, if you have a role in Account A that gives access to an s3 bucket and a lambda, then you want a lambda in Account B to be able to have access to that, you would create a role in B that can assume the role in A and give AssumeRole allow to both of them (with the others arn as a resource)

It seems like you are trying to use it to give a service the ability to use this role which is not necessary - the principle field is what tells a given service that it can use a role.

Im not sure what your "Processing Lamda Role" is supposed to be attached to - if it is attached to a given lambda, then it needs to have the permissions that lambda needs to act - ie: s3, or dynamo, and the basic Execution to execute itself. You can, if you want (and it is recomended, but not required) set an allow permission for the resource of the state machine to Execute it

something like (somewhat psuedo code, please double check the action names and of course the formatting)

{
   action: function:Execute,
   effect: Allow,
   resource: aws:state:machine:arn
}

on the lambda role. If you add principle: aws:the:lambda:arn:who:uses:this:role to the above it will restrict only the mentioned lambda to being able to make use of this part of the policy. - In other words, the state machien will be given (Allow) the Execute Lambda permission (as it is the resource mentioned) but if this role is on another lambda other than the one mentioned in the principle, it cant just execute that one.

IAM can be a little confusing at first - lord knows I struggled with it for months - but it comes down to this:

  • Deny is implicit
  • Explicit allows are needed to do anything
  • Explicit denies trump everything
  • Resources is the arn of the system/service that will be getting these permissions to the system/service this role is attached too
  • Principles are who is allowed to use this role or this particular action.

(that is a really quick and really general overview - there is far more too it than just that, but its a good starting point)

It also becomes confusing that you can, for example, give the state Machine permission to execute lambda a (through Allow execute and resource of that lambda's arn) and not have to do anything on the lambdas role to allow it. Its been given by at least one of the two interacting policies and that is enough. OR you could give the state machine arn permission to allow ont he lambda's role polices and thats enough!

lynkfox
  • 2,003
  • 1
  • 8
  • 16
  • So every time a new item arrives in my dynamo table, it runs a trigger. That trigger runs the step function. The lambda function process_zip_files is only printing the event for now. Nothing else. From your answer, I am not sure what the next steps are... – x89 Nov 19 '21 at 15:30
  • I am using the same role in terraform for both, state function and lambdas. I added more code above. – x89 Nov 19 '21 at 15:31
  • I am running other lambda functions with the same role and set of policies (outside the step function), and they seem to work without any error – x89 Nov 19 '21 at 15:38