Search code examples
githubweburlterraform

terraform module sources github url. which format?


I saw a terraform code which wrote as

source = "github.com/brikis98/terraform-up-and-running-code//code/terraform/04-terraform-module/module-example/modules/services/webserver-cluster?ref=v0.1.0"

But, when I access this URL in chrome, It can't reach its resource.

So. I wonder what this URL follows the format. Is there any rule on it?

double slash (//) is suspicious.. to me.

I already reviewed document in terraform module section. But It doesn't describe about it.


Solution

  • The full documentation on what is valid inside a module source argument is Module Sources.

    The example you've shown in your question includes parts which correspond with two different sections on that page:

    • github.com/brikis98/terraform-up-and-running-code is one of the source address schemes described under GitHub.

      Because GitHub is a commonly-used version control host, Terraform has special support for it and knows that any GitHub repository is to be cloned using Git, so Terraform can automatically rewrite that shorthand into the following canonical form internally:

      git::https://github.com/brikis98/terraform-up-and-running-code

      That longer version includes the git:: prefix which tells Terraform that it should treat the following as a Git URL, and Terraform also automatically adds the https:// prefix to make this an HTTPS URL.

      This git:: prefix is actually the syntax for Generic Git Repositories, so you can see that Terraform is internally transforming this GitHub-specific URL into a generic Git URL. The ?ref=v0.1.0 suffix is also part of the Generic Git source address scheme, as described in Selecting a Revision.

      When you run terraform init Terraform will report the canonical version of the source address as part of its report that it's installing this module package.

    • //code/terraform/04-terraform-module/module-example/modules/services/webserver-cluster is the optional subdirectory specification.

      "Module package" is a generic word for a package of files that Terraform can download which contains one or more modules. A Git repository is one example of a module package as far as Terraform is concerned.

      By default Terraform expects to find the module source code in the root of the module package, but if the source address includes a portion introduced by the // marker then Terraform takes that as a subdirectory within the package where it should find the specific module you were trying to call. This particular GitHub repository contains many different Terraform modules belonging to different parts of the book it's supporting, so references to this repository will always have a subdirectory portion.

    Overall then Terraform understands this source address string by:

    1. Splitting it into "package" and "subdirectory" parts:

      • Package: github.com/brikis98/terraform-up-and-running-code?ref=v0.1.0
      • Subdirectory: code/terraform/04-terraform-module/module-example/modules/services/webserver-cluster
    2. Noticing that the package part is using the github.com shorthand and so rewriting it into the canonical form:

      • Package git::https://github.com/brikis98/terraform-up-and-running-code?ref=v0.1.0

      (This is the package address that terraform init will report when it's installing.)

    3. Now that the package includes the installation method prefix git::, Terraform knows that it should obtain the module package by running a command something like the following:

      • git clone https://github.com/brikis98/terraform-up-and-running-code
      • git checkout v0.1.0

      Terraform always downloads external module packages into a hidden cache directory under the .terraform directory on your local system. The exact structure of that directory is an implementation detail that might change between different versions of Terraform, but in current Terraform the subdirectory is named after the label in your module block.

    4. If the download succeeded then Terraform now has a copy of the package in a directory something like .terraform/modules/example.

      It will then join the subdirectory portion to find the final location of the module in the local cache:

      • .terraform/modules/example/code/terraform/04-terraform-module/module-example/modules/services/webserver-cluster

    That final directory must contain at least one .tf file describing the contents of the module, which Terraform will then load and decode in a similar way to how it decodes the root module.