使用远程执行预配置程序时,instance_count大于2时Terraform卡住了

时间:2019-08-06 03:24:16

标签: 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和单个实例,一切工作都很好。
  • 然后我需要增加计数,并基于几个链接,最终使用null_resource。 因此,我已将问题减少到无法使用null_resource为两个以上的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}"
}

观察

3 个答案:

答案 0 :(得分:2)

更新:最终的诀窍是按照此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

答案 1 :(得分:1)

我在null_resource中使用了此触发器,它对我来说非常理想。当增加实例数并在所有实例上进行配置时,它也可以工作。我正在使用terraform和openstack。

triggers = { instance_ids = join(“,”,openstack_compute_instance_v2.swarm-cluster-hosts [*]。id)}

答案 2 :(得分:0)

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

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