Tfvars: Full Layering
Terraspace Layering in it’s full form allows you to use the same infrastructure code and deploy to different environments, regions, accounts, etc.
Basic Layering
Here’s an example with some concrete values:
$ terraspace build demo
Building .terraspace-cache/us-west-2/dev/stacks/demo
config/stacks/demo/tfvars/base.tfvars (found)
config/stacks/demo/tfvars/dev.tfvars (found)
config/stacks/demo/tfvars/us-west-2.tfvars
config/stacks/demo/tfvars/us-west-2/base.tfvars
config/stacks/demo/tfvars/us-west-2/dev.tfvars
This is an AWS example, if you’re using another cloud provider plugin, the region/location will be specific to that plugin.
Tip: Seeing Layering Clearly
To see the layers being used, use the config.layering.show
option.
config/app.rb
Terraspace.configure do |config|
config.layering.show = true
end
This will show found layers, which is what you want to see most of the time. To see all possible layers, see: Debugging Layering Docs.
Layering Modes: simple, namespace, provider
In Terraspace v2, the namespace and provider level layering is off by default. There are 3 Layering Modes:
- simple: This is the default. It only includes TS_ENV and region.
- namespace: This enables the namespace. The namespace is AWS Account, Azure Subscription, or Google Project.
- provider: This enables the most number of layering. It includes layers that are scoped to the cloud provider also.
If you need v1 behavior, you can use “provider” mode.
config/app.rb
Terraspace.configure do |config|
config.layering.mode = "provider" # simple, namespace, or provider
end
Here’s a concrete example:
$ export TS_LAYERING_SHOW_ALL=1
$ terraspace build demo
Building .terraspace-cache/us-west-2/dev/stacks/demo
config/stacks/demo/tfvars/base.tfvars (found)
config/stacks/demo/tfvars/dev.tfvars (found)
config/stacks/demo/tfvars/us-west-2.tfvars
config/stacks/demo/tfvars/us-west-2/base.tfvars
config/stacks/demo/tfvars/us-west-2/dev.tfvars
config/stacks/demo/tfvars/111111111111.tfvars
config/stacks/demo/tfvars/111111111111/base.tfvars
config/stacks/demo/tfvars/111111111111/dev.tfvars
config/stacks/demo/tfvars/111111111111/us-west-2.tfvars
config/stacks/demo/tfvars/111111111111/us-west-2/base.tfvars
config/stacks/demo/tfvars/111111111111/us-west-2/dev.tfvars
config/stacks/demo/tfvars/aws.tfvars
config/stacks/demo/tfvars/aws/base.tfvars
config/stacks/demo/tfvars/aws/dev.tfvars
config/stacks/demo/tfvars/aws/us-west-2.tfvars
config/stacks/demo/tfvars/aws/us-west-2/base.tfvars
config/stacks/demo/tfvars/aws/us-west-2/dev.tfvars
config/stacks/demo/tfvars/aws/111111111111.tfvars
config/stacks/demo/tfvars/aws/111111111111/base.tfvars
config/stacks/demo/tfvars/aws/111111111111/dev.tfvars
config/stacks/demo/tfvars/aws/111111111111/us-west-2.tfvars
config/stacks/demo/tfvars/aws/111111111111/us-west-2/base.tfvars
config/stacks/demo/tfvars/aws/111111111111/us-west-2/dev.tfvars
Notes:
- Only the app level layers are shown for clarity.
- All layers except for the first, tfvars root folder, are provider specific.
- The region maps to an AWS region, Azure location, or Google region. For Azure,
location
andregion
are aliased. - The
namespace
an AWS account, Azure subscription, or Google project.
Env Folders
A simple layering structure is having the files at the top-level like so:
config/stacks/server/tfvars
├── base.tfvars
├── dev.tfvars
└── prod.tfvars
You can also structure your tfvars so that they are within env folders like so:
config/stacks/server/tfvars
├── base.tfvars
├── dev
│ └── base.tfvars
└── prod
└── base.tfvars
Generally, the simplier structure is should be used. Unless you’re using TS_EXTRA, where the additional folder structure becomes useful for tidying up the multiple extra-base tfvars files.
Project-level and Stack-level Layering
Layering is performed both at the project-level and stack-level.
- Project-level Layering: These are project-wide tfvars set for every stack. These files live in
config/terraform/tfvars
- Stack-level Layering: This are targetted tfvars set the specific stack being deployed. These files can live in the specific stack folder, IE:
config/stacks/demo/tfvars
Here’s a short example to explain. First, the project-level tfvars:
config/terraform/tfvars/base.tfvars
tags = ["common-tag"]
config/terraform/tfvars/dev.tfvars
tags = ["tag-for-all-dev-envs"]
Second, the stack-level tfvars.
config/stacks/demo/tfvars/base.tfvars
labels = ["demo-stack-common-tag"]
config/stacks/demo/tfvars/dev.tfvars
labels = ["demo-stack-tag-for-all-dev-envs"]
Building or deploying the demo stack produces:
$ terraspace build demo
$ ls .terraspace-cache/us-west-2/dev/stacks/demo/*.tfvars
.terraspace-cache/us-west-2/dev/stacks/demo/1-project-base.auto.tfvars
.terraspace-cache/us-west-2/dev/stacks/demo/2-project-dev.auto.tfvars
.terraspace-cache/us-west-2/dev/stacks/demo/3-base.auto.tfvars
.terraspace-cache/us-west-2/dev/stacks/demo/4-dev.auto.tfvars
$
Terraspace layering gives you the power to create shared tfvars at the project-level, and also create targetted tfvars for specific stacks.
Notice how only base.tfvars
and dev.tfvars
is copied over. Only these specific files are used to control layer ordering.
If you that is not enough for your needs, you can even customize layering itself: Custom Layering.