From 98c7817d28754001bbd71aa8698c585ba3f77ae0 Mon Sep 17 00:00:00 2001 From: Philipp Resch Date: Tue, 17 Dec 2019 16:15:57 +0100 Subject: [PATCH 1/7] new option for vnet_gw: generation --- .../resource_arm_virtual_network_gateway.go | 31 +++++++-- ...source_arm_virtual_network_gateway_test.go | 68 +++++++++++++++++++ 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_virtual_network_gateway.go b/azurerm/resource_arm_virtual_network_gateway.go index e015b430bd4e..371beaa5b65d 100644 --- a/azurerm/resource_arm_virtual_network_gateway.go +++ b/azurerm/resource_arm_virtual_network_gateway.go @@ -102,6 +102,19 @@ func resourceArmVirtualNetworkGateway() *schema.Resource { ), }, + "generation": { + Type: schema.TypeString, + Default: network.VpnGatewayGenerationGeneration1, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.VpnGatewayGenerationGeneration1), + string(network.VpnGatewayGenerationGeneration2), + string(network.VpnGatewayGenerationNone), + }, false), + DiffSuppressFunc: suppress.CaseDifference, + }, + "ip_configuration": { Type: schema.TypeList, Required: true, @@ -369,6 +382,10 @@ func resourceArmVirtualNetworkGatewayRead(d *schema.ResourceData, meta interface d.Set("vpn_type", string(gw.VpnType)) } + if string(gw.VpnGatewayGeneration) != "" { + d.Set("generation", string(gw.VpnGatewayGeneration)) + } + if gw.GatewayDefaultSite != nil { d.Set("default_local_network_gateway_id", gw.GatewayDefaultSite.ID) } @@ -420,14 +437,16 @@ func getArmVirtualNetworkGatewayProperties(d *schema.ResourceData) (*network.Vir vpnType := network.VpnType(d.Get("vpn_type").(string)) enableBgp := d.Get("enable_bgp").(bool) activeActive := d.Get("active_active").(bool) + generation := network.VpnGatewayGeneration(d.Get("generation").(string)) props := &network.VirtualNetworkGatewayPropertiesFormat{ - GatewayType: gatewayType, - VpnType: vpnType, - EnableBgp: &enableBgp, - ActiveActive: &activeActive, - Sku: expandArmVirtualNetworkGatewaySku(d), - IPConfigurations: expandArmVirtualNetworkGatewayIPConfigurations(d), + GatewayType: gatewayType, + VpnType: vpnType, + EnableBgp: &enableBgp, + ActiveActive: &activeActive, + VpnGatewayGeneration: generation, + Sku: expandArmVirtualNetworkGatewaySku(d), + IPConfigurations: expandArmVirtualNetworkGatewayIPConfigurations(d), } if gatewayDefaultSiteID := d.Get("default_local_network_gateway_id").(string); gatewayDefaultSiteID != "" { diff --git a/azurerm/resource_arm_virtual_network_gateway_test.go b/azurerm/resource_arm_virtual_network_gateway_test.go index 1ce598de9a6b..94bdfc31420b 100644 --- a/azurerm/resource_arm_virtual_network_gateway_test.go +++ b/azurerm/resource_arm_virtual_network_gateway_test.go @@ -193,6 +193,27 @@ func TestAccAzureRMVirtualNetworkGateway_vpnGw3(t *testing.T) { }) } +func TestAccAzureRMVirtualNetworkGateway_generation(t *testing.T) { + resourceName := "azurerm_virtual_network_gateway.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMVirtualNetworkGateway_generation(ri, testLocation(), "Generation2") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMVirtualNetworkGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMVirtualNetworkGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "generation", "Generation2"), + ), + }, + }, + }) +} + func TestAccAzureRMVirtualNetworkGateway_vpnClientConfig(t *testing.T) { ri := tf.AccRandTimeInt() resourceName := "azurerm_virtual_network_gateway.test" @@ -808,3 +829,50 @@ resource "azurerm_virtual_network_gateway" "test" { } `, rInt, location, rInt, rInt, rInt) } + +func testAccAzureRMVirtualNetworkGateway_generation(rInt int, location string, generation string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvn-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = ["10.0.0.0/16"] +} + +resource "azurerm_subnet" "test" { + name = "GatewaySubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.1.0/24" +} + +resource "azurerm_public_ip" "test" { + name = "acctestpip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Dynamic" +} + +resource "azurerm_virtual_network_gateway" "test" { + name = "acctestvng-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + type = "Vpn" + vpn_type = "RouteBased" + sku = "VpnGw2" + generation = "%s" + + ip_configuration { + public_ip_address_id = "${azurerm_public_ip.test.id}" + private_ip_address_allocation = "Dynamic" + subnet_id = "${azurerm_subnet.test.id}" + } +} +`, rInt, location, rInt, rInt, rInt, generation) +} From b66688a1c4d8780ec00739eb827013f77713bb4c Mon Sep 17 00:00:00 2001 From: Philipp Resch Date: Tue, 17 Dec 2019 16:19:55 +0100 Subject: [PATCH 2/7] added generation to vnetgw data source --- azurerm/data_source_virtual_network_gateway.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/azurerm/data_source_virtual_network_gateway.go b/azurerm/data_source_virtual_network_gateway.go index 0e0271e3c595..f60cdfbc75ff 100644 --- a/azurerm/data_source_virtual_network_gateway.go +++ b/azurerm/data_source_virtual_network_gateway.go @@ -57,6 +57,11 @@ func dataSourceArmVirtualNetworkGateway() *schema.Resource { Computed: true, }, + "generation": { + Type: schema.TypeString, + Computed: true, + }, + "ip_configuration": { Type: schema.TypeList, Computed: true, @@ -224,6 +229,10 @@ func dataSourceArmVirtualNetworkGatewayRead(d *schema.ResourceData, meta interfa d.Set("vpn_type", string(gw.VpnType)) } + if string(gw.VpnGatewayGeneration) != "" { + d.Set("generation", string(gw.VpnGatewayGeneration)) + } + if gw.GatewayDefaultSite != nil { d.Set("default_local_network_gateway_id", gw.GatewayDefaultSite.ID) } From 9d2d24bbb9ec6f1160b8f3762a25456ff99f6467 Mon Sep 17 00:00:00 2001 From: Philipp Resch Date: Tue, 17 Dec 2019 16:26:50 +0100 Subject: [PATCH 3/7] documentation --- website/docs/d/virtual_network_gateway.html.markdown | 2 ++ website/docs/r/virtual_network_gateway.html.markdown | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/website/docs/d/virtual_network_gateway.html.markdown b/website/docs/d/virtual_network_gateway.html.markdown index a3258c33aa41..8e35a4bd7660 100644 --- a/website/docs/d/virtual_network_gateway.html.markdown +++ b/website/docs/d/virtual_network_gateway.html.markdown @@ -51,6 +51,8 @@ output "virtual_network_gateway_id" { * `sku` - Configuration of the size and capacity of the Virtual Network Gateway. +* `generation` - Generation of the Virtual Network Gateway. + * `ip_configuration` - One or two `ip_configuration` blocks documented below. * `vpn_client_configuration` - A `vpn_client_configuration` block which is documented below. diff --git a/website/docs/r/virtual_network_gateway.html.markdown b/website/docs/r/virtual_network_gateway.html.markdown index bbe284055602..c22b9827a50d 100644 --- a/website/docs/r/virtual_network_gateway.html.markdown +++ b/website/docs/r/virtual_network_gateway.html.markdown @@ -143,6 +143,10 @@ The following arguments are supported: ~> **NOTE:** To build a UltraPerformance ExpressRoute Virtual Network gateway, the associated Public IP needs to be sku "Basic" not "Standard" +* `generation` - (Optional) Configuration of the generation if the virtual network + gateway. Valid options are `Generation1`, `Generation2` and `None` and depend on + the `type` and `sku` arguments. Setting `generation` is only supported for + `type` `Vpn`. `Generation2` is only valid for `sku` larger than `VpnGw2` or `VpnGw2AZ`. * `ip_configuration` (Required) One or two `ip_configuration` blocks documented below. An active-standby gateway requires exactly one `ip_configuration` block whereas From 94aacdf905423089a9ee063fac7aadbaadc21abb Mon Sep 17 00:00:00 2001 From: Philipp Resch Date: Tue, 17 Dec 2019 16:45:53 +0100 Subject: [PATCH 4/7] Additional validation of sku, new SKUs for Gen2 --- .../resource_arm_virtual_network_gateway.go | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/azurerm/resource_arm_virtual_network_gateway.go b/azurerm/resource_arm_virtual_network_gateway.go index 371beaa5b65d..8ca4201170c2 100644 --- a/azurerm/resource_arm_virtual_network_gateway.go +++ b/azurerm/resource_arm_virtual_network_gateway.go @@ -97,7 +97,8 @@ func resourceArmVirtualNetworkGateway() *schema.Resource { // and validateArmVirtualNetworkGatewayExpressRouteSku. ValidateFunc: validation.Any( validateArmVirtualNetworkGatewayPolicyBasedVpnSku(), - validateArmVirtualNetworkGatewayRouteBasedVpnSku(), + validateArmVirtualNetworkGatewayRouteBasedVpnSkuGeneration1(), + validateArmVirtualNetworkGatewayRouteBasedVpnSkuGeneration2(), validateArmVirtualNetworkGatewayExpressRouteSku(), ), }, @@ -470,9 +471,16 @@ func getArmVirtualNetworkGatewayProperties(d *schema.ResourceData) (*network.Vir } } - // Sku validation for route-based VPN gateways - if props.GatewayType == network.VirtualNetworkGatewayTypeVpn && props.VpnType == network.RouteBased { - if ok, err := evaluateSchemaValidateFunc(string(props.Sku.Name), "sku", validateArmVirtualNetworkGatewayRouteBasedVpnSku()); !ok { + // Sku validation for route-based VPN gateways of first geneneration + if props.GatewayType == network.VirtualNetworkGatewayTypeVpn && props.VpnType == network.RouteBased && props.VpnGatewayGeneration == network.VpnGatewayGenerationGeneration1 { + if ok, err := evaluateSchemaValidateFunc(string(props.Sku.Name), "sku", validateArmVirtualNetworkGatewayRouteBasedVpnSkuGeneration1()); !ok { + return nil, err + } + } + + // Sku validation for route-based VPN gateways of second geneneration + if props.GatewayType == network.VirtualNetworkGatewayTypeVpn && props.VpnType == network.RouteBased && props.VpnGatewayGeneration == network.VpnGatewayGenerationGeneration2 { + if ok, err := evaluateSchemaValidateFunc(string(props.Sku.Name), "sku", validateArmVirtualNetworkGatewayRouteBasedVpnSkuGeneration2()); !ok { return nil, err } } @@ -783,7 +791,7 @@ func validateArmVirtualNetworkGatewayPolicyBasedVpnSku() schema.SchemaValidateFu }, true) } -func validateArmVirtualNetworkGatewayRouteBasedVpnSku() schema.SchemaValidateFunc { +func validateArmVirtualNetworkGatewayRouteBasedVpnSkuGeneration1() schema.SchemaValidateFunc { return validation.StringInSlice([]string{ string(network.VirtualNetworkGatewaySkuTierBasic), string(network.VirtualNetworkGatewaySkuTierStandard), @@ -797,6 +805,19 @@ func validateArmVirtualNetworkGatewayRouteBasedVpnSku() schema.SchemaValidateFun }, true) } +func validateArmVirtualNetworkGatewayRouteBasedVpnSkuGeneration2() schema.SchemaValidateFunc { + return validation.StringInSlice([]string{ + string(network.VirtualNetworkGatewaySkuNameVpnGw2), + string(network.VirtualNetworkGatewaySkuNameVpnGw3), + string(network.VirtualNetworkGatewaySkuNameVpnGw4), + string(network.VirtualNetworkGatewaySkuNameVpnGw5), + string(network.VirtualNetworkGatewaySkuNameVpnGw2AZ), + string(network.VirtualNetworkGatewaySkuNameVpnGw3AZ), + string(network.VirtualNetworkGatewaySkuNameVpnGw4AZ), + string(network.VirtualNetworkGatewaySkuNameVpnGw5AZ), + }, true) +} + func validateArmVirtualNetworkGatewayExpressRouteSku() schema.SchemaValidateFunc { return validation.StringInSlice([]string{ string(network.VirtualNetworkGatewaySkuTierStandard), From f723782c57818980a31a17d76fd5c983a53bc86f Mon Sep 17 00:00:00 2001 From: Philipp Resch Date: Tue, 17 Dec 2019 16:55:07 +0100 Subject: [PATCH 5/7] minor requested changes --- azurerm/data_source_virtual_network_gateway.go | 5 +---- azurerm/resource_arm_virtual_network_gateway.go | 8 ++------ .../docs/d/virtual_network_gateway.html.markdown | 2 +- .../docs/r/virtual_network_gateway.html.markdown | 15 ++++++++------- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/azurerm/data_source_virtual_network_gateway.go b/azurerm/data_source_virtual_network_gateway.go index f60cdfbc75ff..516a9fe3f015 100644 --- a/azurerm/data_source_virtual_network_gateway.go +++ b/azurerm/data_source_virtual_network_gateway.go @@ -224,15 +224,12 @@ func dataSourceArmVirtualNetworkGatewayRead(d *schema.ResourceData, meta interfa d.Set("type", string(gw.GatewayType)) d.Set("enable_bgp", gw.EnableBgp) d.Set("active_active", gw.ActiveActive) + d.Set("generation", string(gw.VpnGatewayGeneration)) if string(gw.VpnType) != "" { d.Set("vpn_type", string(gw.VpnType)) } - if string(gw.VpnGatewayGeneration) != "" { - d.Set("generation", string(gw.VpnGatewayGeneration)) - } - if gw.GatewayDefaultSite != nil { d.Set("default_local_network_gateway_id", gw.GatewayDefaultSite.ID) } diff --git a/azurerm/resource_arm_virtual_network_gateway.go b/azurerm/resource_arm_virtual_network_gateway.go index 8ca4201170c2..14e9ba359082 100644 --- a/azurerm/resource_arm_virtual_network_gateway.go +++ b/azurerm/resource_arm_virtual_network_gateway.go @@ -105,7 +105,7 @@ func resourceArmVirtualNetworkGateway() *schema.Resource { "generation": { Type: schema.TypeString, - Default: network.VpnGatewayGenerationGeneration1, + Default: string(network.VpnGatewayGenerationGeneration1), Optional: true, ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ @@ -113,7 +113,6 @@ func resourceArmVirtualNetworkGateway() *schema.Resource { string(network.VpnGatewayGenerationGeneration2), string(network.VpnGatewayGenerationNone), }, false), - DiffSuppressFunc: suppress.CaseDifference, }, "ip_configuration": { @@ -378,15 +377,12 @@ func resourceArmVirtualNetworkGatewayRead(d *schema.ResourceData, meta interface d.Set("type", string(gw.GatewayType)) d.Set("enable_bgp", gw.EnableBgp) d.Set("active_active", gw.ActiveActive) + d.Set("generation", string(gw.VpnGatewayGeneration)) if string(gw.VpnType) != "" { d.Set("vpn_type", string(gw.VpnType)) } - if string(gw.VpnGatewayGeneration) != "" { - d.Set("generation", string(gw.VpnGatewayGeneration)) - } - if gw.GatewayDefaultSite != nil { d.Set("default_local_network_gateway_id", gw.GatewayDefaultSite.ID) } diff --git a/website/docs/d/virtual_network_gateway.html.markdown b/website/docs/d/virtual_network_gateway.html.markdown index 8e35a4bd7660..682e7954fe40 100644 --- a/website/docs/d/virtual_network_gateway.html.markdown +++ b/website/docs/d/virtual_network_gateway.html.markdown @@ -51,7 +51,7 @@ output "virtual_network_gateway_id" { * `sku` - Configuration of the size and capacity of the Virtual Network Gateway. -* `generation` - Generation of the Virtual Network Gateway. +* `generation` - The Generation of the Virtual Network Gateway. * `ip_configuration` - One or two `ip_configuration` blocks documented below. diff --git a/website/docs/r/virtual_network_gateway.html.markdown b/website/docs/r/virtual_network_gateway.html.markdown index c22b9827a50d..0a263402c7b9 100644 --- a/website/docs/r/virtual_network_gateway.html.markdown +++ b/website/docs/r/virtual_network_gateway.html.markdown @@ -136,17 +136,18 @@ The following arguments are supported: * `sku` - (Required) Configuration of the size and capacity of the virtual network gateway. Valid options are `Basic`, `Standard`, `HighPerformance`, `UltraPerformance`, - `ErGw1AZ`, `ErGw2AZ`, `ErGw3AZ`, `VpnGw1`, `VpnGw2`, `VpnGw3`, `VpnGw1AZ`, `VpnGw2AZ`, and `VpnGw3AZ` - and depend on the `type` and `vpn_type` arguments. + `ErGw1AZ`, `ErGw2AZ`, `ErGw3AZ`, `VpnGw1`, `VpnGw2`, `VpnGw3`, `VpnGw4`,`VpnGw5`, `VpnGw1AZ`, + `VpnGw2AZ`, `VpnGw3AZ`,`VpnGw4AZ` and `VpnGw5AZ` and depend on the `type`, `vpn_type` and + `generation` arguments. A `PolicyBased` gateway only supports the `Basic` sku. Further, the `UltraPerformance` - sku is only supported by an `ExpressRoute` gateway. + sku is only supported by an `ExpressRoute` gateway. ~> **NOTE:** To build a UltraPerformance ExpressRoute Virtual Network gateway, the associated Public IP needs to be sku "Basic" not "Standard" -* `generation` - (Optional) Configuration of the generation if the virtual network - gateway. Valid options are `Generation1`, `Generation2` and `None` and depend on - the `type` and `sku` arguments. Setting `generation` is only supported for - `type` `Vpn`. `Generation2` is only valid for `sku` larger than `VpnGw2` or `VpnGw2AZ`. +* `generation` - (Optional) The Generation of the Virtual Network gateway. Possible values include `Generation1`, `Generation2` or `None`. + Defaults to `Generation1`. + +-> **NOTE:** The available values depend on the `type` and `sku` arguments - where `Generation2` is only value for a `sku` larger than `VpnGw2` or `VpnGw2AZ`. * `ip_configuration` (Required) One or two `ip_configuration` blocks documented below. An active-standby gateway requires exactly one `ip_configuration` block whereas From e10fedb0f6c908de6cf900473891e81121638765 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Tue, 17 Dec 2019 23:33:23 +0100 Subject: [PATCH 6/7] r/virtual_network_gateway: removing the default value --- azurerm/resource_arm_virtual_network_gateway.go | 1 - website/docs/r/virtual_network_gateway.html.markdown | 1 - 2 files changed, 2 deletions(-) diff --git a/azurerm/resource_arm_virtual_network_gateway.go b/azurerm/resource_arm_virtual_network_gateway.go index 14e9ba359082..1648d582a40f 100644 --- a/azurerm/resource_arm_virtual_network_gateway.go +++ b/azurerm/resource_arm_virtual_network_gateway.go @@ -105,7 +105,6 @@ func resourceArmVirtualNetworkGateway() *schema.Resource { "generation": { Type: schema.TypeString, - Default: string(network.VpnGatewayGenerationGeneration1), Optional: true, ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ diff --git a/website/docs/r/virtual_network_gateway.html.markdown b/website/docs/r/virtual_network_gateway.html.markdown index 0a263402c7b9..c7f1e9358507 100644 --- a/website/docs/r/virtual_network_gateway.html.markdown +++ b/website/docs/r/virtual_network_gateway.html.markdown @@ -145,7 +145,6 @@ The following arguments are supported: ~> **NOTE:** To build a UltraPerformance ExpressRoute Virtual Network gateway, the associated Public IP needs to be sku "Basic" not "Standard" * `generation` - (Optional) The Generation of the Virtual Network gateway. Possible values include `Generation1`, `Generation2` or `None`. - Defaults to `Generation1`. -> **NOTE:** The available values depend on the `type` and `sku` arguments - where `Generation2` is only value for a `sku` larger than `VpnGw2` or `VpnGw2AZ`. From d3014d4f184ab149b94f634701dce2842f7e86fa Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Wed, 18 Dec 2019 06:35:01 +0100 Subject: [PATCH 7/7] r/virtual_network_gateway: `generation` wants to be computed too --- azurerm/resource_arm_virtual_network_gateway.go | 1 + 1 file changed, 1 insertion(+) diff --git a/azurerm/resource_arm_virtual_network_gateway.go b/azurerm/resource_arm_virtual_network_gateway.go index 1648d582a40f..833941be6d3c 100644 --- a/azurerm/resource_arm_virtual_network_gateway.go +++ b/azurerm/resource_arm_virtual_network_gateway.go @@ -106,6 +106,7 @@ func resourceArmVirtualNetworkGateway() *schema.Resource { "generation": { Type: schema.TypeString, Optional: true, + Computed: true, ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ string(network.VpnGatewayGenerationGeneration1),