【问题标题】:Terraform: Call to function "element" failed: cannot read elements from stringTerraform:调用函数“元素”失败:无法从字符串中读取元素
【发布时间】:2021-05-27 17:22:28
【问题描述】:

我正在处理循环以动态添加 acl 规则并获取错误:

错误:函数调用错误 │ │ 在 ..\modules\acl\ressources.tf 第 8 行,资源“aws_network_acl”“pub-acl”中: │ 8: rule_no = element(ingress.value, 0) │ ├──────────────── │ │ ingress.value 是“http” │ │ 调用“元素”函数失败:无法从字符串中读取元素。

错误详情

╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 8, in resource "aws_network_acl" "pub-acl":
│    8:       rule_no    = element(ingress.value, 0)
│     ├────────────────
│     │ ingress.value is "https"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 9, in resource "aws_network_acl" "pub-acl":
│    9:       protocol   = element(ingress.value, 1)
│     ├────────────────
│     │ ingress.value is "http"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 9, in resource "aws_network_acl" "pub-acl":
│    9:       protocol   = element(ingress.value, 1)
│     ├────────────────
│     │ ingress.value is "https"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 10, in resource "aws_network_acl" "pub-acl":
│   10:       action     = element(ingress.value, 2)
│     ├────────────────
│     │ ingress.value is "http"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 10, in resource "aws_network_acl" "pub-acl":
│   10:       action     = element(ingress.value, 2)
│     ├────────────────
│     │ ingress.value is "https"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 11, in resource "aws_network_acl" "pub-acl":
│   11:       cidr_block = element(ingress.value, 3)
│     ├────────────────
│     │ ingress.value is "http"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 11, in resource "aws_network_acl" "pub-acl":
│   11:       cidr_block = element(ingress.value, 3)
│     ├────────────────
│     │ ingress.value is "https"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 12, in resource "aws_network_acl" "pub-acl":
│   12:       from_port  = element(ingress.value, 4)
│     ├────────────────
│     │ ingress.value is "http"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 12, in resource "aws_network_acl" "pub-acl":
│   12:       from_port  = element(ingress.value, 4)
│     ├────────────────
│     │ ingress.value is "https"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 13, in resource "aws_network_acl" "pub-acl":
│   13:       to_port    = element(ingress.value, 5)
│     ├────────────────
│     │ ingress.value is "http"
│
│ Call to function "element" failed: cannot read elements from string.
╵
╷
│ Error: Error in function call
│
│   on ..\modules\acl\ressources.tf line 13, in resource "aws_network_acl" "pub-acl":
│   13:       to_port    = element(ingress.value, 5)
│     ├────────────────
│     │ ingress.value is "https"
│
│ Call to function "element" failed: cannot read elements from string.

我的代码结构是:

-- Dev
  -- main.tf
  -- vars.tf
-- modules
  -- acl
    -- ressources.tf

这是我的 vars.tf

variable "acl_rules" {
  type              = map (any)
  # [rule_no, protocol, action, cidr, from_port, to_port]
  default = {
    http            = [100, "tcp", "allow",  "0.0.0.0/0", 80, 80]
    https           = [110, "tcp", "allow",  "0.0.0.0/0", 443, 443]
    ssh             = [120, "tcp", "allow",  "0.0.0.0/0", 22, 22]
  }
}

这是我的 ma​​in.tf

module "acl" {
  source            = "../modules/acl"
  vpc_id            = module.vpc.vpcId 
  acl_rules         = var.acl_rules
  rules             = ["http", "https"]
}

这是我的 ressources.tf

resource "aws_network_acl" "pub-acl" {
 
  vpc_id            = var.vpc_id

  dynamic "ingress" {
    for_each = var.rules
    content {
      rule_no       = element(ingress.value, 0)
      protocol      = element(ingress.value, 1)
      action        = element(ingress.value, 2)
      cidr_block    = element(ingress.value, 3)
      from_port     = element(ingress.value, 4)
      to_port       = element(ingress.value, 5)
    }
  }
  
}

【问题讨论】:

  • 什么是var.rules?它没有显示在您的问题中。
  • 你好,Marcin,它在 main.tf 中:rules = ["http", "https"]。我注意到没有使用变量 acl_rules,请您帮忙说一下如何结合 var.rulesvar.acl_rules
  • 在输入中,客户端可以给出创建ACL的规则,例如:rules_for_webServ = ["http", "https"]rules_for_dbServ = ["http", "https"] ...然后,它应该为每个创建ACL规则

标签: amazon-web-services terraform


【解决方案1】:

我认为应该是:

resource "aws_network_acl" "pub-acl" {
 
  vpc_id            = var.vpc_id

  dynamic "ingress" {
    for_each = var.rules
    content {
      rule_no       = element(var.acl_rules[ingress.value], 0)
      protocol      = element(var.acl_rules[ingress.value], 1)
      action        = element(var.acl_rules[ingress.value], 2)
      cidr_block    = element(var.acl_rules[ingress.value], 3)
      from_port     = element(var.acl_rules[ingress.value], 4)
      to_port       = element(var.acl_rules[ingress.value], 5)
    }
  }
  
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    相关资源
    最近更新 更多