使用 remote-exec 配置器时,当 instance_count 大于 2 时,Terraform 卡住

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

  • 我正在尝试使用 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 和 的 remote-exec 配置器(其中两个涉及重新启动实例)。对于单个实例 ,一切正常。
  • 然后我需要增加计数并基于几个链接,最终使用了 null_resource。
    因此,我已将问题减少到我什至无法使用 null_resource 为超过 2 个 Windows EC2 实例运行一个 remote-exec 配置程序的程度。

  • 用于重现错误消息的 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}"
    }
    

    观察:
  • 使用一个 remote-exec 配置器,如果将计数设置为 1 或 2,它就可以正常工作。使用计数 3,无法预测所有配置器每次都会在所有实例上运行。然而有一件事是肯定的,Terraform 永远不会完成并且不显示输出变量。它一直显示“null_resource.nullresource[count.index]:仍在创建...”
  • 对于 本地执行供应商 - 一切正常。使用计数值为 1、2 和 7 进行测试。
  • 对于 文件供应商 它在 1、2 和 3 中工作正常,但在 7 中没有完成,但文件已在所有 7 个实例上复制。它一直显示“null_resource.nullresource[count.index]:仍在创建...”
  • 此外,在每次尝试中,remote-exec 供应商都能够连接到实例,而不管计数的值如何,仅此而已,它不会触发内联命令并随机选择跳过该命令并开始显示“仍在创建...”消息。
  • 我已经被这个问题困住了很长一段时间。在调试日志中也找不到任何重要的内容。我知道不建议将 Terraform 用作配置管理工具,但是,如果实例计数仅为 1(即使没有 null_resource),即使使用复杂的配置脚本,一切也能正常工作,这表明 Terraform 应该很容易处理这样的问题基本配置要求。
  • TF_DEBUG 日志:
  • count=2, TF completes successfully and shows Apply complete! .
  • count=3, TF runs the remote-exec on all the three instances however does not complete and doesn't not show the outputs variables. Stuck at "Still creating..."
  • count=3, TF runs the remote-exec only on two instances and skips on nullresource[1] , does not complete and doesn't not show the outputs variables. Stuck at "Still creating..."
  • 任何指针将不胜感激!
  • 最佳答案

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

    您可以尝试以下几点:

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

    现在您可以引用 self connection块以获取实例的私有(private) IP。
  • 添加 triggersnull_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 .

    关于使用 remote-exec 配置器时,当 instance_count 大于 2 时,Terraform 卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57368506/

    相关文章:

    chef-infra - 尝试使用 Chef 引导 Windows 服务器时陷入困境

    powershell - Windows 自定义不适用于 Terraform

    linux - terraform 的问题,为什么在尝试规划特定资源时双引号被忽略

    amazon-web-services - 安装提供程序 "aws": openpgp: signature made by unknown entity时出错

    amazon-web-services - terraform aws - 如何将默认路由添加到 vpc 默认路由表?

    vagrant up 失败,无法加载 winrm

    amazon-web-services - 如何创建具有域加入和预安装应用程序的 Windows ec2 实例

    amazon-web-services - aws 安全组的 Terraform 中的变量值

    terraform - 如何使用terraform从VPC获取子网列表

    AWS 提供商中的 Terraform 配置文件字段使用情况