使用 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。但是我运行遇到了一个问题
- 它说
This object does not have an attribute named "public_ip"
我试过使用 id 而不是 public_ip,它抱怨说 this object does not have an attribute named "id"
- 我保持主 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)
我计划在 AWS 上创建带有服务器节点和代理节点的 puppet 基础设施。为了能够安装人偶服务器和人偶代理程序包,需要将 IP 添加到每个节点上的主机文件中,如下所示
[puppet master ip] puppetmaster puppet
[puppet client ip] puppetclient
我知道在创建资源后 运行s 远程执行。但是我希望它在创建所有资源后 运行 ,这样我就可以一起获取有关主 IP 和客户端 IP 的信息。因此,在创建实例后,我使用了一个空资源来执行 remote-exec provisioner。但是我运行遇到了一个问题
- 它说
This object does not have an attribute named "public_ip"
我试过使用 id 而不是 public_ip,它抱怨说 this object does not have an attribute named "id"
- 我保持主 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)