Heredoc does not work for filter pattern in aws cloudwatch log subscription filter

I am using terraform 0.14.6.

When I run terraform plan I get the following output
Terraform will perform the following actions:

aws_cloudwatch_log_subscription_filter.gopi_test_cwl_subscription_filter will be updated in-place
  ~ resource "aws_cloudwatch_log_subscription_filter" "gopi_test_cwl_subscription_filter" {
      ~ filter_pattern  = <<-EOT
          - {$.kubernetes.labels.component = "my_component"}
          + {
          +   $.kubernetes.labels.component = "my_component"
          + }
        EOT
        id              = "cwlsf-3833117854"
        name            = "gopi_test_cwl_subscription_filter"
        # (3 unchanged attributes hidden)
    }

but when I run terraform apply I get the following error

**Error:** **error updating CloudWatch Log Subscription Filter (xxxx.yyyy.zzzz.com-operational-logs): InvalidParameterException: If a filter pattern starts with '{' it must end with '}'**

This is supposed to be the same filter syntax as pattern argument reference inaws_cloudwatch_log_metric_filter as documented here Filter and Pattern Syntax - Amazon CloudWatch Logs.

In aws_cloudwatch_log_metric_filter I can use heredoc for pattern argument.

This looks to me like it might be an issue with splitting your filter string onto multiple lines, rather than using heredoc syntax.

Are you sure that’s supported by CloudWatch? I can’t find any multi-line examples in the logs.

Since this filter_pattern in aws_cloudwatch_log_subscription_filter is same as the pattern in aws_cloudwatch_log_metric_filter I was expecting it to support heredoc syntax. I am using heredoc in aws_cloudwatch_log_metric_filter and it works there.

If I use a single line it works
filter_pattern = "{$.kubernetes.labels.component = \"my_compenent\"}"

This is the heredoc syntax that does not work

  filter_pattern  = <<-EOT
  {
    $.kubernetes.labels.component = "my_component"
  }
  EOT

The error you’re seeing seems to be coming from the AWS API, not Terraform. Terraform’s heredoc syntax is just another way of representing a string type, and there is no difference between a heredoc string and the equivalent escaped string, so I don’t think that can be the issue.

Instead my best guess is that the AWS API does not accept filter patterns with newlines in this case. That would be strange, if it accepts them in other situations, but I don’t see any Terraform issue here.

If your goal is to avoid escaping " characters, you could write your filter like this:

filter_pattern = chomp(
  <<-EOT
    {$.kubernetes.labels.component = "my_component"}
  EOT
)

This is still a heredoc but will result in a single line string, which I hope will then work.

Thanks. That seems to have worked.