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
+}