hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.77k stars 9.12k forks source link

Issue in creating the aws_cloudwatch_log_subscription_filter for lambda function #14630

Closed jpdentone closed 2 months ago

jpdentone commented 4 years ago

Community Note

Description

I'am upgrading from v12 to v13 and having this issue when running apply

Error: Error creating Cloudwatch log subscription filter: InvalidParameterException: Could not execute the lambda function. Make sure you have given CloudWatch Logs permission to execute your function.

New or Affected Resource(s)

Potential Terraform Configuration

"data “aws_lambda_function” “logdna” {
function_name = “logdna_${var.environment}_cloudwatch”
}

resource “aws_cloudwatch_log_group” “default” {
name = “/ecs/${var.service_id}”
retention_in_days = “14”
}

resource "aws_cloudwatch_log_subscription_filter" "default" {
  count           = var.stream_logs == true ? 1 : 0
  name            = "${var.service_id}_logfilter"
  log_group_name  = aws_cloudwatch_log_group.default.name
  filter_pattern  = ""
  destination_arn = data.aws_lambda_function.logdna.arn

  depends_on = ["aws_lambda_permission.default"]
}

resource “aws_lambda_permission” “default” {
statement_id = “AllowExecutionFrom-service”
action = “lambda:InvokeFunction”
function_name = “logdna_${var.environment}_cloudwatch”
principal = “logs.ca-central-1.amazonaws.com”
source_arn = aws_cloudwatch_log_group.default.arn
}
moritzzimmer commented 4 years ago

We experience the same issue, although it seems like it's related to the aws provider version.

Creating a aws_cloudwatch_log_subscription_filter using terraform ~> 0.13 and hashicorp/aws provider ~> 2.1 is successful, but fails with the mentioned error message when upgrading to ~> 3.1.

Interestingly, it's possible to create a log_subscription_filter with version ~> 3.1 by changing the source_arn of the aws_lambda_permission to "${aws_cloudwatch_log_group.default.arn}:*". But this workaround then fails in version ~> 2.1 of the aws provider with the same error message.

moritzzimmer commented 4 years ago

We use this workaround to support 2.x and 3.x aws providers:

resource "aws_lambda_permission" "cloudwatch_logs" {
  count = var.logfilter_destination_arn != "" ? 1 : 0

  action        = "lambda:InvokeFunction"
  function_name = var.logfilter_destination_arn
  principal     = "logs.${data.aws_region.current.name}.amazonaws.com"
  // workaround for https://github.com/terraform-providers/terraform-provider-aws/issues/14630
  // in aws provider 3.x 'aws_cloudwatch_log_group.lambda.arn' interpolates to something like 'arn:aws:logs:eu-west-1:000000000000:log-group:/aws/lambda/my-group'
  // but we need 'arn:aws:logs:eu-west-1:000000000000:log-group:/aws/lambda/my-group:*'
  source_arn = length(regexall(":\\*$", aws_cloudwatch_log_group.lambda.arn)) == 1 ? aws_cloudwatch_log_group.lambda.arn : "${aws_cloudwatch_log_group.lambda.arn}:*"
}

resource "aws_cloudwatch_log_subscription_filter" "cloudwatch_logs_to_es" {
  count      = var.logfilter_destination_arn != "" ? 1 : 0
  depends_on = [aws_lambda_permission.cloudwatch_logs]

  name            = "elasticsearch-stream-filter"
  log_group_name  = aws_cloudwatch_log_group.lambda.name
  filter_pattern  = ""
  destination_arn = var.logfilter_destination_arn
  distribution    = "ByLogStream"
}
luispabon commented 2 years ago

I'm hitting the same roadblock here with the following code

resource "aws_cloudwatch_log_group" "elasticsearch-cloudwatch-log-group" {
  name              = var.log-group-name
  retention_in_days = 90
}

resource "aws_lambda_permission" "elasticsearch-cloudwatch-log-group" {
  count         = (var.elasticsearch-lambda-receiver-arn == "" ? 0 : 1)
  action        = "lambda:InvokeFunction"
  function_name = var.elasticsearch-lambda-receiver-arn
  principal     = "logs.amazonaws.com"
  source_arn    = aws_cloudwatch_log_group.elasticsearch-cloudwatch-log-group.arn
}

resource "aws_cloudwatch_log_subscription_filter" "elasticsearch-cloudwatch-log-group" {
  count      = (var.elasticsearch-lambda-receiver-arn == "" ? 0 : 1)
  depends_on = [aws_lambda_permission.elasticsearch-cloudwatch-log-group]

  destination_arn = var.elasticsearch-lambda-receiver-arn
  filter_pattern  = ""
  log_group_name  = aws_cloudwatch_log_group.elasticsearch-cloudwatch-log-group.name
  name            = "cloudwatch_logs_to_elasticsearch"
}

It fails on terraform 1.1.8 & aws provider 4.11. However, the :* workaround works:

resource "aws_lambda_permission" "elasticsearch-cloudwatch-log-group" {
  [...]
  source_arn    = "${aws_cloudwatch_log_group.elasticsearch-cloudwatch-log-group.arn}:*"
}

The relevant docs for the aws provider say the former (eg just the arn) is the correct one:

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission image

Crucially, this happened after upgrading the code above from a terraform 0.12 / aws provider 2.42 set up to terraform 1.1.8 / aws 4.11. On the old terraform & provider, the permission would be set to the value I'm using on the workaround above (arn:*).

volenpopov commented 2 years ago

Hey @luispabon, the above usage example screenshot from the terraform aws provider docs that you have attached is for events.amazonaws.com.

If you look closely at the docs you will see that there is a Usage with a CloudWatch log group section, where it states that the source_arn should have a :* at the end.

image
luispabon commented 2 years ago

I had certainly missed that, thank you @volenpopov

luispabon commented 2 years ago

The workaround by @moritzzimmer works well if you have some shared module that must work across provider 2.x to 4.x, thanks for that as well.

Looks like this is a non issue after all?

github-actions[bot] commented 3 months ago

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

github-actions[bot] commented 1 month ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.