How can I reference a module's source within the module?

I would like to be able to reference the module’s source value within the module. In this specific case, I’d like to be able to pass in a source value and use it for resource tagging. We are using modules extensively as a governance tool and would like to be able to track AWS resources built using modules and ensuring they have been built with specific versions of the module. Although, access to meta arguments such as source, version, etc. could be useful for other purposes.

module {
    source = "git::https://example.com/vpc.git?ref=v1.2.0"
}

Then, within the module, be able to parse that value:

locals {
    module_source = reverse(split("/", self.source))[0]  # for example
    module_name = split(".git?ref=", local.module_source)[0]
    module_version = split(".git?ref=", local.module_source)[1]
}

And later use it to tag a resource:

resource aws_instance {
    ...
    tags = {
        module_version = local.module_version
        module_name = local.module_name
    }
}

Is this possible natively? If not, is there a good suggestion for achieving the end-result?

We just declare it as local in the module and tag all the resources with it. Changing the local is a manual process, done just prior to the pull request.

Smart? Not really, but not our biggest problem.

Thanks! I think I’d try to work on some local-exec commands within the module before trying to manage them all manually.

Hi @phillipjf,

Terraform does not have first-class features for this sort of thing because it’s designed to try to ensure that a module’s behavior doesn’t vary depending on where it was installed from. That would tend to be a surprising extra constraint on a module that module callers would not expect.

In a closed ecosystem where everything is controlled by one team you can of course make some different tradeoffs if you want, but you’ll be working against Terraform rather than with it, unfortunately.

In most cases I’ve seen folks just do what @bentterp suggested: make every module aware of its logical name within your system and leave it at that. Subsystem names don’t change often in most systems, so in practice it will tend to just be a “set it and forget it” sort of thing. If your situation is different enough that this becomes an ongoing concern, perhaps you could write a small program that you can run during module development that infers the containing repository name and generates a codebase.tf file with one or more local values in it, which you can then re-rerun if you rename the repository.