use dynamic block to create optional attribute inside resource

Viewed 466

I have to set optional attribute to add custom provider inside a terraform resource to reuse a resource with multiple providers.

i need something like this

resource "aws_kms" "key" {
    provider = aws."custom_alias"

    description = "xxx"
    policy    = "yyy"
 
}

in the above resource block, I want to pass different values to the provider attribute. to use the default provider, I want to pass a null value to this, and to use the custom provider, I want to pass the custom alias of the provider.

The provider attribute doesn't support variables. so I can't just set it to a variable (that would be very easy, not sure why it's not supported!)

I'm thinking I can use a dynamic block to create this attribute inside a resource provider = aws."custom_alis"

Not sure if that's possible to do. as most of the examples, i see for the dynamic block is to cerate a dynamic block inside a resource like

settings {
     xyz = abc
     abc = xyz
}

Not sure using dynamic if I can create an optional attribute inside the resource.

looking for a suggestion on how to handle this use case?

The goal is to add provider attributes inside resources with different values.

Thanks in advance!

1 Answers

Terraform does not support dynamic provider selection. There's already a popular [feature request][1] for this.

What you can do instead is put your re-usable code inside a [module][2] and create the module multiple times with different providers:

module "mymodule_provider1" {
  source = "./path/to/module"
  providers = {
    aws = aws.provider1
  }
}
module "mymodule_provider2" {
  source = "./path/to/module"
  providers = {
    aws = aws.provider2
  }
}

This is the "suggested" way to do it by HashiCorp, but it has the limitation that the number of modules can't be dynamic. If you really need the number of modules to be dynamic and the providers can't be created statically, then you can create the provider inside the module and then use the for_each argument on the module itself. You'd have to pass in the provider initialization values as input arguments into the module.

EDIT: Sorry, it wasn't until I tried it myself that I remembered that Terraform doesn't allow for_each in a module if the module creates providers internally. So, I'm afraid, there's no way I'm aware of to do what you're trying to do. You'll have to create the providers statically.

Related