Skip to content

Commit

Permalink
fix: v4 issues (#326)
Browse files Browse the repository at this point in the history
* fix: docs fixes #297

* chore: module version

* fix: fixes #323

* fix: fixes #289

* fix: fixes bug: When routing intent is enabled in the module subsequent runs attempt to remove the route table association and propagation #289

* docs: make docs

* test: add test for #323
  • Loading branch information
matt-FFFFFF authored Feb 3, 2024
1 parent cdffd0f commit 63d73dd
Show file tree
Hide file tree
Showing 15 changed files with 251 additions and 30 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -764,8 +764,10 @@ Type:

```hcl
map(object({
definition = string
relative_scope = string
definition = string
relative_scope = optional(string, "")
condition = optional(string, "")
condition_version = optional(string, "")
}))
```

Expand Down Expand Up @@ -854,9 +856,9 @@ only one of the virtual networks should have `resource_group_creation_enabled` s
- `vwan_propagated_routetables_labels`: A list of labels of route tables to propagate to the virtual network. [optional - leave empty to use `["default"]`]
- `vwan_propagated_routetables_resource_ids`: A list of resource IDs of route tables to propagate to the virtual network. [optional - leave empty to use `defaultRouteTable` on hub]
- `vwan_security_configuration`: A map of security configuration values for VWAN hub connection - see below. [optional - default empty]
- `secure_internet_traffic`: Whether to forward internet-bound traffic to the destination specified in the routing policy. Not compatible with `routing_intent_enabled`. [optional - default `false`]
- `secure_internet_traffic`: Whether to forward internet-bound traffic to the destination specified in the routing policy. [optional - default `false`]
- `secure_private_traffic`: Whether to all internal traffic to the destination specified in the routing policy. Not compatible with `routing_intent_enabled`. [optional - default `false`]
- `routing_intent_enabled`: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. Not compatible with `secure_internet_traffic` or `secure_private_traffic`. [optional - default `false`]
- `routing_intent_enabled`: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. [optional - default `false`]

### Tags

Expand Down
2 changes: 1 addition & 1 deletion locals.version.tf.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"locals": {
"module_version": "3.5.0"
"module_version": "4.0.1"
}
}
2 changes: 1 addition & 1 deletion main.roleassignment.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module "roleassignment" {
}

# The roleassignments_umi module creates role assignments from the data
# supplied in the var.uni_role_assignments variable
# supplied in the var.umi_role_assignments variable
module "roleassignment_umi" {
source = "./modules/roleassignment"
depends_on = [
Expand Down
4 changes: 2 additions & 2 deletions modules/virtualnetwork/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ only one of the virtual networks should have `resource_group_creation_enabled` s
- `vwan_propagated_routetables_labels`: A list of labels of route tables to propagate to the virtual network. [optional - leave empty to use `["default"]`]
- `vwan_propagated_routetables_resource_ids`: A list of resource IDs of route tables to propagate to the virtual network. [optional - leave empty to use `defaultRouteTable` on hub]
- `vwan_security_configuration`: A map of security configuration values for VWAN hub connection - see below. [optional - default empty]
- `secure_internet_traffic`: Whether to forward internet-bound traffic to the destination specified in the routing policy. Not compatible with `routing_intent_enabled`. [optional - default `false`]
- `secure_internet_traffic`: Whether to forward internet-bound traffic to the destination specified in the routing policy. [optional - default `false`]
- `secure_private_traffic`: Whether to all internal traffic to the destination specified in the routing policy. Not compatible with `routing_intent_enabled`. [optional - default `false`]
- `routing_intent_enabled`: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. Not compatible with `secure_internet_traffic` or `secure_private_traffic`. [optional - default `false`]
- `routing_intent_enabled`: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. [optional - default `false`]

### Tags

Expand Down
24 changes: 14 additions & 10 deletions modules/virtualnetwork/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -162,20 +162,24 @@ resource "azapi_resource" "vhubconnection" {
parent_id = each.value.vwan_hub_resource_id
name = coalesce(each.value.vwan_connection_name, "vhc-${uuidv5("url", azapi_resource.vnet[each.key].id)}")
body = jsonencode({
properties = {
properties = merge({
enableInternetSecurity = each.value.vwan_security_configuration.secure_internet_traffic
remoteVirtualNetwork = {
id = local.virtual_network_resource_ids[each.key]
}
routingConfiguration = each.value.vwan_security_configuration.routing_intent_enabled ? null : {
associatedRouteTable = {
id = each.value.vwan_associated_routetable_resource_id != "" ? each.value.vwan_associated_routetable_resource_id : "${each.value.vwan_hub_resource_id}/hubRouteTables/defaultRouteTable"
}
propagatedRouteTables = {
ids = each.value.vwan_security_configuration.secure_private_traffic ? local.vwan_propagated_noneroutetables_resource_ids[each.key] : local.vwan_propagated_routetables_resource_ids[each.key]
labels = each.value.vwan_security_configuration.secure_private_traffic ? ["none"] : local.vwan_propagated_routetables_labels[each.key]
},
# Only supply routingConfiguration if routing_intent_enabled is set to false
each.value.vwan_security_configuration.routing_intent_enabled ? {} : {
routingConfiguration = {
associatedRouteTable = {
id = each.value.vwan_associated_routetable_resource_id != "" ? each.value.vwan_associated_routetable_resource_id : "${each.value.vwan_hub_resource_id}/hubRouteTables/defaultRouteTable"
}
propagatedRouteTables = {
ids = each.value.vwan_security_configuration.secure_private_traffic ? local.vwan_propagated_noneroutetables_resource_ids[each.key] : local.vwan_propagated_routetables_resource_ids[each.key]
labels = each.value.vwan_security_configuration.secure_private_traffic ? ["none"] : local.vwan_propagated_routetables_labels[each.key]
}
}
}
}
})
})
ignore_body_changes = each.value.vwan_security_configuration.routing_intent_enabled ? ["properties.routingConfiguration"] : []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
resource "azapi_resource" "rg" {
type = "Microsoft.Resources/resourceGroups@2021-04-01"
parent_id = "/subscriptions/${var.subscription_id}"
name = "${var.virtual_networks["primary"].name}-hub"
location = var.virtual_networks["primary"].location
}

resource "azapi_resource" "vwan" {
type = "Microsoft.Network/virtualWans@2021-08-01"
name = "${var.virtual_networks["primary"].name}-vwan"
location = azapi_resource.rg.location
parent_id = azapi_resource.rg.id
body = jsonencode({
properties = {
type = "Standard"
allowBranchToBranchTraffic = true
disableVpnEncryption = false
}
})
}

resource "azapi_resource" "fwpol" {
type = "Microsoft.Network/firewallPolicies@2023-09-01"
parent_id = azapi_resource.rg.id
location = azapi_resource.rg.location
name = "fwpolicy"
body = jsonencode({
properties = {
sku = {
tier = "Standard"
}
threatIntelMode = "Alert"
}
})
}

resource "azapi_resource" "vhub" {
type = "Microsoft.Network/virtualHubs@2021-08-01"
name = "${var.virtual_networks["primary"].name}-vhub"
location = azapi_resource.vwan.location
parent_id = azapi_resource.rg.id
body = jsonencode({
properties = {
addressPrefix = "192.168.100.0/23"
sku = "Standard"
virtualWan = {
id = azapi_resource.vwan.id
}
}
})
}

resource "azapi_resource" "hubfw" {
type = "Microsoft.Network/azureFirewalls@2023-09-01"
name = "hubfw"
location = azapi_resource.rg.location
parent_id = azapi_resource.rg.id
body = jsonencode({
properties = {
sku = {
name = "AZFW_Hub"
tier = "Standard"
}
virtualHub = {
id = azapi_resource.vhub.id
}
hubIPAddresses = {
publicIPs = {
count = 1
}
}
firewallPolicy = {
id = azapi_resource.fwpol.id
}
}
})
}

resource "azapi_resource" "hubfw_routingintent" {
type = "Microsoft.Network/virtualHubs/routingIntent@2023-09-01"
parent_id = azapi_resource.vhub.id
name = "hubfw-routingintent"
body = jsonencode({
properties = {
routingPolicies = [
{
destinations = ["Internet"]
name = "PublicTraffic"
nextHop = azapi_resource.hubfw.id
},
{
destinations = ["PrivateTraffic"]
name = "PrivateTraffic"
nextHop = azapi_resource.hubfw.id
}
]
}
})

}

locals {
virtual_network_primary_merged = merge(var.virtual_networks["primary"], {
vwan_hub_resource_id = azapi_resource.vhub.id
})
virtual_network_secondary_merged = merge(var.virtual_networks["secondary"], {
vwan_hub_resource_id = azapi_resource.vhub.id
})
virtual_networks_merged = {
primary = local.virtual_network_primary_merged
secondary = local.virtual_network_secondary_merged
}
}

module "virtualnetwork_test" {
source = "../../"
subscription_id = var.subscription_id
virtual_networks = local.virtual_networks_merged
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_version = ">= 1.3.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.7.0"
}
azapi = {
source = "Azure/azapi"
version = ">= 1.0.0"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
variable "subscription_id" {
type = string
}

variable "virtual_networks" {
type = any
}
4 changes: 2 additions & 2 deletions modules/virtualnetwork/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ only one of the virtual networks should have `resource_group_creation_enabled` s
- `vwan_propagated_routetables_labels`: A list of labels of route tables to propagate to the virtual network. [optional - leave empty to use `["default"]`]
- `vwan_propagated_routetables_resource_ids`: A list of resource IDs of route tables to propagate to the virtual network. [optional - leave empty to use `defaultRouteTable` on hub]
- `vwan_security_configuration`: A map of security configuration values for VWAN hub connection - see below. [optional - default empty]
- `secure_internet_traffic`: Whether to forward internet-bound traffic to the destination specified in the routing policy. Not compatible with `routing_intent_enabled`. [optional - default `false`]
- `secure_internet_traffic`: Whether to forward internet-bound traffic to the destination specified in the routing policy. [optional - default `false`]
- `secure_private_traffic`: Whether to all internal traffic to the destination specified in the routing policy. Not compatible with `routing_intent_enabled`. [optional - default `false`]
- `routing_intent_enabled`: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. Not compatible with `secure_internet_traffic` or `secure_private_traffic`. [optional - default `false`]
- `routing_intent_enabled`: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. [optional - default `false`]
### Tags
Expand Down
4 changes: 2 additions & 2 deletions tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0
github.com/Azure/terratest-terraform-fluent v0.7.0
github.com/Azure/terratest-terraform-fluent v0.8.0
github.com/google/uuid v1.6.0
github.com/gruntwork-io/terratest v0.46.11
github.com/stretchr/testify v1.8.4
Expand Down Expand Up @@ -55,7 +55,7 @@ require (
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl/v2 v2.19.1 // indirect
github.com/hashicorp/terraform-json v0.18.0 // indirect
github.com/hashicorp/terraform-json v0.21.0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/jinzhu/copier v0.4.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 h1:UrGzkHueDwAWDdjQxC+QaXHd4tVCkISYE9j7fSSXF8k=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0/go.mod h1:qskvSQeW+cxEE2bcKYyKimB1/KiQ9xpJ99bcHY0BX6c=
github.com/Azure/terratest-terraform-fluent v0.7.0 h1:2I+5xOP6RoFCkhov3JhbC5DX8VJIFC2NxpLHw1y2YzE=
github.com/Azure/terratest-terraform-fluent v0.7.0/go.mod h1:lrnMGg+gfJ5KvasYWRX3oYan0TPk6/OIlD6zVs96jf4=
github.com/Azure/terratest-terraform-fluent v0.8.0 h1:QqVlAtPRrfG5bnMFWfn4g7LZM0BwrdybxH036tSRwzE=
github.com/Azure/terratest-terraform-fluent v0.8.0/go.mod h1:ceJO/9aUX4GBipgN2Bru6XTRJE8vXTF6hqtXeBVpNDE=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
Expand Down Expand Up @@ -418,8 +418,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI=
github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
github.com/hashicorp/terraform-json v0.18.0 h1:pCjgJEqqDESv4y0Tzdqfxr/edOIGkjs8keY42xfNBwU=
github.com/hashicorp/terraform-json v0.18.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk=
github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U=
github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
Expand Down
35 changes: 35 additions & 0 deletions tests/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,41 @@ func TestIntegrationResourceGroups(t *testing.T) {
}
}

func TestIntegrationUmiRoleAssignment(t *testing.T) {
t.Parallel()

v := map[string]any{
"subscription_id": "00000000-0000-0000-0000-000000000000",
"location": "westeurope",
"disable_telemetry": true,
"umi_enabled": true,
"umi_name": "umi",
"umi_resource_group_name": "rg-umi",
"umi_role_assignments": map[string]any{
"umi_ra": map[string]any{
"definition": "Owner",
"relative_scope": "",
},
},
}

test, err := setuptest.Dirs(moduleDir, "").WithVars(v).InitPlanShowWithPrepFunc(t, utils.AzureRmAndRequiredProviders)
require.NoError(t, err)
defer test.Cleanup()

resources := []string{
`module.usermanagedidentity[0].azapi_resource.umi`,
`module.usermanagedidentity[0].azapi_resource.rg_lock[0]`,
`module.usermanagedidentity[0].azapi_resource.rg[0]`,
`module.roleassignment_umi["umi_ra"].azurerm_role_assignment.this`,
}

check.InPlan(test.PlanStruct).NumberOfResourcesEquals(len(resources)).ErrorIsNil(t)
for _, v := range resources {
check.InPlan(test.PlanStruct).That(v).Exists().ErrorIsNil(t)
}
}

func getMockInputVariables() map[string]any {
return map[string]any{
"location": "northeurope",
Expand Down
39 changes: 39 additions & 0 deletions tests/virtualnetwork/virtualnetworkDeploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,45 @@ func TestDeployVirtualNetworkValidVhubConnection(t *testing.T) {
test.ApplyIdempotent().ErrorIsNil(t)
}

// TestDeployVirtualNetworkValidVhubConnectionAndRoutingIntent tests the deployment of a virtual network
// with a virtual WAN connection and routing intent.
func TestDeployVirtualNetworkValidVhubConnectionAndRoutingIntent(t *testing.T) {
t.Parallel()

utils.PreCheckDeployTests(t)
testDir := "testdata/" + t.Name()
v, err := getValidInputVariables()
require.NoErrorf(t, err, "could not generate valid input variables, %s", err)
primaryvnet := v["virtual_networks"].(map[string]map[string]any)["primary"]
secondaryvnet := v["virtual_networks"].(map[string]map[string]any)["secondary"]
primaryvnet["vwan_connection_enabled"] = true
secondaryvnet["vwan_connection_enabled"] = true
primaryvnet["vwan_security_configuration"] = map[string]any{
"routing_intent_enabled": true,
}
secondaryvnet["vwan_security_configuration"] = map[string]any{
"routing_intent_enabled": true,
}

test, err := setuptest.Dirs(moduleDir, testDir).WithVars(v).Init(t)
require.NoError(t, utils.AzureRmAndRequiredProviders(test))

require.NoError(t, err)
defer test.Cleanup()

// defer terraform destroy with retry
rtyDestroy := setuptest.Retry{
Max: 3,
Wait: 10 * time.Minute,
}
rtyApply := setuptest.Retry{
Max: 5,
Wait: 5 * time.Minute,
}
defer test.DestroyRetry(rtyDestroy) //nolint:errcheck
test.ApplyIdempotentRetry(rtyApply).ErrorIsNil(t)
}

// TestDeployVirtualNetworkSubnetIdempotency tests that we can make changes
// to the subnet configuration outside the module and that subsequent runs of terraform apply
// are idempotent. See main.tf file in the testdata directory for more details.
Expand Down
6 changes: 4 additions & 2 deletions variables.usermanagedidentity.tf
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ DESCRIPTION

variable "umi_role_assignments" {
type = map(object({
definition = string
relative_scope = string
definition = string
relative_scope = optional(string, "")
condition = optional(string, "")
condition_version = optional(string, "")
}))
nullable = false
default = {}
Expand Down
4 changes: 2 additions & 2 deletions variables.virtualnetwork.tf
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ only one of the virtual networks should have `resource_group_creation_enabled` s
- `vwan_propagated_routetables_labels`: A list of labels of route tables to propagate to the virtual network. [optional - leave empty to use `["default"]`]
- `vwan_propagated_routetables_resource_ids`: A list of resource IDs of route tables to propagate to the virtual network. [optional - leave empty to use `defaultRouteTable` on hub]
- `vwan_security_configuration`: A map of security configuration values for VWAN hub connection - see below. [optional - default empty]
- `secure_internet_traffic`: Whether to forward internet-bound traffic to the destination specified in the routing policy. Not compatible with `routing_intent_enabled`. [optional - default `false`]
- `secure_internet_traffic`: Whether to forward internet-bound traffic to the destination specified in the routing policy. [optional - default `false`]
- `secure_private_traffic`: Whether to all internal traffic to the destination specified in the routing policy. Not compatible with `routing_intent_enabled`. [optional - default `false`]
- `routing_intent_enabled`: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. Not compatible with `secure_internet_traffic` or `secure_private_traffic`. [optional - default `false`]
- `routing_intent_enabled`: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. [optional - default `false`]
### Tags
Expand Down

0 comments on commit 63d73dd

Please sign in to comment.