Azure / terraform-azurerm-lz-vending

Terraform module to deploy landing zone subscriptions (and much more) in Azure
https://registry.terraform.io/modules/Azure/lz-vending/azurerm
MIT License
166 stars 79 forks source link

feat: add an additional flag to deploy default resource providers #349

Closed kewalaka closed 6 months ago

kewalaka commented 7 months ago

Description

Is your feature request related to an issue?

When calling the vending module, there are two variables that control resource providers:

subscription_register_resource_providers_enabled subscription_register_resource_providers_and_features

I would like a mechanism to deploy the defaults but I can't see a way to do this in a generic way.

Lets assume you pass it via a var:

module "lz_vending" {
  source   = "Azure/lz-vending/azurerm"
  version  = "4.0.2"
  for_each = local.landing_zone_data_map

  # resource providers
  subscription_register_resource_providers_and_features = var.resource_providers

This would allow you to specify no resource providers ({}) or a map - but there's no option that means "use the default setting"

In order to use the default, i'd need to replicate that default value in the root module code.

Describe the solution you'd like

One possible way to accomplish this would be to have a flag:

variable "subscription_register_resource_providers_defaults" {
  type        = bool
  description = <<DESCRIPTION
Whether to register the default set of resource providers for the subscription.
DESCRIPTION
  default     = false
}

locals {
  subscription_register_resource_providers = var.subscription_register_resource_providers_defaults ? 
  {
        "Microsoft.ApiManagement"           = [],
        "Microsoft.AppPlatform"             = [],
        # etc
  } 
  : var.subscription_register_resource_providers_and_features
}

Thoughts on this approach? Am I missing an obvious way to do this more cleanly?

jaredfholgate commented 6 months ago

@kewalaka You just need to set subscription_register_resource_providers_enabled to true and not set a value for subscription_register_resource_providers_and_features to use the defaults. I'm not sure if I am missing something here?

kewalaka commented 6 months ago

hi @jaredfholgate the issue is in the code that calls the module. Lets say you want to support a scenario where a user can optionally specify the resource providers they want.

We create a variable - say var.resource_providers

module "lz_vending" {
   <snip>
   # the root module variable assignment allows users to decide what RPs they want registered.
   subscription_register_resource_providers_and_features = var.resource_providers
   <snip>
}

This variable is populated by some external vars (I use a yaml file, but they same is true if you're using a tfvars)

If you don't have that assignment, how would you provide the capability for a user to specify what RPs they want to deploy?

With the above;

.. as far as I can see there's no way to not pass in a variable. (the only wacky thing I can think of is to duplicate the entire block and not do any assignment based on some flag, but that's worse than just making a copy of the default providers in a local within the calling code. 😊)

Apologies if i'm missing something obvious - I just can't see it.

matt-FFFFFF commented 6 months ago

@kewalaka

Can you set it to null in the YAML?

kewalaka commented 6 months ago

@kewalaka

Can you set it to null in the YAML?

holy moly, how does that work...

# the yaml snippet
resource_providers_enabled: true

terraform snippet:

module "lz_vending" {
  source = "git::https://github.com/kewalaka/terraform-azurerm-lz-vending?ref=feat/add-rg-dependency"
  # version  = "4.1.0"
  for_each = local.landing_zone_data_map

  <snip/>

  # resource providers
  subscription_register_resource_providers_enabled      = try(each.value.resource_providers_enabled, null) == null ? false : each.value.resource_providers_enabled
  subscription_register_resource_providers_and_features = try(each.value.resource_providers_and_features, null)

  <snip/>
}

but i thought nullable=false meant you can't assign null? 🀯

thanks though @matt-FFFFFF , that works perfectly

image

jaredfholgate commented 6 months ago

@kewalaka Can you set it to null in the YAML?

holy moly, how does that work...

# the yaml snippet
resource_providers_enabled: true

terraform snippet:

module "lz_vending" {
  source = "git::https://github.com/kewalaka/terraform-azurerm-lz-vending?ref=feat/add-rg-dependency"
  # version  = "4.1.0"
  for_each = local.landing_zone_data_map

  <snip/>

  # resource providers
  subscription_register_resource_providers_enabled      = try(each.value.resource_providers_enabled, null) == null ? false : each.value.resource_providers_enabled
  subscription_register_resource_providers_and_features = try(each.value.resource_providers_and_features, null)

  <snip/>
}

but i thought nullable=false meant you can't assign null? 🀯

thanks though @matt-FFFFFF , that works perfectly

image

Per the docs: https://developer.hashicorp.com/terraform/language/values/variables#disallowing-null-input-values

If nullable is false and the variable has a default value, then Terraform uses the default when a module input argument is null.