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 hosts provider-specific documentation.
In this tutorial, you will release 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 add documentation to the HashiCups provider, 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.
Warning: 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 will need:
- Golang 1.15+ installed and configured.
- The Terraform 0.14+ CLI installed locally.
- GNUPG (
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 you own.
Note: 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.
If you have just completed the previous tutorials in this collection, follow the steps below. If not, switch to the "New set up" tab.
Navigate to your
terraform-provider-hashicups directory. Next, fetch new changes.
$ git fetch
Then, checkout the
implement-import branch. This step is optional but recommended to ensure that your code matches the code from the previous tutorials.
$ git checkout implement-import
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
»Document your provider
The Terraform Registry contains documentation for the providers it hosts. This enables users to reference provider-specific documentation as they develop their configuration. It is best practice for provider developers to actively maintain their provider's documentation.
»Generate provider documentation
tfplugindocs tool to automatically generate documentation for your provider in the format required by the Terraform Registry. The plugin will read the descriptions and schema of each resource and data source in your provider and generate the relevant Markdown files for you.
$ go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs rendering website for provider "terraform-provider-hashicups" exporting schema from Terraform compiling provider "hashicups" generating missing resource content generating template for "hashicups_order" generating missing data source content generating template for "hashicups_coffees" generating template for "hashicups_order" generating missing provider content generating template for "terraform-provider-hashicups" cleaning rendered website dir rendering templated website to static markdown rendering "data-sources/coffees.md.tmpl" rendering "data-sources/order.md.tmpl" rendering "index.md.tmpl" rendering "resources/order.md.tmpl"
The command should create a
docs directory containing
resources subdirectories, and pre-populate them with the relevant files.
$ tree -L 3 docs ├── docs │ ├── data-sources │ │ ├── coffees.md │ │ └── order.md │ ├── index.md │ └── resources │ └── order.md
Now that you have your provider documentation skeleton, update each documentation resource file to describe each resource. The following command will update the documentation in your local repository to match the master branch of the HashiCups provider.
$ curl --output docs/index.md https://raw.githubusercontent.com/hashicorp/terraform-provider-hashicups/master/docs/index.md && \ curl --output docs/data-sources/order.md https://raw.githubusercontent.com/hashicorp/terraform-provider-hashicups/master/docs/data-sources/order.md && \ curl --output docs/data-sources/coffees.md https://raw.githubusercontent.com/hashicorp/terraform-provider-hashicups/master/docs/data-sources/coffee.md && \ curl --output docs/resources/order.md https://raw.githubusercontent.com/hashicorp/terraform-provider-hashicups/master/docs/resources/order.md
Review these changes by opening the files in the
docs directory in your text editor.
Refer to the Provider Documentation documentation page for additional information on documenting Terraform providers.
»Add GoReleaser configuration
GoReleaser is a tool for building Go projects for multiple platforms, creating a checksums file, and signing the release.
Copy the GoReleaser configuration from the
terraform-provider-scaffolding repository to the root of your repository.
$ curl --output .goreleaser.yml https://raw.githubusercontent.com/hashicorp/terraform-provider-scaffolding/main/.goreleaser.yml
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.
»Add GitHub Action workflow
Create a GitHub Actions workspace directory in your repository. This GitHub Action will release new versions of your provider whenever you tag a commit on the main branch.
$ mkdir -p .github/workflows
Copy the GitHub Actions workflow from the
terraform-provider-scaffolding repository to
.github/workflows/release.yml in your repository.
$ curl --output .github/workflows/release.yml https://raw.githubusercontent.com/hashicorp/terraform-provider-scaffolding/main/.github/workflows/release.yml
»Generate GPG Signing Key
You need a GPG Signing Key to sign your provider binaries using GoReleaser and to verify your provider in the Terraform Registry.
Generate your GPG key pair. When prompted, press
Enter to accept the default
RSA and RSA option.
$ gpg --full-generate-key gpg (GnuPG) 2.2.27; 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 (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) (14) Existing key from card Your selection?
4096 when prompted.
RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) 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.
GnuPG needs to construct a user ID to identify your key. Real name: Terraform Education Email address: firstname.lastname@example.org Comment:
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 GPG public key
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.
$ gpg --armor --export "KEY_ID" -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBGB91soBEACp/u6jJZAKeVahHGtR6jzDFcOvivhUFV2fuwBBW/jxqYrWEeEX +rny8oChQjCABHG9bUxhSSqPyfCK/kUI3VK8Qrxpby6dQgqOFuF61P1mBI0BppLF JGydv8J9SIIbYJOyajFzMLrvL+xvKD1AblRFBtQke8ts+gz9B+oW7SmAVMb3gM4n # … -----END PGP PUBLIC KEY BLOCK-----
»Generate GPG private key
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 --armor --export-secret-keys "KEY_ID" -----BEGIN PGP PRIVATE KEY BLOCK----- lQdFBGB91soBEACp/u6jJZAKeVahHGtR6jzDFcOvivhUFV2fuwBBW/jxqYrWEeEX +rny8oChQjCABHG9bUxhSSqPyfCK/kUI3VK8Qrxpby6dQgqOFuF61P1mBI0BppLF JGydv8J9SIIbYJOyajFzMLrvL+xvKD1AblRFBtQke8ts+gz9B+oW7SmAVMb3gM4n # … -----END PGP PRIVATE KEY BLOCK-----
»Add GitHub secrets for GitHub Action
The GitHub Action requires your GPG private key and passphrase to generate a release.
In your forked GitHub repository, go to "Settings" then "Secrets" and add the following 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.
»Create a provider release
The GitHub Action will trigger and create a release for your provider whenever a new valid version tag is pushed to the repository. Terraform providers 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
»Verify provider release
In your forked repository, go to "Actions". You should find the GitHub Action workflow you created earlier running.
Tip: 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 it completes, you should find the release on the right-hand side of your main repository page.
»Add GPG public key to Terraform Registry
Go to the Terraform Registry and sign in with your GitHub account.
Click "Save" to add your public signing key.
»Publish your provider to Terraform Registry
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 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.
Warning: 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 first 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.
The final HashiCups provider can be found on the master branch.
A full list of official, verified, 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!
- The Terraform Provider Scaffolding is a quick start repository for creating a Terraform provider. Use this GitHub template when you are ready to create a custom provider.
- 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 SDK, refer to the Terraform Plugin SDK Documentation.
- To learn how to publish a Terraform provider to the Terraform Registry, refer to the Publishing Providers to the Terraform Registry documentation.