Terraform 空资源执行顺序

标签 terraform

问题:

我正在尝试在 Digital Ocean 上构建一个 Docker Swarm 集群,由 3 个“管理器”节点和许多工作节点组成。工作节点的数量与这个问题并不特别相关。我正在尝试对 Docker Swarm 配置内容进行模块化,因此它没有专门与 digitalocean 提供程序耦合,而是可以接收一个 IP 地址列表来对抗配置集群。

为了提供主节点,第一个节点需要进入 swarm 模式,这会生成一个加入 key ,其他主节点将使用该 key 加入第一个节点。 “null_resource”s 被用于对主节点执行远程配置,但是,我无法弄清楚 dafuq 如何确保第一个主节点完成其工作(“docker swarm init ...”),然后再拥有另一个“null_resource"配置程序针对需要加入第一个主节点的其他主节点执行。它们都并行且可预测地运行,但它不起作用。

此外,试图弄清楚如何收集第一个节点生成的连接 token 并使其可用于其他节点。我已经考虑过使用 Consul 执行此操作,并将加入 token 存储为 key ,并在其他节点上获取该 key - 但这并不理想,因为......仍然存在确保 Consul 集群已配置并准备就绪的问题(所以同样的问题)。

主文件

variable "master_count" { default = 3 }

# master nodes
resource "digitalocean_droplet" "master_nodes" {
  count               = "${var.master_count}"
  ... etc, etc
}

module "docker_master" {
  source          = "./docker/master"
  private_ip      = "${digitalocean_droplet.master_nodes.*.ipv4_address_private}"
  public_ip       = "${digitalocean_droplet.master_nodes.*.ipv4_address}"
  instances       = "${var.master_count}"
}

docker /主人/main.tf
variable "instances" {}
variable "private_ip" { type = "list" }
variable "public_ip" { type = "list" }


# Act only on the first item in the list of masters...
resource "null_resource" "swarm_master" {
  count = 1

  # Just to ensure this gets run every time
  triggers {
    version = "${timestamp()}"
  }

  connection {
    ...
    host = "${element(var.public_ip, 0)}"
  }

  provisioner "remote-exec" {
    inline = [<<EOF
      ... install docker, then ...

      docker swarm init --advertise-addr ${element(var.private_ip, 0)}

      MANAGER_JOIN_TOKEN=$(docker swarm join-token manager -q)
      # need to do something with the join token, like make it available
      # as an attribute for interpolation in the next "null_resource" block
    EOF
    ]
  }
}


# Act on the other 2 swarm master nodes (*not* the first one)
resource "null_resource" "other_swarm_masters" {
  count = "${var.instances - 1}"

  triggers {
    version = "${timestamp()}"
  }

  # Host key slices the 3-element IP list and excludes the first one
  connection {
    ...
    host = "${element(slice(var.public_ip, 1, length(var.public_ip)), count.index)}"
  }

  provisioner "remote-exec" {
    inline = [<<EOF
      SWARM_MASTER_JOIN_TOKEN=$(consul kv get docker/swarm/manager/join_token)
      docker swarm join --token ??? ${element(var.private_ip, 0)}:2377
    EOF
    ]
  }

  ##### THIS IS THE MEAT OF THE QUESTION ###
  # How do I make this "null_resource" block not run until the other one has
  # completed and generated the swarm token output? depends_on doesn't
  # seem to do it :(
}

通过阅读 github 问题,我觉得这不是一个不常见的问题......但它踢我的屁股。任何建议表示赞赏!

最佳答案

@victor-m 的评论是正确的。如果您使用 null_resource并对任何前者的属性进行以下触发,然后它们将按顺序执行。

resource "null_resource" "first" {
  provisioner "local-exec" {
    command = "echo 'first' > newfile"
  }
}

resource "null_resource" "second" {
  triggers = {
    order = null_resource.first.id
  }

  provisioner "local-exec" {
    command = "echo 'second' >> newfile"
  }
}

resource "null_resource" "third" {
  triggers = {
    order = null_resource.second.id
  }

  provisioner "local-exec" {
    command = "echo 'third' >> newfile"
  }
}
$ terraform apply

null_resource.first: Creating...
null_resource.first: Provisioning with 'local-exec'...
null_resource.first (local-exec): Executing: ["/bin/sh" "-c" "echo 'first' > newfile"]
null_resource.first: Creation complete after 0s [id=3107778766090269290]
null_resource.second: Creating...
null_resource.second: Provisioning with 'local-exec'...
null_resource.second (local-exec): Executing: ["/bin/sh" "-c" "echo 'second' >> newfile"]
null_resource.second: Creation complete after 0s [id=3159896803213063900]
null_resource.third: Creating...
null_resource.third: Provisioning with 'local-exec'...
null_resource.third (local-exec): Executing: ["/bin/sh" "-c" "echo 'third' >> newfile"]
null_resource.third: Creation complete after 0s [id=6959717123480445161]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
为了确保,cat新文件,这是预期的输出
$ cat newfile
first
second
third

关于Terraform 空资源执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44465429/

相关文章:

mysql - 无法使用 terraform 使用 AWSAuthenticationPlugin 创建 mysql 用户

azure - 运行 Terraform Apply 时 Azure Key Vault 访问策略出现问题

amazon-web-services - Terraform:将 CloudFormation 模板写入磁盘

aws-cloudformation - terraform tf 文件或模块可以自动使资源过期吗?

amazon-web-services - 修改Terraform中自动生成的资源

google-cloud-platform - Google Cloud 转发规则 http -> https 使用 terraform

sql-server - Powershell Invoke-Sqlcmd 命中错误的数据库 - 系统,为什么?

azure - 如何在 terraform 中设置 winrm AllowUnencrypted ="true"和 auth @{Basic ="true"}

amazon-web-services - 无法生成 id 和 arn

terraform - 将 JSON 字符串解码为地形图