gpt4 book ai didi

terraform - 如何让 Terraform 中的 Docker 提供程序在尝试连接之前等待地址可用?

转载 作者:行者123 更新时间:2023-12-04 02:36:00 25 4
gpt4 key购买 nike

我在 Terraform 中有以下资源:

provider "docker" {
host = "tcp://${digitalocean_droplet.docker_server.ipv4_address}:2376/"
}

这取决于值 ipv4_address在它可以连接到 docker 机器之前被知道。在供应另一个资源之前,该值是未知的:

resource "digitalocean_droplet" "docker_server" {
image = "docker-18-04"
name = "docker_server"
region = "nyc2"
size = "512mb"
private_networking = true
ssh_keys = [
var.ssh_fingerprint
]

connection {
user = "root"
type = "ssh"
private_key = file(var.pvt_key)
timeout = "2m"
}
}

当我跑 terraform plan ,我收到以下错误:

Error: Error initializing Docker client: unable to parse docker host ``

on docker.tf line 1, in provider "docker": 1: provider "docker" {



看来 ipv4_address为空,因为 docker 插件在配置之前尝试连接到 docker 机器。我如何告诉它在尝试连接之前等待机器配置?

我尝试过的一件事:
provider "docker" {
host = "tcp://${digitalocean_droplet.docker_server.ipv4_address}:2376/"
depends_on = [
digitalocean_droplet.docker_server.ipv4_address,
]
}

当我这样做时,我收到此错误:

Error: Reserved argument name in provider block

on docker.tf line 4, in provider "docker": 4: depends_on = [

The provider argument name "depends_on" is reserved for use by Terraform in a future version.



但阅读更多内容 depends_on ,反正我不认为这是解决方案。

最佳答案

不幸的是 provider区块不支持 expressions指的是resource attribute .

此限制在 provider configuration 中进行了解释。文档:

The configuration arguments defined by the provider may be assigned using expressions, which can for example allow them to be parameterized by input variables.

However, since provider configurations must be evaluated in order to perform any resource type action, provider configurations may refer only to values that are known before the configuration is applied.

In particular, avoid referring to attributes exported by other resources unless their values are specified directly in the configuration.



例如,这会起作用(但不能解决您的问题):
variable "docker_host" {
type = string
}

provider "docker" {
host = "tcp://${var.docker_host}:2376/"
}

但有出路。

解决方案分为两步:
  • 将您的 terraform 配置分为两部分(每个部分都必须位于自己的
    目录),其中 docker 提供者依赖于提供者的那个
    部署液滴。请注意,这意味着您必须发出
    terraform 命令分别(您需要应用两次)。
  • 在两个状态之间建立一个单向、只读的“连接”
    使用名为 remotestate 的功能:

  • Retrieves state data from a Terraform backend. This allows you to use the root-level outputs of one or more Terraform configurations as input data for another configuration.



    如果您还没有使用“真正的”远程后端,例如 S3 + DynamoDB,您仍然可以使用 local backend 轻松进行实验。如下。

    目录布局:
    ├── docker                   <== this performs docker operation
    │ ├── main.tf
    │ └── terraform.tfstate
    └── server <== this deploys the droplet
    ├── main.tf
    └── terraform.tfstate

    下面的代码片段使用的是 AWS,但适应 DO 是微不足道的。

    文件 server/main.tf 包含类似于
    resource "aws_instance" "server" {     <= equivalent to the Droplet
    ...
    }

    output "ipv4_address" {
    value = aws_instance.server.public_ip
    }

    文件 docker/main.tf 包含类似于
    data "terraform_remote_state" "docker_server" {
    backend = "local"

    config = {
    path = "${path.module}/../server/terraform.tfstate"
    }
    }

    provider "docker" {
    host = "tcp://${data.terraform_remote_state.docker_server.outputs.ipv4_address}:2376/"
    }

    最后:
    cd server
    terraform apply
    cd ../docker
    terraform apply

    请记住:您还必须单独执行 terraform destroy ,按 LIFO 顺序:
    先毁 docker ,然后销毁 server .

    关于terraform - 如何让 Terraform 中的 Docker 提供程序在尝试连接之前等待地址可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61789874/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com