-
Notifications
You must be signed in to change notification settings - Fork 176
Description
When publishing modules from a monorepo to the HCP Terraform private registry using source_directory and tag_prefix, there is no way to specify the module provider name. The
module_provider attribute has an ExactlyOneOf constraint with vcs_repo, preventing their combined use.
However, the HCP Terraform UI allows specifying the provider name when creating VCS-backed modules with source directories, indicating the underlying API supports this combination.
Monorepo Directory Structure
Our repository is organized by provider, with modules nested underneath:
terraform-modules/ # Repository root
├── random/ # Provider: random
│ └── random-string/ # Module: random-string
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── aws/ # Provider: aws
│ └── vpc/ # Module: vpc
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── azurerm/ # Provider: azurerm
│ └── resource-group/ # Module: resource-group
│ └── main.tf
└── registry/ # Registry automation
└── main.tf # Publishes modules to HCP Terraform
We use tag-based versioning with prefixes to version each module independently:
- random-random-string-v1.0.0 → publishes random/random-string as v1.0.0
- aws-vpc-v2.1.0 → publishes aws/vpc as v2.1.0
Desired Configuration
locals {
module_files = fileset("${path.module}/..", "*/*/main.tf")
modules = {
for path in local.module_files :
"${dirname(dirname(path))}-${basename(dirname(path))}" => {
provider = dirname(dirname(path)) # e.g., "random"
name = basename(dirname(path)) # e.g., "random-string"
source_dir = dirname(path) # e.g., "random/random-string"
tag_prefix = "${dirname(dirname(path))}-${basename(dirname(path))}-"
}
if dirname(dirname(path)) != "registry"
}
}
resource "tfe_registry_module" "modules" {
for_each = local.modules
organization = "My-Org"
name = each.value.name
module_provider = each.value.provider # ❌ Blocked by provider validation
vcs_repo {
identifier = "my-org/terraform-modules"
oauth_token_id = "ot-xxx"
source_directory = each.value.source_dir
tag_prefix = each.value.tag_prefix
tags = true
}
}
Current Behavior
The provider rejects this configuration:
Error: Invalid combination of arguments
with tfe_registry_module.modules["random-random-string"],
on main.tf line 25, in resource "tfe_registry_module" "modules":
25: module_provider = each.value.provider
"module_provider": only one of `module_provider,vcs_repo` can be specified,
but `module_provider,vcs_repo` were specified.
Testing Without module_provider
When omitting module_provider (and optionally name), the API returns:
Error: Error creating registry module from repository my-org/terraform-modules: unprocessable entity
Validation failed: Name is invalid
This confirms the API requires explicit name/provider values for repositories that don't follow the terraform-- naming convention.
Root Cause
The provider schema defines:
"module_provider": {
ExactlyOneOf: []string{"vcs_repo"},
...
}
This constraint was appropriate before monorepo support (source_directory/tag_prefix) was added in v0.69.0, but it now prevents valid use cases.
Expected Behavior
Allow module_provider (and name) to be specified alongside vcs_repo when source_directory is set, since:
- The HCP Terraform UI supports this workflow
- The API requires these values for non-standard repo names
- Monorepos with source_directory inherently don't follow terraform-- naming
Proposed Solution
Modify the schema validation to conditionally allow module_provider when vcs_repo.source_directory is set:
"module_provider": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
// Remove ExactlyOneOf, or make it conditional on source_directory
},
Alternatively, add provider as an attribute within the vcs_repo block for monorepo configurations.
Workarounds (All Suboptimal)
- Create via UI, import to Terraform - Doesn't scale for new modules
- Use API directly via provisioner - No state management
- Restructure repo to terraform-- directories - Breaking change
Environment
- Terraform: >= 1.14.0
- Provider version: 0.73.0
- HCP Terraform (cloud)