【问题标题】:How to create dependencies between modules and providers (for refresh)如何在模块和提供者之间创建依赖关系(用于刷新)
【发布时间】:2020-10-22 10:25:36
【问题描述】:

我无法让 terraform 中的模块之间的依赖关系正常工作。问题似乎是由于没有正确评估提供者的依赖关系。

我有:

  • 在 docker 中设置 rabbitmq 的 docker 容器资源
  • 一个依赖于rabbitmq容器的定时器资源,以确保它启动
  • 一些用于设置交换、队列、用户等的 rabbitmq 资源。

当一切都在同一个模块中时,这一切都很好。我只需将计时器作为依赖项添加到将配置 rabbitmq 的 everything

我现在想将 docker 容器的配置和rabbitmq 配置到不同的模块中,以便配置块可以在其他地方重用。我似乎无法让一个模块等待另一个模块。刷新时似乎总是失败。

我已尝试根据睡眠计时器生成(部署容器的模块的)输出:

output "remote_host" {
  value = "localhost"
  depends_on = [time_sleep.rabbitmq_ready]
}

然后我将该输出用作模块的参数:

module "rabbitmq" {
  source = "./modules/rabbitmq"
  api_url = "http://${module.container.remote_host}:15672"
  username = "admin"
  password = module.container.admin_password
}

理论上这应该意味着rabbitmq提供者在容器完全启动并运行之前不知道如何连接(直到睡眠完成)。

但我明白了,容器根本没有启动:

module.rabbitmq.rabbitmq_queue.data_export: Refreshing state... [id=sites.data_export@/]

Error: Get "http://127.0.0.1:15672/api/queues/%2F/sites.data_export": dial tcp 127.0.0.1:15672: connect: connection refused

这表明depends_on = [time_sleep.rabbitmq_ready] 在刷新步骤期间已被忽略,并且值 (localhost) 正在返回而无需等待依赖项。

有什么想法吗?

【问题讨论】:

    标签: terraform


    【解决方案1】:

    听起来您想使用模块 A 的输出作为模块 B 的参数,因此您希望模块 B 等待模块 A。

    Terraform 文档建议仅将depends_on 用作最后的手段(请参阅Output Values page 的最后一段),而是构建文件以便 Terraform 可以自己找出依赖关系。

    例如,具有以下文件结构:

    .
    +-- main.tf
    +-- _vpc
    |   +-- main.tf
    |   +-- variables.tf
    |   +-- outputs.tf
    +-- _rds
    |   +-- main.tf
    |   +-- variables.tf
    

    以及./main.tf中包含的以下内容:

    module "vpc" {
      source = "./vpc"
    }
    
    module "rds" {
      source = "./rds"
      vpc_id = module.vpc.vpc_id
      subnet_ids = [ module.vpc.subnet_a_id , module.vpc.subnet_b_id, module.vpc.subnet_c_id ]
    }
    

    ...模块rds 中使用var.vpc_id var.subnet_ids 的任何资源都将等到vpc 模块输出这些资源。

    【讨论】:

    • 这里的问题是模块边界没有任何影响。正如您所说,terraform 将等到它们的输出准备好。对于此处描述的问题,没有什么会延迟或可能会延迟读取输出。 time_sleep 是确保容器有机会初始化所必需的,但该事件根本不会生成任何值。所以在这个问题中,depends_on 已经被用作最后的手段,因此是不可避免的。
    • 您是否按照registry.terraform.io/providers/hashicorp/time/latest/docs/… 中的描述在time_sleep @PhilipCouling 中使用时间值?
    • 如问题中所述,当事物不分为模块时,这一切都有效。当 rabbitmq 资源直接依赖于 time_sleep 时,此方法有效。但是当我将这些资源移动到一个模块中时,它们不能直接依赖于模块之外的东西。我试图通过使 module 依赖于相同的time_sleep 来解决这个问题,但如上所述,这不起作用。 短版; time_sleep 配置正确。
    • @PhilipCouling -- 只是我,还是这里有循环依赖?容器模块输出"remote_host"depends_on rabbitmq 模块。而 rabbitmq 模块又在其属性之一中消耗{module.container.remote_host},因此隐式依赖于容器模块。我想知道这是否可以通过 Terraform 完成后的脚本来解决,有点像:stackoverflow.com/a/49743473/9754418
    • 这里没有循环依赖。 rabbitmq 配置依赖于 rabbitmq 容器。再一次,我没有将任何东西包装在一个模块中就可以让这一切正常工作。但是 terraform 似乎并没有正确遵守模块的依赖关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    相关资源
    最近更新 更多