简体   繁体   English

Terraform aws dynamodb item - 准备数据

[英]Terraform aws dynamodb item - preparation of data

I'm trying to load data into a dynamodb table from input variables.我正在尝试将数据从输入变量加载到 dynamodb 表中。 I'm using locals to manipulate the input data into the correct shape for loading into my table.我正在使用 locals 将输入数据操作成正确的形状以加载到我的表中。 What seems like a simple thing has看似简单的事情却有

My Variable definition:我的变量定义:

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 = []
}

Initialising that variable:初始化该变量:

  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"
    }
    ]
  }]

My attempt to convert the variables into a dynamodb item entry.我尝试将变量转换为 dynamodb 项目条目。 This is where my problem is.这就是我的问题所在。

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}"}
  }
]
}

  ])
}

This produces the following error:这会产生以下错误:

Invalid value for "v" parameter: cannot convert tuple to map of any single type.

Loading into dynamodb table (obviously not getting that far):加载到 dynamodb 表中(显然没有那么远):

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
}

If I didn't have to do the substitions I could have something like this which works, but I can't figure out how to include my substitutions in this?:如果我不必做替换我可以有这样的东西可以工作,但我不知道如何在其中包含我的替换?:

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
  ])
}

You can add Substitutions to your second form using jsonencode :您可以使用jsonencodeSubstitutions添加到您的第二种形式:

    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
  ])
  

But this is unlikely to work anyway, as TF can't process such a complex data structure and you will end up with cannot unmarshal array error.但这无论如何都不太可能起作用,因为 TF 无法处理如此复杂的数据结构,您最终会遇到cannot unmarshal array错误。 The issue has been already reported in TF several times, eg here .该问题已在 TF 中多次报告,例如此处

Thus you have to simplify your templates items to be regular flat maps, not nested, or use local-exec to populate your dynamodb table.因此,您必须将templates项简化为常规平面图,而不是嵌套,或者使用local-exec来填充您的 dynamodb 表。

I've solved this.我已经解决了这个问题。 The solution is to jsonencode the whole json object and use the dynamodb L and M Attribute Type for my list of substituion objects.解决方案是对整个 json object 进行 jsonencode,并将 dynamodb L 和 M 属性类型用于我的替换对象列表。

Note the cannot unmarshall array error appeared to be related to not using the correct Attribute type for an array when inserting into DDB.请注意,无法解组数组错误似乎与插入 DDB 时未使用正确的数组属性类型有关。 I found this post useful: How can I store an array into dynamoDB table我发现这篇文章很有用: How can I store an array into dynamoDB table

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}"}
    }
   }] }

})
  
  ])
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM