如何在地形工作区(DNS)之间访问资源?

如何在地形工作区(DNS)之间访问资源?,dns,google-cloud-platform,terraform,google-cloud-dns,Dns,Google Cloud Platform,Terraform,Google Cloud Dns,我的基础架构有3个环境。它们都一样,但大小不一。我知道这是一个很好的地形工作区用例。事实上,它在这方面运作良好。但如果这不是正确的方法,请纠正我 现在我唯一的问题是在工作区内管理DNS。我使用Google provider,它通过两种类型的资源工作:一种是表示区域的Google\u dns\u managed\u zone,另一种是每个dns记录的Google\u dns\u record\u set类型。 请注意,记录集类型需要有对托管区域类型的引用 考虑到这一点,我需要从生产环境管理DNS区

我的基础架构有3个环境。它们都一样,但大小不一。我知道这是一个很好的地形工作区用例。事实上,它在这方面运作良好。但如果这不是正确的方法,请纠正我

现在我唯一的问题是在工作区内管理DNS。我使用Google provider,它通过两种类型的资源工作:一种是表示区域的
Google\u dns\u managed\u zone
,另一种是每个dns记录的
Google\u dns\u record\u set
类型。
请注意,记录集类型需要有对托管区域类型的引用

考虑到这一点,我需要从生产环境管理DNS区域。我无法在其他工作区中共享该资源,因为我应该能够在不破坏DNS区域的情况下销毁开发或临时工作区。
我试图用
count
解决这个问题。我使用它作为一个布尔值,如下面的代码所示,并发现它相当粗糙,但这就是我在Terraform社区中发现的。欢迎任何改进。
这允许我将区域和生产记录(如下图所示的MX)仅显示在prod工作区中

但当涉及到仅在特定工作区中管理记录集时,我就被卡住了。例如,在dev工作区中创建nginx并自动为其创建DNS记录集(如dev.example.com)时,我就需要它。
为此,我需要访问托管区域资源。如下所示,我使用
terraform\u remote\u state
从prod工作区访问资源。就我的理解而言,这适用于
输出
,如下所示。当我选择prod工作区时,我确实可以输出托管区域。然后,如果我选择了另一个工作区,使用远程状态将成功地从prod检索托管区域。但我的问题是Terraform在
输出
行失败,因为它只存在于prod工作区中,不存在于任何其他工作区中,因此无法输出

所以这有点胡说八道,我不明白是否有更好的方法来实现这一点。我做了一些调查,询问了社区,但没有找到答案。在我看来,管理DNS对于所有基础设施来说都是通用的,应该很好地加以涵盖。我做错了什么?应该怎么做

locals {
  environment="${terraform.workspace}"

  dns_zone_managers = {
    "dev"     = "0"
    "staging" = "0"
    "prod"    = "1"
}

  dns_zone_manager = "${lookup(local.dns_zone_managers, local.environment)}"
}

resource "google_dns_managed_zone" "base_zone" {                                                                                                                                               
  name     = "base_zone"                                                                                                                                                               
  dns_name = "example.com."                                                                                                                                                                    
  count = "${local.dns_zone_manager}"                                                                                                                                                          
}                                                                                                                                                                                              

resource "google_dns_record_set" "mx" {                                                                                                                                                        
  name = "${google_dns_managed_zone.base_zone.dns_name}"                                                                                                                                       
  managed_zone = "${google_dns_managed_zone.base_zone.name}"                                                                                                                                   
  type = "MX"                                                                                                                                                                                  
  ttl  = 300                                                                                                                                                                                   

  rrdatas = [                                                                                                                                                                                  
    "10 spool.mail.example.com.",                                                                                                                                                                
    "50 fb.mail.example.com."                                                                                                                                                                    
  ]                                                                                                                                                                                            
  count = "${local.dns_zone_manager}"                                                                                                                                                          
}

data "terraform_remote_state" "dns" {
    backend = "local"
    workspace = "prod"
}

output "dns_zone_name" {
  value = "${google_dns_managed_zone.base_zone.*.name[0]}"
}
然后,我可以仅在特定工作区中引入记录集,再次使用
count
,并通过远程状态引用托管区域,如下所示:

resource "google_dns_record_set" "a" {
  name = "dev"
  managed_zone = "${data.terraform_remote_state.dns.dns_zone_name}"
  type = "A"
  ttl  = 300

  rrdatas = ["1.2.3.4"]
}

过去我通过为所有根级资源(如dns)创建一个根地形项目来解决这个问题。然后,另一个项目可以导入terraform_remote_状态。隔离某些基础设施是一个好主意,以减少出现问题时的影响。例如dns、db、compute。所以,如果为compute部署了一个糟糕的地形配置,它将不会影响关键基础设施,如db和dns。作为奖励,它使管理根dns更容易,因为您不需要多个环境。谢谢@CalebMacdonaldBlack,听起来很有趣。你愿意把你的评论扩展成一个答案吗?@Bastian看一看,我过去已经通过为所有根级资源(如dns)创建一个根地形项目解决了这个问题。然后,另一个项目可以导入terraform_remote_状态。隔离某些基础设施是一个好主意,以减少出现问题时的影响。例如dns、db、compute。所以,如果为compute部署了一个糟糕的地形配置,它将不会影响关键基础设施,如db和dns。作为奖励,它使管理根dns更容易,因为您不需要多个环境。谢谢@CalebMacdonaldBlack,听起来很有趣。你愿意把你的评论扩展成一个答案吗?@Bastian看一看