【问题标题】:Using a string in JSON format in Terraform variables在 Terraform 变量中使用 JSON 格式的字符串
【发布时间】:2021-09-23 22:03:19
【问题描述】:

我正在 Terraform 版本 0.14.15 上使用 for_each 方法创建一些资源。该资源有一个属性 input_parameters,它将 JSON 格式的字符串作为其值。我正在使用单独的对象在地图变量中定义这个值。我指定为 JSON 格式的字符串的值,执行时出现错误,我需要声明一个字符串。任何有关修复此错误的见解都会有所帮助。下面是我声明资源和变量的方式。

资源

resource "aws_config_config_rule" "managed_rules" {
  for_each         = var.managed_rules
  name             = each.value.name
  description      = each.value.description
  input_parameters = each.value.input_parameters

  source {
    owner             = each.value.owner
    source_identifier = each.value.source_identifier
  }

  depends_on = [aws_config_configuration_recorder.config_recorder]
}

变量

variable "managed_rules" {
  type = map(object({
    name              = string
    description       = string
    owner             = string
    source_identifier = string
# Is there a variable for strings in JSON format?
    input_parameters  = string
  }))
  default = {
    "1" = {
      name              = "alb-http-to-https-redirection-check"
      description       = "Checks whether HTTP to HTTPS redirection is configured on all HTTP listeners of Application Load Balancers. The rule is NON_COMPLIANT if one or more HTTP listeners of Application Load Balancer do not have HTTP to HTTPS redirection configured."
      owner             = "AWS"
      source_identifier = "ALB_HTTP_TO_HTTPS_REDIRECTION_CHECK"
      input_parameters = {
        "MaximumExecutionFrequency" : "TwentyFour_Hours",
      }
  }

错误

This default value is not compatible with the variable's type constraint:
element "2": attribute "input_parameters": string required.

使用 jsonencode 函数更新代码并将 input_parameters 更改为 any 后,这是错误:

    This default value is not compatible with the variable's type constraint:
collection elements cannot be unified.

【问题讨论】:

  • 试试jsonencodejsonencode(each.value.input_parameters)
  • 对于更新的问题:input_parameters = jsonencode(each.value.input_parameters) in aws_config_config_rule

标签: json string amazon-web-services terraform config


【解决方案1】:

这里发生了一些事情:

  1. 资源要求 input_parameters 是 JSON 编码的字符串
  2. 变量类型为字符串
  3. 您将对象类型传递给仅接受字符串类型的变量

所以 (2) 和 (3) 是冲突的。在某些时候,您必须将对象转换为 JSON 字符串。您可以在将其作为输入变量传递之前执行此操作,也可以将输入变量更改为接受对象并将对象提供给资源时将其转换为 JSON。

我会选择第二个选项,因为将对象而不是字符串传递到模块中更直观。所以,试试这个:

resource "aws_config_config_rule" "managed_rules" {
  for_each         = var.managed_rules
  name             = each.value.name
  description      = each.value.description
  input_parameters = jsonencode(each.value.input_parameters)

  source {
    owner             = each.value.owner
    source_identifier = each.value.source_identifier
  }

  depends_on = [aws_config_configuration_recorder.config_recorder]
}


variable "managed_rules" {
  type = map(object({
    name              = string
    description       = string
    owner             = string
    source_identifier = string
# Is there a variable for strings in JSON format?
    input_parameters  = any
  }))
  default = {
    "1" = {
      name              = "alb-http-to-https-redirection-check"
      description       = "Checks whether HTTP to HTTPS redirection is configured on all HTTP listeners of Application Load Balancers. The rule is NON_COMPLIANT if one or more HTTP listeners of Application Load Balancer do not have HTTP to HTTPS redirection configured."
      owner             = "AWS"
      source_identifier = "ALB_HTTP_TO_HTTPS_REDIRECTION_CHECK"
      input_parameters = {
        "MaximumExecutionFrequency" : "TwentyFour_Hours",
      }
  }

请注意,我在资源的input_parameters 中使用了jsonencode,并将该字段的变量类型更改为any(因此它将接受任何结构的对象)。

【讨论】:

  • 感谢您的洞察力。它肯定有帮助,但现在我遇到了一个不同的错误。我会编辑和更新。
  • 现在这是我不熟悉的。在这种情况下,将变量类型切换回string,从资源中删除jsonencode,将默认对象包装在jsonencode 中,并将输入变量包装在jsonencode 中。
  • 这种方法的问题是你不能在变量中调用函数。
  • 啊,好点@DaveMichaels。不过,您可以将默认值指定为原始 JSON 字符串,例如default = "{\"1\" = {\"name\" = ...}}"
【解决方案2】:

您可以按如下方式创建 json 字符串

variable "managed_rules" {

  type = map(object({
    name              = string
    description       = string
    owner             = string
    source_identifier = string
# Is there a variable for strings in JSON format?
    input_parameters  = string
  }))
  
  default = {
    "1" = {
      name              = "alb-http-to-https-redirection-check"
      description       = "Checks whether HTTP to HTTPS redirection is configured on all HTTP listeners of Application Load Balancers. The rule is NON_COMPLIANT if one or more HTTP listeners of Application Load Balancer do not have HTTP to HTTPS redirection configured."
      owner             = "AWS"
      source_identifier = "ALB_HTTP_TO_HTTPS_REDIRECTION_CHECK"
      input_parameters = <<EOL
      {
        "MaximumExecutionFrequency" : "TwentyFour_Hours",
      }
EOL
  }
 } 
}  

但是如果你想解析这个字符串,你必须使用jsondecode。你不能在变量中使用函数,所以必须稍后再做。

【讨论】:

  • 感谢您的洞察力。我可以使用 Terraform 进行编译,但现在我遇到了一个错误,指出 InvalidParameterValueException: Invalid JSON pass in the inputParameters field。
  • @DaveMichaels 对不起,但我很困惑你的 TF 脚本的当前状态是什么。还是和问题一样吗?
【解决方案3】:
input_parameters = {
    "MaximumExecutionFrequency" : "TwentyFour_Hours",
  }

这必须是字符串而不是对象,因为您将其定义为字符串

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2014-02-13
    • 1970-01-01
    • 2017-07-05
    • 2021-04-21
    • 1970-01-01
    相关资源
    最近更新 更多