Home > Software engineering >  How to attach iam policy to Lambda function for SNS publish access?
How to attach iam policy to Lambda function for SNS publish access?

Time:12-01

I am trying to allow my Lambda function permissions so that it can publish an SNS message.

I am creating my Lambda in Terraform:

resource "aws_lambda_function" "DynamoDB_SNS_Lambda" {
  s3_bucket     = var.bucket_id
  s3_key        = "s3key.zip"
  handler       = "index.handler"
  runtime       = "nodejs16.x"
  role          = aws_iam_role.lambda_iam_role.arn
  function_name = "lambda_name"
}

I am then creating a new IAM role:

resource "aws_iam_role" "lambda_iam_role" {
  name = "sns_lambda_iam_role"
  assume_role_policy = data.aws_iam_policy_document.sns_lambda_policy.json
}

data "aws_iam_policy_document" "sns_lambda_policy" {
  
  statement {
    sid     = ""
    effect  = "Allow"

    actions = [
      "sns:Publish",
    ]

    resources = [
      var.order_update_sns_topic_arn
    ]
    
  }
}

I am then trying to attach a policy to that IAM role to allow SNS permissions.

resource "aws_iam_role_policy_attachment" "lambda_basic_execution" {
  role       = aws_iam_role.lambda_iam_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonSNSRole"
}

When I run terraform apply, I get the following error:

module.Lambda.aws_iam_role.lambda_iam_role: Modifying... [id=sns_lambda_iam_role]
╷
│ Error: error updating IAM Role (sns_lambda_iam_role) assume role policy: MalformedPolicyDocument: Has prohibited field Resource
│   status code: 400, request id: 98a57a4c-1839-4a04-b903-e7deb409c71e
│ 
│   with module.Lambda.aws_iam_role.lambda_iam_role,
│   on modules/lambda/main.tf line 17, in resource "aws_iam_role" "lambda_iam_role":
│   17: resource "aws_iam_role" "lambda_iam_role" {

Am I creating my aws_iam_policy_document correctly?

Am I correct in thinking I need to attach the policy to the role with aws_iam_role_policy_attachment?

CodePudding user response:

This is incorrect assume policy. Assume policy tells only who/what can assume the role, not what permissions the role has. In your case, only lambda can assume the role. And the actual permissions can be set using inline_policy. For example:

resource "aws_iam_role" "lambda_iam_role" {
  name = "sns_lambda_iam_role"

  assume_role_policy =  jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      },
    ]
  })
  
  inline_policy {
    name   = "policy-8675309"
    policy = data.aws_iam_policy_document.sns_lambda_policy.json
  }
  
} 
  • Related