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:
setoradda block at the top level,- then
updatea sub-block, - and even
deletesome 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_devicewith 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
tagsmap key ("Environment" = "production"). - Nested
"set": Insideprovisioner, we look for"remote-exec"and add/replace itsinlinescript array. - Nested
"delete": Removes theuser_dataattribute from theaws_instance.webblock.
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, orlabelsat 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!