Terraform — недопустимое значение интерполяции шаблона

#amazon-web-services #terraform #amazon-cloudformation

#amazon-веб-сервисы #terraform #amazon-облачная информация

Вопрос:

Я пытаюсь использовать terraform для создания подписки на аномалии с помощью AWS Cloudformation. На основе: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ce-anomalysubscription.html

Когда я тестировал план Terraform, я получаю:

 │ Error: Invalid template interpolation value


│     │ each.value.NotificationsEmail is tuple with 1 element
│
│ Cannot include the given value in a string template: string required.
 

resource.tf

 resource "aws_cloudformation_stack" "anomaly_detection" {
  name = "${var.StackName}${each.value.Key}"

  for_each = { for i in local.anomalies : "${i.Key}" => i }

  template_body = <<EOF
  AWSTemplateFormatVersion: "2010-09-09"
  Description: Cost Anomaly Detection
  Resources:
    CostExplorer:
      Type: AWS::CE::AnomalySubscription
      Properties:
        Frequency: DAILY
        MonitorArnList: [!Ref CostExplorerServiceAnomalyMonitor]
        Subscribers: ${each.value.NotificationsEmail}
        SubscriptionName: DailyAnomalySubscription
        Threshold: ${each.value.Threshold}

EOF
}
 
 locals {
  anomalies = flatten([
    for k, v in var.Anomalies : [
        {
          Key                    = k
          Type                   = v.Type
          NotificationsEmail     = v.NotificationsEmail
          Threshold              = v.Threshold
        }
    ]
  ])
}
 
 Anomalies = {
  Subscription = {
    Type  = "Daily"
    Threshold = 500
    NotificationsEmail = [
      {
        Type = "EMAIL"
        Address = "test@xyz.com"
      },
      {
        Type = "EMAIL"
        Address = "test2@xyz.com"
      }]
  }
}
 

На основе:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ce-anomalysubscription-subscriber.html

     NotificationsEmail = [
      {
        Type = "EMAIL"
        Address = "test@xyz.com"
      },
      {
        Type = "EMAIL"
        Address = "test2@xyz.com"
      }]
 

Ответ №1:

Структура heredoc всегда является строкой, поэтому terraform жалуется, что не может интерполировать ваш кортеж.

Поскольку то, что вы фактически передаете в heredoc, — это документ YAML, вы можете закодировать свой кортеж в YAML с помощью jsonencode .

Зачем кодировать JSON? Как указано в документации, YAML — это просто надмножество JSON:

yamlencode всегда использует «блочный стиль» YAML для сопоставлений и последовательностей, если только сопоставление или последовательность не являются пустыми. Чтобы сгенерировать YAML в стиле потока, используйте jsonencode вместо этого: стиль потока YAML является надмножеством синтаксиса JSON.

Источник: https://www.terraform.io/docs/language/functions/yamlencode.html


Учитывая упрощенный:

 variable "NotificationsEmail" {
  default = {
    Type = "EMAIL"
    Address = "test2@xyz.com"
  }
}

output "test" {
  value = <<EOF
  AWSTemplateFormatVersion: "2010-09-09"
  Description: Cost Anomaly Detection
  Resources:
    CostExplorer:
      Type: AWS::CE::AnomalySubscription
      Properties:
        Frequency: DAILY
        MonitorArnList: [!Ref CostExplorerServiceAnomalyMonitor]
        Subscribers: ${jsonencode(var.NotificationsEmail)}
        SubscriptionName: DailyAnomalySubscription
  EOF
}
 

Это приводит к ожидаемому:

 AWSTemplateFormatVersion: "2010-09-09"
Description: Cost Anomaly Detection
Resources:
  CostExplorer:
    Type: AWS::CE::AnomalySubscription
    Properties:
      Frequency: DAILY
      MonitorArnList: [!Ref CostExplorerServiceAnomalyMonitor]
      Subscribers: {"Address":"test2@xyz.com","Type":"EMAIL"}
      SubscriptionName: DailyAnomalySubscription
 

Это совершенно правильный документ YAML.

Комментарии:

1. Спасибо! Он отлично работает с шаблоном.

2. Как передать значение по параметрам? параметры = { NotificationsEmail = «${jsonencode(each.value. NotificationsEmail)}» Пороговое значение = каждое значение. Threshold } получает jsonencode в виде строки

3. @headincl0ud Если это сработало, то ответ должен быть принят.

4. Ясне @Марчин, я был уверен, что ты будешь первым в этой теме, наилучшие пожелания тебе из Вроцлава 🙂

5. @headincl0ud опоздал на 10 часов:-) Поздравляю.