【问题标题】:Terraform count.index function used in provisioner error供应商错误中使用的 Terraform count.index 函数
【发布时间】:2018-10-19 17:23:52
【问题描述】:

我在 terraform 中使用以下代码:

#-----Workernodes-----

resource "aws_instance" "nodes-opt-us1-k8s" {
  instance_type = "${var.k8s-node_instance_type}"
  ami           = "${var.k8s-node_ami}"
  count         = "${var.NodeCount}"

  tags {
    Name = "nodes-opt-us1-k8s"
  }

  key_name               = "${aws_key_pair.k8s-node_auth.id}"
  vpc_security_group_ids = ["${aws_security_group.opt-us1-k8s_sg.id}"]
  subnet_id              = "${aws_subnet.opt-us1-k8s.id}"

#-----Link Terraform worker nodes to Ansible playbooks-----

  provisioner "local-exec" {
    command = <<EOD
cat <<EOF > aws_worker_nodes_IP
[workers]
${aws_instance.nodes-opt-us1-k8s.*.public_ip[count.index]}
EOF
EOD
  }
}

我的节点数有两个正在创建的 ec2 实例。一切都只适用于一个实例,因此错误必须与 count.index 语法有关,或者它在某处丢失,但无法通过它。

但是我得到这个错误返回:

错误:aws_instance.nodes-opt-us1-k8s:连接信息不能包含引用自身的 splat 变量

我询问了 Linux Academy 的导师,如果不深入研究,他们无法发现错误。我对 terraform 还很陌生,想在这里联系一下,看看以前是否发现过这个问题……我在谷歌上搜索了很多选项,但没有看到类似的东西。

【问题讨论】:

    标签: terraform terraform-provider-aws


    【解决方案1】:

    在为资源使用配置器并引用自身时,您需要使用self.ATTRIBUTE syntax

    因此,您的资源和配置器应如下所示:

    resource "aws_instance" "nodes-opt-us1-k8s" {
      instance_type = "${var.k8s-node_instance_type}"
      ami           = "${var.k8s-node_ami}"
      count         = "${var.NodeCount}"
    
      tags {
        Name = "nodes-opt-us1-k8s"
      }
    
      key_name               = "${aws_key_pair.k8s-node_auth.id}"
      vpc_security_group_ids = ["${aws_security_group.opt-us1-k8s_sg.id}"]
      subnet_id              = "${aws_subnet.opt-us1-k8s.id}"
    
    #-----Link Terraform worker nodes to Ansible playbooks-----
    
      provisioner "local-exec" {
        command = <<EOD
    cat <<EOF > aws_worker_nodes_IP
    [workers]
    ${self.public_ip}
    EOF
    EOD
      }
    }
    

    这也在provisioner docs 中作为示例给出。

    请注意,上面的配置程序块将在每次运行时覆盖您的 aws_worker_nodes_IP 文件,这意味着它只会向您显示要在 AWS 中创建的最后一个实例的输出(不保证订单)。

    如果您想将 IP 附加到文件中,您可以使用cat &lt;&lt;EOF &gt;&gt; aws_worker_nodes_IP 每次都附加您的heredoc 的整个正文,或者您可能需要考虑使用一个单独的配置器来收集所有的 IP 地址您正在使用null_resource pattern 创建的实例:

    resource "aws_instance" "nodes-opt-us1-k8s" {
      instance_type = "${var.k8s-node_instance_type}"
      ami           = "${var.k8s-node_ami}"
      count         = "${var.NodeCount}"
    
      tags {
        Name = "nodes-opt-us1-k8s"
      }
    
      key_name               = "${aws_key_pair.k8s-node_auth.id}"
      vpc_security_group_ids = ["${aws_security_group.opt-us1-k8s_sg.id}"]
      subnet_id              = "${aws_subnet.opt-us1-k8s.id}"
    }
    
    resource "null_resource" "cluster" {
      # If any instance IPs change we need to change the list of IPs
      triggers {
        cluster_instance_ips = "${join(",", aws_instance.nodes-opt-us1-k8s.*.public_ip)}"
      }
    
      provisioner "local-exec" {
        command = <<EOD
    cat <<EOF > aws_worker_nodes_IP
    [workers]
    ${aws_instance.nodes-opt-us1-k8s.*.public_ip}
    EOF
    EOD
      }
    }
    

    【讨论】:

    • 发生 2 个错误:此错误两次...但基础设施确实填充到 AWS 但文件“aws_worker_nodes_IP 未在 terraform 中创建。发生 2 个错误:* aws_instance.nodes- opt-us1-k8s[1]:发生 1 个错误:* 在第 17 列第 3 行:对不可索引类型的无效索引操作:TypeString in:cat aws_worker_nodes_IP [workers] ${self.public_ip [count.index]} EOF
    • ${self.public_ip} 更改没有帮助。它仍然只添加了一个工人,而不是两者。
    • 这就是我要完成的工作 * aws_instance.nodes-opt-us1-k8s[1]: 1 error(s) occurred: * 在第 17 列第 3 行:对非索引操作无效-可索引类型:TypeString in:cat aws_worker_nodes_IP [workers] ${self.public_ip[0]} ${self.public_ip[1]} EOF
    【解决方案2】:

    我自己无法对此进行测试,您是否尝试过插值 ${self.private_ip} ?而不是 ${aws_instance.nodes-opt-us1-k8s.*.public_ip[count.index]}

    问候,

    【讨论】:

      猜你喜欢
      • 2020-01-16
      • 2018-10-22
      • 2021-08-06
      • 2019-08-14
      • 2019-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-14
      相关资源
      最近更新 更多