-
Notifications
You must be signed in to change notification settings - Fork 705
Integrating Remote and Local State
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
This section 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
For example, a module may require any combination of the id
, tags
, location
, and name
attributes. We opt to destructure the combined objects at the resource level. Example:
At the root level, pass in the entire combined object for resource groups
module "example" {
source = "./modules/some_module/example"
for_each = local.some_module.example
client_config = local.client_config
global_settings = local.global_settings
name = each.value.name
resource_groups = local.combined_objects_resource_groups
settings = each.value
}
Then in the modules
directory, for that specific resource, create a variables.tf
that expects this resource_groups
object
variable "resource_groups" {
}
Then destructure this variable in the resource's .tf
file. In the example below, the resource_group_name
and location
are extracted from var.resource_groups
location = can(local.global_settings.regions[each.value.region]) ? local.global_settings.regions[each.value.region] : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location
resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name
The following example is an anti-pattern that causes resources to be redeployed when a resource of the same type is added or removed.
resource_group_name = coalesce(
try(var.resource_groups[var.settings.resource_group.lz_key][var.settings.resource_group.key].name, null),
try(var.resource_groups[var.client_config.landingzone_key][var.settings.resource_group.key].name, null),
try(var.resource_groups[var.settings.resource_group.lz_key][var.settings.resource_group_key].name, null),
try(var.resource_groups[var.client_config.landingzone_key][var.settings.resource_group_key].name, null),
)
location = coalesce(
try(var.resource_groups[var.settings.resource_group.lz_key][var.settings.resource_group.key].location, null),
try(var.resource_groups[var.client_config.landingzone_key][var.settings.resource_group.key].location, null),
try(var.resource_groups[var.settings.resource_group.lz_key][var.settings.resource_group_key].location, null),
try(var.resource_groups[var.client_config.landingzone_key][var.settings.resource_group_key].location, null),
)
We use the combined_objects_resource_groups
to illustrate how the local state is combined with the remote state to create the combined object.
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, {})
)
}
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)
}
The remote objects is initialized here. This is how locals.combined_objects.tf
can reference the remote 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 = {}
}