【问题标题】:Why does terraform + apt-get fail, intermittently?为什么 terraform + apt-get 会间歇性地失败?
【发布时间】:2017-07-05 21:46:39
【问题描述】:

我正在使用 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 count=4 运行它时,一些节点会间歇性地失败并出现 apt-get 错误,例如:

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

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

  • 亚马逊上的多个 AMI 副本,不相同
  • 多个不相同的 apt-get 镜像

哪个更有可能?我还缺少其他任何可能性吗?
是否有我可以使用的 apt-get “force” 类型标志来使配置更加可重复?

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

【问题讨论】:

    标签: amazon-web-services amazon-ec2 apt-get amazon-ami terraform


    【解决方案1】:

    Terraform 的 remote-exec 配置器功能只会生成一个 shell 脚本,该脚本会上传到新实例并运行您指定的命令。很可能您实际上遇到了cloud-init 的问题,该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(从上面的 sn-p 修改):

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      • 2019-04-18
      相关资源
      最近更新 更多