Skip to content

Terraform can't access private providers from TFC organizations with underscores in their names #32694

@nfagerlund

Description

@nfagerlund

Terraform Version

1.4.0-beta2

Terraform Configuration Files

terraform {
  required_providers {
    fakerancher = {
      source  = "app.staging.terraform.io/example_corp/fakerancher"
      version = ">= 0.0.1"
    }
  }

  cloud {
    hostname = "app.staging.terraform.io"
    organization = "example_corp"
    workspaces {
      name = "beta-jam"
    }
  }
}

Debug Output

(Omitting, since I already found the code in question.)

Expected Behavior

Terraform should be able to download and use providers published in any valid organization namespace, from the public registry or from TFC/TFE's private registry.

Actual Behavior

If a TFC organization has underscores in its name (edit: or doubled hyphens --), Terraform cannot access any providers it publishes:

Initializing Terraform Cloud...
There are some problems with the configuration, described below.

The Terraform configuration must be valid before initialization so that
Terraform can determine which modules and providers need to be installed.
╷
│ Error: Invalid provider namespace
│
│   on main.tf line 4, in terraform:
│    4:       source  = "app.staging.terraform.io/example_corp/fakerancher"
│
│ Invalid provider namespace "" in source "app.staging.terraform.io/example_corp/fakerancher": must contain only
│ letters, digits, and dashes, and may not use leading or trailing dashes"
╵

(Note also the malformed error message, with an empty string in place of the provided namespace.)

I've tracked this down to tfaddr.ParseProviderPart, in the hashicorp/terraform-registry-address package. It uses idna hostname parsing rules to parse namespace and name segments, which I'm pretty sure is invalid given the semantics of those segments; in addition to excluding valid org names, it also flattens the case of the address, which can result in self-inflicted 404s for namespaces that include capital letters.

It should instead match the behavior of our own registries, which basically comes down to [0-9A-Za-z][\w\-]*[0-9A-Za-z].

Steps to Reproduce

  1. terraform init (that's all)

Additional Context

No response

References

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions