Terraform 中定义动态块设备选择的最佳方法

huangapple go评论72阅读模式
英文:

Best way to define dynamic block device selection in Terraform

问题

I'll provide the translated code portion as requested:

locals {
  device_names = tolist([
    "xvda",
    "xvdb",
    "xvdc",
    "xvdd",
    # (and so on for however many devices you expect to need to support,
    # presumably up to "z" at the worst)
  ])
}

Please note that this is the translated code section from your provided text, and I won't answer any questions related to translation or provide additional information.

英文:

I'm trying to go off of the solution accepted in https://stackoverflow.com/questions/75257194/format-ascii-number-to-ascii-character-in-terraform but am still a bit confused how to go about the following:

Your example suggests that your goal is to map from an integer to a letter to use as a device name for an EC2 volume attachment. I think the most straightforward answer to meet that need with Terraform would be to hand-write (or, if you wish, use a one-off script to generate) a lookup table:

locals {
  device_names = tolist([
    "xvda",
    "xvdb",
    "xvdc",
    "xvdd",
    # (and so on for however many devices you expect to need to support,
    # presumably up to "z" at the worst)
  ])
}

So, my situation is that I will have to use the same TF module to spin up EC2s that require different numbers of block devices. Some larger than others. So let's say I have a lookup table that has device names from "/dev/sda, /dev/sdb, ... all the way to /dev/sdz." I'm still struggling to connect how to use an integer to say I want 6 block devices, and then get "/dev/sda, /dev/sdb, /dev/sdc, /dev/sdd, /dev/sde, /dev/sdf" as a result.

My intention would be to have a *.tf input file that would override default variables in order to get my desired result. So, for example, I might have a variable called data_file_count = 6. With that, I would hope to get my six block devices provisioned. In a subsequent run of the same module, I may have a different *.tf input file that sets data_file_count = 12 and get my 12 block devices provisioned for the EC2 instance...

Trying to find a lean and concise way to accomplish this... appreciate any help!

Thanks,
Steve

答案1

得分: 1

首先,正如原答案所说,你需要指定一个包含设备名称的列表。你必须确保列表中有足够的元素。如果你希望有12个设备,那么你必须在列表中至少指定12个名称:

locals {
  device_names = tolist([
    "/dev/sda",
    "/dev/sdb",
    "/dev/sdc",
    "/dev/sdd",
    "/dev/sde",
    "/dev/sdf",
    "/dev/sdg",
    "/dev/sdh",
    "/dev/sdi",
    "/dev/sdj",
    "/dev/sdk",
    "/dev/sdl"
    # (and so on for however many devices you expect to need to support,
    # presumably up to "z" at the worst)
  ])
}

其次,正如你所说,你需要声明一个变量来表示你想要附加到实例的设备数量。我将称此变量为number_of_devices,你可以随意命名。

variable "number_of_devices" {
  type    = number
  default = 6 # 可选的默认值
}

现在,为了获取包含名称的子列表,我们可以使用terraform中的slice函数。

例如:

output "devices" {
  value = slice(local.device_names, 0, var.number_of_devices)
}

假设number_of_devices的值是6,我们将得到以下结果:

devices = tolist([
  "/dev/sda",
  "/dev/sdb",
  "/dev/sdc",
  "/dev/sdd",
  "/dev/sde",
  "/dev/sdf",
])

现在,最复杂的部分。为了使用这个子列表来实际获得所需数量的设备,你可以使用Terraform的dynamic块。例如:

resource "aws_instance" "this" {
  ami           = ...
  instance_type = "t4g.nano"
  tags = {
    Name = "test"
  }

  dynamic "ebs_block_device" {
    for_each = slice(local.device_names, 0, var.number_of_devices) # 注意带有名称的子列表
    content {
      device_name = ebs_block_device.value
    }
  }
}

请记住,这段代码只是用来示范如何使用动态块的示例。为了创建一个EC2实例,你可能还需要配置很多其他内容,而且你可能需要避免与根设备的设备命名冲突。

英文:

First of all, as the original answer says, you have to specify a list with the device names. You have to make sure that you have enough elements in the list. If you expect 12 devices, you have to specify at least 12 names in the list:

locals {
  device_names = tolist([
    "/dev/sda",
    "/dev/sdb",
    "/dev/sdc",
    "/dev/sdd",
    "/dev/sde",
    "/dev/sdf",
    "/dev/sdg",
    "/dev/sdh",
    "/dev/sdi",
    "/dev/sdj",
    "/dev/sdk",
    "/dev/sdl"
    # (and so on for however many devices you expect to need to support,
    # presumably up to "z" at the worst)
  ])
}

Second, as you said, you have to declare a variable for the number of devices you want to attach to an instance. I will call this variable number_of_devices, you may call it however you want.

variable "number_of_devices" {
  type    = number
  default = 6 # optional default value
}

Now, in order to get a sublist with the names, we can use the slice function from terraform.

For example:

output "devices" {
  value = slice(local.device_names, 0, var.number_of_devices)
}

Assuming the value for number_of_devices is 6, we will get the following result:

devices = tolist([
  "/dev/sda",
  "/dev/sdb",
  "/dev/sdc",
  "/dev/sdd",
  "/dev/sde",
  "/dev/sdf",
])

Now, the trickiest part. In order to use this sublist to actually have as many devices as you need, you can use a dynamic block from Terraform. For example:

resource "aws_instance" "this" {
  ami           = ...
  instance_type = "t4g.nano"
  tags = {
    Name = "test"
  }

  dynamic "ebs_block_device" {
    for_each = slice(local.device_names, 0, var.number_of_devices) # notice the sublist with the names
    content {
      device_name = ebs_block_device.value
    }
  }
}

Keep in mind, this code was meant to be just an example of how to use the a dynamic block. In order to provision an EC2 instance, you may want to configure a bunch of other stuff and also you may want to avoid device naming collision with the root device.

huangapple
  • 本文由 发表于 2023年8月5日 04:58:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76839075.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定