This question was originally asked on Stackoverflow.
I would like to understand when it is recommended to use terraform_remote_state
over common data filter approaches.
I see cases like images, which are not managed by another terraform state in which case the obvious (and only) choice are data filters. However, in most cases I could choose between terraform_remote_state
and other data filters. I could not find an official recommendation on that matter.
Let’s take an example (The following code does not run as is and is simplified to only show the main idea):
Let us assume we have a central component with its own state/workspace
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
}
....
Option 1: Whitelist vault cidr in another tf workspace with data filters
postgres/main.tf:
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
}
Option 2: Whitelist vault cidr in another tf workspace with terraform_remote_state
postgres/main.tf:
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
}
Personally, I prefer terraform_remote_state
because it feels less ambiguous and more declarative from a module perspective (i.e., you consciously declare output variables that should be used by other workspaces). However, I’m interested if there are solid reasons against it or if there are some best practices I’m not aware of.
Is there an officially recommended way for scenarios like that?