Terraform
Design a Stack
Stacks allow you to break down your existing infrastructure into logical components, making it easier to deploy and manage as a cohesive system. Designing a Stack begins with planning how to structure your infrastructure and thinking about how you intend to deploy the resources your Stack defines.
Background
Every Stack requires two files: a Stack configuration file and a deployment configuration file. The Stack configuration file defines the infrastructure your Stack will provision when you deploy it. The deployment configuration files are where you define how many times to deploy the infrastructure your Stack defines.
Before writing your Stack configuration, we recommend planning and designing how you want to use your new Stack:
- Understand your existing infrastructure and break it down into manageable components.
- Understand how you want to deploy the infrastructure your Stack defines.
- Align your Stack’s component organization with your deployment strategy.
You aim to create a flexible and reusable Stack configuration, enabling you to manage your infrastructure lifecycle efficiently.
Understand your infrastructure
Before writing your Stack configuration, we recommend assessing your current infrastructure setup and planning how you want to deploy your Stack’s infrastructure.
Break down your infrastructure
Each Stack should represent a single system or application with a shared lifecycle. Start by analyzing your current infrastructure and identifying the components HCP Terraform should manage together. Components are typically groups of related resources, such as an application’s backend, frontend, or database layer, deployed and scaled together.
We recommend structuring your Stacks along technical boundaries to keep them modular and manageable. For example, you can create a dedicated Stack for shared services, such as networking infrastructure for VPCs, subnets, or routing tables, and separate Stacks for application components that consume those shared services. This separation allows you to manage shared services independently while passing information between Stacks. For more details, refer to Pass data from one Stack to another.
Sketch out your configuration
We recommend sticking to technical boundaries when structuring a Stack configuration. A single Stack should represent a single system with a shared lifecycle.
While keeping a Stack as self-contained as possible is ideal, there are valid cases where a Stack must consume outputs from another Stack. For example, a shared networking Stack can publish outputs like vpc_id or subnet IDs, which downstream application Stacks can consume as inputs. This approach ensures modularity and allows you to manage dependencies between Stacks using well-defined interfaces. For more details, refer to Pass data from one Stack to another.
Plan to add a component block to your configuration for every top-level module you want to include in your Stack. After establishing your top-level modules, you can use child modules without adding additional component
blocks.
Plan your deployments
Stack deployments define how to repeat your Stack's defined infrastructure. We recommend considering how HCP Terraform should deploy the infrastructure your Stack defines. Your deployment plan can change depending on whether you need separate deployments for different environments, cloud provider accounts, or regions.
If your deployment process requires automation, such as auto-approving specific changes in your test deployment, you can also design orchestration rules to help manage your Stack deployments. Learn more about setting conditions for stack deployment plans.
Plan for scalability
When designing your Stack, consider how it should scale as your infrastructure grows. For example, if you anticipate adding more environments or regions, design your Stack to accommodate these changes.
To keep your Stack configuration concise, you can use the locals block to share values across your deployments.
# deployments.tfdeploy.hcl
# Define variables that multiple deployments use.
locals {
tf_organization = "<organization_name>"
tf_project_name = "<project_name>"
}
Additionally, using meta-arguments like for_each
in your configuration can help streamline the creation of multiple components, making your configuration more flexible and scalable.
Next steps
After planning out your Stack, learn how to make your design a reality by defining a Stack configuration.