将多个 ebs 卷附加到每个 ec2 实例

Posted

技术标签:

【中文标题】将多个 ebs 卷附加到每个 ec2 实例【英文标题】:attaching multiple ebs volumes to each ec2 instance 【发布时间】:2021-11-26 22:26:55 【问题描述】:

我正在尝试将多个 ebs 卷附加到每个实例。在这个特定场景中,我尝试将两个 ebs 卷(/dev/sde、/dev/sdf)附加到我正在创建的两个 ec2 实例中的每一个。 ebs 卷的数量和 ec2 实例的数量是变量(这意味着它们可以更改。每个 ec2 3 ebs 卷,总共 3 个 ec2 等,因此它们不是恒定的)。

但由于某种原因,我收到此错误

Error: Error attaching volume (vol-0f1ace71d7af68b36) to instance
(i-029671a0d4d152761), message: "Invalid value '/dev/sde' for unixDevice. Attachment 
point/dev/sde is already in use", code: "InvalidParameterValue"

所以这是附件工作的块

resource "aws_instance" "data_node" 
  count= var.ec2_count
  instance_type = var.instance_type
  availability_zone = "us-east-1b"
  ami = "ami-0747bdcabd34c712a"
  key_name = "test-ec2"
  tags = 
    Name = "ec2-attr"
  



resource "aws_ebs_volume" "test_volume" 
  count       = var.ec2_count * var.test_ebs_volume_count
  size= 16000
  type = "gp2"
  availability_zone = "us-east-1b"
  tags = 
         Name = "1e-volume-$count.index + 1"
  




resource "aws_volume_attachment" "volume_attachement" 
  count       = var.ec2_count * var.test_ebs_volume_count
  volume_id   = aws_ebs_volume.test_volume.*.id[count.index]
  device_name = element(var.ec2_device_names, (count.index))
  instance_id = element(aws_instance.data_node.*.id, ((count.index+1)%2))



variable "ec2_device_names" 
  description = "multiple devices for each ec2 instance"
  default = [
    "/dev/sde",
    "/dev/sdf"
  ]



variable "ec2_count" 
  default = 2


variable "test_ebs_volume_count" 
  default = 2


variable "test_ebs_volume_size" 
 default = 16000

我能够看到正在创建的所有 4 个 ebs 卷,以及正在创建的 2 个 ec2 实例。但是一个 ec2 实例附加了 /dev/sde,而另一个实例附加到了另一个 ec2 上的 /dev/sdf

我想查看 /dev/sde 和 /dev/sdf 都附加到第一个 ec2 实例和第二个 ec2 实例。

  first ec2:
                /dev/sde    
                /dev/sdf     

  second ec2:
               /dev/sde
               /dev/sdf

我知道“aws_volume_attachment”块代码中缺少某些内容。任何建议将不胜感激。

如果我改变它,我可以让它工作

variable "ec2_device_names" 
      description = "multiple devices for each ec2 instance"
      default = [
        "/dev/sde",
        "/dev/sdf"
      ]
    

variable "ec2_device_names" 
      description = "multiple devices for each ec2 instance"
      default = [
        "/dev/sde",
        "/dev/sde",
         "/dev/sdf",
        "/dev/sdf"

      ]
    

因为我只使用 2 个 ec2 实例,所以上述解决方案有效,但如果我必须拥有 3 个 ec2 实例,则变为

variable "ec2_device_names" 
      description = "multiple devices for each ec2 instance"
      default = [
        "/dev/sde",
        "/dev/sde",
        "/dev/sde",
         "/dev/sdf",
         "/dev/sdf",
        "/dev/sdf"

      ]
    

看到这不是一个优雅的解决方案。

【问题讨论】:

你能分享剩下的代码吗?你如何创建卷?你如何设置实例? @Marcin 嗨,我更新了这个问题。我还提出了一个可行的解决方案(但你可以看到这不是我想要的)。问题是在aws_volume_attach 块中循环ec2_device_names 和ec2 instances_ids。 @Marcin,感谢您的解决方案。我仍在反复考虑使用您提供的解决方案,或者只是使用ec2_device_names 我能够工作的方式。我知道这不是一个优雅的解决方案,但它看起来超级简单,其他人也很容易理解。还在和队友聊天。我会及时通知你我们在这个方面的发展方向。 我的 anwser 适用于任意数量的实例和卷。为了更容易,您必须更改输入变量。 【参考方案1】:

我会重新组织您的代码,并且主要使用for_each,而不是计数。以下是您可以做什么的工作示例


variable "ec2_count" 
  default = 2


variable "test_ebs_volume_count" 
  default = 2


variable "test_ebs_volume_size" 
 default = 8



variable "ec2_device_names" 
  description = "multiple devices for each ec2 instance"
  default = [
    "/dev/sde",
    "/dev/sdf"
  ]




resource "aws_instance" "data_node" 
  count= var.ec2_count
  instance_type = "t2.micro"
  availability_zone = "us-east-1b"
  ami = "ami-0747bdcabd34c712a"
  #key_name = "test-ec2"
  tags = 
    Name = "ec2-attr"
  


locals 
    # local map to keep track of relationships between
    # ec2 instances and volume devices
    instance_device_map = merge([
        for idx1, instance in aws_instance.data_node:
          for idx2, ec2_device_name in var.ec2_device_names:
               "$instance.id-$ec2_device_name" => 
                        instance_id     = instance.id
                        ec2_device_name = ec2_device_name
                        index = idx1*length(var.ec2_device_names) + idx2
                 
           
    ]...)


resource "aws_ebs_volume" "test_volume" 
  for_each       = local.instance_device_map
  size= 8
  type = "gp2"
  availability_zone = "us-east-1b"
  tags = 
         Name = "1e-volume-$each.value.index"
  




resource "aws_volume_attachment" "volume_attachement" 
  for_each    = local.instance_device_map
  volume_id   = aws_ebs_volume.test_volume[each.key].id
  device_name = each.value.ec2_device_name
  instance_id = each.value.instance_id



output "tgest" 
    value = local.instance_device_map

【讨论】:

以上是关于将多个 ebs 卷附加到每个 ec2 实例的主要内容,如果未能解决你的问题,请参考以下文章

将 EBS 卷附加到 AutoScalingGroup

如何从备份中排除附加到 EC2 实例的某些 EBS 卷?

sh 使用AWS控制台创建EBS卷并将其附加到EC2实例

将 EBS 添加到 Ubuntu EC2 实例

如何减少 EC2 实例的根 EBS 卷大小?

在启动 Amazon EC2 Linux 实例时自动挂载 EBS 卷