Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 5 additions & 29 deletions internal/services/network/virtual_network_gateway_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package network

import (
"bytes"
"context"
"fmt"
"log"
"math"
Expand Down Expand Up @@ -49,8 +48,6 @@ func resourceVirtualNetworkGateway() *pluginsdk.Resource {
Delete: pluginsdk.DefaultTimeout(120 * time.Minute),
},

CustomizeDiff: pluginsdk.CustomizeDiffShim(resourceVirtualNetworkGatewayCustomizeDiff),

Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Expand Down Expand Up @@ -674,23 +671,6 @@ func resourceVirtualNetworkGateway() *pluginsdk.Resource {
return resource
}

func resourceVirtualNetworkGatewayCustomizeDiff(ctx context.Context, d *pluginsdk.ResourceDiff, _ interface{}) error {
gatewayType := d.Get("type").(string)

// Validate that public_ip_address_id is not set for ExpressRoute gateways
if gatewayType == string(virtualnetworkgateways.VirtualNetworkGatewayTypeExpressRoute) {
ipConfigs := d.Get("ip_configuration").([]interface{})
for i, ipConfigRaw := range ipConfigs {
ipConfig := ipConfigRaw.(map[string]interface{})
if publicIPID, ok := ipConfig["public_ip_address_id"].(string); ok && publicIPID != "" {
return fmt.Errorf("`ip_configuration.%d.public_ip_address_id` cannot be set when `type` is set to `ExpressRoute`", i)
}
}
}

return nil
}

func resourceVirtualNetworkGatewayCreate(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Network.VirtualNetworkGateways
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
Expand Down Expand Up @@ -789,8 +769,7 @@ func resourceVirtualNetworkGatewayRead(d *pluginsdk.ResourceData, meta interface
d.Set("sku", string(pointer.From(props.Sku.Name)))
}

gatewayType := pointer.From(props.GatewayType)
if err := d.Set("ip_configuration", flattenVirtualNetworkGatewayIPConfigurations(props.IPConfigurations, gatewayType)); err != nil {
if err := d.Set("ip_configuration", flattenVirtualNetworkGatewayIPConfigurations(props.IPConfigurations)); err != nil {
return fmt.Errorf("setting `ip_configuration`: %+v", err)
}

Expand Down Expand Up @@ -1427,7 +1406,7 @@ func flattenVirtualNetworkGatewayBgpPeeringAddresses(input *[]virtualnetworkgate
return output, nil
}

func flattenVirtualNetworkGatewayIPConfigurations(ipConfigs *[]virtualnetworkgateways.VirtualNetworkGatewayIPConfiguration, gatewayType virtualnetworkgateways.VirtualNetworkGatewayType) []interface{} {
func flattenVirtualNetworkGatewayIPConfigurations(ipConfigs *[]virtualnetworkgateways.VirtualNetworkGatewayIPConfiguration) []interface{} {
flat := make([]interface{}, 0)

if ipConfigs != nil {
Expand All @@ -1446,12 +1425,9 @@ func flattenVirtualNetworkGatewayIPConfigurations(ipConfigs *[]virtualnetworkgat
}
}

// Do not include public_ip_address_id for ExpressRoute gateways
if gatewayType != virtualnetworkgateways.VirtualNetworkGatewayTypeExpressRoute {
if pip := props.PublicIPAddress; pip != nil {
if id := pip.Id; id != nil {
v["public_ip_address_id"] = *id
}
if pip := props.PublicIPAddress; pip != nil {
if id := pip.Id; id != nil {
v["public_ip_address_id"] = *id
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package network_test
import (
"context"
"fmt"
"os"
"testing"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
Expand Down Expand Up @@ -355,6 +356,37 @@ func TestAccVirtualNetworkGateway_expressRoute(t *testing.T) {
})
}

func TestAccVirtualNetworkGateway_expressRouteWithPublicIPAddressId(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_virtual_network_gateway", "test")
r := VirtualNetworkGatewayResource{}
legacyGatewayID := os.Getenv("ARM_TEST_LEGACY_EXPRESSROUTE_GATEWAY_ID")
Comment thread
alkarp marked this conversation as resolved.

if legacyGatewayID == "" {
t.Skip("Skipping as `ARM_TEST_LEGACY_EXPRESSROUTE_GATEWAY_ID` was not specified")
}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.expressRouteWithPublicIPAddressIdBrownfield(legacyGatewayID),
ResourceName: data.ResourceName,
ImportState: true,
ImportStateId: legacyGatewayID,
ImportStateVerify: true,
},
{
Config: r.expressRouteWithPublicIPAddressIdBrownfield(legacyGatewayID),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("type").HasValue("ExpressRoute"),
check.That(data.ResourceName).Key("ip_configuration.0.public_ip_address_id").Exists(),
),
},
Comment thread
alkarp marked this conversation as resolved.
{
Config: r.expressRouteWithPublicIPAddressIdBrownfield(legacyGatewayID),
PlanOnly: true,
},
Comment thread
alkarp marked this conversation as resolved.
Outdated
})
}

func TestAccVirtualNetworkGateway_expressRouteErGwScale(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_virtual_network_gateway", "test")
r := VirtualNetworkGatewayResource{}
Expand Down Expand Up @@ -1420,6 +1452,43 @@ resource "azurerm_virtual_network_gateway" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger)
}

func (VirtualNetworkGatewayResource) expressRouteWithPublicIPAddressIdBrownfield(existingGatewayID string) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

locals {
gateway_id = "%s"
gateway_name = split("/", local.gateway_id)[8]
resource_group_name = split("/", local.gateway_id)[4]
}

data "azurerm_virtual_network_gateway" "existing" {
name = local.gateway_name
resource_group_name = local.resource_group_name
}

resource "azurerm_virtual_network_gateway" "test" {
name = local.gateway_name
location = data.azurerm_virtual_network_gateway.existing.location
resource_group_name = local.resource_group_name

type = "ExpressRoute"
vpn_type = data.azurerm_virtual_network_gateway.existing.vpn_type
sku = data.azurerm_virtual_network_gateway.existing.sku
generation = data.azurerm_virtual_network_gateway.existing.generation

ip_configuration {
name = data.azurerm_virtual_network_gateway.existing.ip_configuration[0].name
public_ip_address_id = data.azurerm_virtual_network_gateway.existing.ip_configuration[0].public_ip_address_id
private_ip_address_allocation = data.azurerm_virtual_network_gateway.existing.ip_configuration[0].private_ip_address_allocation
subnet_id = data.azurerm_virtual_network_gateway.existing.ip_configuration[0].subnet_id
}
}
`, existingGatewayID)
}

func (VirtualNetworkGatewayResource) expressRouteErGwScale(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/virtual_network_gateway.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ The `ip_configuration` block supports:

* `public_ip_address_id` - (Optional) The ID of the public IP address to associate with the Virtual Network Gateway.

~> **Note:** `public_ip_address_id` should not be specified when `type` is set to `ExpressRoute`.
~> **Note:** For `ExpressRoute` gateways, Azure may use auto-assigned Hosted-On-Behalf-Of (HOBO) public IPs for newer deployments. Existing gateways can still expose a `public_ip_address_id`. For more information, see [Auto-assigned public IP](https://learn.microsoft.com/en-us/azure/expressroute/expressroute-about-virtual-network-gateways#auto-assigned-public-ip).

---

Expand Down