How to use OpenTofu Exclude
OpenTofu --exclude
vs. --target
Infrastructure as Code (IaC) tools like OpenTofu have changed how we manage cloud resources. The usual workflow involves planning and applying changes to your entire configuration. However, in complex, large-scale environments, or during specific operational scenarios like troubleshooting or phased rollouts, applying everything every time isn't always practical. This is where selective operations come into play.
OpenTofu offers two primary command-line flags for this purpose: the long-standing --target
and the more recent --exclude
. Understanding their difference and appropriate use cases is key to efficient and safe infrastructure management. While these CLI tools offer granular control, it's also worth noting that managing the broader lifecycle, governance, and collaboration around IaC often benefits from overarching platforms that can enhance visibility and control, such as Scalr.
The --target
Flag: Focusing In
The --target
flag allows you to narrow the scope of tofu plan
or tofu apply
operations to specific resources and their upstream dependencies. Anything not targeted or depended upon by a target is ignored.
Syntax:
tofu plan -target=<RESOURCE_ADDRESS>
tofu apply -target=<RESOURCE_ADDRESS_1> -target=<RESOURCE_ADDRESS_2>
RESOURCE_ADDRESS
can be a specific resource instance (e.g.,aws_instance.example[0]
), a whole resource (e.g.,aws_instance.example
), or an entire module (e.g.,module.my_module
).
Common Use Cases for --target
:
- Troubleshooting: Isolating a misbehaving resource to re-apply its configuration.
- Iterative Development: Applying and testing changes to a new component in isolation.
- Disaster Recovery: Quickly re-provisioning specific failed components.
Limitations of --target
: While useful, --target
has its downsides:
- Cumbersome for Multiple Resources: Specifying many targets is tedious and error-prone. Community discussions have even floated ideas like
--target-file
to alleviate this. - Risk of Configuration Drift: Routinely targeting subsets can lead to other resources drifting from their defined state, as they aren't being evaluated. This undermines the "source of truth" principle of IaC.
- "Tunnel Vision": It's easy to miss indirect dependencies or the impact on the system if not careful.
The --exclude
Flag: Strategically Omitting
Introduced in OpenTofu 1.9.0, the --exclude
flag is the logical counterpart to --target
. It instructs OpenTofu to operate on all resources except those specified and any resources that depend on them (downstream dependencies).
Syntax:
tofu plan -exclude=<RESOURCE_ADDRESS>
tofu apply -exclude=<RESOURCE_ADDRESS_1> -exclude=<MODULE_ADDRESS>
For example:
# Exclude a specific S3 bucket and an entire networking module
tofu apply -exclude=aws_s3_bucket.sensitive_logs -exclude=module.legacy_network
Key Distinction: You cannot use --target
and --exclude
in the same command. You must choose one approach.
Dependency Handling with --exclude
: This is critical: excluding a resource also excludes everything that depends on it. For instance, excluding a core networking module might also exclude compute instances or load balancers relying on its outputs. A solid understanding of your dependency graph is essential.
When --target
Isn't Ideal (And --exclude
Might Be Better)
The introduction of --exclude
addressed scenarios where --target
felt awkward or impractical:
- Applying to the Majority of a Large Configuration: If you need to update 95 out of 100 resources, listing 95
-target
flags is inefficient and risky. It's far simpler to use-exclude
for the 5 resources you want to skip. - Intent is "Everything But These Few": When your mental model is "update everything except X, Y, and Z,"
--exclude
directly translates that intent into your command, making it more readable and self-documenting. - Reducing Command Line Clutter: A few
-exclude
flags are cleaner than a potentially long list of-target
flags, improving readability for manual execution and CI/CD scripts. - Decreasing Risk of Forgetting Inclusions: With
--target
for a broad update, you risk forgetting a resource that should have been included.--exclude
defaults to including everything not explicitly omitted (or dependent on an omission).
After (Clearer with --exclude
):
tofu apply -exclude=resource.x -exclude=resource.y -exclude=resource.z
Before (Impractical with --target
):
# Imagine listing dozens or hundreds of targets...
tofu apply -target=resource.a -target=resource.b ... (and 93 more)
Key Scenarios and Advantages for --exclude
- Managing Large Configurations with Few Exceptions: As noted, this is win for
--exclude
. If a module is under maintenance or a resource is unstable, excluding it is easy. - Phased Rollouts and Testing: Incrementally introduce changes by excluding certain regions or resource types initially. For example, deploy a new feature to a staging environment while excluding production resources.
- Temporarily Bypassing Problematic Resources: If a resource has drifted or is causing apply errors,
--exclude
allows you to proceed with other updates while you investigate the problematic component. - Simplifying Operations by Inverting Logic: When omission is the goal,
--exclude
aligns with that operational logic, reducing cognitive load.
Summary Table: --target
vs. --exclude
Feature |
|
|
---|---|---|
Primary Function | Include only specified resources & their dependencies. | Exclude specified resources & their dependents. |
Operational Logic | Inclusion | Exclusion |
Dependency Handling | Includes upstream dependencies of targeted resources. | Excludes downstream resources that depend on excluded items. |
Pros | Precision for isolated changes; clear scope for single-item focus. | Simplicity for broad changes with few exceptions; clearer "omit" intent. |
Cons | Cumbersome for many targets; risk of forgetting inclusions. | Risk of over-exclusion due to cascading dependencies; needs graph knowledge. |
Mutual Exclusivity | Cannot be used with | Cannot be used with |
Drift Risk | Yes, if used routinely without full applies. | Yes, if used routinely without full applies. |
Best Practices and Broader Considerations
While powerful, both --target
and --exclude
deviate from the standard "apply everything" workflow and should be used judiciousely.
- Prefer Full Applies: Whenever possible, full applies are best to ensure your entire infrastructure aligns with your code, decreasing drift.
- Always
plan
Beforeapply
: Carefully review the execution plan to confirm the scope of changes is exactly what you intend. - Version Control and CI/CD: For anything beyond a quick fix, the intent and commands should be version-controlled. CI/CD pipelines using these flags need clear documentation and careful control. This is an area where platforms like Scalr add value by providing robust frameworks for versioning, approval workflows, and policy enforcement around IaC operations.
- Configuration Drift: This is a risk with any partial apply strategy. Regularly scheduled full applies are crucial. Tools that offer automated drift detection, a feature often found in comprehensive IaC management platforms like Scalr, can proactively alert you to discrepancies.
- Team Communication: Ensure clear communication when performing partial applies, especially in shared environments.
Conclusion: Choosing the Right Tool for the Job
OpenTofu's --target
and --exclude
flags provide essential flexibility for managing complex infrastructure.
- Use
--target
for small, well-defined, inclusive operations. - Use
--exclude
when omitting a few items from a broader operation is simpler and clearer.
These flags are valuable tools in an operator's toolkit. However, managing IaC effectively at scale involves more than just CLI commands. It requires a holistic approach to governance, collaboration, cost management, and security. Platforms like Scalr complement tools like OpenTofu by providing the necessary guardrails, visibility, and automation to manage the entire lifecycle of your infrastructure, ensuring that even granular operations fit within a well-defined and secure operational model. By understanding both the low-level controls and the high-level management strategies, teams can truly master their Infrastructure as Code.