Extending the Panfactum Configuration
While our panfactum.hcl
provides a lot of functionality out-of-the-box, you may want to add or change
functionality on a global basis.
To accomplish this, define your own shared.hcl
with its own behavior in the root of the environment folder.
Add the following include
block to each module's terragrunt.hcl
after the "panfactum"
include
:
include "shared" {
path = find_in_parent_folders("shared.hcl")
}
This will merge your custom settings with the Panfactum default settings (see the docs for different merge strategies).
Accessing the Scoped YAML Variables
In your shared.hcl
, you may find it helpful to reference values defined in the global.yaml
, environment.yaml
,
region.yaml
, and module.yaml
files, especially because you can add arbitrary values to these files.
Unfortunately, it is not currently possible to import the resolved values
directly from the panfactum.hcl
into your shared.hcl
due to this outstanding issue.
Until that issue is resolved, you should copy this block into your shared.hcl
:
locals {
global_raw_vars = try(yamldecode(file(find_in_parent_folders("global.yaml"))), {})
global_user_vars = try(yamldecode(file(find_in_parent_folders("global.user.yaml"))), {})
global_vars = merge({}, local.global_raw_vars, local.global_user_vars)
global_extra_tags = lookup(local.global_vars, "extra_tags", {})
global_extra_inputs = lookup(local.global_vars, "extra_inputs", {})
environment_raw_vars = try(yamldecode(file(find_in_parent_folders("environment.yaml"))), {})
environment_user_vars = try(yamldecode(file(find_in_parent_folders("environment.user.yaml"))), {})
environment_vars = merge({}, local.environment_raw_vars, local.environment_user_vars)
environment_extra_tags = lookup(local.environment_vars, "extra_tags", {})
environment_extra_inputs = lookup(local.environment_vars, "extra_inputs", {})
region_raw_vars = try(yamldecode(file(find_in_parent_folders("region.yaml"))), {})
region_user_vars = try(yamldecode(file(find_in_parent_folders("region.user.yaml"))), {})
region_vars = merge({}, local.region_raw_vars, local.region_user_vars)
region_extra_tags = lookup(local.region_vars, "extra_tags", {})
region_extra_inputs = lookup(local.region_vars, "extra_inputs", {})
module_raw_vars = try(yamldecode(file(find_in_parent_folders("${get_terragrunt_dir()}/module.yaml"))), {})
module_user_vars = try(yamldecode(file(find_in_parent_folders("${get_terragrunt_dir()}/module.user.yaml"))), {})
module_vars = merge({}, local.module_raw_vars, local.module_user_vars)
module_extra_tags = lookup(local.module_vars, "extra_tags", {})
module_extra_inputs = lookup(local.module_vars, "extra_inputs", {})
# Merge all of the vars with order of precedence
vars = merge(
local.global_vars,
local.environment_vars,
local.region_vars,
local.module_vars
)
extra_tags = merge(
local.global_extra_tags,
local.environment_extra_tags,
local.region_extra_tags,
local.module_extra_tags
)
extra_inputs = merge(
local.global_extra_inputs,
local.environment_extra_inputs,
local.region_extra_inputs,
local.module_extra_inputs
)
}
You will then be able to access the properly scoped variable via local.vars
at other places in your shared.hcl
configuration.
Supporting Additional Providers
One common customization will be adding additional OpenTofu (Terraform) providers for your organization's custom modules. We recommend aligning your provider configuration setup with how Panfactum defines and enables our built-in providers. This conforms to the official terragrunt recommendation for managing providers.
Let's assume that you want to build modules that require the Datadog terraform provider, and you want all modules to use the same provider settings.
-
Ensure that each module has an
include
block for your customshared.hcl
(see above). -
Create a new
datadog.tf
file with the following contents (example). Add it to theenvironments/providers/
directory alongside the other provider snippets.provider "datadog" { api_url = "https://api.datadoghq.com/" }
-
Add the following snippet to your
shared.hcl
:generate "datadog_provider" { path = "datadog.tf" if_exists = "overwrite_terragrunt" contents = strcontains(try(file(find_in_parent_folders("${get_terragrunt_dir()}/.terraform.lock.hcl")), ""), "registry.opentofu.org/DataDog/datadog") ? file("${path_relative_from_include()}/providers/datadog.tf") : "" }