Globals
Globals allow you to establish data that can be reused across multiple stacks, using a hierarchical merge semantics. This ensures consistent and easy data sharing within your project.
Defining Globals
Globals are added to your Terramate configuration file within a globals
block. Here's an example:
globals {
env = "staging"
values = [ 1, 2, 3 ]
obj = {
value = "string"
}
}
A globals block also permits setting attributes within an existing object. To illustrate, the following block appends properties to the global.obj
variable defined above:
globals obj {
number = 10
}
After this, global.obj
would appear as:
{
value = "string"
number = 10
}
Multiple labels can be provided, and Terramate will automatically establish the object keys as necessary. Here's an example:
globals "obj" "child" "grandchild" {
list = []
}
This will make the global.obj
appear as:
{
value = "string"
number = 10
child = {
grandchild = {
list = []
}
}
}
Additionally, the map block is supported inside the globals
block for building complex objects.
The globals can be referenced on the code generation:
generate_hcl "backend.tf" {
content {
backend "type" {
param = "value-${global.env}"
}
}
}
globals {
env = "staging"
}
Referencing Metadata and other Globals
globals {
extended_stack_path = "extended/${terramate.path}"
}
They can also reference other globals:
globals {
info = "something"
extended_stack_path = "${global.info}/extended/${terramate.path}"
}
Usage of Globals across multiple Terramate Files
Globals can be defined across multiple Terramate files, with the set of files in a specific directory referred to as a configuration. Following this terminology:
- A project has multiple configurations, one for each of its directories.
- The most specific configuration is the stack directory.
- The most general configuration is the project root directory.
- Globals can't be redefined in the same configuration.
- Globals can be redefined in different configurations.
- Globals can reference globals from other configurations.
Each stack will have its globals defined by loading them from the stack directory and up until the project root is reached. This is called the stack globals set.
When globals are redefined across different configurations, a simple merge strategy is adopted:
- Globals with different names are merged.
- For globals with identical names, the more specific configuration replaces the general one.
Working with Globals: An Example
Consider a project with the following structure:
.
└── stacks
├── stack-1
│ └── terramate.tm.hcl
└── stack-2
└── terramate.tm.hcl
For stack-1, the available configurations, listed from most specific to most general, are:
- stacks/stack-1
- stacks
- . (the project root dir)
To create globals that will be available for all stacks in the entire project just add a Terramate configuration file in the project root with some useful globals:
globals {
project_name = "awesome-project"
useful = "useful"
}
Now any stack in the project can reference these globals in their Terramate configuration.
Suppose one of the stacks, stack-1, wants to introduce more globals. This can be done by adding globals to the stack configuration in the file 'stacks/stack-1/globals.tm.hcl':
globals {
stack_data = "some specialized stack-1 data"
}
With this change, the globals set for 'stacks/stack-1' becomes:
project_name = "awesome-project"
useful = "useful"
stack_data = "some specialized stack-1 data"
For 'stacks/stack-2', the globals remain:
project_name = "awesome-project"
useful = "useful"
Now, let's redefine a global on stacks/stack-1
. We do that by changing stacks/stack-1/globals.tm.hcl
:
globals {
useful = "overriden by stack-1"
stack_data = "some specialized stack-1 data"
}
This modification changes stacks/stack-1
globals set to:
project_name = "awesome-project"
useful = "overriden by stack-1"
stack_data = "some specialized stack-1 data"
For stacks/stack-2
, the globals set remains unchanged:
project_name = "awesome-project"
useful = "useful"
Overriding is conducted at the global name level, meaning objects, maps, lists, and sets are not merged but entirely replaced by the most specific configuration with the same global name.
For instance, suppose we add this to our project root configuration:
globals {
project_name = "awesome-project"
useful = "useful"
object = { field_a = "field_a", field_b = "field_b" }
}
And redefine object
in 'stacks/stack-1/globals.tm.hcl':
globals {
object = { field_a = "overriden_field_a" }
}
The stacks/stack-1
globals set becomes:
project_name = "awesome-project"
useful = "useful"
object = { field_a = "overriden_field_a" }
For stacks/stack-2
, it remains:
project_name = "awesome-project"
useful = "useful"
object = { field_a = "field_a", field_b = "field_b" }
Unsetting Globals
To unset a global, assign the value unset
to it:
globals {
a = unset
}
Upon unsetting, any access to the global will fail, as if the global was never defined. This behavior affects the global throughout the entire hierarchy, leaving it undefined for all child configurations.
It's essential to note that unset
can only be used in direct assignments to a global. It is not allowed in any other context.