如何克服Digitalocean Droplet上的“错误:循环”

时间:2019-11-16 00:08:41

标签: terraform

我确定这是一个简单的问题,目前我不知道该怎么解释。

我使用3个小滴(称为rs),并有一个模板文件来配置每个小滴。

[..]

data "template_file" "rsdata" {
  template = file("files/rsdata.tmpl")
  count    = var.count_rs_nodes
  vars = {
    docker_version   = var.docker_version
    private_ip_rs    = digitalocean_droplet.rs[count.index].ipv4_address_private
    private_ip_mysql = digitalocean_droplet.mysql.ipv4_address_private
  }
}

resource "digitalocean_droplet" "rs" {
  count              = var.count_rs_nodes
  image              = var.image
  name               = "${var.prefix}-rs-${count.index}"
  region             = var.region
  size               = var.rs_size
  private_networking = true
  user_data          = data.template_file.rsdata.rendered
  ssh_keys           = var.ssh_keys
  depends_on         = ["digitalocean_droplet.mysql"]
}

[..]

当我执行Terraform申请时,我得到: Error: Cycle: digitalocean_droplet.rs, data.template_file.rsdata

请注意,这是Terraform 0.12

我在做错什么,请问我该如何克服?

1 个答案:

答案 0 :(得分:0)

由于data.template_file.rsdata资源引用了digitalocean_droplet.rs资源,反之亦然,返回此错误。这为Terraform创造了一个不可能的情况:Terraform无法使用任何顺序来处理这些信息,从而确保每个步骤都可以使用所有必需的数据。

关键问题是,在创建液滴的过程中分配了液滴的专用IPv4地址,但是user_data在创建过程中被使用,因此它不能包含尚待分配的IPv4地址。已分配。

最简单的处理方法是将小滴的IP地址作为其user_data的一部分,而是安排处理该user_data的任何软件在运行时直接从网络接口获取主机的IP地址。在该Droplet中运行的内核将知道IP地址是什么,因此原则上您可以从那里检索它。


如果由于某种原因而不可避免地在user_data中包括IP地址(例如,如果有一组虚拟机都需要彼此注意的话,则可能会发生这种情况),则更复杂的选择是将IP地址的分配与实例的创建分开。 DigitalOcean没有一种机制可以独立于它们所属的小滴来创建私有网络接口,因此在这种情况下,有必要通过digitalocean_floating_ip使用公共IP地址,但可能不会适用于所有情况:

resource "digitalocean_floating_ip" "rs" {
  count = var.count_rs_nodes

  region = var.region
}

resource "digitalocean_droplet" "rs" {
  count = var.count_rs_nodes

  image              = var.image
  name               = "${var.prefix}-rs-${count.index}"
  region             = var.region
  size               = var.rs_size
  private_networking = true
  ssh_keys           = var.ssh_keys
  user_data = templatefile("${path.module}/files/rsdata.tmpl", {
    docker_version   = var.docker_version
    private_ip_rs    = digitalocean_floating_ip.rs[count.index].ip_address
    private_ip_mysql = digitalocean_droplet.mysql.ipv4_address_private
  })
}

resource "digitalocean_floating_ip_assignment" "rs" {
  count = var.count_rs_nodes

  ip_address = digitalocean_floating_ip.rs[count.index].ip_address
  droplet_id = digitalocean_droplet.rs[count.index].id
}

由于在启动液滴之后,“浮动IP分配”是作为一个单独的步骤创建的,因此在将浮动IP与实例相关联之前会存在一些延迟,因此,依赖该IP地址的任何软件都必须具有弹性在创建关联之前运行。

请注意,我也从使用data "template_file"切换到the templatefile function,因为该数据源仅提供与Terraform 0.11配置的向后兼容性。建议使用内置功能在Terraform 0.12中呈现外部模板文件,并且避免需要单独的配置块。