Configure stacks
Terramate detects stacks based on the existence of a stack {}
block. The name of the file is not important and can be different from stack.tm.hcl
. There can be exactly one stack block defined in a stack.
- Define stack metadata:
name
,description
,id
,tags
. - Set an explicit order of execution:
before
,after
. - Configure forced execution:
watch
,wants
,wanted_by
.
stack {
id = "7b5f4d89-70a7-42f0-972f-3be8550e65df"
name = "My Awesome Stack Name"
description = "My Awesome Stack Description"
tags = [
"aws",
"vpc",
"bastion",
]
}
General Stack Metadata
id
The stack ID must be a string
composed of alphanumeric chars, dashes, and underscores. The ID can't be bigger than 64 bytes, is case insensitive and must be unique over the whole project. It is required when synchronizen data to Terramate Cloud.
It is recommended to use a lowercase UUIDv4 as stack ID as this is the default when a stack is created using the terramate create
command.
When stacks are cloned a new UUIDv4 is generated for cloned stacks.
When id
is missing in stacks, the terramate create --ensure-id
command can be used to add a UUIDv4 to stacks that did not define an id
yet.
Example:
id = "7b5f4d89-70a7-42f0-972f-3be8550e65df"
The id is available as terramate.stack.id
variable in Code Generation.
name
The optional stack name can be any string. It is supposed to give the stack a human-readable Name.
If not set, it defaults to the basename of the stack path.
The stack name will be synchronized to Terramate Cloud and shown in addition to the stack path to identify a stack.
name = "My Awesome Stack Name"
The name is available as terramate.stack.name
variable in Code Generation.
description
The stack description can be any string and can include multiple lines.
It will be synchronized to Terramate Cloud and shown in the Stacks Details area.
description = "My Awesome Stack Description"
The description is available as terramate.stack.description
variable in Code Generation.
tags
The tags list is a set of strings and each tag needs to be a lowercase alphanumeric string that can also contain dashes and underscores.
Tags can be used to target/filter stacks in various commands and shall be used when defining order of execution of a stack.
Terramate Cloud allows to filter stacks by tags.
tags = [
"aws",
"vpc",
"bastion",
]
Tags are available as terramate.stack.tags
variable in Code Generation and can be used to conditionally generate code for stacks having or not having specific stacks defined.
Examples of commands with tags support:
Listing having or not having tags set:
terramate list --tags a
terramate list --no-tags b
Running any command in stacks having or not having tags set:
terramate run --tags c -- echo "hi from stack with tag c"
terramate run --no-tags d -- echo "hi from stack without tag d"
Running
my script
Terramate Script in stacks having or not having tags set:terramate script run --tags e my script
terramate script run --no-tags f my script
Explicit Order of Execution
TIP
It's a best practice to use tags instead of paths for defining the order of execution of stacks with before
and after
.
after
The after
attribute ensures that a stack runs only after the specified stacks. You can specify a list of strings, where each string can be:
A stack path (e.g., /some/stack-1).
A tag filter to match multiple stacks.
A directory path (e.g.,
/some
), which automatically includes all stacks within that directory. For example,hclafter = ["/some"]
is the same as:
hclafter = [ "/some/stack-1", "/some/stack-2" ]
You can use both project absolute paths (like /other/stack
) and paths relative to the directory of the current stack (e.g., ../other/stack
)
after = [
"tag:prod:networking",
"/prod/apps/auth",
]
The stack above will run after all stacks tagged with prod
and networking
and after /prod/apps/auth
stack.
See the orchestration docs for details.
before
Defines the list of stacks that this stack must run before
, following the same rules as after
.
before = [
"tag:prod:networking",
"/prod/apps/auth",
]
Influence Change Detection
watch
The list of files that must be watched for changes in the change detection.
watch = [
"/policies/mypolicy.json"
]
The configuration above will mark the stack as changed whenever the file /policies/mypolicy.json
changes.
Forced Execution
WARNING
Using forced execution is an anti pattern and will lead to a bigger blast radius. Consider combining the stacks for easier maintainability instead. Im most scenarios defining Order of Execution is sufficient to guarantee changes are applied in order.
wants
This attribute defines a list of stacks that will be run whenever this stack is run. You can specify a list of strings following the same rules as in after
, example:
wants = [
"/other/stack"
]
This can be useful to force a dependency relationship between stacks - for example, if a dependent stack is outside of the scope (the nested directory hierarchy). E.g., if we had the following hierarchy:
/stacks
/stack-a
/stack-a-1
/stack-a-2
/stack-b
Running terramate -C stacks/stack-a
would run stack-a
, stack-a-1
and stack-a-2
.
But if stack-a-2
always requires stack-b to run, we could put wants = ["/stacks/stack-b"]
into the stack-a-2
configuration and it would always be added to the execution list whenever stack-a-2
was targeted.
INFO
It's very important to note that adding a stack to wants
does not alter the run order. If you want a dependent stack to run before or after another you must also use the before
and after
attributes.
wanted_by
This attribute is similar to stack.wants
but works reversely. That is, using the same hierarchy as above, we could achieve the same result (including stack-b
whenever we trigger stack-a-2
) by putting wanted_by = ["/stacks/stack-a-2"]
in the stack-b configuration.
/stacks
/stack-a
/stack-a-1
/stack-a-2
/stack-b
# stack-b/stack.tm.hcl
wanted_by = ["/stacks/stack-a-2"]