使用 remote-exec 为一组实例设置 Public IP 信息

Set Public IP information using remote-exec for a set of instances

我计划在 AWS 上创建带有服务器节点和代理节点的 puppet 基础设施。为了能够安装人偶服务器和人偶代理程序包,需要将 IP 添加到每个节点上的主机文件中,如下所示

[puppet master ip] puppetmaster puppet
[puppet client ip] puppetclient

我知道在创建资源后 运行s 远程执行。但是我希望它在创建所有资源后 运行 ,这样我就可以一起获取有关主 IP 和客户端 IP 的信息。因此,在创建实例后,我使用了一个空资源来执行 remote-exec provisioner。但是我运行遇到了一个问题

  1. 它说 This object does not have an attribute named "public_ip"

我试过使用 id 而不是 public_ip,它抱怨说 this object does not have an attribute named "id"

  1. 我保持主 IP 不变并仅循环代理 IP,以便能够将它们都放入每个实例的 /etc/hosts 文件中。我的方法在远程执行部分是否正确?

这里是完整的代码

provision_ec2.tf

resource "aws_key_pair" "puppet" {
  key_name   = "puppet"
  public_key = file("puppet.pub")
}

# Provision Puppet Server
resource "aws_instance" "puppet_instances" {
for_each = toset(local.expanded_names)
  ami             = var.ami
  instance_type   = var.instance_type
  key_name        = aws_key_pair.puppet.key_name
  security_groups = ["${aws_security_group.puppet-server.name}"] 
  
tags = {
    Name        = each.value
  } 
}

resource "null_resource" "provisioner" {
  count = "${var.total_count}"

  triggers = {
    master_ip = "${element(aws_instance.puppet_instances.*.public_ip, count.index)}"
  }

  connection {
    host        = "${element(aws_instance.puppet_instances.*.public_ip, count.index)}"
    type        = "ssh"
    user        = "ubuntu"
    private_key = file("puppet")
  }

  # set hostname
  provisioner "remote-exec" {
        inline = [
      "sudo echo ${element(aws_instance.puppet_instances.*.public_ip,0)} puppetmaster puppet>>/etc/hosts",
      "sudo echo ${element(aws_instance.puppet_instances.*.public_ip, count.index)} puppetclient>>/etc/hosts"
    ]
  }
}

locals {
  expanded_names = flatten([
    for name, count in var.host_name : [
      for i in range(count) : format("%s-%02d", name, i+1)
    ]
  ])
}

variables.tf

# Set the instances type. For puppet, choose instance with minimum 2GB RAM
variable "instance_type" {
  default = "t2.small"
}
# Set the region in which the instances will be provisioned. Default region is N.Virgina
variable "aws_region" {
  default = "us-east-1"
}
# Sepcify the AMI to be used
variable "ami" {
  default = "ami-09e67e426f25ce0d7"
}
# Set the hostnames for the instances as per the count
variable "host_name" {
  type = map(number)
  default = {
    "Puppet-Server" = 1
    "Puppet-Agent"  = 3
  }
}
variable "total_count" {
  default = 4
}

security_groups.tf

# Create Security Groups
resource "aws_security_group" "puppet-server" {
  name        = "puppet-server-SG"
  description = "Security Group for puppet master instance"

  ingress {
    from_port   = "0"
    to_port     = "0"
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = "0"
    to_port     = "0"
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name        = "puppet-server-SG"
  }
}

我不知道如何实现这一目标。

既然你用的是for_each,你应该先用values。所以应该是:

master_ip = element(values(aws_instance.puppet_instances)[*].public_ip, count.index)