Publish Modules¶
Modules can be published to the boring-registry using the upload module command.
Published modules can be referenced in code, for example like the following example configuration:
module "tls-private-key" {
source = "boring-registry.example.com/acme/tls-private-key/aws"
version = "~> 0.1"
}
Uploading modules using the CLI¶
Modules can be published to the registry with the upload module command.
The command:
- Discovers
boring-registry.hclfiles by walking the directory recursively (by default) - Packages each module into an archive
- Uploads the archive to the configured storage backend
The boring-registry.hcl file should be placed in the root directory of the module and must contain a metadata block with the following fields:
metadata {
namespace = "acme" # required: namespace for the module
name = "tls-private-key" # required: module name
provider = "aws" # required: provider name
version = "0.1.0" # required by default, must be omitted when using --version flag
}
Module versioning¶
Modules use version numbers following the Semantic Versioning 2.0 conventions.
The version of a module to be published can be specified in two ways:
- In the
boring-registry.hclfile - allows for recursive discovery of multiple (nested) modules from a root directory - Via the
--versionCLI flag - useful for dynamic versioning, for example in CI/CD pipelines.
Allows to set the version depending on git tags, build metadata, or semantic release tools.
When using the --version flag, the version field in the boring-registry.hcl must not be set:
metadata {
namespace = "acme"
name = "tls-private-key"
provider = "aws"
# version is omitted when using --version flag
}
The --version flag is mutually exclusive with recursive module discovery (--recursive)!
An example usage to upload a module with --versioning is boring-registry upload module --version "0.1.0" ./path/to/tls-private-key.
Recursive vs. non-recursive upload¶
By default, the upload module command walks the directory tree recursively, searching for all boring-registry.hcl files and uploading each discovered module.
This is convenient for uploading multiple modules at once.
Use --recursive=false to disable recursive discovery and only upload the module in the specified directory.
Handling Existing Module Versions¶
By default, the upload module command will silently skip modules that already exist in the registry.
This ensures that re-running uploads is idempotent and doesn’t fail.
This behavior can be disabled by setting the --ignore-existing=false flag.
Module version constraints¶
Version constraints allow you to filter which module versions get uploaded based on their version string.
This is useful for implementing branch-specific upload policies in CI/CD pipelines, for example.
Note
Version constraints work with both versioning approaches (version specified in boring-registry.hcl or via the --version flag).
Semantic Version Constraints¶
The --version-constraints-semver flag filters modules based on semantic versioning rules.
It uses the Version Constraint Syntax used in OpenTofu/Terraform.
The following showcases some common use cases:
Exclude pre-releases (production releases only)¶
# Only uploads releases like 0.1.0, 2.1.5
# Skips pre-releases like 1.0.0-beta, 2.0.0-rc1
boring-registry upload module --version-constraints-semver=">=v0" ./modules/
This is useful for restricting CI to only publish releases from the
main branch.
Multiple version constraints can be passed as well:
# Only publishes release versions >= 1.0.0 and < 3.0.0
boring-registry upload module --version-constraints-semver=">=1.0.0,<3.0.0" ./modules/
Regular Expression Constraints¶
The --version-constraints-regex flag allows you to filter versions using a regular expression pattern.
This provides more flexible matching than semantic version constraints.
Only upload pre-releases¶
# Match only pre-release versions like 1.0.0-beta, 2.0.0-rc.1
boring-registry upload module --version-constraints-regex="^[0-9]+\.[0-9]+\.[0-9]+-|\d*[a-zA-Z-][0-9a-zA-Z-]*$" ./modules/`
This is useful for allowing pre-releases to be published from feature branches for testing, while preventing publishing releases from non-main branches.
Examples¶
Fail early if module version already exists¶
By default the upload module command will silently ignore already uploaded versions of a module and return exit code 0.
This can become a problem for tagging mono-repositories as it is not clear if the module version is new or already uploaded.
Setting the --ignore-existing=false flag will force the upload command to return exit code 1 in such case.
In combination with --recursive=false the exit code can be used to create a Git tag only if a new version was uploaded.
for i in $(ls -d */); do
printf "Operating on module \"${i%%/}\"\n"
# upload the given directory
./boring-registry upload module --recursive=false --ignore-existing=false ${i%%/}
# tag the repo with a tag composed out of the boring-registry.hcl if not already exist
if [ $? -eq 0 ]; then
# git tag the repository with the version from boring-registry.hcl
# hint: use mattolenik/hclq to parse the hcl file
fi
done