通过公共数据过滤器使用terraform_远程_状态

通过公共数据过滤器使用terraform_远程_状态,terraform,Terraform,我想了解什么时候建议使用terraform\u remote\u state而不是常用的数据过滤方法 我看到像图像这样的情况,它们不是由另一个地形状态管理的,在这种情况下,显而易见的(也是唯一的)选择是数据过滤器。 然而,在大多数情况下,我可以在terraform\u remote\u state和其他数据过滤器之间进行选择。我找不到关于这件事的正式建议 让我们举个例子 (以下代码不是按原样运行的,而是简化为仅显示主要思想): 假设我们有一个具有自己状态/工作区的中心组件 vault/main.

我想了解什么时候建议使用
terraform\u remote\u state
而不是常用的数据过滤方法

我看到像图像这样的情况,它们不是由另一个地形状态管理的,在这种情况下,显而易见的(也是唯一的)选择是数据过滤器。 然而,在大多数情况下,我可以在
terraform\u remote\u state
和其他数据过滤器之间进行选择。我找不到关于这件事的正式建议

让我们举个例子 (以下代码不是按原样运行的,而是简化为仅显示主要思想):

假设我们有一个具有自己状态/工作区的中心组件

vault/main.tf:

terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "vault/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

resource "openstack_networking_subnetpool_v2" "vault" {
  name              = "vault"
  prefixes          = ["10.1.0.0/16"]
  min_prefixlen     = 24
  default_prefixlen = 24
}

resource "openstack_networking_network_v2" "vault" {
  name           = "vault"
}

resource "openstack_networking_subnet_v2" "vault" {
  name            = "vault"
  network_id      = openstack_networking_network_v2.vault.id
  subnetpool_id   = openstack_networking_subnetpool_v2.vault.id
}

// Make cidr available for terraform_remote_state approach
output "cidr" {
  value = openstack_networking_subnet_v2.vault.cidr
}

....
terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "postgres/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

data "openstack_identity_project_v3" "vault" {
  // assuming vault is setup in its own project
  name = "vault"
}

data "openstack_networking_network_v2" "vault" {
  name      = "vault"
  tenant_id = data.openstack_identity_project_v3.vault.id
}

data "openstack_networking_subnet_v2" "vault" {
  name      = "vault"
  tenant_id = data.openstack_identity_project_v3.vault.id
}

resource "openstack_networking_secgroup_v2" "postgres" {
  name        = "postgres"
  description = "Allow vault connection"
}

resource "openstack_networking_secgroup_rule_v2" "allow-vault" {
  direction         = "ingress"
  ethertype         = "IPv4"
  security_group_id = openstack_networking_secgroup_v2.postgres.id
  remote_ip_prefix  = data.openstack_networking_subnet_v2.vault.cidr 
}
terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "postgres/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

data "terraform_remote_state" "vault" {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "vault/all.tfstate"
  }
}

resource "openstack_networking_secgroup_v2" "postgres" {
  name        = "postgres"
  description = "Allow vault connection"
}

resource "openstack_networking_secgroup_rule_v2" "allow-vault" {
  direction         = "ingress"
  ethertype         = "IPv4"
  security_group_id = openstack_networking_secgroup_v2.postgres.id
  remote_ip_prefix  = data.terraform_remote_state.vault.cidr 
}

选项1:在另一个tf工作区中使用数据筛选器将vault cidr列入白名单 postgres/main.tf:

terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "vault/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

resource "openstack_networking_subnetpool_v2" "vault" {
  name              = "vault"
  prefixes          = ["10.1.0.0/16"]
  min_prefixlen     = 24
  default_prefixlen = 24
}

resource "openstack_networking_network_v2" "vault" {
  name           = "vault"
}

resource "openstack_networking_subnet_v2" "vault" {
  name            = "vault"
  network_id      = openstack_networking_network_v2.vault.id
  subnetpool_id   = openstack_networking_subnetpool_v2.vault.id
}

// Make cidr available for terraform_remote_state approach
output "cidr" {
  value = openstack_networking_subnet_v2.vault.cidr
}

....
terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "postgres/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

data "openstack_identity_project_v3" "vault" {
  // assuming vault is setup in its own project
  name = "vault"
}

data "openstack_networking_network_v2" "vault" {
  name      = "vault"
  tenant_id = data.openstack_identity_project_v3.vault.id
}

data "openstack_networking_subnet_v2" "vault" {
  name      = "vault"
  tenant_id = data.openstack_identity_project_v3.vault.id
}

resource "openstack_networking_secgroup_v2" "postgres" {
  name        = "postgres"
  description = "Allow vault connection"
}

resource "openstack_networking_secgroup_rule_v2" "allow-vault" {
  direction         = "ingress"
  ethertype         = "IPv4"
  security_group_id = openstack_networking_secgroup_v2.postgres.id
  remote_ip_prefix  = data.openstack_networking_subnet_v2.vault.cidr 
}
terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "postgres/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

data "terraform_remote_state" "vault" {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "vault/all.tfstate"
  }
}

resource "openstack_networking_secgroup_v2" "postgres" {
  name        = "postgres"
  description = "Allow vault connection"
}

resource "openstack_networking_secgroup_rule_v2" "allow-vault" {
  direction         = "ingress"
  ethertype         = "IPv4"
  security_group_id = openstack_networking_secgroup_v2.postgres.id
  remote_ip_prefix  = data.terraform_remote_state.vault.cidr 
}

选项2:将另一个tf工作区中具有terraform_remote_状态的vault cidr列入白名单 postgres/main.tf:

terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "vault/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

resource "openstack_networking_subnetpool_v2" "vault" {
  name              = "vault"
  prefixes          = ["10.1.0.0/16"]
  min_prefixlen     = 24
  default_prefixlen = 24
}

resource "openstack_networking_network_v2" "vault" {
  name           = "vault"
}

resource "openstack_networking_subnet_v2" "vault" {
  name            = "vault"
  network_id      = openstack_networking_network_v2.vault.id
  subnetpool_id   = openstack_networking_subnetpool_v2.vault.id
}

// Make cidr available for terraform_remote_state approach
output "cidr" {
  value = openstack_networking_subnet_v2.vault.cidr
}

....
terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "postgres/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

data "openstack_identity_project_v3" "vault" {
  // assuming vault is setup in its own project
  name = "vault"
}

data "openstack_networking_network_v2" "vault" {
  name      = "vault"
  tenant_id = data.openstack_identity_project_v3.vault.id
}

data "openstack_networking_subnet_v2" "vault" {
  name      = "vault"
  tenant_id = data.openstack_identity_project_v3.vault.id
}

resource "openstack_networking_secgroup_v2" "postgres" {
  name        = "postgres"
  description = "Allow vault connection"
}

resource "openstack_networking_secgroup_rule_v2" "allow-vault" {
  direction         = "ingress"
  ethertype         = "IPv4"
  security_group_id = openstack_networking_secgroup_v2.postgres.id
  remote_ip_prefix  = data.openstack_networking_subnet_v2.vault.cidr 
}
terraform {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "postgres/all.tfstate"
  }
}

provider "openstack" {
  version     = "1.19"
  cloud       = "openstack"
}

data "terraform_remote_state" "vault" {
  backend "azurerm" {
    storage_account_name = "tfstates"
    container_name       = "tfstates"
    key                  = "vault/all.tfstate"
  }
}

resource "openstack_networking_secgroup_v2" "postgres" {
  name        = "postgres"
  description = "Allow vault connection"
}

resource "openstack_networking_secgroup_rule_v2" "allow-vault" {
  direction         = "ingress"
  ethertype         = "IPv4"
  security_group_id = openstack_networking_secgroup_v2.postgres.id
  remote_ip_prefix  = data.terraform_remote_state.vault.cidr 
}
就我个人而言,我更喜欢
terraform\u remote\u state
,因为从模块的角度看,它感觉不那么模棱两可,更具声明性(即,您有意识地声明其他工作区应该使用的输出变量)。然而,我感兴趣的是是否有充分的理由反对它,或者是否有一些我不知道的最佳实践

对于这样的场景,有官方推荐的方法吗?

在HashiCorp讨论论坛上给出了很好的建议

然而,他没有就这一主题作出回应,因此我用自己的话总结了要点,以便完成


适当的HashiCorp方法是第三种选择:将参数写入配置存储,如concur

这有多种好处:

  • 您可以控制向其他工具公开的内容 (问题选项2的好处:明确发布)
  • 您在地形工作区之间没有紧密耦合(问题选项1的好处:解耦)。即,可变生产者与可变消费者解耦
  • 其他工具,包括Terraform本身,可以在以后使用这些值


  • 我建议你读这本书,因为它更深入

    直接接触hashicorp社区: