避免更新 Terraform 中的资源

Posted

技术标签:

【中文标题】避免更新 Terraform 中的资源【英文标题】:Avoid Update of resources in Terraform 【发布时间】:2017-11-11 21:09:06 【问题描述】:

目前,我们正在使用 Terraform 为我们的应用程序使用蓝/绿部署模型。

我们的 TF 文件有蓝色和绿色的资源,如下所示 -

resource "aws_instance" "green_node" 
  count = "$var.node_count * var.keep_green * var.build"

  lifecycle = 
    create_before_destroy = true
  

  ami                         = "$var.green_ami_id"
  instance_type               = "$lookup(var.instance_type,lower(var.env))"
  security_groups             = "$split(",", lookup(var.security_groups, format("%s-%s", lower(var.env),var.region)))"
  subnet_id                   = "$element(split(",", lookup(var.subnets, format("%s-%s", lower(var.env),var.region))), count.index)"
  iam_instance_profile        = "$var.iam_role"
  key_name                    = "$var.key_name"
  associate_public_ip_address = "false"

  tags 
    Name            = "node-green-$var.env-$count.index + 1"
  

  user_data = "$data.template_cloudinit_config.green_node.rendered"




resource "aws_instance" "blue_node" 
  count = "$var.node_count * var.keep_blue * var.build"

  lifecycle = 
    create_before_destroy = true
  

  ami                         = "$var.blue_ami_id"
  instance_type               = "$lookup(var.instance_type,lower(var.env))"
  security_groups             = "$split(",", lookup(var.security_groups, format("%s-%s", lower(var.env),var.region)))"
  subnet_id                   = "$element(split(",", lookup(var.subnets, format("%s-%s", lower(var.env),var.region))), count.index)"
  iam_instance_profile        = "$var.iam_role"
  key_name                    = "$var.key_name"
  associate_public_ip_address = "false"

  tags 
    Name              = "node-blue-$var.env-$count.index + 1"
  
  user_data = "$data.template_cloudinit_config.blue_node.rendered"


我的问题 - 有没有办法在不更新蓝色资源的情况下更新绿色资源,反之亦然Without Using Targeted Plan。例如。如果我们更新安全组(var.security_groups) 这是一个公共变量,那么蓝色和绿色都会发生更新,我将不得不做一个有针对性的计划(seen below)以避免蓝色资源与新安全组的更新 -

terraform plan -out=green.plan -target=<green_resource_name>

【问题讨论】:

你想如何调用 terraform?我不认为你可以在每次运行时自动在绿色和蓝色之间切换,如果这就是你的要求的话。 如果我想更新绿色,我目前正在制定一个有针对性的计划来停止蓝色资源的更新。我想知道是否有更好的方法来做到这一点。 【参考方案1】:

这是个好问题。

如果您需要使蓝/绿堆栈按您的预期工作并降低代码的复杂性,您可以use terraform modules,并设置一个变量来控制您将更新哪种颜色。

因此,当您需要更新蓝色或绿色资源时,堆栈会共享模块。定义一个变量,如TF_VAR_stack_color为蓝色或绿色

在您尝试在模块中创建/更新的任何资源的名称中添加$var.stack_color

module "nodes" 
  source  = "modules/nodes"
  name    = "$var.name-$var.stack_color-$var.others"
  ...

因此,您可以使用以下命令部署蓝色资源,而不会影响正在运行的绿色资源。

TF_VAR_stack_color=blue terraform plan 

terraform plan -var stack_color=blue 

使用 terraform 模块,您无需为蓝色和绿色节点编写资源 aws_instance 两次。

我建议通过terraform init 将资源分成不同的状态文件,因此它们将是完全独立的堆栈。

【讨论】:

以上是关于避免更新 Terraform 中的资源的主要内容,如果未能解决你的问题,请参考以下文章

如何在Ansible set_fact中使用fact?

将现有 GKE 集群添加到 terraform stat 文件

如何处理 terraform 进程崩溃并避免重试时资源泄漏?

AWS on Terraform - 如何避免“强制使用新资源”

Terraform GCP:无需用户停机即可更新 Cloud Run 服务

Terraform:运行空资源后如何强制资源更新?