为什么terraform + apt-get会间歇性失败?

问题描述:

我使用terraform创建于AWS EC2多发节点:为什么terraform + apt-get会间歇性失败?

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" 
     ] 
    } 
} 

当我跑这跟说数= 4,一些节点间歇性地无法用apt-得到这样的错误:

aws_instance.myapp.1 (remote-exec): E: Unable to locate package awscli 

而其他3个节点发现awscli就好了。现在,所有节点都是从相同的AMI创建的,使用完全相同的配置命令,为什么只有其中一些失败?的变化可能来自于:

在亚马逊的AMI
  • 多个副本,这是不相同的
  • 多apt-get的镜子,不相同

哪个更容易?我错过了其他任何可能性?
是否有一个我可以使用的apt-get“force”类型标志,这将使配置更加可重复?

通过脚本自动配置的整点是避免这种节点之间的变化:/

Terraform的remote-exec供应方的功能只是生成上传到新的实例并运行这些命令你一个shell脚本指定。很有可能您遇到cloud-init问题,该问题配置为在标准Ubuntu AMI上运行,并且Provisioner正在尝试运行,而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。您可以为您的实例指定user-data像这样在Terraform(从片段上方修改):

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 
    } 
} 
+0

等待'引导finished'似乎为我工作。 – RaGe