在使用远程exec provisioner时,当实例计数大于2时,Terraform会阻塞 我正在尝试使用null_资源为Terraform的remote exec provisioner配置多个Windows EC2实例

在使用远程exec provisioner时,当实例计数大于2时,Terraform会阻塞 我正在尝试使用null_资源为Terraform的remote exec provisioner配置多个Windows EC2实例,terraform,terraform-provider-aws,winrm,remote-execution,Terraform,Terraform Provider Aws,Winrm,Remote Execution,$terraform-v 地形v0.12.6 provider.aws v2.23.0 provider.null v2.1.2 最初,我使用的是三个远程exec Provisioner(其中两个涉及重新启动实例),没有null_资源,对于单个实例,一切都非常正常 然后,我需要增加计数,并基于几个链接,最终使用null_资源。 因此,我已将问题减少到无法使用null_资源为超过2个Windows EC2实例运行一个远程exec provisioner的程度。 用于复制错误消息的Terrafo

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

  • 最初,我使用的是三个远程exec Provisioner(其中两个涉及重新启动实例),没有null_资源,对于单个实例,一切都非常正常
  • 然后,我需要增加计数,并基于几个链接,最终使用null_资源。 因此,我已将问题减少到无法使用null_资源为超过2个Windows EC2实例运行一个远程exec provisioner的程度。
用于复制错误消息的Terraform模板:

观察结果:

  • 对于一个远程exec provisioner,如果count设置为1或2,则可以正常工作。对于计数3,不可预测的是,每次都会在所有实例上运行所有供应器。但是有一件事是可以肯定的,Terraform永远不会完成,也不会显示输出变量。它一直显示“null\u resource.nullresource[count.index]:仍在创建…”
  • 对于本地exec provisioner,一切正常。测试计数的值为1、2和7
  • 对于文件provisioner而言,其1、2和3的工作正常,但7的工作没有结束,但文件已在所有7个实例上复制。它一直显示“null\u resource.nullresource[count.index]:仍在创建…”
  • 此外,在每次尝试中,remote exec provisioner都能够连接到实例,而不考虑count的值,只是,它不会触发内联命令,并随机选择跳过该命令,并开始显示“仍在创建…”消息
  • 我已经被这个问题困扰了很长一段时间了。在调试日志中也找不到任何重要内容。我知道Terraform不建议用作配置管理工具,但是,如果实例数仅为1(即使没有null_资源),即使使用复杂的配置脚本,一切都可以正常工作,这表明Terraform应该可以轻松地处理这样的基本配置需求
  • TF_调试日志:
  • 任何指点都将不胜感激
更新:最终的诀窍是将地形降级为
v11.14

您可以尝试以下几点:

  • 内联
    远程执行
  • 现在,您可以在
    连接
    块中引用以获取实例的私有IP

  • 触发器添加到
    null\u资源中

  • 您可以使用重新创建
    null\u资源
    ,从而重新执行
    remote exec

    我在null\u资源中使用了此触发器,它非常适合我。当实例数量增加时,它也可以工作,并且它可以在所有实例上进行配置

    触发器={ 实例_id=join(“,”,openstack_compute_instance_v2.swarm集群主机[*].id)}


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

    希望这对您有所帮助:

    请不要过于简单化,找出你的错误所在是没有帮助的。将您的示例简化为其他人可以运行,但仍会看到与您相同的错误。感谢您的反馈。我已经修改了代码,现在就可以复制了。@ydaetskcoR添加了模板,这样比以前的代码片段更容易复制。谢谢Aleksi的建议。我已经尝试过#1,但当我在aws#U实例块中遇到与remote exec相同的问题时,最终使用了null#U资源。尝试了2次,但仍然是相同的问题。Terraform跳过在其中一个实例上运行provisioner,并陷入“仍在创建…”状态。在
    内联
    命令的开头和结尾添加
    sleep
    如何?根据有些人还被降级到terraform
    v11.14
    ,这在你的情况下可能不是一个选项?再次尝试(在命令前后放置睡眠)。不起作用。所发生的事情是,正如在最初的帖子中所提到的,Terraform在所有三个实例上运行了provisioner,显示一个资源的创建完成了,然后被其他两个实例的“仍在创建…”消息卡住了,并且从未显示“应用完成!”绿色消息。虽然本期讨论的是文件provisioner,但我仍将尝试降级并很快更新。我将该版本降级为v11.14,并且神奇地工作了。似乎是v0.12.6中的一个bug。非常感谢你在这方面花时间!在一个问题上花上几周的时间来发现这样的事情真是太糟糕了:)我会尽力让Hashicorp注意到这一点。同时,你能在回答中写同样的内容吗?好的。。。这似乎已经做到了。。。3使用
    null_资源的并行
    chef
    供应在降级并将语法恢复为
    v.0.11.14
    后顺利进行。我不知道我怎么没早点找到这根线。但至少它现在起作用了。
    //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}"
    }
    
    resource "aws_instance" "ec2instance" {
      count         = "${var.instance_count}"
      # ...
      provisioner "remote-exec" {
        connection {
          # ...
        }
        inline = [
          # ...
        ]
      }
    }
    
    resource "null_resource" "nullresource" {
      triggers {
        host    = "${element(aws_instance.ec2instance.*.private_ip, count.index)}" # Rerun when IP changes
        version = "${timestamp()}" # ...or rerun every time
      }
      # ...
    }