Generate a Terraform provider from OpenAPI / Swagger

Terraform is an infrastructure-as-code tool that uses providers to manage cloud infrastructure through API calls. Creating and maintaining Terraform providers, which are typically written in Go, requires specialized skills and frequent updates to keep up with API changes.

Speakeasy simplifies creating and maintaining Terraform providers by generating providers from OpenAPI documents. This eliminates the need for Go expertise, keeps providers up-to-date, and reduces the complexity of developing and maintaining providers for cloud environments.

For a detailed overview of supported features, refer to the Terraform support matrix.

Prerequisites

To create a Terraform provider with Speakeasy, you need:

Spec FormatSupported
OpenAPI 3.0
OpenAPI 3.1
JSON Schema
Postman Collection🔜
Success Icon

TIP

If you are using an unsupported spec format, use these tools to help you convert to a supported format:

Add annotations

Use the x-speakeasy-entity annotation to specify objects to be included as Terraform entities in the 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 document.

  1. Required vs. optional: If a property is required in the CREATE request body, it’s marked as Required: true; otherwise, it’s Optional: true.
  2. Computed properties: Properties that appear in a response body but are absent from the CREATE request are marked as Computed: true. This indicates that Terraform will compute the properties’ values.
  3. The ForceNew property: If a property exists in the CREATE request but is not present in the UPDATE request, it’s labeled ForceNew.
  4. 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.
  5. READ, UPDATE, and DELETE dependencies: Every parameter essential for READ, UPDATE, or DELETE operations must either be part of the CREATE API response body or be consistently required in the CREATE API request. This ensures that all necessary parameters are available for these operations.
Success Icon

TIP

Use additional x-speakeasy annotations to customize your provider as necessary.

Enhance generated documentation

Speakeasy helps you autogenerate documentation using the HashiCorp terraform-plugin-docs tools and packages. For best results, we recommend:

  1. Include descriptions: Ensure your OpenAPI document contains detailed descriptions of resources, attributes, and operations. Clear and concise descriptions help users understand the purpose and use of each component.
  2. Provide examples: Use examples in your OpenAPI document 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 the following usage snippet for the pet resource:

"petstore_pet" "my_pet" {
id = 10
name = "doggie"
photo_urls = [
"...",
]
}.

Generate a Terraform provider

Run the Speakeasy quickstart command:

speakeasy quickstart

Follow the interactive guide, providing the necessary information when prompted, including the path to the spec. Select terraform as the language.

When you’ve completed the quickstart, you can regenerate the Terraform provider at any time by running speakeasy run.

Frequently Asked Questions

Do the generated Terraform providers support importing resources?

Yes, generated Terraform providers support importing resources. However, certain prerequisites and considerations must be taken into account:

Prerequisites

  1. API specification: Ensure the OpenAPI document defines an annotated and type-complete API operation for reading each resource. Tag the operation with x-speakeasy-entity-operation: MyEntity#read.

  2. Complete READ operation: Attributes of a resource not defined in the READ API are set to null by Terraform during the import process.

Simple keys

A simple key is a single required ID field that 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 the direct import of resources with multiple ID fields. Speakeasy generates code that enables import functionality by requiring users to provide a JSON-encoded object with all necessary parameters. In addition to generating documentation, Speakeasy generates appropriate error messages to be displayed if the proper syntax is not followed.

Import composite keys by block

An import block allows you to import a resource into the Terraform state by generating the corresponding Terraform configuration. Using a composite key, the import block will look like this:

test.tf
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 using the CLI

To import a resource with composite keys using the Terraform CLI, 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" }'