Integrating Remote and Local State - GlennChia/terraform-azurerm-caf GitHub Wiki
The file that is responsible for merging the local and remote state is locals.combined_objects.tf
. This guide comprises the Application
section which shows how to use the combined object in a module and the Background
section which shows
Application
This seciton covers the pattern on how to use the combined_object in the module.
First, understand the attributes provided by the resource_groups
object. These attributes are:
- name
- location
- tags
- rbac_id
- id
Now, several possible patterns emerge depending on the number of attributes that the module needs to reference
Reference one attribute
For example, if a module requires only the attribute name
and maps it to resource_group_name
, then we opt to destructure the combined objects at the module level. Example:
module "example" {
source = "./modules/some_module/example"
for_each = local.some_module.example
name = each.value.name
resource_group_name = local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.resource_group_key].name
}
Then in the modules
directory, for that specific resource, create a variables.tf
that expects this resource_group_name
variable "resource_group_name" {
description = "Name of the existing resource group to deploy the virtual machine"
}
Then this variable is easily referenced in the resource's .tf
file
resource_group_name = var.resource_group_name
Reference multiple attributes
For example, a module may require the tags
, location
, and name
attribute. In this case, we opt to destructure the combined ibjects at the resource level. Example:
module "example" {
source = "./modules/some_module/example"
for_each = local.some_module.example
name = each.value.name
resource_group = local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.resource_group_key]
}
Then in the modules
directory, for that specific resource, create a variables.tf
that expects this resource_group
object
variable "resource_group" {
}
Then destructure this variable in the resource's .tf
file
resource_group_name = var.resource_group.name
Note: There could be cases where we want to resolve the landing zone key within the resource itself (for example if certain resources use a specified lz_key rather than the common one). For this use case, the module level will look like:
module "example" {
source = "./modules/some_module/example"
for_each = local.some_module.example
name = each.value.name
resource_groups = local.combined_objects_resource_groups
# inject the lz_key here
}
Then within the resource, destructure similar to how it was done at the module level but now do it at the resource level.
Background
We use the combined_objects_resource_groups
to illustrate this.
locals.combined_objects.tf
The relevant snippet shows that combined_objects_resource_groups
merges the local state that comes from local.resource_groups
with the remote state that comes from var.remote_objects.resource_groups
.
locals {
combined_objects_resource_groups = merge(
tomap({
(local.client_config.landingzone_key) = local.resource_groups
}),
try(var.remote_objects.resource_groups, {})
)
}
resource_groups.tf
This module initialize the resource groups and stores the outputs in the locals
. This is how locals.combined_objects.tf
can reference the local resource groups by using local.resource_groups
.
locals {
resource_groups = merge(module.resource_groups, module.resource_group_reused)
}
variables.tf
The remote objects is initialized here. This is how locals.combined_objects.tf
can reference the local resource groups by using var.remote_objects.resource_groups
. This variable has its values injected behind the scenes by the caf_launchpad
or landing zone.
variable "remote_objects" {
description = "Remote objects is used to allow the landing zone to retrieve remote tfstate objects and pass them to the caf module"
default = {}
}