Search code examples
terraform

How do two slashes in Terraform source work?


Here is my Terraform Karpenter module:

module "karpenter" {
  source = "terraform-aws-modules/eks/aws//modules/karpenter"
  cluster_name = module.eks.cluster_name
  node_iam_role_additional_policies = {
    AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
  }
}

You can see source has two slashes between "aws" and "modules". I initially thought I made a mistake, however, it turns out two slashes work well.

The document also has two slash.

If I update to one slash and run terraform apply, it will actually throw error instead:

│ Error: Invalid module source address
│
│   on main.tf line 73, in module "karpenter":
│   73:   source       = "terraform-aws-modules/eks/aws/modules/karpenter"
│
│ Terraform failed to determine your intended installation method for remote module package "terraform-aws-modules/eks/aws/modules/karpenter".
│
│ If you intended this as a path relative to the current module, use "./terraform-aws-modules/eks/aws/modules/karpenter" instead. The "./" prefix indicates that the address is a relative filesystem path.
╵

This is folder structure of .terraform after I run terraform init:

enter image description here

For curiosity, could someone help explain how does this path with two slashes work in the source? Thanks!


Solution

  • The use of double slashes (//) in the Terraform module source path references subdirectories within a module repository. Let me attempt explaining this in the best way possible.

    Terraform allows module source addresses to take different forms:

    • Local paths
    • Git repositories
    • Terraform Registry modules

    To specify a subdirectory within a Terraform Registry module or Git repository, use // in the source path:

    source = "<module-source>//<subdirectory>"
    

    In your case:

    source = "terraform-aws-modules/eks/aws//modules/karpenter"
    
    • terraform-aws-modules/eks/aws points to the module on the Terraform Registry.
    • //modules/karpenter tells Terraform to use the karpenter subdirectory within that module.

    Using a single slash (/) leads to an error:

    source = "terraform-aws-modules/eks/aws/modules/karpenter"
    

    This error occurs because Terraform interprets this as a local relative path, not a subdirectory in the Registry module, resulting in an invalid module source address error.

    After running terraform init, Terraform stores modules in:

    • .terraform/modules/

    This directory reflects the module paths specified in your configuration.

    To wrap it all up, using // correctly directs Terraform to subdirectories within remote module repositories, avoiding path interpretation issues. For more details, check the Terraform documentation on modules in package sub-directories.

    Hope this helps.