【问题标题】:Terraform stucks when instance_count is more than 2 while using remote-exec provisioner当 instance_count 大于 2 时使用 remote-exec 配置程序时 Terraform 卡住
【发布时间】:2020-06-25 16:45:06
【问题描述】:
  • 我正在尝试使用 null_resource 使用 Terraform 的 remote-exec 供应器供应多个 Windows EC2 实例。

$ terraform -v Terraform v0.12.6 provider.aws v2.23.0 provider.null v2.1.2

  • 最初,我使用三个远程执行配置程序(其中两个涉及重新启动实例)没有 null_resource 并且对于单个实例,一切正常。
  • 然后我需要增加计数并基于多个链接,最终使用了 null_resource。 因此,我已将问题减少到我什至无法使用 null_resource 为超过 2 个 Windows EC2 实例运行一个远程执行配置程序的程度。

重现错误信息的 Terraform 模板:

//VARIABLES

variable "aws_access_key" {
  default = "AK"
}
variable "aws_secret_key" {
  default = "SAK"
}
variable "instance_count" {
  default = "3"
}
variable "username" {
  default = "Administrator"
}
variable "admin_password" {
  default = "Password"
}
variable "instance_name" {
  default = "Testing"
}
variable "vpc_id" {
  default = "vpc-id"
}

//PROVIDERS
provider "aws" {
  access_key = "${var.aws_access_key}"
  secret_key = "${var.aws_secret_key}"
  region     = "ap-southeast-2"
}

//RESOURCES
resource "aws_instance" "ec2instance" {
  count         = "${var.instance_count}"
  ami           = "Windows AMI"
  instance_type = "t2.xlarge"
  key_name      = "ec2_key"
  subnet_id     = "subnet-id"
  vpc_security_group_ids = ["${aws_security_group.ec2instance-sg.id}"]
  tags = {
    Name = "${var.instance_name}-${count.index}"
  }
}

resource "null_resource" "nullresource" {
  count = "${var.instance_count}"
  connection {
    type     = "winrm"
    host     = "${element(aws_instance.ec2instance.*.private_ip, count.index)}"
    user     = "${var.username}"
    password = "${var.admin_password}"
    timeout  = "10m"
  }
   provisioner "remote-exec" {
     inline = [
       "powershell.exe Write-Host Instance_No=${count.index}"
     ]
   }
//   provisioner "local-exec" {
//     command = "powershell.exe Write-Host Instance_No=${count.index}"
//   }
//   provisioner "file" {
//       source      = "testscript"
//       destination = "D:/testscript"
//   }
}
resource "aws_security_group" "ec2instance-sg" {
  name        = "${var.instance_name}-sg"
  vpc_id      = "${var.vpc_id}"


//   RDP
  ingress {
    from_port   = 3389
    to_port     = 3389
    protocol    = "tcp"
    cidr_blocks = ["CIDR"]
    }

//   WinRM access from the machine running TF to the instance
  ingress {
    from_port   = 5985
    to_port     = 5985
    protocol    = "tcp"
    cidr_blocks = ["CIDR"]
    }

  tags = {
    Name        = "${var.instance_name}-sg"
  }

}
//OUTPUTS
output "private_ip" {
  value = "${aws_instance.ec2instance.*.private_ip}"
}

观察:

【问题讨论】:

  • 请不要过于简单化,找出错误的地方是没有帮助的。将您的示例简化为 minimal reproducible example,其他人可以运行但仍会看到与您相同的错误。
  • 感谢您的反馈。我已经修改了代码,现在可以复制了。
  • @ydaetskcoR 添加了模板,这样比之前的 sn-p 更容易复制。

标签: terraform terraform-provider-aws winrm remote-execution


【解决方案1】:

更新:最终的诀窍是按照 issue comment 将 Terraform 降级为 v11.14

您可以尝试一些事情:

  1. 内联remote-exec:
resource "aws_instance" "ec2instance" {
  count         = "${var.instance_count}"
  # ...
  provisioner "remote-exec" {
    connection {
      # ...
    }
    inline = [
      # ...
    ]
  }
}

现在您可以参考connection 块内的self 来获取实例的私有IP。

  1. triggers添加到null_resource
resource "null_resource" "nullresource" {
  triggers {
    host    = "${element(aws_instance.ec2instance.*.private_ip, count.index)}" # Rerun when IP changes
    version = "${timestamp()}" # ...or rerun every time
  }
  # ...
}

您可以使用triggers attribute 重新创建null_resource,从而重新执行remote-exec

【讨论】:

  • 感谢 Aleksi 的建议。当我在 aws_instance 块中遇到与 remote-exec 相同的问题时,我已经尝试过 #1 并最终使用了 null_resource。尝试了#2,但仍然是同样的问题。 Terraform 跳过在其中一个实例上运行配置程序并卡在“仍在创建...”。
  • inline 命令的开头和结尾添加sleep 怎么样?根据this answer。有些人还通过降级到 terraform v11.14 来修复 report a similar issue,但在您的情况下这可能不是一个选择?
  • 再次尝试(在命令之前和之后设置睡眠)。不工作。发生的事情是,正如原始帖子中提到的,Terraform 在所有三个实例上运行配置程序,显示一个资源的创建已完成,然后卡在其他两个实例的“仍在创建...”消息中并且从未显示“申请完成!”绿色消息。虽然this issue 谈到了文件配置器,但我还是会尽快降级和更新。
  • 我将版本降级到 v11.14 并且神奇地起作用了。似乎是 v0.12.6 中的错误。非常感谢您花时间在这方面!在一个问题上花费数周时间才发现这样的事情真的很糟糕 :) 我会尽量引起 Hashicorp 的注意。同时,请您在答案中写下相同的内容以便我接受吗?
  • 是的......似乎已经做到了......使用null_resource的3个并行chef条款在降级并将语法恢复为v.0.11.14后顺利且成功。我不知道我怎么没有早点找到这个帖子。但至少现在可以了。
【解决方案2】:

我在 null_resource 中使用了这个触发器,它非常适合我。当实例数量增加并在所有实例上进行配置时,它也可以工作。我使用的是 terraform 和 openstack。

触发器= { instance_ids = join(",",openstack_compute_instance_v2.swarm-cluster-hosts[*].id) }

【讨论】:

    【解决方案3】:

    Terraform 0.12.26 为我解决了类似的问题(在部署多个 VM 时使用多个文件配置器)

    希望这可以帮助您: https://github.com/hashicorp/terraform/issues/22006

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-09
      • 2020-06-02
      • 2019-09-08
      • 2021-10-26
      • 1970-01-01
      • 2014-12-28
      • 2014-01-09
      • 1970-01-01
      相关资源
      最近更新 更多