The Terraform Registry is HashiCorp's public repository of Terraform providers and modules. Whenever you initialize a Terraform configuration, Terraform attempts to download the necessary providers from the Terraform Registry. The registry also hosts provider-specific documentation.
In this tutorial, you will create a release for a Terraform provider that interacts with the API of a fictional coffee-shop application called HashiCups. Then, you will rehearse the steps to publish the provider to the Terraform Registry. To do so, you will generate a GPG signing key, set up the GitHub action used to generate the provider's release artifacts, then add your GPG keys to the Terraform Registry. Publishing providers to the registry is permanent, so to keep the registry un-cluttered you will not actually publish the HashiCups provider.
Please do not publish your copy of HashiCups to the Terraform Registry. Use this tutorial as a reference to publish your own custom Terraform provider.
To follow this tutorial, you need:
- Go 1.19+ installed and configured.
- Terraform v1.0.3+ installed locally.
- The GNUPG CLI command (
gpg) installed locally.
- A GitHub account.
To release and publish the HashiCups provider to the Terraform Registry, you must publicly host the source code in a GitHub repository that you own.
You cannot un-publish a provider once you publish it to Terraform Registry. As a result, pay very close attention to the GitHub repository and organization you use. For example, consider whether you want to publish as yourself or your company.
Navigate to your
Your code should match the
from the example repository.
Create an empty, public GitHub repository and name it
In your local
terraform-provider-hashicups directory, complete the following steps to push the code to your new repository.
First, remove the current remote
origin. This disassociates the local repository from
hashicorp/terraform-provider-hashicups, so you can add a new
$ git remote rm origin
Then, add a remote repository that points to your newly-created GitHub repository, replacing
GH_ORG with your GitHub organization name or username.
$ git remote add origin https://github.com/GH_ORG/terraform-provider-hashicups.git
Next, move the existing code to the
$ git branch -M main
Finally, push the code to your GitHub repository.
$ git push -u origin main
The Registry Manifest provides additional information about the provider to the Terraform Registry.
Verify that the
terraform-registry-manifest.json file exists in the root of your repository.
Notice that the contents of the file specify the version of the file itself, and the Terraform protocol version that the provider uses.
GoReleaser is a tool for building Go projects for multiple platforms, creating a checksums file, and signing the release.
Verify that the
.goreleaser.yml file exists in the root of your repository.
This configuration generates and signs the necessary release artifacts to publish your provider to Terraform Registry. The GitHub Action workflow will run GoReleaser with this configuration. HashiCorp maintains this GoReleaser configuration file to use with any provider you release.
Verify that the
release.yml file exists in the
This GitHub Action will release new versions of your provider whenever you tag a commit on the main branch.
You need a GPG Signing Key to sign your provider binaries using GoReleaser and to verify your provider in the Terraform Registry. The Terraform Registry only supports RSA and DSA keys.
Generate your GPG key pair. When prompted to select which kind of key, respond
1 to select the
RSA and RSA option.
$ gpg --full-generate-key
gpg (GnuPG) 2.3.6; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(14) Existing key from card
4096 when prompted for the key size.
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Enter to accept the default option, indicating that the key does not expire.
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Confirm your selection by entering
Is this correct? (y/N) y
Create a user ID at the prompt. Use your own information, not the example information below. Leave the comment blank.
GnuPG needs to construct a user ID to identify your key.
Real name: Terraform Education
Email address: firstname.lastname@example.org
When prompted, confirm your
USER-ID by entering
O. Save your
USER-ID, you will use this later to generate your private and public keys.
You selected this USER-ID:
"Terraform Education <email@example.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
Finally, create and confirm your passphrase. This passphrase is used to decrypt your GPG private key, select a strong passphrase and keep it secure.
Generate your GPG public key. Later, you will add this key to the Terraform Registry. When you publish a new version of your provider to the Terraform Registry, the registry will validate that the release is signed with this keypair and Terraform will verify the provider during
KEY_ID with the
USER-ID you used when creating your GPG key (Your
name and email address).
$ gpg --armor --export "KEY_ID"
-----BEGIN PGP PUBLIC KEY BLOCK-----
-----END PGP PUBLIC KEY BLOCK-----
Generate your GPG private key. GoReleaser will use this to sign the provider releases.
KEY_ID with the
USER-ID you used when creating your GPG key. GPG
will prompt you to enter the passphrase you created earlier.
$ gpg --armor --export-secret-keys "KEY_ID"
-----BEGIN PGP PRIVATE KEY BLOCK-----
-----END PGP PRIVATE KEY BLOCK-----
Be sure to save your production GPG keys and passphrases and back them up in a secure location.
The GitHub Action requires your GPG private key and passphrase to generate a release.
In your forked GitHub repository, go to Settings, then Secrets, then Actions, and click the New repository secret button to add the following repository secrets.
GPG_PRIVATE_KEY. This is the private GPG key you generated in the previous step. Include the
PASSPHRASE. This is the passphrase for your GPG private key.
The GitHub Action will trigger and create a release for your provider whenever a new valid version tag is pushed to the repository. Terraform provider versions must follow the Semantic Versioning standard (
First, add your changes to a new commit.
$ git add .
Then, commit your changes.
$ git commit -m 'Add docs, goreleaser, and GH actions'
Next, create a new tag.
$ git tag v0.2.1
Finally, push the tag to GitHub.
$ git push origin v0.2.1
In your forked repository, go to Actions. You should find the GitHub Action workflow you created earlier running.
You may need to acknowledge and approve workflow actions before the GitHub Action runs. If you need to do so, approve the workflow actions and manually trigger the run.
Once the GitHub Action completes, you should find the release on the right-hand side of your main repository page.
Go to the Terraform Registry and sign in with your GitHub account.
Click Save to add your public signing key.
Since you cannot un-publish a provider from the Terraform Registry, you will not actually publish your HashiCups provider in this tutorial. However, this section walks you through the steps you would follow for a real provider. It is safe to follow most of the steps in this section, but do not click the Publish button at the end.
In the Terraform Registry, select Publish, then Providers from the top navigation bar.
Select your organization, then the GitHub repository containing your Terraform provider.
Do not click Publish. Use this tutorial as a reference to publish your own custom Terraform provider. Please do not publish your copy of HashiCups to the Terraform Registry.
Congratulations! You have released your provider and walked through the steps to add it to the Terraform Registry.
Over the course of these tutorials, you re-created the HashiCups provider and learned how to create data sources, authenticate the provider to the HashiCups client, create resources with CRUD functionality, and import existing resources. In addition, you have released and published the HashiCups provider to the Terraform Registry.
A full list of official, partner, and community Terraform providers can be found on the Terraform Provider Registry. We encourage you to find a provider you are interested in and start contributing!
- To quickly create a new Terraform provider, the Terraform Provider Scaffolding Framework is a template repository that can be cloned.
- To learn more about different methods to release and publish Terraform providers, refer to the Publishing Providers documentation page.
- To learn more about documenting Terraform providers, refer to the Provider Documentation documentation page.
- To learn more about the Terraform Plugin Framework, refer to the Terraform Plugin Framework documentation.
- Submit any Terraform Plugin Framework bug reports or feature requests to the development team in the Terraform Plugin Framework Github repository.
- Submit any Terraform Plugin Framework questions in the Terraform Plugin Framework Discuss forum.