From a3ed5b66d9b6706fec597b0c25ad5233a3a305c6 Mon Sep 17 00:00:00 2001 From: Luke Taylor <77284962+luke-taylor@users.noreply.github.com> Date: Wed, 27 Sep 2023 23:19:56 +0100 Subject: [PATCH] feat: add use azapi option for subscription creation. (#253) * Add initial config * run make fmt and make docs * run make lint * run make test * update test * Fix Test * Update GO Version --------- Co-authored-by: Matt White <16320656+matt-FFFFFF@users.noreply.github.com> --- README.md | 21 +++++ main.subscription.tf | 1 + modules/subscription/README.md | 9 ++ modules/subscription/locals.tf | 2 +- modules/subscription/main.tf | 25 +++++- modules/subscription/outputs.tf | 2 +- .../main.tf | 5 ++ modules/subscription/variables.tf | 8 ++ tests/go.mod | 2 +- tests/go.sum | 13 +++ tests/subscription/subscriptionDeploy_test.go | 89 +++++++++++++++++++ tests/subscription/subscription_test.go | 46 ++++++++++ variables.subscription.tf | 21 +++++ 13 files changed, 239 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 040c1360..6578c68e 100644 --- a/README.md +++ b/README.md @@ -558,6 +558,27 @@ Type: `map(string)` Default: `{}` +### [subscription\_use\_azapi](#input\_subscription\_use\_azapi) + +Description: Whether to create a new subscription using the azapi provider. This may be required if the principal running +terraform does not have the required permissions to create a subscription under the default management group. +If enabled, the following must also be supplied: +- `subscription_alias_name` +- `subscription_display_name` +- `subscription_billing_scope` +- `subscription_workload` +Optionally, supply the following to enable the placement of the subscription into a management group: +- `subscription_management_group_id` +- `subscription_management_group_association_enabled` +If disabled, supply the `subscription_id` variable to use an existing subscription instead. +> **Note**: When the subscription is destroyed, this module will try to remove the NetworkWatcherRG resource group using `az cli`. +> This requires the `az cli` tool be installed and authenticated. +> If the command fails for any reason, the provider will attempt to cancel the subscription anyway. + +Type: `bool` + +Default: `false` + ### [subscription\_workload](#input\_subscription\_workload) Description: The billing scope for the new subscription alias. diff --git a/main.subscription.tf b/main.subscription.tf index b55d14a3..03a53d4e 100644 --- a/main.subscription.tf +++ b/main.subscription.tf @@ -13,5 +13,6 @@ module "subscription" { subscription_management_group_association_enabled = var.subscription_management_group_association_enabled subscription_management_group_id = var.subscription_management_group_id subscription_tags = var.subscription_tags + subscription_use_azapi = var.subscription_use_azapi subscription_workload = var.subscription_workload } diff --git a/modules/subscription/README.md b/modules/subscription/README.md index f059b399..2b225b7b 100644 --- a/modules/subscription/README.md +++ b/modules/subscription/README.md @@ -171,6 +171,14 @@ Type: `map(string)` Default: `{}` +### [subscription\_use\_azapi](#input\_subscription\_use\_azapi) + +Description: Whether to use the azapi\_resource resource to create the subscription alias. This includes the subscription alias in the management group. + +Type: `bool` + +Default: `false` + ### [subscription\_workload](#input\_subscription\_workload) Description: The billing scope for the new subscription alias. @@ -188,6 +196,7 @@ Default: `""` The following resources are used by this module: +- [azapi_resource.subscription](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/resource) (resource) - [azurerm_management_group_subscription_association.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_group_subscription_association) (resource) - [azurerm_subscription.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subscription) (resource) diff --git a/modules/subscription/locals.tf b/modules/subscription/locals.tf index 7d3b2402..9f10adc7 100644 --- a/modules/subscription/locals.tf +++ b/modules/subscription/locals.tf @@ -1,6 +1,6 @@ locals { # subscription_id_alias is the id of the newly created subscription, if it exists. - subscription_id_alias = try(azurerm_subscription.this[0].subscription_id, null) + subscription_id_alias = try(azurerm_subscription.this[0].subscription_id, jsondecode(azapi_resource.subscription[0].output).properties.subscriptionId, null) # subscription_id is the id of the newly created subscription, or the id supplied by var.subscription_id. subscription_id = coalesce(local.subscription_id_alias, var.subscription_id) diff --git a/modules/subscription/main.tf b/modules/subscription/main.tf index 0b945a44..0019c805 100644 --- a/modules/subscription/main.tf +++ b/modules/subscription/main.tf @@ -1,6 +1,6 @@ # The azurerm_subscription resource represents the subscription alias that is being created. resource "azurerm_subscription" "this" { - count = var.subscription_alias_enabled ? 1 : 0 + count = var.subscription_alias_enabled && !var.subscription_use_azapi ? 1 : 0 subscription_name = var.subscription_display_name alias = var.subscription_alias_name billing_scope_id = var.subscription_billing_scope @@ -11,7 +11,28 @@ resource "azurerm_subscription" "this" { # This resource ensures that we can manage the management group for the subscription # throughout its lifecycle. resource "azurerm_management_group_subscription_association" "this" { - count = var.subscription_management_group_association_enabled ? 1 : 0 + count = var.subscription_management_group_association_enabled && !var.subscription_use_azapi ? 1 : 0 management_group_id = "/providers/Microsoft.Management/managementGroups/${var.subscription_management_group_id}" subscription_id = "/subscriptions/${local.subscription_id}" } + +resource "azapi_resource" "subscription" { + count = var.subscription_alias_enabled && var.subscription_use_azapi ? 1 : 0 + + type = "Microsoft.Subscription/aliases@2021-10-01" + name = var.subscription_alias_name + parent_id = "/" + + body = jsonencode({ + properties = { + displayName = var.subscription_display_name + workload = var.subscription_workload + billingScope = var.subscription_billing_scope + additionalProperties = { + managementGroupId = var.subscription_management_group_association_enabled ? "/providers/Microsoft.Management/managementGroups/${var.subscription_management_group_id}" : null + tags = var.subscription_tags + } + } + }) + response_export_values = ["properties.subscriptionId"] +} diff --git a/modules/subscription/outputs.tf b/modules/subscription/outputs.tf index 367f7623..7a371fde 100644 --- a/modules/subscription/outputs.tf +++ b/modules/subscription/outputs.tf @@ -15,7 +15,7 @@ DESCRIPTION } output "management_group_subscription_association_id" { - value = var.subscription_management_group_association_enabled ? azurerm_management_group_subscription_association.this[0].id : null + value = var.subscription_management_group_association_enabled ? try(azurerm_management_group_subscription_association.this[0].id, null) : null description = < **Note**: When the subscription is destroyed, this module will try to remove the NetworkWatcherRG resource group using `az cli`. +> This requires the `az cli` tool be installed and authenticated. +> If the command fails for any reason, the provider will attempt to cancel the subscription anyway. +DESCRIPTION +}