0
votes

I'm writing a Lambda function that should be triggered (after X amount of time) using a CloudWatch event. I have almost the configuration working, but I can't get the policy business from AWS right. This is what I have so far:

data "aws_iam_policy_document" "this" {
  statement {
    actions = ["sts:AssumeRole"]
    effect  = "Allow"
    principals {
      identifiers = ["lambda.amazonaws.com"]
      type        = "Service"
    }
  }
  statement {
    actions   = [
      "logs:CreateLogStream",
      "logs:PutLogEvents",
    ]
    effect    = "Allow"
    resources = ["arn:aws:logs:*:*:*"]
  }
}

resource "aws_iam_role_policy_attachment" "this" {
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
  role       = aws_iam_role.this.name
}

resource "aws_iam_role" "this" {
  assume_role_policy = data.aws_iam_policy_document.this.json
  name               = "AWSLambdaSpringCloudFunctionBasicExecutionRole"
}

I just want the Lambda to be able to write to CloudWatch and be triggered by the CloudWatch Event source...that's all, no more permissions. I'm creating the Log Group via Terraform, so no need for logs:CreateLogGroup.

When I do terraform apply (version 0.12.24) this error pops out:

aws_iam_role.this: Creating...

Error: Error creating IAM Role AWSLambdaSpringCloudFunctionBasicExecutionRole: MalformedPolicyDocument: Has prohibited field Resource
    status code: 400, request id: 12ad676e-b98e-4c60-bedd-bf17487bd51d

Is there a way to declare the AWS Lambda policy and assume role policy together? If not, what are the recommended Terraform resources/data sources for doing this?

2
Did you miss effect: "Allow" on second statement?Oleksii Donoha
Updated...I do have it, forgot to type it :/x80486

2 Answers

1
votes

You're trying to define multiple statements in assume_role_policy, which is not a regular policy, but a "trust relation" type of policy. It only describes who can assume role and under which conditions.

From my understanding (limited Terraform knowledge) you need to move second statement to its own policy and then attach it via aws_iam_role_policy_attachment

0
votes

I was using, as Oleksii pointed out, the wrong resource to create the IAM policy; this is the complete example:

data "aws_iam_policy_document" "assume_role" {
  statement {
    actions = ["sts:AssumeRole"]
    effect  = "Allow"
    principals {
      identifiers = ["lambda.amazonaws.com"]
      type        = "Service"
    }
  }
}

resource "aws_iam_role_policy_attachment" "assume_role" {
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
  role       = aws_iam_role.lambda.name
}

resource "aws_iam_role" "lambda" {
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
  name               = "Use Any Identifier/Name You Want Here For IAM Role"
}

data "aws_iam_policy_document" "logs" {
  statement {
    actions   = [
      "logs:CreateLogStream",
      "logs:PutLogEvents",
    ]
    effect    = "Allow"
    resources = ["arn:aws:logs:*:*:*"]
  }
}

resource "aws_iam_policy_attachment" "logs" {
  name       = "Use Any Identifier/Name You Want Here For IAM Policy Logs"
  policy_arn = aws_iam_policy.logs.arn
  roles      = [aws_iam_role.lambda.name]
}

resource "aws_iam_policy" "logs" {
  name   = "Use Any Identifier/Name You Want Here For IAM Policy Logs"
  policy = data.aws_iam_policy_document.logs.json
}