Terraform Registry

You can configure the Speakeasy Generation Action to publish a generated Terraform provider. Speakeasy Terraform provider generation does not support operating in monorepo mode, as you need to create a separate repository for the Terraform provider with the appropriate name format. To publish the generated Terraform provider, you need to do the following:

  1. The repository you make for the Terraform provider must:
    • Be given the name terraform-provider-{NAME}, where NAME is lowercase.
    • Be public.
  2. Sign your Terraform provider releases with a signing key. Create and export a signing key following the instructions in the GitHub documentation for generating a new GPG key (opens in a new tab). Generate your GPG key using either the RSA or DSA algorithm.
  3. Take note of the following values:
    • The GPG private key.
    • The GPG passphrase.
    • The GPG public key.
  4. Add the ASCII-armored public key to the Terraform registry.
  5. Your GPG private key and GPG passphrase will be configured automatically if entered into the Speakeasy CLI. Ensure that the following secrets are available to your repository:
    • The GPG private key, terraform_gpg_secret_key.
    • The GPG passphrase, terraform_gpg_passphrase.
  6. The first time you publish a Terraform provider generated using the Speakeasy Generation Action, you need to manually add it to the Terraform Registry. Subsequent updates will be published automatically. To begin this process, follow the Terraform registry instructions (opens in a new tab) and agree to any Terraform terms and conditions. Note that you will need to be an organizational admin to complete this step.
  7. Add the following file to your .github/workflows directory to indicate create releases for your Terraform provider using GoReleaser. If all the above steps have been completed the HashiCorpy registry will automatically pick up new changes.
terraform_publish.yaml

# Terraform Provider release workflow.
name: Release
# This GitHub action creates a release when a tag that matches the pattern
# "v*" (e.g. v0.1.0) is created.
on:
push:
tags:
- 'v*'
workflow_dispatch:
# Releases need permissions to read and write the repository contents.
# GitHub considers creating releases and uploading assets as writing content.
permissions:
contents: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
with:
# Allow goreleaser to access older tag information.
fetch-depth: 0
- uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
with:
go-version-file: 'go.mod'
cache: true
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@111c56156bcc6918c056dbef52164cfa583dc549 # v5.2.0
id: import_gpg
with:
gpg_private_key: ${{ secrets.terraform_gpg_secret_key }}
passphrase: ${{ secrets.terraform_gpg_passphrase }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0
with:
args: release --clean
env:
# GitHub sets the GITHUB_TOKEN secret automatically.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}

  1. Finally, create a GoReleaser (opens in a new tab) file in the root of your repository:
.goreleaser.yml

# Visit https://goreleaser.com for documentation on how to customize this
# behavior.
version: 2
before:
hooks:
# this is just an example and not a requirement for provider building or publishing
- go mod tidy
builds:
- env:
# goreleaser does not work with CGO, it could also complicate
# usage by users in CI/CD systems like Terraform Cloud where
# they are unable to install libraries.
- CGO_ENABLED=0
mod_timestamp: '{{ .CommitTimestamp }}'
flags:
- -trimpath
ldflags:
- '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}'
goos:
- freebsd
- windows
- linux
- darwin
goarch:
- amd64
- '386'
- arm
- arm64
ignore:
- goos: darwin
goarch: '386'
binary: '{{ .ProjectName }}_v{{ .Version }}'
archives:
- format: zip
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
checksum:
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
algorithm: sha256
signs:
- artifacts: checksum
args:
# if you are using this in a GitHub action or some other automated pipeline, you
# need to pass the batch flag to indicate it's not interactive.
- "--batch"
- "--local-user"
- "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key
- "--output"
- "${signature}"
- "--detach-sign"
- "${artifact}"
release:
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
# If you want to manually examine the release before it goes live, uncomment this line:
# draft: true
changelog:
disable: true

Whenever you generate and merge a new PR for your Terraform provider, it will be automatically versioned and released to the Hashicorp Registry.