如果您使用for_each而不是count,那么如何获得子网ID? 就我而言,我正在做类似的事情
resource "aws_instance" "k8s" {
for_each = var.profiles
ami = data.aws_ami.latest-ubuntu.id
instance_type = "t2.medium"
iam_instance_profile = "${each.value}"
subnet_id = ??????????????
vpc_security_group_ids = [var.security_group]
key_name = var.keyname
connection {
type = "ssh"
host = self.public_ip
user = "ubuntu"
private_key = file(var.private_key_path)
}
tags = {
Name = "${each.key}"
}
}
这是因为我正在创建相似的实例,但是需要为其分配不同的实例配置文件。
理想情况下,我会做类似的事情
subnet_id = element(var.subnets, count.index )
将实例放置在不同的子网中,但我认为 count 和 for_each 不能在同一块定义中使用。
我必须拥有子网和4个实例,并且想遍历子网,将每个实例放在一个实例中。
有什么想法吗? 谢谢。
答案 0 :(得分:1)
如果100
是列表,则可以使用var.profiles
获取每个元素的索引。
答案 1 :(得分:0)
您可以将个人资料作为对象列表提供:
例如:
variable "profiles" {
type = list(object({
name = string
key = string
}))
default =
[
{name = "exemple" , key = "exemplekey" },
{name = "exemple2" , key = "exemplekey2" }
]
}
像这样each.key
将包含列表中元素的索引,而each.value
将包含对象{name,key}
所以您的代码将是这样
resource "aws_instance" "k8s" {
for_each = var.profiles
ami = data.aws_ami.latest-ubuntu.id
instance_type = "t2.medium"
iam_instance_profile = each.value
subnet_id = element(var.subnets , each.key)
vpc_security_group_ids = [var.security_group]
key_name = var.keyname
connection {
type = "ssh"
host = self.public_ip
user = "ubuntu"
private_key = file(var.private_key_path)
}
tags = {
Name = each.value.key
}
}
答案 2 :(得分:0)
使用资源for_each
的一种好的通用策略是设计传递给它的数据结构,以使each.value
包含资源块内所需的所有按实例数据。
在这种情况下,这意味着for_each
资源的aws_instance
表达式将是一个对象映射,其中每个对象都具有实例配置文件和子网ID。
实现该目标的一种方法是编写一个for
expression并将var.profiles
(可能是一个set(string)
值)转换为一个对象映射,以获得所需的结果。例如:
resource "aws_instance" "k8s" {
for_each = {
# This assigns a subnet to each of the profiles
# by first sorting them by name to produce a list
# and then selecting subnets based on the order
# of the sort result.
for i, profile_name in sort(var.profiles) : profile_name => {
iam_instance_profile = profile_name
subnet_id = element(var.subnets, i)
}
}
ami = data.aws_ami.latest-ubuntu.id
instance_type = "t2.medium"
iam_instance_profile = each.value.iam_instance_profile
subnet_id = each.value.subnet_id
vpc_security_group_ids = [var.security_group]
key_name = var.keyname
}
将count.index
与element
元素一起使用依赖于具有自己索引的每个项目,但是对于一组字符串却并非如此,因此在上文中,我使用sort
来假设在这种情况下,只要实例最终在子网之间大致均匀分布,将哪个子网分配给每个实例就不重要了。
但是,要牢记这一点有很大的含义:如果以后在var.profiles
中添加新项目,则可能会导致subnet_id
重新分配现有实例,因此要求重新创建这些实例。如果您不希望如此,那么您需要以某种方式使每个配置文件对子网的选择更加明确,这可以通过将var.profiles
设为list(string)
而不是{{ 1}},然后记录新配置文件仅应添加到该列表的末尾,或者您也可以通过使set(string)
本身成为对象的映射,将决定向上移动到模块的调用者中然后为每个配置文件指定一个子网:
var.profiles
在这种情况下,您的资源块将变得更加简单,因为变量值已经具有合适的形状:
variable "profiles" {
type = map(object({
subnet_id = string
}))
}