如何在 Terraform 中获取在另一个模块中创建的 LB 名称(用于创建 DNS 记录)

How in Terraform to get a LB name created in another module (for a DNS records' creation)

我正在使用 Terraform (v. 12.10) 创建一个 DNS 记录 AWS 并且想要获取已经创建的 ALB 的名称(在另一个模块中)。

我已阅读文档但未找到任何解决方案。有什么办法吗?

resource "aws_route53_record" "dns" {
  provider        = <AWS>
  zone_id         = <ZONE_ID>
  name            = <NAME>
  ttl             = 30
  type            = "CNAME"
  records         = <LB_created_previously>
}

模块定义

$ cat module/out.tf
output "somevar" {
value = "somevalue"
}

使用模块:

$ cat main.tf
module "getname" {
source = "./module"
}
resource "aws_sns_topic" "user_updates" {
  name = module.getname.somevar
}


目录结构:

$ tree
.
├── main.tf
├── module
│   └── out.tf
└── terraform.tfstate

terraform apply

$ terraform  apply

..
  + create

Terraform will perform the following actions:

  # aws_sns_topic.user_updates will be created
  + resource "aws_sns_topic" "user_updates" {
      + arn    = (known after apply)
      + id     = (known after apply)
      + name   = "somevalue"
      + policy = (known after apply)
    }

...

  Enter a value: yes

aws_sns_topic.user_updates: Creating...
aws_sns_topic.user_updates: Creation complete after 1s [id=arn:aws:sns:us-east-1:123456789:somevalue]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Module Composition

这里基本上有两种选择。

选项 1 - 如果你的资源创建(在你的情况下是 DNS 记录)和模块创建的 ALB 在同一个地方(相同的 terraform.tfstate 文件) - 这或多或少被 samtoddler 上面的答案或你的伪代码看起来像这样:

resource "aws_route53_record" "dns" {
  provider        = <AWS>
  zone_id         = <ZONE_ID>
  name            = <NAME>
  ttl             = 30
  type            = "CNAME"
  records         = [module.<LB__module_definiton_name>.elb_dns_name]
}

在您的 ELB 模块中,您需要像这样的东西:

output "elb_dns_name" {
value = aws_elb.<LB_created_previously>.dns_name
}

在选项二中,您必须在模块本身中定义相同的输出。 但是,如果您的 DNS 资源代码处于不同的文件夹/terraform 状态,您将需要求助于 terraform 远程状态:

data "terraform_remote_state" "elb" {
  backend = "mybackendtype"
  config = {
    ...
  }
}

然后您的代码将如下所示:

resource "aws_route53_record" "dns" {
  provider        = <AWS>
  zone_id         = <ZONE_ID>
  name            = <NAME>
  ttl             = 30
  type            = "CNAME"
  records         = [data.terraform_remote_state.elb.outputs.elb_dns_name]
}

顺便说一句,当你有 ELB 时,最好使用 Alias instead of a CNAME record, which based on the terraform documentation for the dns records resource,你的伪代码将是:

resource "aws_route53_record" "dns" {
  zone_id         = <ZONE_ID>
  name            = <NAME>
  type    = "A"

  alias {
    name                   = module.<LB__module_definiton_name>.elb_dns_name
    zone_id                = module.<LB__module_definiton_name>.elb_zone_id
    evaluate_target_health = true
  }
}