Dynamically retrieve `resource_type` from an object/resource

I would like to create a module which will enable monitoring settings on a resource (Azure) depending on its type, i.e. virtual network will have its own config as opposed to virtual machine. Ideally, I just want to pass a resource to the module (e.g. azurerm_virtual_network.this) as an input variable. It can be defined as ANY type. All I need from it is its type (e.g. azurerm_virtual_network) and Id. By having its type I can use lookup on a config map and get monitoring and logging categories I need for that particular resource type, then configure it y having its ID.

So, I believe I can pass any variable to the module (type any, default)… but I’ve no idea if there’s a simple way to then extract resource_type inside of the module? Does it preserve the resource type at all, or does it perform type conversion behind the scenes to object type removing all meta data?

Thanks!

Hi @tymofii.dmytrenko,

In Terraform there is a distinction between a resource (declared by a resource block) and the object values that are produced by applying it. A reference to example.foo produces an object whose type is derived from the schema of resource type “example”, but that object doesn’t know that it is an “example”, only that it has a particular set of attributes.

Therefore to model what you are describing with Terraform will require a different approach.

For Azure in particular, the remote API tends to generate fully-qualified ID strings that include the object type and the object name, along with subscription ID and resource group information where relevant. If that is true for all of the resource types you are interested in here then you could require only an id attribute and let that provide all of the needed information packed into a single string:

variable "target" {
  type = object({
    id = string
  })
}

A variable declared as above will accept the object representation of any resource type and allow you to access its ID as var.target.id.

One terminology note to keep in mind here is that both Terraform and Azure have a concept called “resource” but they are only indirectly related. In Terraform that word represents the resource block, while I’m Azure it represents each of the (possibly-multiple) remote objects that the Terraform resource block represents. Therefore when the Azure provider arguments use the word “resource” they will typically mean it in the Azure API sense of the word, and not in the Terraform sense of the word. In particular, a “resource ID” in provider arguments means a string like I described above with all of the information packed into it, and not Terraform’s own resource instance addresses.

@apparentlymart thanks a lot for this level of detail. I think this matches how I thought it works :slight_smile: meaning I either have to extract resource type from the ID using regex, or just pass an additional variable to the module describing the type of a resource (which makes it less dynamic if you know what I mean). Ok, at least I know the restrictions! Thanks again