2017-02-16 37 views
1

我使用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」類型標誌,這將使配置更加可重複?

通過腳本自動配置的整點是避免這種節點之間的變化:/

回答

4

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