我使用terraform在aws上创建多个ec2节点:
resource "aws_instance" "myapp" {
count = "${var.count}"
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "m4.large"
vpc_security_group_ids = ["${aws_security_group.myapp-security-group.id}"]
subnet_id = "${var.subnet_id}"
key_name = "${var.key_name}"
iam_instance_profile = "${aws_iam_instance_profile.myapp_instance_profile.id}"
connection {
user = "ubuntu"
private_key = "${file("${var.key_file_path}")}"
}
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get upgrade -y",
"sudo apt-get install -f -y openjdk-7-jre-headless git awscli"
]
}
}
当我使用say = 4运行时,某些节点间歇性地因apt-get错误而失败,如:
aws_instance.myapp.1 (remote-exec): E: Unable to locate package awscli
而其他3个节点发现awscli就好了。现在所有节点都是从同一个AMI创建的,使用完全相同的配置命令,为什么只有部分节点失败?变化可能来自:
哪个更有可能?我还缺少任何其他可能性吗?
有没有一个特定的力量"我可以使用的类型标志会使配置更加可重复吗?
通过脚本自动配置的重点是避免节点之间的这种变化:/
答案 0 :(得分:5)
Terraform的remote-exec
配置器功能只生成一个shell脚本,该脚本将上载到新实例并运行您指定的命令。很可能你实际遇到cloud-init
配置为在标准Ubuntu AMI上运行的问题,并且配置程序试图在cloud-init
运行时运行,所以你正在运行到时间/冲突。
您可以让脚本等到cloud-init
完成配置之后。 cloud-init
在/var/lib/cloud/instance/boot-finished
中创建了一个文件,因此您可以将此内容与您的供应商联系起来:
until [[ -f /var/lib/cloud/instance/boot-finished ]]; do
sleep 1
done
或者,您可以利用cloud-init
并拥有install arbitrary packages for you。您可以在Terraform中为您的实例指定user-data
(从上面的代码段修改):
resource "aws_instance" "myapp" {
count = "${var.count}"
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "m4.large"
vpc_security_group_ids = ["${aws_security_group.myapp-security-group.id}"]
subnet_id = "${var.subnet_id}"
key_name = "${var.key_name}"
iam_instance_profile = "${aws_iam_instance_profile.myapp_instance_profile.id}"
user_data = "${data.template_cloudinit_config.config.rendered}"
}
# Standard cloud-init stuff
data "template_cloudinit_config" "config" {
# I've
gzip = false
base64_encode = false
part {
content_type = "text/cloud-config"
content = <<EOF
packages:
- awscli
- git
- openjdk-7-headless
EOF
}
}