简体   繁体   中英

attaching multiple ebs volumes to each ec2 instance

I am trying to attach multiple ebs volumes to each instance. In this particular scenario, I am trying to attach two ebs volumes (/dev/sde, /dev/sdf) to each of the two ec2 instances I am creating. The number of ebs volumes and the number of ec2 instances are variables (meaning they can change. 3 ebs volumes to each ec2 for total of 3 ec2s etc so they are not constant).

But some reason, I am getting this error

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"

so here is the block for that attachment work

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
}

I am able to see all 4 ebs volumes being created, and 2 ec2 instances being created. But one ec2 instance has /dev/sde attached, and the other one is attached to on the other ec2 to /dev/sdf

I wanted to see both /dev/sde, and /dev/sdf attached to first ec2 instance and second ec2 instance.

  first ec2:
                /dev/sde    
                /dev/sdf     

  second ec2:
               /dev/sde
               /dev/sdf

I know there is something I am missing in "aws_volume_attachment" block code. Any suggestions would be greatly appreciated.

I am able to make it work if I change this

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

TO

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

      ]
    }

Because I am working with only 2 ec2 instances, the above solution works, but if I have to have 3 ec2 instances that becomes

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

      ]
    }

see this is not quite an elegant solution.

I would re-organize your code , and mostly use for_each , instead of count. Below is working example of what you can do:


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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM