【问题标题】:Terraform - creating multiple EBS volumesTerraform - 创建多个 EBS 卷
【发布时间】:2022-02-28 20:43:16
【问题描述】:

如何创建多个 EBS 卷并将其附加到一个实例?

以下代码在附加单个 EBS 卷时有效。我主要关心的是在 EBS 卷的大小和设备名称之间创建一个映射。我尝试了各种方法,创建列表等。但没有运气。

# Create EBS volume
resource "aws_ebs_volume" "ebs_volume" {
  count                 = "${var.ec2_create_volume == true ? var.ec2_instance_count : 0 }"
  availability_zone     = "${aws_instance.ec2.*.availability_zone[count.index]}"
  size                  = "${var.ec2_ebs_volume_size}"
  type                  = "${var.ec2_ebs_volume_type}"
}

# Attach EBS Volume
resource "aws_volume_attachment" "volume_attachment" {
  count                 = "${var.ec2_create_volume == true ? var.ec2_instance_count : 0 }"
  device_name           = "${var.ec2_device_name}"
  volume_id             = "${aws_ebs_volume.ebs_volume.*.id[count.index]}"
  instance_id           = "${aws_instance.ec2.*.id[count.index]}"
}

【问题讨论】:

  • 每个实例的 EBS 数量会变化还是保持不变?
  • @MattSchuchard 他们会保持不变
  • 如果出现错误,错误日志在哪里?
  • 那么您希望能够根据命令行参数创建多个不同大小的驱动器吗?
  • @kichik 没有。我只是想创建多个 EBS 卷并将其附加到单个实例,而不为每个卷创建多个资源。

标签: amazon-web-services terraform


【解决方案1】:

你快到了,尝试使用element(list, index) - 它会循环遍历列表。例如,此配置将成功创建 2 个 ec2 实例,每个实例附加 3 个额外的 ebs 卷:

variable "ec2_device_names" {
  default = [
    "/dev/sdd",
    "/dev/sde",
    "/dev/sdf",
  ]
}

variable "ec2_instance_count" {
  default = 2
}

variable "ec2_ebs_volume_count" {
  default = 3
}

resource "aws_instance" "ec2" {
  count         = "${var.ec2_instance_count}"
  ami           = "${var.aws_ami_id}"
  instance_type = "${var.ec2_instance_type}"
}

resource "aws_ebs_volume" "ebs_volume" {
  count             = "${var.ec2_instance_count * var.ec2_ebs_volume_count}"
  availability_zone = "${element(aws_instance.ec2.*.availability_zone, count.index)}"
  size              = "${var.ec2_ebs_volume_size}"
}

resource "aws_volume_attachment" "volume_attachement" {
  count       = "${var.ec2_instance_count * var.ec2_ebs_volume_count}"
  volume_id   = "${aws_ebs_volume.ebs_volume.*.id[count.index]}"
  device_name = "${element(var.ec2_device_names, count.index)}"
  instance_id = "${element(aws_instance.ec2.*.id, count.index)}"
}

【讨论】:

  • ec2_ebs_volume_size 对于所有卷都相同的问题。
  • 当您想向 ec2_ebs_volume_size 添加列表时,我修改了 size 参数以使其工作
  • 很好,但是当我尝试将其用于 5 个卷和 12 个实例时,我意识到此更改将涵盖任何实例和卷组合。 instance_id = "${element(aws_instance.node.*.id, (count.index / var.ec2_ebs_extra_volume_count))}"
  • 我这样做是为了可以用一个长列表预填充ec2_device_names,然后给出任意的var.ec2_ebs_extra_volume_count,但仍然让每个实例都有可预测的命名(即在每个节点上以/dev/sdd 开头): device_name = element(slice(var.ec2_device_names, 0, var.ec2_ebs_extra_volume_count), count.index)
  • 这在以下情况下与我一起工作,2 个实例和奇数个卷,但有 2 个实例和偶数个卷失败,并出现以下错误 Error attaching volume (vol-xxx) to instance (i-xxx), message: "Invalid value '/dev/sdz' for unixDevice. Attachment point /dev/sdz is already in use", code: "InvalidParameterValue"
【解决方案2】:

以防其他人正在寻找答案。下面的解决方案适用于跨多个 az 的多个实例。这里 device_name 是字符串列表,因此我们需要传递与附加卷数一样多的名称,volume_count 是数字列表的长度 additional_volume_size.

resource "aws_ebs_volume" "ebs_volume" {
      count             = var.instance_count * var.volume_count
      availability_zone = aws_instance.ec2[floor(count.index/var.volume_count)].availability_zone
      size              = var.additional_volume_size[count.index%var.volume_count]
    }

resource "aws_volume_attachment" "volume_attachement" {
      count       = var.instance_count * var.volume_count
      volume_id   = element(aws_ebs_volume.ebs_volume.*.id, count.index)
      device_name = element(var.device_name, count.index)
      instance_id = element(aws_instance.ec2.*.id, floor(count.index/var.volume_count))
    }

【讨论】:

    【解决方案3】:

    具有多个不同大小的 EBS 卷的多个 EC2 实例。这适用于奇数或偶数卷。

    instance_count = 3
    ebs_volume_count        = 2
    ec2_ebs_volume_size     = [10, 15]
    ec2_device_names        = ["/dev/sdd", "/dev/sde"]
    
    variable "instance_count" {
      type        = number
      default     = 1
    }
    
    variable "ebs_volume_count" {
      type        = number
      default     = 0
    }
    
    variable "ec2_ebs_volume_size" {
      type        = list(any)
      default = [
        10
      ]
    }
    
    variable "ec2_device_names" {
      type = list(any)
      default = [
        "/dev/sdd"
      ]
    }
    
    variable "availability_zones" {
      type        = list(any)
    }
    
    variable "subnet_ids" {
      type        = list(any)
    }
    
    resource "aws_instance" "ec2_instance" {
      count         = var.instance_count 
      ami           = var.aws_ami_id
      availability_zone       = var.availability_zones[count.index]
      subnet_id               = var.subnet_ids[count.index]
      instance_type = var.ec2_instance_type
    }
    
    resource "aws_ebs_volume" "ebs_volume" {
      count             = var.instance_count * var.ebs_volume_count
      availability_zone = "${element(aws_instance.ec2_instance.*.availability_zone, floor (count.index/var.ebs_volume_count))}"
      size              = var.ec2_ebs_volume_size[count.index%var.ebs_volume_count]
    }
    
    resource "aws_volume_attachment" "volume_attachement" {
      count       = var.instance_count * var.ebs_volume_count
      volume_id   = aws_ebs_volume.ebs_volume.*.id[count.index]
      device_name = var.ec2_device_names[count.index%var.ebs_volume_count]
      instance_id = "${element(aws_instance.ec2_instance.*.id, floor (count.index/var.ebs_volume_count))}"
    }
    

    【讨论】:

      猜你喜欢
      • 2019-04-06
      • 2017-07-25
      • 2023-03-25
      • 2021-11-12
      • 2021-12-08
      • 2018-07-28
      • 1970-01-01
      • 2019-08-16
      • 2020-07-27
      相关资源
      最近更新 更多