Expand description
A Terraform Provider and Module Registry implementation backed by GitHub Releases.
This crate provides a complete implementation of both the Terraform Provider Registry Protocol and the Terraform Module Registry Protocol, allowing you to host Terraform providers and modules using GitHub Releases as the storage backend.
§Features
- GitHub Authentication: Supports both Personal Access Tokens and GitHub App authentication.
- GPG Signing: Provider package verification using GPG signatures.
- Provider Registry: Full compliance with Terraform’s Provider Registry Protocol.
- Module Registry: Full compliance with Terraform’s Module Registry Protocol, supporting both public and private repositories.
- Flexible Configuration: Builder pattern for easy setup and customization.
§Quick Start
use tf_registry::{Registry, EncodingKey};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Build the registry with Personal Access Token
let registry = Registry::builder()
.github_token("ghp_your_github_token")
.gpg_signing_key(
"ABCD1234EFGH5678".to_string(),
EncodingKey::Pem("-----BEGIN PGP PUBLIC KEY BLOCK-----\n...\n-----END PGP PUBLIC KEY BLOCK-----".to_string())
)
.build()
.await?;
// Create an Axum router
let app = registry.create_router();
// Start the server
let listener = tokio::net::TcpListener::bind("0.0.0.0:9000").await?;
axum::serve(listener, app).await?;
Ok(())
}§GitHub PAT Authentication
The simplest way to authenticate. Suitable for local development or single-user setups:
use tf_registry::{Registry, EncodingKey};
let registry = Registry::builder()
.github_token(std::env::var("GH_TOKEN")?)
.gpg_signing_key(
"ABCD1234EFGH5678".to_string(),
EncodingKey::Pem(std::env::var("GPG_PUBLIC_KEY")?)
)
.build()
.await?;§GitHub App Authentication
Recommended for production deployments due to better security, higher rate limits, and fine-grained repository access control:
use tf_registry::{Registry, EncodingKey};
let registry = Registry::builder()
.github_app(
123456, // Your GitHub App ID
EncodingKey::Base64("base64_encoded_private_key".to_string())
)
.gpg_signing_key(
"ABCD1234EFGH5678".to_string(),
EncodingKey::Pem(std::env::var("GPG_PUBLIC_KEY")?)
)
.build()
.await?;§Custom Configuration
let registry = Registry::builder()
.github_token("ghp_token")
.gpg_signing_key("KEY_ID".to_string(), EncodingKey::Pem("...".to_string()))
.providers_api_base_url("/custom/terraform/providers/v1/")
.modules_api_base_url("/custom/terraform/modules/v1/")
.build()
.await?;§GitHub Release Requirements
§Providers
For providers, each GitHub release must include:
- Provider packages:
terraform-provider-{name}_{version}_{os}_{arch}.zip - Checksums file:
terraform-provider-{name}_{version}_SHA256SUMS - Signature file:
terraform-provider-{name}_{version}_SHA256SUMS.sig - Registry manifest: A
terraform-registry-manifest.jsonfile in the repository root
§Modules
For modules, the registry maps each GitHub Release tag to a module version. No special release assets are required — the module source code is downloaded directly from the GitHub tarball API. To access private repositories, configure the registry with a PAT or GitHub App that has read access to those repos.
§Example Terraform Usage
§Provider
terraform {
required_providers {
myprovider = {
source = "registry.example.com/myorg/myprovider"
version = "1.0.0"
}
}
}§Module
The module source address follows the format <registry>/<namespace>/<name>/<system>,
where system is the name of the remote system the module targets (e.g. aws, azurerm,
kubernetes). It commonly matches a provider type name but can be any keyword that makes
sense for your registry’s organisation.
module "mymodule" {
source = "registry.example.com/myorg/mymodule/aws"
version = "1.0.0"
}Structs§
- Registry
- The main Terraform Provider Registry.
- Registry
Builder - A builder for configuring and creating a
Registry.
Enums§
- Encoding
Key - Encoding key types
- Registry
Error - Errors that can occur while configuring, building, or operating the
crate::Registry.