如何使Terraform中的Docker提供程序在尝试连接到某个地址之前等待该地址可用?

如何使Terraform中的Docker提供程序在尝试连接到某个地址之前等待该地址可用?,terraform,terraform-remote-state,terraform-provider-docker,Terraform,Terraform Remote State,Terraform Provider Docker,我在Terraform中拥有以下资源: provider "docker" { host = "tcp://${digitalocean_droplet.docker_server.ipv4_address}:2376/" } 这取决于在连接到docker机器之前已知的值ipv4\u地址。在配置另一个资源之前,此值是未知的: resource“digitalocean\u droplet”“docker\u服务器”{ image=“docker-18-04” name=“docker\

我在Terraform中拥有以下资源:

provider "docker" {
    host = "tcp://${digitalocean_droplet.docker_server.ipv4_address}:2376/"
}
这取决于在连接到docker机器之前已知的值
ipv4\u地址
。在配置另一个资源之前,此值是未知的:

resource“digitalocean\u droplet”“docker\u服务器”{
image=“docker-18-04”
name=“docker\u服务器”
region=“nyc2”
size=“512mb”
私有网络=真
ssh_密钥=[
var.ssh_指纹
]
联系{
user=“root”
type=“ssh”
私钥=文件(var.pvt\u密钥)
超时=“2m”
}
}
当我运行
terraform plan
时,我得到以下错误:

错误:初始化Docker客户端时出错:无法分析Docker主机 ``

在docker.tf第1行的提供程序“docker”中:1:提供程序“docker”{

由于docker插件试图在设置docker计算机之前连接到该计算机,因此,
ipv4\u地址
似乎为空。我如何告诉它在尝试连接到该计算机之前等待设置该计算机


我试过一件事: 当我这样做时,我会出现以下错误:

错误:提供程序块中的保留参数名称

在docker.tf第4行的提供程序“docker”中:4:依赖=[

提供程序参数名称“dependens_on”保留供用户使用 未来版本中的地形

但是阅读更多的
取决于
,我不认为这是解决方案。

不幸的是,块不支持引用

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

提供程序定义的配置参数可以使用 表达式,例如,可以通过输入参数化这些表达式 变量

但是,由于必须按顺序评估提供程序配置 要执行任何资源类型操作,提供程序配置只能参考 应用配置之前已知的值

特别是,, 避免引用由其他资源导出的属性,除非它们的值 直接在配置中指定

例如,这会起作用(但不能解决您的问题):

但有一条出路

解决方案由两个步骤组成:

  • 将您的地形配置分为两部分(每个部分必须位于自己的 目录),其中具有docker提供程序的依赖于 部署液滴。请注意,这意味着您必须 terraform命令单独使用(需要应用两次)
  • 在两个状态之间建立单向只读“连接” 使用名为:
  • 从Terraform后端检索状态数据。这允许您使用 一个或多个地形配置的根级输出,作为另一个地形配置的输入数据 配置

    在您还没有使用“真正的”远程后端(如S3+DynamoDB)的情况下,您仍然可以按如下方式轻松地使用

    目录布局:

    ├── docker                   <== this performs docker operation
    │   ├── main.tf
    │   └── terraform.tfstate
    └── server                   <== this deploys the droplet
        ├── main.tf
        └── terraform.tfstate
    
    最后:

    cd server
    terraform apply
    cd ../docker
    terraform apply
    
    请记住:您还必须按照后进先出顺序执行单独的
    地形销毁

    首先销毁
    docker
    ,然后销毁
    服务器

    这非常简洁,非常有用,我很感激。这个解决方案的问题是,在您接受已知主机的ECDSA密钥指纹之前,ssh不会在服务器实例上工作,而现在是manual@lfmunozSSH必须被初始化的事实与此无关解决方案。我建议从阅读开始并问一个新问题。@Hassan正在尝试做的事情与已经做的事情(kubernetes提供者配置取决于创建的资源)是否类似?
    ├── docker                   <== this performs docker operation
    │   ├── main.tf
    │   └── terraform.tfstate
    └── server                   <== this deploys the droplet
        ├── main.tf
        └── terraform.tfstate
    
    resource "aws_instance" "server" {     <= equivalent to the Droplet
      ...
    }
    
    output "ipv4_address" {
      value = aws_instance.server.public_ip
    }
    
    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