代码之家  ›  专栏  ›  技术社区  ›  Nishant Singh

如何创建3个EBS卷并通过Terraform连接到每个实例

  •  0
  • Nishant Singh  · 技术社区  · 8 年前

    我正在尝试通过Terraform创建“N”个实例,我希望每个实例都附带3个EBS卷。我正在尝试以下Terraform片段来执行此操作:

    resource "aws_instance" "provision-data-nodes" {
      count                  = "${var.data_node_count}"
      ami                    = "${var.ami_id}"
      instance_type          = "${var.machine_type}"
      key_name               = "elasticsearch-prod"
      vpc_security_group_ids = ["${aws_security_group.es-sec-group.id}"]
    
      #availability_zone = "${element(var.azs, count.index)}"
      subnet_id = "${element(var.subnets, count.index)}"
    
      tags {
        Name = "${var.data_name}-${count.index+1}"
        Type = "es-data"
      }
    
      root_block_device {
        volume_size = 100
        volume_type = "gp2"
      }
    }
    
    resource "aws_ebs_volume" "data-ebs-volumes" {
      count             = "${var.data_node_count * 3}"
      availability_zone = "${element(var.azs, count.index)}"
      size              = "${var.volume_size_data}"
      type              = "gp2"
    
      tags {
        Name = "${var.data_name}-${count.index+1}"
        Type = "es-data-vols"
      }
    }
    
    resource "aws_volume_attachment" "data-ebs-volumes-attach" {
      count       = "${var.data_node_count * 3}"
      device_name = "${element(var.block_device_names, count.index)}"
    
      #device_name = "${var.block_device_names}"
      #volume_id   = "${element(aws_ebs_volume.data-ebs-volumes.*.id,count.index)}"
      volume_id = "${aws_ebs_volume.data-ebs-volumes.*.id[count.index]}"
    
      #instance_id = "${element(aws_instance.provision-data-nodes.*.id,count.index)}"
      instance_id = "${aws_instance.provision-data-nodes.*.id[count.index]}"
    }
    

    变量data\u node\u count=2,因此实际上应该创建2个*3=6个驱动器,因此3个驱动器应该连接到第一个实例,其他3个应该连接到下一个实例,依此类推,随着data\u node\u count的增加。

    Terraform在运行计划时输出以下错误:

    Error: Error running plan: 1 error(s) occurred:
    
    * aws_volume_attachment.data-ebs-volumes-attach: 4 error(s) occurred:
    
    * aws_volume_attachment.data-ebs-volumes-attach[2]: index 2 out of range for list aws_instance.provision-data-nodes.*.id (max 2) in:
    
    ${aws_instance.provision-data-nodes.*.id[count.index]}
    * aws_volume_attachment.data-ebs-volumes-attach[5]: index 5 out of range for list aws_instance.provision-data-nodes.*.id (max 2) in:
    
    ${aws_instance.provision-data-nodes.*.id[count.index]}
    * aws_volume_attachment.data-ebs-volumes-attach[3]: index 3 out of range for list aws_instance.provision-data-nodes.*.id (max 2) in:
    
    ${aws_instance.provision-data-nodes.*.id[count.index]}
    * aws_volume_attachment.data-ebs-volumes-attach[4]: index 4 out of range for list aws_instance.provision-data-nodes.*.id (max 2) in:
    
    ${aws_instance.provision-data-nodes.*.id[count.index]}
    

    因此,我无法将这3个卷分别连接到这2个实例中的每一个。

    1 回复  |  直到 8 年前
        1
  •  3
  •   ydaetskcoR    8 年前

    你似乎在使用 element(list, index) list[index] 在这里可以互换,但实际上它们有细微的不同。

    虽然 列表[索引] 是一种略为紧凑的语法,它不会通过列表长度模化的列表进行循环。 元素(列表、索引) 另一方面,它确实做到了这一点。

    因此,给出以下列表:

    variable "list" {
      default = [
        1,
        2,
      ]
    }
    

    这将导致索引超出范围异常错误:

    output "loop" {
      value = "${var.list[3]}"
    }
    

    而这将返回 2 :

    output "loop_element" {
      value = "${element(var.list, 3)}"
    }
    

    您还应注意,EBS卷附件的循环不会以您认为的方式运行:

    变量 data_node_count = 2. ,这样实际上应该创建2*3=6个驱动器,因此3个驱动器应该连接到第一个实例,其他3个应该连接到下一个实例,依此类推 data\u node\u计数 增加了。

    相反,附件会将第一个卷连接到第一个实例,将第二个卷连接到第二个实例,将第三个卷连接到第一个实例,将第四个卷连接到第二个实例,依此类推,在实例之间交替。