在我们的一个账户中,很久以前就创建了AWS私有子网。没有匹配的公有子网,这些私有子网中也没有资源。因此,下面的aws_subnet.private_subnets[0]和aws_subnet.private_subnets[1]是空子网
aws_subnet.private_subnets[0]
aws_subnet.private_subnets[1]
aws_subnet.private_subnets[2]
aws_subnet.private_subnets[3]
aws_subnet.private_subnets[4]子网是使用terrform创建的,如下所示:
resource "aws_subnet" "private_subnets" {
count = length(split(",", var.private_subnets))
cidr_block = element(split(",", var.private_subnets), count.index)其中var.private_subnets是包含5个不同CIDR块的字符串。
我想要整理它,但我尝试从字符串中删除前两个CIDR块,但它仍然试图重新创建它们,因为它想要更改:
从aws_subnet.private_subnets[2]到aws_subnet.private_subnets[0],
从aws_subnet.private_subnets[3]到aws_subnet.private_subnets[1],
aws_subnet.private_subnets[4]到aws_subnet.private_subnets[2]
我不希望这种情况发生,因为那样我就需要在新的子网中重新部署我们所有的EC2s。那么解决这个问题的最好方法是什么呢?是否要将它们从状态中删除,方法是:
terraform state rm aws_subnet.private_subnets[0]
然后使用以下命令更改它们:
terraform state mv 'aws_subnet.private_subnets[2]' 'aws_subnet.private_subnets[0]'
我没有太多的工作与国家和打破这可能会导致很多问题,所以我只是想确定。或者更好的方法是在AWS中手动删除它们,然后再次运行terraform?-我不确定这是否会导致与当前相同的问题
发布于 2021-11-03 01:10:36
如果你改变源集合的方式会影响到哪些对象属于哪些索引,那么你确实需要使用像terraform state mv这样的策略来向Terraform解释索引分配是如何改变的。
在你的例子中,看起来是这样的:
terraform state rm 'aws_subnet.private_subnets[0]'
terraform state rm 'aws_subnet.private_subnets[1]'
terraform state mv 'aws_subnet.private_subnets[2]' 'aws_subnet.private_subnets[0]'
terraform state mv 'aws_subnet.private_subnets[3]' 'aws_subnet.private_subnets[1]'
terraform state mv 'aws_subnet.private_subnets[4]' 'aws_subnet.private_subnets[2]'这些操作的顺序很重要,因为Terraform无法跟踪同一地址上的两个不同对象,因此在将另一个实例移动到目标索引之前,我们需要始终释放目标索引。
这里的var.private_subnets似乎是一个字符串,其中包含以逗号分隔的CIDR块列表。在现代Terraform中,最好将其声明为一组字符串--这样每个CIDR块就是一个单独的元素--然后使用for_each而不是count,这样Terraform将通过CIDR块字符串本身来跟踪实例,而不是通过它们在列表中的任意位置来跟踪实例。
variable "private_subnets" {
type = set(string)
}
resource "aws_subnet" "private_subnets" {
for_each = var.private_subnets
cidr_block = each.value
}此更改还需要使用terraform state mv进行一些迁移工作,因此,既然您无论如何都要做这些工作,那么在同一时间进行此更改可能是有益的,从而避免为了达到现代习惯用法而进行两次迁移。
您的问题中没有包含CIDR地址的实际值,因此我将假定顺序地址为10.x.0.0/16,其中"x“与索引相同。在该方案下,您的迁移将看起来像这样:
terraform state rm 'aws_subnet.private_subnets[0]'
terraform state rm 'aws_subnet.private_subnets[1]'
terraform state mv 'aws_subnet.private_subnets[2]' 'aws_subnet.private_subnets["10.2.0.0/16"]'
terraform state mv 'aws_subnet.private_subnets[3]' 'aws_subnet.private_subnets["10.3.0.0/16"]'
terraform state mv 'aws_subnet.private_subnets[4]' 'aws_subnet.private_subnets["10.4.0.0/16"]'请注意,在这种情况下,新地址的实例键是包含实际CIDR前缀的字符串,而不是列表中的整数位置。
这意味着它们不再有任何固有的顺序,Terraform将理解,如果您向集合中添加新的东西,这意味着创建一个新的子网,如果您从集合中删除一项,则意味着删除相应的子网。如果将来删除CIDR前缀,则在执行此一次性迁移后,您将不需要使用terraform state mv来修复位置,因为它们不再具有特定的位置。
https://stackoverflow.com/questions/69800470
复制相似问题