You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Terraform中遵循DRY原则优化重复的Contact配置块

精简Terraform Route53域名配置的几种方法

针对你配置中重复的registrant_contact、admin_contact和tech_contact块,有以下几种精简方案:

方案一:结合For_Each与Dynamic块批量管理域名

如果你的域名数量较多,可以将域名列表统一管理,通过单个资源块结合Dynamic生成重复的Contact配置:

locals {
  contact = {
    address_line_1 = "Berlin"
    city           = "Berlin"
    contact_type   = "PERSON"
    country_code   = "DE"
    email          = var.aws_billing_mails[0]
    first_name     = "Foo"
    last_name      = "Bar"
    zip_code       = "12345"
    phone_number   = "+49.123456789"
  }
  # 统一管理所有需要注册的域名
  domains = {
    my_domain       = "mydomain.com"
    my_other_domain = "myotherdomain.com"
  }
}

resource "aws_route53domains_registered_domain" "all_domains" {
  for_each = local.domains

  domain_name        = each.value
  auto_renew         = true
  transfer_lock      = true
  registrant_privacy = true
  admin_privacy      = true
  tech_privacy       = true

  # 动态生成registrant_contact块
  dynamic "registrant_contact" {
    for_each = [local.contact]
    content {
      address_line_1 = registrant_contact.value.address_line_1
      city           = registrant_contact.value.city
      contact_type   = registrant_contact.value.contact_type
      country_code   = registrant_contact.value.country_code
      email          = registrant_contact.value.email
      first_name     = registrant_contact.value.first_name
      last_name      = registrant_contact.value.last_name
      zip_code       = registrant_contact.value.zip_code
      phone_number   = registrant_contact.value.phone_number
    }
  }

  # 动态生成admin_contact块
  dynamic "admin_contact" {
    for_each = [local.contact]
    content {
      address_line_1 = admin_contact.value.address_line_1
      city           = admin_contact.value.city
      contact_type   = admin_contact.value.contact_type
      country_code   = admin_contact.value.country_code
      email          = admin_contact.value.email
      first_name     = admin_contact.value.first_name
      last_name      = admin_contact.value.last_name
      zip_code       = admin_contact.value.zip_code
      phone_number   = admin_contact.value.phone_number
    }
  }

  # 动态生成tech_contact块
  dynamic "tech_contact" {
    for_each = [local.contact]
    content {
      address_line_1 = tech_contact.value.address_line_1
      city           = tech_contact.value.city
      contact_type   = tech_contact.value.contact_type
      country_code   = tech_contact.value.country_code
      email          = tech_contact.value.email
      first_name     = tech_contact.value.first_name
      last_name      = tech_contact.value.last_name
      zip_code       = tech_contact.value.zip_code
      phone_number   = tech_contact.value.phone_number
    }
  }
}

方案二:用模块封装重复逻辑

将域名注册的通用逻辑封装为模块,后续新增域名只需调用模块传入参数即可:

步骤1:创建模块文件

在项目目录下新建modules/route53_domain/main.tf,内容如下:

variable "domain_name" {
  type        = string
  description = "要注册的域名"
}

variable "contact" {
  type = object({
    address_line_1 = string
    city           = string
    contact_type   = string
    country_code   = string
    email          = string
    first_name     = string
    last_name      = string
    zip_code       = string
    phone_number   = string
  })
  description = "域名联系人信息"
}

resource "aws_route53domains_registered_domain" "domain" {
  domain_name        = var.domain_name
  auto_renew         = true
  transfer_lock      = true
  registrant_privacy = true
  admin_privacy      = true
  tech_privacy       = true

  registrant_contact {
    address_line_1 = var.contact.address_line_1
    city           = var.contact.city
    contact_type   = var.contact.contact_type
    country_code   = var.contact.country_code
    email          = var.contact.email
    first_name     = var.contact.first_name
    last_name      = var.contact.last_name
    zip_code       = var.contact.zip_code
    phone_number   = var.contact.phone_number
  }

  admin_contact {
    address_line_1 = var.contact.address_line_1
    city           = var.contact.city
    contact_type   = var.contact.contact_type
    country_code   = var.contact.country_code
    email          = var.contact.email
    first_name     = var.contact.first_name
    last_name      = var.contact.last_name
    zip_code       = var.contact.zip_code
    phone_number   = var.contact.phone_number
  }

  tech_contact {
    address_line_1 = var.contact.address_line_1
    city           = var.contact.city
    contact_type   = var.contact.contact_type
    country_code   = var.contact.country_code
    email          = var.contact.email
    first_name     = var.contact.first_name
    last_name      = var.contact.last_name
    zip_code       = var.contact.zip_code
    phone_number   = var.contact.phone_number
  }
}

步骤2:在根模块中调用模块

locals {
  contact = {
    address_line_1 = "Berlin"
    city           = "Berlin"
    contact_type   = "PERSON"
    country_code   = "DE"
    email          = var.aws_billing_mails[0]
    first_name     = "Foo"
    last_name      = "Bar"
    zip_code       = "12345"
    phone_number   = "+49.123456789"
  }
}

module "my_domain" {
  source      = "./modules/route53_domain"
  domain_name = "mydomain.com"
  contact     = local.contact
}

module "my_other_domain" {
  source      = "./modules/route53_domain"
  domain_name = "myotherdomain.com"
  contact     = local.contact
}

方案三:简化单个资源内的Contact块

如果不想用模块或批量管理,也可以在单个资源内用Dynamic块减少重复代码:

locals {
  contact = {
    address_line_1 = "Berlin"
    city           = "Berlin"
    contact_type   = "PERSON"
    country_code   = "DE"
    email          = var.aws_billing_mails[0]
    first_name     = "Foo"
    last_name      = "Bar"
    zip_code       = "12345"
    phone_number   = "+49.123456789"
  }
}

resource "aws_route53domains_registered_domain" "my_domain" {
  domain_name        = "mydomain.com"
  auto_renew         = true
  transfer_lock      = true
  registrant_privacy = true
  admin_privacy      = true
  tech_privacy       = true

  dynamic "registrant_contact" {
    for_each = [local.contact]
    content {
      address_line_1 = registrant_contact.value.address_line_1
      city           = registrant_contact.value.city
      contact_type   = registrant_contact.value.contact_type
      country_code   = registrant_contact.value.country_code
      email          = registrant_contact.value.email
      first_name     = registrant_contact.value.first_name
      last_name      = registrant_contact.value.last_name
      zip_code       = registrant_contact.value.zip_code
      phone_number   = registrant_contact.value.phone_number
    }
  }

  dynamic "admin_contact" {
    for_each = [local.contact]
    content {
      address_line_1 = admin_contact.value.address_line_1
      city           = admin_contact.value.city
      contact_type   = admin_contact.value.contact_type
      country_code   = admin_contact.value.country_code
      email          = admin_contact.value.email
      first_name     = admin_contact.value.first_name
      last_name      = admin_contact.value.last_name
      zip_code       = admin_contact.value.zip_code
      phone_number   = admin_contact.value.phone_number
    }
  }

  dynamic "tech_contact" {
    for_each = [local.contact]
    content {
      address_line_1 = tech_contact.value.address_line_1
      city           = tech_contact.value.city
      contact_type   = tech_contact.value.contact_type
      country_code   = tech_contact.value.country_code
      email          = tech_contact.value.email
      first_name     = tech_contact.value.first_name
      last_name      = tech_contact.value.last_name
      zip_code       = tech_contact.value.zip_code
      phone_number   = tech_contact.value.phone_number
    }
  }
}

内容的提问来源于stack exchange,提问作者msdundar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:10:23