使用 terraform 的 Route 53 故障转移策略

Posted

技术标签:

【中文标题】使用 terraform 的 Route 53 故障转移策略【英文标题】:Route 53 failover policy with terraform 【发布时间】:2019-03-26 04:44:52 【问题描述】:

我尝试使用 terraform 在 AWS 上为域创建故障转移策略,问题是它在 route53 资源后面仅附加一个 elb dns 名称作为 PRIMARY 和 SECONDARY。我实际上希望它使用 North-Virginia elb 名称作为 PRIMARY,俄勒冈州作为 SECONDARY。

这是一个多区域架构,我创建了具有相同源目录的模块。

文件名:route53.tf

resource "aws_route53_record" "www1" 
  zone_id = "Zone-ID"
  name    = "www1"
  type    = "A"
  #ttl     = "5"

  failover_routing_policy 
    type = "PRIMARY"
  

  set_identifier = "www1"
  #records        = ["$aws_elb.web.dns_name"]
  alias 
    name                   = "$aws_elb.web.dns_name"
    zone_id                = "$aws_elb.web.zone_id"
    evaluate_target_health = true
  


resource "aws_route53_record" "www2" 
  zone_id = "Zone-ID"
  name    = "www2"
  type    = "A"
  #ttl     = "5"

  failover_routing_policy 
    type = "SECONDARY"
  

  set_identifier = "www2"
  #records        = ["$aws_elb.web.dns_name"]
  alias 
    name                   = "$aws_elb.web.dns_name"
    zone_id                = "$aws_elb.web.zone_id"
    evaluate_target_health = true
  

文件名:alb_elb.tf

resource "aws_elb" "web" 
  name               = "web-elb"
  availability_zones = "$var.az"

  listener 
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  

  health_check 
    healthy_threshold   = 2
    unhealthy_threshold = 2
    timeout             = 3
    target              = "HTTP:8000/"
    interval            = 30
  

  instances                   = ["$aws_instance.web.*.id"]
  cross_zone_load_balancing   = true
  idle_timeout                = 400
  connection_draining         = true
  connection_draining_timeout = 400

  tags 
    Name = "foobar-terraform-elb"
  

文件名:main.tf。

module "north-virginia" 
  source = "./modules/production"
  region = "us-east-1"
  az = ["us-east-1a", "us-east-1b", "us-east-1c"]


module "oregon" 
  source = "./modules/production"
  region = "us-west-2"
  az = ["us-west-2a", "us-west-2b", "us-west-2c"]

文件名:./production/module/main.tf

variable region  

variable az  
type = "list" 


provider "aws" 
  region = "$var.region"
  profile = "personal"
  shared_credentials_file = "~/.aws/credentials"


data "aws_caller_identity" "current" 

output "account_id" 
  value = "$data.aws_caller_identity.current.account_id"

目录树:

.
├── main.tf
└── modules
    ├── dev
    │   ├── ec2.tf
    │   ├── main.tf
    │   └── route53.tf
    ├── production
    │   ├── aws_elb.tf
    │   ├── aws_instance.tf
    │   ├── main.tf
    │   └── route53.tf
    └── qa
        ├── ec2.tf
        ├── main.tf
        └── route53.tf

【问题讨论】:

这个问题没有提供足够的信息来帮助回答它。你能在这里展示一个更完整的例子吗?查看所有相关(但仅此而已) Terraform 代码以及代码库的任何特定结构将有所帮助。现在我们还需要看看您是如何创建两个 ELB 的,因为您的示例似乎显示了 2 个完全独立的 DNS 记录,其中主集和辅助集(不正确)并且都指向同一个 ELB。如果您尝试创建minimal reproducible example,我建议您先运行它以检查它是否存在与您的真实代码相同的问题 我已经为 elb 和 main.tf 添加了代码。 alb_elb.tfroute53.tf 都在模块中吗?你在用 region 变量做什么?您是否也使用它来配置提供程序块?你也可以展示那部分吗? 是的,它们是模块的一部分。我正在使用区域变量从要与模块一起使用的 main.tf 获取区域名称。是的,我将它与提供程序块一起使用。我已经用目录树和 main.tf 更新了问题。 【参考方案1】:

在您的 production/alb_elb.tf 中添加以下内容:

output "dns_name" 
value = "$aws_elb.web.dns_name"

这将输出 DNS 名称。 在您的 main.tf 中为 route53 创建一个单独的模块。 该模块应如下所示:

module "route53" 
  source = "./modules/route53"
  name1 = "$module.north-virginia.dns_name"
  name2 = "$module.oregon.dns_name"

您的 route53.tf 应该类似于:

variable "name1" ()
varibale "name2" ()
resource "aws_route53_record" "www1" 
  zone_id = "Zone-ID"
  name    = "www1"
  type    = "A"
  #ttl     = "5"

  failover_routing_policy 
    type = "PRIMARY"
  

  set_identifier = "www1"
  #records        = ["$aws_elb.web.dns_name"]
  alias 
    name                   = "$var.name1"
    zone_id                = "$aws_elb.web.zone_id"
    evaluate_target_health = true
  


resource "aws_route53_record" "www2" 
  zone_id = "Zone-ID"
  name    = "www2"
  type    = "A"
  #ttl     = "5"

  failover_routing_policy 
    type = "SECONDARY"
  

  set_identifier = "www2"
  #records        = ["$aws_elb.web.dns_name"]
  alias 
    name                   = "$var.name2"
    zone_id                = "$aws_elb.web.zone_id"
    evaluate_target_health = true
  

【讨论】:

以上是关于使用 terraform 的 Route 53 故障转移策略的主要内容,如果未能解决你的问题,请参考以下文章

Terraform - 找不到匹配的 Route53Zone

terraform - 如何为 DNS 创建 Route53?

使用 terraform 在 route53 上获取托管域的 zone_id

使用 Terraform 创建多个 DNS Route53 A 记录

在 aws_route53_record terraform 资源中使用“计数”

Terraform 与 A​​PI-Gateway、Route53 和 SSL 认证相互依赖问题