Create Your Terraform Provider From OpenAPI / Swagger
Introduction
Terraform is an infrastructure-as-code tool that manages cloud infrastructure via API calls using providers. Creating and maintaining these providers, typically written in Go, requires specialized skills and frequent updates to accommodate API changes.
Speakeasy simplifies this process by generating Terraform providers directly from OpenAPI specifications. This eliminates the need for Go expertise, ensures providers remain up-to-date, and reduces the complexity of developing and maintaining providers for cloud environments.
For more details refer to the Terraform support matrix.
1. Prerequisites
To get started with creating the Speakeasy Terraform provider, you need:
- Speakeasy CLI
- An API spec in a supported format:
Spec Format | Supported |
---|---|
OpenAPI 3.0 | ✅ |
OpenAPI 3.1 | ✅ |
JSON Schema | ✅ |
Postman Collection | 🔜 |
TIP
If you are using an unsupported spec format, use these tools to help you convert to a supported format:
2. Add Annotations
Annotate objects representing Terraform entities with x-speakeasy-entity
to determine their inclusion in the Terraform provider.
paths:/pet:post:...x-speakeasy-entity-operation: Pet#create...Pet:x-speakeasy-entity: Pet...
Terraform Usage:
resource "petstore_pet" "myPet" {...}
Speakeasy infers Terraform types from your JSON schema, focusing on the semantics of the CREATE
and UPDATE
requests and responses. You don’t need to define any specific Terraform types in your OpenAPI spec.
- Required vs. Optional: If a property is required in the
CREATE
request body, it’s marked asRequired: true
; otherwise, it’sOptional: true
. - Computed Properties: Properties that appear in a response body but are absent from the
CREATE
request are marked asComputed: true
. This indicates that Terraform will compute the properties’ values. - The
ForceNew
Property: If a property exists in theCREATE
request but is not present in theUPDATE
request, it’s labeledForceNew
. - Enum Validation: When an attribute is defined as an enum, Speakeasy configures a
Validator
for runtime type checks. This ensures that all request properties precisely match one of the enumerated values. READ
,UPDATE
, andDELETE
Dependencies: Every parameter essential forREAD
,UPDATE
, orDELETE
operations must either be part of theCREATE
API response body or be consistently required in theCREATE
API request. This ensures that all necessary parameters are available for these operations.
TIP
Use additional x-speakeasy
annotations to
customize your provider as necessary.
4. Enhance Generated Documentation
Speakeasy helps you autogenerate documentation using the HashiCorp terraform-plugin-docs
tools and packages. For best results, we recommend:
- Include Descriptions: Ensure your OpenAPI spec contains detailed descriptions of resources, attributes, and operations. Clear and concise descriptions help users understand the purpose and use of each component.
- Provide Examples: Use examples in your OpenAPI spec to illustrate how resources and attributes should be configured. Speakeasy leverages these examples to generate usage snippets that users can refer to when starting with your provider.
The Swagger Pet Store generates a usage snippet for the pet resource like the following:
id = 10name = "doggie"photo_urls = ["...",]}.
5. Generate Terraform
- Run the Speakeasy
quickstart
command:
speakeasy quickstart
- Follow the interactive guide and provide the necessary information when prompted, including the path to spec. Make sure to choose
terraform
as the language of choice. Once you’ve finished the quickstart, you can regenerate the Terraform provider at any point by runningspeakeasy run
.
Frequently Asked Questions
Do the generated Terraform providers support the ability to import resources?
Yes, generated Terraform providers do support the ability to import resources. However, there are specific prerequisites and considerations to keep in mind:
Prerequisites
-
API Specification: It is essential to have an annotated and type-complete API operation defined for reading each resource in the OpenAPI specification. Tag the operation with
x-speakeasy-entity-operation: MyEntity#read
. -
Comprehensive
READ
Operation: If any attribute of a resource is not defined in theREAD
API, Terraform will set that attribute tonull
during the import process.
Simple Keys
A simple key is a single required ID field and is directly exposed to terraform import
operations. For example, if the pet
resource has a single id
field, the import command will look like this: terraform import petstore_pet.my_pet my_pet_id
.
Handling Composite Keys
Speakeasy natively supports direct import for resources with multiple ID fields. Speakeasy generates code that supports import syntax through a user providing a JSON-encoded object with all required parameters defined. Documentation, and appropriate error messages if this syntax isn’t followed will also be generated.
Import Composite Keys by block
An import block is a way to import a resource into the Terraform state by generating a Terraform specification. Using a composite key, the import block will look like this:
import {id = jsonencode({primary_key_one: "9cedad30-2a8a-40f7-9d65-4fabb04e54ff"primary_key_two: "e20c40a0-40e8-49ac-b5d0-6e2f41f9e66f"})to = my_test_resource.my_example}
terraform plan -generate-config-out=generated.tf
Import composite keys by CLI
To import a resource with composite keys using the Terraform CLI, you can use the terraform import
command:
terraform import my_test_resource.my_example '{ "primary_key_one": "9cedad30-2a8a-40f7-9d65-4fabb04e54ff", "primary_key_two": "e20c40a0-40e8-49ac-b5d0-6e2f41f9e66f" }'