Terraform aws dynamodb 项目 - 数据准备
Terraform aws dynamodb item - preparation of data
我正在尝试从输入变量将数据加载到 dynamodb table。我正在使用 locals 将输入数据处理成正确的形状,以便加载到我的 table 中。看似简单的事情却有
我的变量定义:
variable "templates" {
description = "List of templates available to be used by notifications."
type = list(object({
description = string
html_part = string
text_part = string
template_id = string
subject = string
substitutions = list(object({
name = string
default = string
required = bool
}))
}))
default = []
}
正在初始化该变量:
templates = [{
template_id = "TestNotification1"
subject = "This is a test"
description = "Test notification 1"
html_part = <<EOT
<html>
<body>
{{test}} This {{test1}} is {{test2}} the HTML Part
</body>
</html>
EOT
text_part = "This is a test"
substitutions = [{
default = "test"
required = true
name = "test1"
}
]
}]
我尝试将变量转换为 dynamodb 项目条目。这就是我的问题所在。
locals {
templates = tomap([for template in var.templates :
{
"TemplateId": { "S": "${template.template_id}"},
"Type": { "S": "STANDARD"},
"TemplateDescription": { "S": "${template.description}"},
"Subject": { "S": "${template.subject}"},
"HtmlPart": { "S": "${replace(template.html_part,"\n","")}"},
"TextPart": { "S": "${template.text_part}"},
"Substitutions":[for substitution in template.substitutions : {
"Name" : { "S": "${substitution.name}"},
"Required" : { "S": "${substitution.required}"},
"DefaultValue" : { "S": "${substitution.default}"}
}
]
}
])
}
这会产生以下错误:
Invalid value for "v" parameter: cannot convert tuple to map of any single type.
正在加载到 dynamodb table(显然没有那么远):
resource "aws_dynamodb_table_item" "templates" {
table_name = aws_dynamodb_table.default_template_table.name
hash_key = "TemplateId"
for_each = local.templates
item = each.value
}
如果我不需要做替换,我可以有类似这样的东西,但我不知道如何在其中包含我的替换?:
locals {
templates = toset([for template in var.templates :
<<ITEM
{
"TemplateId": { "S": "${template.template_id}"},
"Type": { "S": "STANDARD"},
"TemplateDescription": { "S": "${template.description}"},
"Subject": { "S": "${template.subject}"},
"HtmlPart": { "S": "${replace(template.html_part,"\n","")}"},
"TextPart": { "S": "${template.text_part}"}
}
ITEM
])
}
您可以使用 jsonencode
:
将 Substitutions
添加到您的第二个表单
templates = toset([for template in var.templates :
<<ITEM
{
"TemplateId": { "S": "${template.template_id}"},
"Type": { "S": "STANDARD"},
"TemplateDescription": { "S": "${template.description}"},
"Subject": { "S": "${template.subject}"},
"HtmlPart": { "S": "${replace(template.html_part,"\n","")}"},
"TextPart": { "S": "${template.text_part}"},
"Substitutions":${jsonencode([for substitution in template.substitutions : {
"Name" : { "S": "${substitution.name}"},
"Required" : { "S": "${substitution.required}"},
"DefaultValue" : { "S": "${substitution.default}"}
}])}
}
ITEM
])
但这不太可能奏效,因为 TF 无法处理如此复杂的数据结构,您最终会遇到 cannot unmarshal array
错误。该问题已在 TF 中多次报告,例如here.
因此您必须将 templates
项目简化为常规平面图,而不是嵌套,或者使用 local-exec
填充您的 dynamodb table。
我已经解决了这个问题。解决方案是 json 对整个 json 对象进行编码,并为我的替换对象列表使用 dynamodb L 和 M 属性类型。
注意 cannot unmarshall array 错误似乎与插入 DDB 时未使用正确的数组属性类型有关。我发现这个 post 很有用:
locals {
templates = toset([for template in var.templates :
jsonencode({
"TemplateId": { "S": "${template.template_id}"},
"Type": { "S": "STANDARD"},
"TemplateDescription": { "S": "${template.description}"},
"Subject": { "S": "${template.subject}"},
"HtmlPart": { "S": "${replace(template.html_part,"\n","")}"},
"TextPart": { "S": "${template.text_part}"},
"Substitutions":{"L": [for substitution in template.substitutions : {
"M" : {
"Name" : { "S": "${substitution.name}"},
"DefaultValue" : { "S": "${substitution.default}"}
}
}] }
})
])
我正在尝试从输入变量将数据加载到 dynamodb table。我正在使用 locals 将输入数据处理成正确的形状,以便加载到我的 table 中。看似简单的事情却有
我的变量定义:
variable "templates" {
description = "List of templates available to be used by notifications."
type = list(object({
description = string
html_part = string
text_part = string
template_id = string
subject = string
substitutions = list(object({
name = string
default = string
required = bool
}))
}))
default = []
}
正在初始化该变量:
templates = [{
template_id = "TestNotification1"
subject = "This is a test"
description = "Test notification 1"
html_part = <<EOT
<html>
<body>
{{test}} This {{test1}} is {{test2}} the HTML Part
</body>
</html>
EOT
text_part = "This is a test"
substitutions = [{
default = "test"
required = true
name = "test1"
}
]
}]
我尝试将变量转换为 dynamodb 项目条目。这就是我的问题所在。
locals {
templates = tomap([for template in var.templates :
{
"TemplateId": { "S": "${template.template_id}"},
"Type": { "S": "STANDARD"},
"TemplateDescription": { "S": "${template.description}"},
"Subject": { "S": "${template.subject}"},
"HtmlPart": { "S": "${replace(template.html_part,"\n","")}"},
"TextPart": { "S": "${template.text_part}"},
"Substitutions":[for substitution in template.substitutions : {
"Name" : { "S": "${substitution.name}"},
"Required" : { "S": "${substitution.required}"},
"DefaultValue" : { "S": "${substitution.default}"}
}
]
}
])
}
这会产生以下错误:
Invalid value for "v" parameter: cannot convert tuple to map of any single type.
正在加载到 dynamodb table(显然没有那么远):
resource "aws_dynamodb_table_item" "templates" {
table_name = aws_dynamodb_table.default_template_table.name
hash_key = "TemplateId"
for_each = local.templates
item = each.value
}
如果我不需要做替换,我可以有类似这样的东西,但我不知道如何在其中包含我的替换?:
locals {
templates = toset([for template in var.templates :
<<ITEM
{
"TemplateId": { "S": "${template.template_id}"},
"Type": { "S": "STANDARD"},
"TemplateDescription": { "S": "${template.description}"},
"Subject": { "S": "${template.subject}"},
"HtmlPart": { "S": "${replace(template.html_part,"\n","")}"},
"TextPart": { "S": "${template.text_part}"}
}
ITEM
])
}
您可以使用 jsonencode
:
Substitutions
添加到您的第二个表单
templates = toset([for template in var.templates :
<<ITEM
{
"TemplateId": { "S": "${template.template_id}"},
"Type": { "S": "STANDARD"},
"TemplateDescription": { "S": "${template.description}"},
"Subject": { "S": "${template.subject}"},
"HtmlPart": { "S": "${replace(template.html_part,"\n","")}"},
"TextPart": { "S": "${template.text_part}"},
"Substitutions":${jsonencode([for substitution in template.substitutions : {
"Name" : { "S": "${substitution.name}"},
"Required" : { "S": "${substitution.required}"},
"DefaultValue" : { "S": "${substitution.default}"}
}])}
}
ITEM
])
但这不太可能奏效,因为 TF 无法处理如此复杂的数据结构,您最终会遇到 cannot unmarshal array
错误。该问题已在 TF 中多次报告,例如here.
因此您必须将 templates
项目简化为常规平面图,而不是嵌套,或者使用 local-exec
填充您的 dynamodb table。
我已经解决了这个问题。解决方案是 json 对整个 json 对象进行编码,并为我的替换对象列表使用 dynamodb L 和 M 属性类型。
注意 cannot unmarshall array 错误似乎与插入 DDB 时未使用正确的数组属性类型有关。我发现这个 post 很有用:
locals {
templates = toset([for template in var.templates :
jsonencode({
"TemplateId": { "S": "${template.template_id}"},
"Type": { "S": "STANDARD"},
"TemplateDescription": { "S": "${template.description}"},
"Subject": { "S": "${template.subject}"},
"HtmlPart": { "S": "${replace(template.html_part,"\n","")}"},
"TextPart": { "S": "${template.text_part}"},
"Substitutions":{"L": [for substitution in template.substitutions : {
"M" : {
"Name" : { "S": "${substitution.name}"},
"DefaultValue" : { "S": "${substitution.default}"}
}
}] }
})
])