Publishing & Distribution
Module Overview
Publishing your provider to the Terraform Registry makes it accessible to the global Terraform community. This module covers versioning, signing, releasing, and distribution strategies.
Why Publish to the Registry?
Discoverability
Published providers:
- Appear in Terraform Registry search
- Get documentation hosted automatically
- Enable easy installation via
terraform init - Build community trust
User Experience
Registry providers offer:
- Automatic version resolution
- Verified checksums
- Signed releases
- Integrated documentation
- Usage analytics
Standardization
Registry publication enforces:
- Consistent naming conventions
- Documentation standards
- Release practices
- Security requirements
Publishing Requirements
Technical Requirements
- GitHub Repository
- Public repository
- Naming:
terraform-provider-{name} - GPG-signed releases
- Documentation
- Provider documentation
- Resource documentation
- Example configurations
- Guides
- Versioning
- Semantic versioning (SemVer)
- Git tags for releases
- Changelog
- Testing
- Acceptance tests
- CI/CD pipeline
- Test coverage
- Licensing
- Open source license (MPL 2.0 recommended)
- License file in repository
Publishing Process
┌─────────────────┐
│ Prepare Release │
│ - Version tag │
│ - Changelog │
│ - Docs │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Sign Release │
│ - GPG key │
│ - Sign commits │
│ - Sign tags │
└────────┬────────┘
│
▼
┌─────────────────┐
│ GitHub Release │
│ - Create tag │
│ - Goreleaser │
│ - Artifacts │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Terraform │
│ Registry │
│ - Link repo │
│ - Verify │
│ - Publish │
└─────────────────┘
Semantic Versioning
Version Format
MAJOR.MINOR.PATCH
1.2.3
│ │ └── Patch: Bug fixes, no breaking changes
│ └──── Minor: New features, backward compatible
└────── Major: Breaking changes
Version Examples
# Initial development
v0.1.0 # First release
v0.2.0 # Add new resources
v0.3.0 # Add new features
# Stable releases
v1.0.0 # First stable release
v1.1.0 # Add new data source
v1.2.0 # Add new resource
v1.2.1 # Bug fix
v2.0.0 # Breaking change (rename attribute)
Pre-release Versions
# Alpha versions
v0.1.0-alpha.1
v0.1.0-alpha.2
# Beta versions
v0.1.0-beta.1
v0.1.0-beta.2
# Release candidates
v1.0.0-rc.1
v1.0.0-rc.2
# Final release
v1.0.0
Module Chapters
This module covers provider publishing and distribution:
Chapter 1: Terraform Registry →
Learn about the Terraform Registry and its requirements.
Topics:
- Registry overview
- Account setup
- Repository requirements
- Namespace and naming
- Registry benefits
Chapter 2: Versioning & Releases →
Implement semantic versioning and create releases.
Topics:
- Semantic versioning
- Changelog management
- Git tags and releases
- Version constraints
- Deprecation strategies
Chapter 3: Release Automation →
Automate release process with GoReleaser and GitHub Actions.
Topics:
- GoReleaser configuration
- GitHub Actions workflow
- Multi-platform builds
- Artifact generation
- Release notes automation
Chapter 4: Signing & Security →
Sign releases and implement security best practices.
Topics:
- GPG key generation
- Signing commits and tags
- Checksum verification
- Security scanning
- Vulnerability management
Chapter 5: Registry Publication →
Publish provider to Terraform Registry.
Topics:
- Registry account setup
- Linking GitHub repository
- Initial publication
- Documentation hosting
- Provider verification
Chapter 6: Distribution Strategies →
Explore alternative distribution methods.
Topics:
- Private registry
- Direct downloads
- Mirror configuration
- Enterprise distribution
- Air-gapped environments
Chapter 7: Publishing Lab →
Practice the complete publishing workflow.
Topics:
- Prepare release
- Configure GoReleaser
- Sign and publish
- Verify on registry
- Test installation
Publishing Quick Reference
Repository Structure
terraform-provider-cachecloud/
├── .github/
│ └── workflows/
│ ├── release.yml
│ └── test.yml
├── .goreleaser.yml
├── docs/
│ ├── index.md
│ ├── resources/
│ └── data-sources/
├── examples/
├── internal/
├── LICENSE
├── README.md
├── CHANGELOG.md
├── main.go
└── go.mod
Release Checklist
- ✅ Update version in code
- ✅ Update CHANGELOG.md
- ✅ Update documentation
- ✅ Run all tests
- ✅ Create and sign git tag
- ✅ Push tag to GitHub
- ✅ Verify GoReleaser run
- ✅ Check GitHub release
- ✅ Verify registry publication
- ✅ Test provider installation
Version Constraints
terraform {
required_providers {
cachecloud = {
source = "example/cachecloud"
# Exact version
version = "1.2.3"
# Minimum version
version = ">= 1.0.0"
# Version range
version = ">= 1.0.0, < 2.0.0"
# Pessimistic constraint
version = "~> 1.2" # >= 1.2.0, < 1.3.0
}
}
}
GoReleaser Configuration
Basic Configuration
# .goreleaser.yml
version: 2
before:
hooks:
- go mod tidy
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
mod_timestamp: '{{ .CommitTimestamp }}'
flags:
- -trimpath
ldflags:
- '-s -w -X main.version={{.Version}}'
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm64
- arm
ignore:
- goos: windows
goarch: arm64
archives:
- format: zip
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
checksum:
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
algorithm: sha256
signs:
- artifacts: checksum
args:
- "--batch"
- "--local-user"
- "{{ .Env.GPG_FINGERPRINT }}"
- "--output"
- "${signature}"
- "--detach-sign"
- "${artifact}"
release:
draft: false
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
GitHub Actions Workflow
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: $
passphrase: $
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
version: latest
args: release --clean
env:
GPG_FINGERPRINT: $
GITHUB_TOKEN: $
Registry Provider Block
Once published, users install your provider:
terraform {
required_providers {
cachecloud = {
source = "example/cachecloud"
version = "~> 1.0"
}
}
}
provider "cachecloud" {
api_key = var.cachecloud_api_key
}
Distribution Metrics
Track Usage
Registry provides metrics:
- Download counts
- Version distribution
- Geographic distribution
- Terraform version usage
Analytics Dashboard
Provider: cachecloud
├── Total Downloads: 15,234
├── Active Versions:
│ ├── 1.2.3: 8,456 (55%)
│ ├── 1.2.2: 3,245 (21%)
│ └── 1.1.0: 2,133 (14%)
├── Terraform Versions:
│ ├── 1.5.x: 9,234 (60%)
│ └── 1.4.x: 4,567 (30%)
└── Top Regions:
├── US-East: 6,234 (41%)
├── EU-West: 4,567 (30%)
└── AP-South: 2,234 (15%)
Best Practices
1. Clear Versioning
# ✅ Good: Clear semantic versioning
v1.0.0 # Initial stable release
v1.1.0 # New feature
v1.1.1 # Bug fix
v2.0.0 # Breaking change
# ❌ Bad: Unclear versioning
v1
v2-alpha
latest
2. Comprehensive Changelog
# ✅ Good: Detailed changelog
## [1.2.0] - 2026-06-30
### Added
- Support for Redis 7.0 (#45)
- New `log_delivery_configuration` attribute (#47)
### Changed
- Default engine version changed from 6.2 to 7.0 (#46)
### Fixed
- Import now correctly handles multi-region caches (#48)
# ❌ Bad: Vague changelog
## [1.2.0]
- Updates and fixes
3. Security
# ✅ Good: Signed releases
git tag -s v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
# ❌ Bad: Unsigned releases
git tag v1.0.0
git push origin v1.0.0
What You’ll Learn
By the end of this module, you’ll be able to:
- ✅ Understand Terraform Registry requirements
- ✅ Implement semantic versioning
- ✅ Automate releases with GoReleaser
- ✅ Sign releases with GPG
- ✅ Publish to Terraform Registry
- ✅ Configure distribution strategies
- ✅ Monitor provider usage
- ✅ Manage provider lifecycle
Getting Started
Begin with Chapter 1: Terraform Registry to learn about registry requirements and setup.
Previous: ← Documentation Lab
Next: Terraform Registry →
Last updated: June 30, 2026