Operations Reference
This document describes the four primary operations—add
, update
, set
, and delete
—that the Terraform Editor API supports. Each of these operations targets specific Terraform blocks or attributes, letting you create, modify, or remove infrastructure definitions programmatically.
Note: Before exploring these operations in depth, be sure to review the Overview for a high-level explanation of how Terraform blocks are structured in JSON. If you want details on how to select specific blocks (like using
where
,index
, orlabels
), see the Selectors guide. For insights into nesting these operations inside each other, check out Nested Operations.
1. add
Use add
when you want to create a new block or attribute set.
- Behavior:
- It fails if a matching block already exists.
- If no block of that type or label exists, it creates one from scratch.
- Typical Use Case: Adding an entirely new resource, provider, or module block to your Terraform code.
Example
"add": {
"resource": {
"aws_s3_bucket": {
"my_bucket": [
{
"attributes": {
"bucket": "my-new-bucket"
}
}
]
}
}
}
- What Happens:
- The API looks for any
resource "aws_s3_bucket" "my_bucket"
block. - If it exists, the request fails (duplicate).
- If not, it creates a new S3 bucket resource with the given attribute.
- The API looks for any
2. update
Use update
to modify an existing block or attributes.
- Behavior:
- Must match exactly one existing block. If it can't find a block or finds multiple blocks without enough selectors, the operation fails.
- Only changes the attributes you provide, leaving others untouched.
Example
"update": {
"resource": {
"aws_instance": {
"main": [
{
"attributes": {
"instance_type": "t2.micro"
}
}
]
}
}
}
- What Happens:
- The API finds
resource "aws_instance" "main"
—there must be exactly one match. - It updates the
instance_type
to"t2.micro"
. - If no
main
block or multiplemain
blocks exist, you'll need a selector (like"where": {"instance_type": "t2.small"}
or an"index": 0
) to disambiguate.
- The API finds
3. set
Use set
for an "upsert": it creates the block if it doesn't exist, or updates the block if it does.
- Behavior:
- If there's exactly one matching block, it updates that block's attributes.
- If no matching block is found, it creates a new one.
- If multiple matching blocks are found, it fails (unless you use selectors to narrow it down).
Example
"set": {
"provider": {
"google": [
{
"where": {
"alias": "europe"
},
"attributes": {
"region": "europe-west2"
}
}
]
}
}
- What Happens:
- The API looks for a provider block with
alias = "europe"
. - If found, it updates
region
to"europe-west2"
. - If not found, it creates a new
provider "google"
block withalias = "europe"
and sets theregion
attribute accordingly.
- The API looks for a provider block with
set
Without Selectors
If you omit selectors in a situation where there are multiple matching blocks of the same name, the API returns an ambiguity error. For example, if you just say:
"set": {
"provider": {
"google": [
{
"attributes": {
"project": "my-new-project"
}
}
]
}
}
…but you already have two different provider "google"
blocks, this operation can't decide which one to update. You'll need a selector like index
, where
, or labels
.
4. delete
Use delete
to remove a block or specific attributes.
- Behavior:
- Must match exactly one existing block or set of attributes.
- If no match is found or there are multiple matches, it fails.
Deleting Blocks
"delete": {
"resource": {
"aws_instance": {
"main": []
}
}
}
- What Happens:
- The API looks for exactly one
resource "aws_instance" "main"
block and removes it entirely.
- The API looks for exactly one
Deleting Specific Attributes
You can remove only certain attributes instead of removing the entire block:
"delete": {
"resource": {
"aws_instance": {
"main": [
{
"attributes": ["user_data", "iam_instance_profile"]
}
]
}
}
}
- What Happens:
- Finds
aws_instance.main
and deletes only theuser_data
andiam_instance_profile
attributes. - The block itself remains (along with any other attributes).
- Finds
Special Block Types
Locals
The locals
block type is special because it doesn't follow the normal structure. Instead of attributes within the block operations, the attributes themselves are the content of the block:
"locals": [
{
"add": {
"attributes": {
"environment": "production",
"owner": "platform-team"
}
}
}
]
TFVars
The tfvars
block type is used for manipulating .tfvars
files which contain variable assignments.
For detailed information about working with .tfvars
files, see the TFVars Support guide.
Interpolation Support
The API fully supports Terraform interpolation syntax within attribute values. This includes variable references, resource references, function calls, and complex expressions.
For comprehensive information about using interpolation, see the Interpolation Support guide.
Ambiguity & Matching Rules
When multiple blocks match the same name or label, you must use selectors like index
, where
, or labels
to avoid ambiguity. Each operation handles ambiguity differently:
- Add: Fails if a block of the same name already exists.
- Update: Fails if 0 or >1 blocks match.
- Set: Creates a new block if none found; fails if multiple found.
- Delete: Fails if 0 or >1 blocks match.
For more on selectors and examples of targeting exactly the block(s) you want, see the Selectors guide.
Putting It All Together
These four operations give you the power to programmatically transform your Terraform code. You can combine them in the same request, nesting them under different blocks for complex changes. To see how these operations interact in deeper hierarchical scenarios, check out Nested Operations.
Next Steps
- Explore Selectors to learn how to pinpoint the exact blocks you want to modify.
- Dive into Nested Operations for examples of advanced, multi-level changes.
- Check out the Examples in our Guides section for real-world use cases.