Search code examples
amazon-web-servicesterraformterraform-provider-awsaws-policiesterraform-aws-modules

MalformedPolicyDocument: Policy document should not specify a principal


I am trying to create a state function with terraform. First I create a policy and assign it to an existing role processing_lambda_role.

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


resource "aws_sfn_state_machine" "sfn_state_machine" {
  name     = local.step_function_name
  role_arn = aws_iam_role.processing_lambda_role.arn

  definition = <<EOF
{
  "Comment": "Get Incoming Files",
  "StartAt": "GetIncomingFiles",
  "States": {
    "GetIncomingFiles": {
      "Type": "Task",
      "Resource": "${aws_lambda_function.get_incoming_lambda.arn}",
      "ResultPath": "$.Output",
      "End": true
    }
  }
}
EOF
}

I get this error:

Error: Error putting IAM role policy terraform-20211117095209110000000005: MalformedPolicyDocument: Policy document should not specify a principal.
│       status code: 400, request id: 1dd8ac18-a514-4ef3-93ae-91383e5baa07
│ 
│   with module.ingest_system["ems"].aws_iam_role_policy.sfn_policy,
│   on ../../modules/ingest_system/step_function.tf line 1, in resource "aws_iam_role_policy" "sfn_policy":
│    1: resource "aws_iam_role_policy" "sfn_policy" {

and that's how the role was originally defined:

resource "aws_iam_role" "processing_lambda_role" {
  name = local.processing_lambda_role_name
  path = "/service-role/"

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

Solution

  • sts:AssumeRole should be in role's assume_role_policy. For example, if you want to create sfn_role for your sfn, then:

    
    resource "aws_iam_role" "sfn_role" {
      assume_role_policy = jsonencode({
        Version   = "2012-10-17"
        Statement = [
          {
            Effect    = "Allow"
            Principal = { Service = "states.amazonaws.com" }
            Action    = "sts:AssumeRole"
          }
        ]
      })
    }
    
    resource "aws_iam_role_policy" "sfn_policy" {
      policy = jsonencode(
    {
      "Version": "2012-10-17",
      "Statement": [    
        {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "lambda:InvokeFunction",
                    "lambda:InvokeAsync"
                ],
                "Resource": "*"
            }
      ]
    }
      )
      role = aws_iam_role.sfn_role.id
    }
    
    resource "aws_sfn_state_machine" "sfn_state_machine" {
      name     = local.step_function_name
      role_arn = aws_iam_role.sfn_role.arn
      # ....
    }