Terraform - 模板插值无效
Terraform - Invalid template interpolation value
我正在尝试使用 terraform 通过 AWS Cloudformation 创建一个 AnomalySubscription。
基于: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"
}]
}
}
NotificationsEmail = [
{
Type = "EMAIL"
Address = "test@xyz.com"
},
{
Type = "EMAIL"
Address = "test2@xyz.com"
}]
heredoc 结构始终是字符串,这就是为什么 terraform 抱怨它无法插入元组的原因。
由于您在 heredoc 中实际提供的是 YAML 文档,因此您可以使用 jsonencode
.
将您的元组编码为 YAML
为什么JSON编码?正如文档中所指出的,YAML 只是 JSON:
的超集
yamlencode
always uses YAML's "block style" for mappings and sequences, unless the mapping or sequence is empty. To generate flow-style YAML, use jsonencode
instead: YAML flow-style is a superset of JSON syntax.
来源: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 文档。
我正在尝试使用 terraform 通过 AWS Cloudformation 创建一个 AnomalySubscription。 基于: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"
}]
}
}
NotificationsEmail = [
{
Type = "EMAIL"
Address = "test@xyz.com"
},
{
Type = "EMAIL"
Address = "test2@xyz.com"
}]
heredoc 结构始终是字符串,这就是为什么 terraform 抱怨它无法插入元组的原因。
由于您在 heredoc 中实际提供的是 YAML 文档,因此您可以使用 jsonencode
.
为什么JSON编码?正如文档中所指出的,YAML 只是 JSON:
的超集
yamlencode
always uses YAML's "block style" for mappings and sequences, unless the mapping or sequence is empty. To generate flow-style YAML, usejsonencode
instead: YAML flow-style is a superset of JSON syntax.
来源: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 文档。