【问题标题】:Deterministic name server addresses确定性名称服务器地址
【发布时间】:2020-07-04 11:50:37
【问题描述】:

使用 AWS,我如何在 terraform 应用/销毁执行之间获得确定性名称服务器地址?

目前,我的名称服务器是这样的:

ns-XXX.awsdns-YY.com. 
ns-XXX.awsdns-YY.org. 
ns-XXX.awsdns-YY.net. 
ns-XXX.awsdns-YY.co.uk.

每次我运行应用/销毁时,XXXYY 的值都会发生变化。

所以如果我有一个在 godaddy/namecheap/other 注册的域,那么这些也需要更新,这需要时间来传播。

所以我想知道有没有办法影响 XXX/YY 的值是什么,以便它们可以在会话之间持续存在?

例如,我尝试了这个,虽然它设置了我想要的名称服务器,但不幸的是它无法解析。

resource "aws_route53_record" "ns" {
  allow_overwrite = true
  name            = "my_fixed_ns"
  ttl             = 30
  type            = "NS"
  zone_id         = aws_route53_zone.zone.zone_id
  records         = [
    "ns1.amazon.com",
    "ns2.amazon.org",
    "ns3.amazon.net",
    "ns4.amazon.co.uk"
  ]
}

【问题讨论】:

  • 我会将它移到一个单独的 terraform 模板中,您不会经常破坏它。
  • @markB 谢谢,是的,这基本上就是我最终要做的。

标签: amazon-web-services terraform amazon-route53 terraform-provider-aws


【解决方案1】:

您可以使用reusable delegation sets 使 Route53 区域对每个区域使用相同的名称服务器,无论是多个并发区域还是一遍又一遍地重建区域:

一组四个权威名称服务器,可用于多个托管区域。默认情况下,Route 53 将随机选择的名称服务器分配给每个新的托管区域。为了更轻松地将大量域的 DNS 服务迁移到 Route 53,您可以创建一个可重用的委派集,然后将可重用的委派集与新的托管区域相关联。 (您无法更改与现有托管区域关联的名称服务器。)

在 Terraform 中,这些是使用 aws_route53_delegation_set resource 创建的,文档中给出的示例如下所示:

resource "aws_route53_delegation_set" "main" {
  reference_name = "DynDNS"
}

resource "aws_route53_zone" "primary" {
  name              = "hashicorp.com"
  delegation_set_id = aws_route53_delegation_set.main.id
}

resource "aws_route53_zone" "secondary" {
  name              = "terraform.io"
  delegation_set_id = aws_route53_delegation_set.main.id
}

如果您要销毁区域并重建它们并想要相同的名称服务器,那么您需要确保不要同时销毁委托集。

如果您只想选择区域,可以通过运行 terraform destroy -target aws_route53_zone.example 来实现。

或者,您可以在一个目录中创建委托集,然后在单独的目录中创建 Route53 区域(以及其他任何内容),而不破坏委托集资源目录。所以你会有这样的东西:

.
├── delegation-set
│   └── delegation-set.tf
└── route53-zone
    └── route53-zone.tf


### delegation-set.tf

resource "aws_route53_delegation_set" "example" {
  reference_name = "Example"
}

output "delegation_set_id" {
  value = aws_route53_delegation_set.example.id
}

### route53-zone.tf

data "aws_route53_delegation_set" "example" {
  id = "INSERT_DELEGATION_SET_ID_HERE"
}

resource "aws_route53_zone" "example" {
  name              = "example.com"
  delegation_set_id = data.aws_route53_delegation_set.example.id
}

不幸的是,正如您在上面的示例中看到的那样,aws_route53_delegation_set data source 仅获取委托集的 ID 而不能为其提供调用者引用,因此您需要对生成和输出的引用 ID 进行硬编码运行terraform apply delegation-set

您也可以使用terraform_remote_state data source 代替aws_route53_delegation_set 数据源:

### route53-zone.tf

data "terraform_remote_state" "delegation_set" {
  backend = "remote"

  config = {
    organization = "example"
    workspaces = {
      name = "delegation-set"
    }
  }
}

resource "aws_route53_zone" "example" {
  name              = "example.com"
  delegation_set_id = data.terraform_remote_state.delegation_set.id
}

上述配置需要适应您存储状态的方式。

【讨论】:

  • 已经尝试过了,重建区域会产生不同的名称服务器
  • 你每次都要删除委托集吗?这将重置名称服务器。您需要保留委托,然后在您正在应用和销毁 Route53 区域的位置使用 delegation set data source 引用它。
  • 是的,我结束了将委托集拆分为单独的状态(称为 state1),存储在 S3 远程,然后在项目中(称为状态 2),引用状态的输出1. 这样我就可以部署 state1 并让它持续存在,然后根据需要应用/销毁 state2。
  • 我已经更新了答案,提供了一个更长、更有效的示例,说明如何处理销毁和重建区域以及在每个重建周期中保持名称服务器相同。
  • 我有大约 5 分钟的 Terraform 经验,所以我仍然在拼凑石头,但我相信行中的第一个点 value = aws_route53.delegation_set.example.id 靠近中间第二个示例代码应该是一个下划线。请告诉我这只是一个错字,我实际上开始了解一些关于 Terraform 的事情 ;-)
猜你喜欢
  • 2015-07-27
  • 1970-01-01
  • 2018-05-23
  • 2021-12-05
  • 2018-03-20
  • 1970-01-01
  • 2013-12-17
  • 1970-01-01
  • 2013-03-27
相关资源
最近更新 更多