merge-tfvars is a helper tool for merging multiple .tfvars files into a
single .tfvars file.
In systems that have common conventions around running Terraform, it is
convenient to maintain layered .tfvars files — for example, a shared defaults
file alongside environment-specific overrides. merge-tfvars combines these
files into a single output, preserving the structure and comments of each
input file.
When the same variable is defined in multiple files, the last file on the
command line wins, consistent with Terraform's own behavior for multiple
-var-file arguments. The overridden definition is removed from the earlier
file's output so that each variable appears exactly once.
This project was forked from terraform-filter-vars and modified to support preserving comments and original .tfvars file structure, while ignoring the filtering functionality because module parsing is dependent on the version of Terraform, and we don't need the filtering functionality.
In the example subdirectory there are two .tfvars files:
# a.tfvars
foo = "foo from a.tfvars"
# Bar is blah blah blah
bar = "bar from a.tfvars"
# b.tfvars
# a.tfvars defines this one too, but if b.tfvars is later in the arguments list
# then it will "win" and override it.
bar = "bar from b.tfvars"
baz = "baz from b.tfvars"
boop = "boop from b.tfvars"
Running merge-tfvars produces a merged result:
$ merge-tfvars ./example/a.tfvars ./example/b.tfvars
foo = "foo from a.tfvars"
# a.tfvars defines this one too, but if b.tfvars is later in the arguments list
# then it will "win" and override it.
bar = "bar from b.tfvars"
baz = "baz from b.tfvars"
boop = "boop from b.tfvars"
Notice that bar from a.tfvars (along with its comment) has been removed
because b.tfvars provides an overriding definition. The foo definition
from a.tfvars remains since no later file redefines it.
The output can be written to a file using the -o option or shell I/O
redirection:
$ merge-tfvars -o merged.tfvars ./example/a.tfvars ./example/b.tfvars
If creating a temporary file isn't desirable, and if the shell supports
automatic FIFO-based I/O redirection, the result can be passed directly to
Terraform. For example, in bash:
$ terraform plan -var-file=<(merge-tfvars defaults.tfvars overrides.tfvars)