What is a Terraform Provider
A Terraform provider is a plugin that extends Terraform, allowing it to manage external resources such as cloud services. It serves as a mediator between Terraform and external APIs, using the Terraform Plugin Protocol (opens in a new tab) for communication.
Terraform providers, built with the terraform-plugin-framework (opens in a new tab), include:
- Resources and Data Sources: described using a Terraform Type Schema, which is a
map[string]Attribute
, where an Attribute could be Primitive, Composite, or List. - Create, Read, Update and Delete methods: the interface through which the provider interacts with an external resource (usually an API) to reconcile a desired terraform specification with the actual state of the resource.
- Plan Validators: defined to enable the validation of a desired specification at Plan-time, without making API calls to the external resource.
- Plan Modifiers: defined to enable custom semantics around the Terraform Type Schema, and how it is reconciled with the external state to make a Plan.
- Resource imports: defined to enable Terraform Specifications to be generated from existing resources.
A simple CRUD example
Let's explore how to define a resource and map API operations to Terraform methods using annotations for CRUD actions.
Defining a Resource
Use x-speakeasy-entity
to define a resource that you want to use terraform to manage.
/drinks: post: x-speakeasy-entity-operation: Drink#create requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/Drink" responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" /drinks/{id}: parameters: - name: id in: path required: true schema: type: string get: x-speakeasy-entity-operation: Drink#read responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" post: x-speakeasy-entity-operation: Drink#update requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/Drink" responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" delete: x-speakeasy-entity-operation: Drink#delete responses: "202": description: OKcomponents: schemas: Drink: x-speakeasy-entity: Drink type: object properties: name: description: The name of the drink. type: string examples: - Old Fashioned - Manhattan - Negroni type: $ref: "#/components/schemas/DrinkType" price: description: The price of one unit of the drink in US cents. type: number examples: - 1000 # $10.00 - 1200 # $12.00 - 1500 # $15.00 required: - name - price
Mapping API Operations to Resources Methods
An OpenAPI specification tracks a large list of Operation
objects (opens in a new tab).
For a Terraform Provider generated by Speakeasy, the key element is the the x-speakeasy-entity-operation
annotation. This annotation clarifies the purpose of each operation in terms of how it affects the associated remote entity.
/drinks: post: x-speakeasy-entity-operation: Drink#create requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/Drink" responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" /drinks/{id}: parameters: - name: id in: path required: true schema: type: string get: x-speakeasy-entity-operation: Drink#read responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" post: x-speakeasy-entity-operation: Drink#update requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/Drink" responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" delete: x-speakeasy-entity-operation: Drink#delete responses: "202": description: OKcomponents: schemas: Drink: x-speakeasy-entity: Drink type: object properties: name: description: The name of the drink. type: string examples: - Old Fashioned - Manhattan - Negroni id: description: The ID of the drink readOnly: true type: string type: $ref: "#/components/schemas/DrinkType" price: description: The price of one unit of the drink in US cents. type: number examples: - 1000 # $10.00 - 1200 # $12.00 - 1500 # $15.00 required: - name - price
Defining a Resource
Use x-speakeasy-entity
to define a resource that you want to use terraform to manage.
Mapping API Operations to Resources Methods
An OpenAPI specification tracks a large list of Operation
objects (opens in a new tab).
For a Terraform Provider generated by Speakeasy, the key element is the the x-speakeasy-entity-operation
annotation. This annotation clarifies the purpose of each operation in terms of how it affects the associated remote entity.
/drinks: post: x-speakeasy-entity-operation: Drink#create requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/Drink" responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" /drinks/{id}: parameters: - name: id in: path required: true schema: type: string get: x-speakeasy-entity-operation: Drink#read responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" post: x-speakeasy-entity-operation: Drink#update requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/Drink" responses: "200": content: application/json: schema: $ref: "#/components/schemas/Drink" delete: x-speakeasy-entity-operation: Drink#delete responses: "202": description: OKcomponents: schemas: Drink: x-speakeasy-entity: Drink type: object properties: name: description: The name of the drink. type: string examples: - Old Fashioned - Manhattan - Negroni type: $ref: "#/components/schemas/DrinkType" price: description: The price of one unit of the drink in US cents. type: number examples: - 1000 # $10.00 - 1200 # $12.00 - 1500 # $15.00 required: - name - price
Managing Complex API Semantics with Speakeasy
APIs can have unique semantics not fully described by OpenAPI specs. To address this we have:
- Inference Rules: Automatically derive most API semantics from the OpenAPI spec, with the exception of the
x-speakeasy-entity-operation
annotation. - OpenAPI Extensions: For more complex cases, use extensions to provide detailed configurations. These extensions are documented in the Terraform Extensions section of this documentation.
- Support: Our engineering team continually updates inference rules and extensions to accommodate new API patterns.
Read more in our documentation here, or view more examples here.