Reputation: 2125
I am using Terraform to manage some cloudwatch alarms, and when Terraform destroys the alarms I want it to also delete the anomaly detection on the underlying metrics. As far as I can tell, I cannot manage the metrics themselves directly in Terraform (see https://github.com/hashicorp/terraform-provider-aws/issues/18344).
I am using a local-exec provisioner block and I think my problem is the command I'm trying to run involves some JSON. I was also trying to leave some newlines in the command itself for readability sake. I am really struggling with the way Terraform handles string literals. I've tried EOT, EOF, using a variable but I just can't get it to work.
Here's the command I'm trying to get Terraform to execute (this command works from my terminal)
aws cloudwatch delete-anomaly-detector \
--single-metric-anomaly-detector
'{
"Namespace": "AWS/ApplicationELB",
"AccountId": "redacted",
"MetricName": "RequestCountPerTarget",
"Dimensions": [
{
"Name": "TargetGroup",
"Value": "redacted"
}
],
"Stat": "Average"
}'
Here's my Terraform configuration (truncated for brevity)
resource "aws_cloudwatch_metric_alarm" "example" {
alarm_name = "example"
#....
#redacted for brevity
#....
provisioner "local-exec" {
when = destroy
command = format("aws cloudwatch delete-anomaly-detector --single-metric-anomoly-detector '%s'", jsonencode({
Namespace = "AWS\\ApplicationELB"
AccountId = "redacted"
MetricName = "RequestCountPerTarget"
Dimensions = [{
Name = "TargetGroup"
Value = "redacted"
}]
Stat = "Average"
}
))
}
}
When I run terraform apply
it does execute, but the command isn't executed properly by the interpreter.
module.example.aws_cloudwatch_metric_alarm.example[0] (local-exec): Executing: ["/bin/sh" "-c" "aws cloudwatch delete-anomaly-detector --single-metric-anomoly-detector '{"AccountId":"redacted","Dimensions":[{"Name":"TargetGroup","Value":"redacted"}],"MetricName":"RequestCountPerTarget","Namespace":"AWS\\ApplicationELB","Stat":"Average"}'"]
module.example.aws_cloudwatch_metric_alarm.example[0] (local-exec): usage: aws [options] [ ...] [parameters] (local-exec): usage: aws [options] [ ...] [parameters]
I also created some gists if that's easier to read.
AWS command I'm trying to get Terraform to run
Upvotes: 0
Views: 77
Reputation: 1356
<<EOT Block: The <<EOT (a Here Document) is used to manage multi-line strings without worrying about escaping newlines or quotes. This makes the JSON string more readable.
resource "aws_cloudwatch_metric_alarm" "example" {
alarm_name = "example"
#....
#redacted for brevity
#....
provisioner "local-exec" {
when = destroy
command = <<EOT
aws cloudwatch delete-anomaly-detector --single-metric-anomaly-detector '{
"Namespace": "AWS/ApplicationELB",
"AccountId": "redacted",
"MetricName": "RequestCountPerTarget",
"Dimensions": [
{
"Name": "TargetGroup",
"Value": "redacted"
}
],
"Stat": "Average"
}'
EOT
}
}
I also updated Namespace to use AWS/ApplicationELB directly without double backslashes (\), as the double backslashes were likely misinterpreted.
Upvotes: 0