Nested Operations
Terraform code is inherently hierarchical: resources can contain sub-blocks (like ebs_block_device
, provisioner
, or connection
), and those sub-blocks might contain their own sub-blocks, and so on. The Terraform Editor API makes it simple to nest your changes, so you can:
set
oradd
a block at the top level,- then
update
a sub-block, - and even
delete
some attributes within that sub-block, - all in a single request.
This document shows you how to structure these layered changes effectively.
Layered Structure Basics
Within each block definition, you can include the four operations—add
, update
, set
, and delete
—to affect child blocks or attributes. We group these nested operations under:
attributes
(the direct key-value pairs of the block)blockTypes
(sub-blocks, likeprovisioner
,ebs_block_device
, etc.)
Example Layout
{
"set": {
"resource": {
"aws_instance": {
"main": [
{
"update": {
"attributes": {
"instance_type": "t3.small"
},
"blockTypes": {
"ebs_block_device": [
{
"where": { "device_name": "/dev/sdf" },
"attributes": {
"volume_size": 200
}
}
]
}
},
"add": {
"blockTypes": {
"ebs_block_device": [
{
"attributes": {
"device_name": "/dev/sdg",
"volume_size": 100
}
}
]
}
}
}
]
}
}
}
}
- Top-level:
"set"
onresource.aws_instance.main
. - Inside that block:
"update"
certain attributes (instance_type
) and modify an existingebs_block_device
."add"
a newebs_block_device
with its own attributes.
How to Nest
1. Identify Your Top-Level Block
Decide which Terraform block you want to target first. For instance, resource.aws_instance.main
or provider.google
. Then specify the operation (add
, update
, set
, or delete
) at that level.
2. Place the Next Operation Inside
Within the array item for that block, you can include nested operations as peer keys:
add
: for adding sub-blocks or attributesupdate
: for modifying existing sub-blocks or attributesset
: for upsert-style changes in sub-blocksdelete
: for removing sub-blocks or attributes
In each nested operation, you’ll specify attributes
to change and/or blockTypes
for lower-level sub-blocks.
3. Go Deeper with blockTypes
When you want to manipulate a sub-block (e.g., ebs_block_device
or provisioner
), you put it under "blockTypes"
:
"add": {
"blockTypes": {
"provisioner": [
{
"labels": ["local-exec"],
"attributes": {
"command": "echo new script"
}
}
]
}
}
This example adds a new provisioner "local-exec"
sub-block with a "command"
attribute.
Ambiguity & Selector Use
As with top-level operations, you need to ensure your nested operations don’t accidentally target multiple sub-blocks. If a sub-block can appear more than once, you may need:
where
: If sub-block attributes can be filtered (e.g.,device_name
,command
, etc.).index
: To pick the first, second, third instance, and so on.labels
: If the sub-block itself is labeled (e.g.,provisioner "local-exec"
).
Example: Combining Multiple Nested Operations
{
"update": {
"resource": {
"aws_instance": {
"web": [
{
"attributes": {
"tags": {
"Environment": "production"
}
},
"set": {
"blockTypes": {
"provisioner": [
{
"labels": ["remote-exec"],
"attributes": {
"inline": [
"echo Deploying..."
]
}
}
]
}
},
"delete": {
"attributes": ["user_data"]
}
}
]
}
}
}
}
- Top-Level:
"update"
onresource.aws_instance.web
(must match exactly one block). - Attributes: We add/update a
tags
map key ("Environment" = "production"
). - Nested
"set"
: Insideprovisioner
, we look for"remote-exec"
and add/replace itsinline
script array. - Nested
"delete"
: Removes theuser_data
attribute from theaws_instance.web
block.
Tips for Nested Operations
- Plan Your Hierarchy: Identify which block you’re starting with, then move down layer by layer.
- Keep JSON Organized: Large multi-level changes can get unwieldy—consider breaking them into smaller, well-labeled sections.
- Selectors at Each Level: If you have repeated sub-blocks, always consider whether you need
where
,index
, orlabels
at that level. - Combine with
add
,update
,set
,delete
: Each nested level can have its own mix of operations depending on what you need.
When to Avoid Nested Operations
If you find yourself building a very long chain of nested edits, you might consider:
- Splitting the request into multiple smaller operations for clarity, or
- Refactoring your Terraform code so repeated blocks or deeply nested structures are minimized.
Too much nesting can make your request more complicated to read and debug. However, if it logically belongs in one transaction, nesting is perfectly valid and often convenient.
Next Steps
- Revisit the Operations Reference for more details on
add
,update
,set
, anddelete
. - Learn how to target the right blocks in Selectors.
- Check out Best Practices for tips on organizing large or complex edits.
That’s it for Nested Operations—you’re now equipped to make multi-level changes in a single request!