Arcones
Arcones

Reputation: 4712

How can I get the Terraform module name programmatically?

I have defined the following Terraform module:

module "lambda" {
  source                = "../lambda"
  region                =  "us-west-1"
  account               = "${var.account}"
}

How can I take advantage from the module name to set the source parameter with an interpolation? I wish something like:

module "lambda" {
  source                = "../${this.name}"
  region                =  "us-west-1"
  account               = "${var.account}"
}

Upvotes: 14

Views: 18034

Answers (3)

brownlee
brownlee

Reputation: 24

As mentioned, self is not available in modules so you would have to pass the name explicitly.

I'm adding another example since the above examples don't differentiate between the name of the module and the instances that call it.

Here is the "router" module:

variable "name" {
  description = "The name of this instance"
  type = string
}

locals {
  module = basename(path.module)
}

output "message" {
  value = "${var.name} is a instance of ${local.module}"
}

Here is a root module that instantiates two routers by calling the router module twice:

terraform {
}

module "r1" {
  source = "../modules/router"
  name = "r1"  # must match module label since there is no "self"
}

module "r2" {
  source = "../modules/router"
  name = "r2"  # must match module label since there is no "self"
}

locals {
  module_messages = [
    module.r1.message,
    module.r2.message,
  ]
}

output "main" {
  value = local.module_messages
}

Upvotes: 0

DjangoHeads
DjangoHeads

Reputation: 649

locals {
  module = basename(abspath(path.module))
}

{
...
  some-id = local.module
...
}

Upvotes: 11

charli
charli

Reputation: 1778

I think is not possible. There's a self that allows you to reference attributes within your resource, but the identifier is not an attribute. Also, self is only allowed within provisioners.

I guess the only way to accomplish what you want is templating the .tf files, like:

module {{ my-module}} {
  source                = "../{{ my-module }}"
  region                =  "us-west-1"
  account               = "${var.account}"

but you should render the templates before terraform init. It's straightforward to setup in a CI pipeline, but I find it cumbersome when working locally.

Upvotes: 5

Related Questions