Skip to content

Customize Terraform Properties

Remap API Property to Terraform Attribute Name

Section titled “Remap API Property to Terraform Attribute Name”

The x-speakeasy-name-override annotation adjusts the Terraform attribute name within a resource while remapping all the API data handling internally. This is useful, for example, to standardize differing API property names across operations to a single attribute name.

unique_id:
type: string
x-speakeasy-name-override: id

The annotation also has other SDK customization capabilities, however, those are generally unnecessary for Terraform providers as the generated Go SDK is internal to the provider code.

Align API Parameter With Terraform Property

Section titled “Align API Parameter With Terraform Property”

The x-speakeasy-match annotation adjusts the API parameter name to align with a Terraform state property. If mismatches occur, a generation error will highlight appropriate root-level properties for accurate mapping.

paths:
/pet/{petId}:
delete:
parameters:
- name: petId
x-speakeasy-match: id
x-speakeasy-entity-operation: Pet#delete

Customize Status Codes for Missing Resources

Section titled “Customize Status Codes for Missing Resources”

By default, Terraform removes a resource from state when a Read operation returns an HTTP 404 Not Found status code. However, some APIs use different status codes to indicate a resource is missing or has been deleted, such as 403 Forbidden or 410 Gone.

The x-speakeasy-entity-missing-codes extension allows you to specify additional HTTP status codes that should trigger resource removal during Read operations. Apply this extension at the operation level on Read endpoints.

paths:
"/pet/{petId}":
get:
x-speakeasy-entity-operation: Pet#read
x-speakeasy-entity-missing-codes:
- 403
- 410
parameters:
- name: petId
in: path
required: true
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
"403":
description: Forbidden - resource has been deleted
"404":
description: Not found
"410":
description: Gone - resource permanently deleted

When any of the specified status codes are returned during a Read operation, Terraform will automatically remove the resource from state and propose recreation on the next plan. The 404 status code is always checked by default, so you only need to specify additional codes.

Setting a property default value that matches your API responses when unconfigured will enhance the Terraform plan to include the known value, rather than propagate the value as unknown (known after apply) during creation and updates.

Speakeasy generation automatically adds a Terraform schema attribute default with OAS default value, for each of the following OAS types:

OAS Schema TypeOAS default Support
arrayPartial ([] and values of boolean/number/string item types only)
booleanYes
mapNo
numberYes
objectPartial (null only)
oneOfNo
stringYes

For unsupported or advanced use cases, the Terraform SDK supports calling schema-defined custom default logic. Create the custom code implementing the Terraform type-specific resource/schema/defaults package interface in any code location and use the OAS x-speakeasy-terraform-custom-default extension to reference that implementation in the schema definition.

In this example, a custom string default implementation is created in internal/customdefaults/example.go:

package customdefaults
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/defaults"
"github.com/hashicorp/terraform-plugin-framework/types"
)
func Example() defaults.String {
return exampleDefault{}
}
type exampleDefault struct{}
func (d exampleDefault) Description(ctx context.Context) string {
return "Example custom default description"
}
func (d exampleDefault) MarkdownDescription(ctx context.Context) string {
return "Example custom default description"
}
func (d exampleDefault) DefaultString(ctx context.Context, req defaults.StringRequest, resp *defaults.StringResponse) {
resp.PlanValue = types.StringValue("example custom default")
}

With the following OAS configuration on the target property:

example:
type: string
x-speakeasy-terraform-custom-default:
imports:
- github.com/examplecorp/terraform-provider-examplecloud/internal/customdefaults
schemaDefinition: customdefaults.Example()

The imports configuration is optional if the custom code is within the internal/provider package and does not require additional imports.

Properties marked as x-speakeasy-param-sensitive will be concealed from the console output of Terraform. This helps to ensure the confidentiality of sensitive data within Terraform operations.

components:
schemas:
Pet:
type: object
properties:
name:
type: string
secret:
type: string
x-speakeasy-param-sensitive: true

Mark a schema attribute as a write only argument (WriteOnly: true in the schema definition) with the x-speakeasy-terraform-write-only extension. Write only functionality prevents values from ever being exposed in plan or state data as a more complete secret value solution over sensitive attributes.

Warning

Write only functionality is only supported in Terraform/OpenTofu 1.11 and later. Using it on earlier versions of Terraform/OpenTofu will result in a configuration error.

components:
schemas:
Pet:
type: object
properties:
name:
type: string
secret:
type: string
x-speakeasy-terraform-write-only: true

Add OAS deprecated: true within a property to automatically return a warning diagnostic with a generic deprecation message when the property is configured in Terraform. Customize the messaging with the OAS x-speakeasy-deprecation-message extension.

Info

Terraform always returns deprecation warnings for configured properties, but has limitations for displaying these warnings with response-only properties that are referenced elsewhere in the configuration. Terraform Feature Request

In this example, Terraform will display a warning diagnostic with Custom deprecation message if the property is configured:

example:
type: string
deprecated: true
x-speakeasy-deprecation-message: Custom deprecation message

When x-speakeasy-terraform-ignore: true, this extension ensures the specified property and any interactions involving it are omitted from Terraform’s state management.

Info

This extension completely suppresses the property from the Terraform state. If you want to suppress a specific operation, use x-speakeasy-ignore: true to omit the operation from the annotated CRUD method. For example, if a field is present in both the CREATE and READ response bodies, omitting it from the READ response body will turn off drift detection for that field. The field will remain in the CREATE response body and the Terraform state.

components:
schemas:
Pet:
x-speakeasy-entity: Pet
type: object
properties:
optionalMetadata:
x-speakeasy-terraform-ignore: true
type: string
name:
type: string
required:
- name
resource "petstore_pet" "mypet" {
name = "myPet"
# Attempting to set an ignored parameter results in an error
# optionalMetadata = true
}

Use x-speakeasy-terraform-ignore: schema to prevent generation errors when the property is required across API operations for the same Terraform operation and it should only be removed from the Terraform schema/state.

Set the x-speakeasy-terraform-custom-type extension to switch a property from the terraform-plugin-framework base type (e.g. types.String) to a custom type. Custom types typically include format-specific validation logic (such as a baked-in regular expression) or semantic equality handling to prevent unintentional value differences (such as ignoring inconsequential whitespace).

The following terraform-plugin-framework base types are supported for custom types:

  • Bool
  • Float32
  • Float64
  • Int32
  • Int64
  • List
  • Map
  • Set
  • String

In this example, the ipv4_address string property will use the custom iptypes.IPv4Address type:

ipv4_address:
type: string
x-speakeasy-terraform-custom-type:
imports:
- github.com/hashicorp/terraform-plugin-framework-nettypes/iptypes
schemaType: "iptypes.IPv4AddressType{}"
valueType: iptypes.IPv4Address

When contentMediaType: application/json is set on a property, it is automatically configured as a JSON-encoded string attribute with validation and semantic equality (e.g. ignore whitespace difference) behaviors. The JSON-encoded string is the value sent to and from the API.

To explicitly convert the Terraform schema to use a JSON-encoded string attribute when the OpenAPI Specification schema has a differing type, set the x-speakeasy-type-override extension to any. This allows inlining the specification of the attribute’s value, accommodating attributes with variable or dynamic structures.

components:
schemas:
Pet:
x-speakeasy-entity: Pet
type: object
properties:
deep:
x-speakeasy-type-override: any
type: object
properties:
object:
type: object
additionalProperties: true
properties:
in:
type: object
properties:
here:
type: string
name:
type: string
required:
- name
resource "petstore_pet" "mypet" {
name = "myPet"
deep = jsonencode({
object = {
with = "anything"
defined = true
}
})
}

Setting the x-speakeasy-param-suppress-computed-diff to true suppresses unnecessary Terraform plan changes for computed attributes that are not definitively known until after application. This is useful in scenarios where computed attributes frequently cause spurious plan changes.

components:
schemas:
Pet:
x-speakeasy-entity: Pet
type: object
properties:
name:
type: string
status:
x-speakeasy-param-suppress-computed-diff: true
type: string

Warning

Applying this modifier when x-speakeasy-entity-operation: my_resource#read is not defined may result in drift between the Terraform plan and remote state should updates to attributes happen outside of Terraform changes. Please only apply this when necessary.

Filter Data Resource Results by Response Values

Section titled “Filter Data Resource Results by Response Values”

Some list API endpoints do not support server-side filtering. The x-speakeasy-response-filter extension enables client-side filtering of list API responses in data resources, allowing Terraform users to narrow results by matching property values.

When applied to a response property, the generated data resource schema promotes that property to an optional, configurable attribute. If a user provides a value for a filter attribute, the generated provider filters the API response array on the client side, returning only items where the property matches the configured value.

Info

This extension only applies to data resources that read from list API endpoints returning arrays. Only top-level primitive fields (string, number, boolean, integer) are supported as filter properties.

Mark response properties with x-speakeasy-response-filter: true to make them available as filter attributes in the data resource:

components:
schemas:
Pet:
x-speakeasy-entity: Pets
type: object
properties:
name:
type: string
x-speakeasy-response-filter: true
species:
type: string
x-speakeasy-response-filter: true
id:
type: integer
age:
type: integer

With the corresponding list operation:

paths:
/pets:
get:
summary: List all pets
x-speakeasy-entity-operation: Pets#read
responses:
"200":
description: OK
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"

Terraform users can then filter the data resource results:

data "example_pets" "dogs" {
name = "Buddy"
species = "dog"
}

The generated provider fetches all pets from the API and returns only items where name equals "Buddy" and species equals "dog".

For APIs where the response is wrapped in an object, the extension works with the array items. Filter fields are automatically hoisted from the array item level to the data resource root for a flat configuration experience:

components:
schemas:
PetList:
x-speakeasy-entity: Pets
type: object
properties:
data:
type: array
items:
type: object
properties:
name:
type: string
x-speakeasy-response-filter: true
id:
type: integer

The Terraform configuration remains flat regardless of the API response structure:

data "example_pets" "my_pet" {
name = "Buddy"
}