Skip to content

Commit

Permalink
[azurerm_express_route_circuit_peering]- enhance - support for ipv4_e…
Browse files Browse the repository at this point in the history
…nabled gateway_manager_etag (hashicorp#17338)

Co-authored-by: xuzhang3 <Zhangxu894765>
  • Loading branch information
xuzhang3 authored Aug 9, 2022
1 parent dc94da0 commit ebd138d
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 35 deletions.
113 changes: 84 additions & 29 deletions internal/services/network/express_route_circuit_peering_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,24 @@ func resourceExpressRouteCircuitPeering() *pluginsdk.Resource {

"primary_peer_address_prefix": {
Type: pluginsdk.TypeString,
Required: true,
Optional: true,
RequiredWith: []string{
"secondary_peer_address_prefix",
},
},

"secondary_peer_address_prefix": {
Type: pluginsdk.TypeString,
Required: true,
Optional: true,
RequiredWith: []string{
"primary_peer_address_prefix",
},
},

"ipv4_enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
Default: true,
},

"vlan_id": {
Expand Down Expand Up @@ -119,7 +131,7 @@ func resourceExpressRouteCircuitPeering() *pluginsdk.Resource {
Schema: map[string]*pluginsdk.Schema{
"microsoft_peering": {
Type: pluginsdk.TypeList,
Required: true,
Optional: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
Expand Down Expand Up @@ -159,6 +171,12 @@ func resourceExpressRouteCircuitPeering() *pluginsdk.Resource {
Required: true,
},

"enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
Default: true,
},

"route_filter_id": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -188,6 +206,11 @@ func resourceExpressRouteCircuitPeering() *pluginsdk.Resource {
Optional: true,
ValidateFunc: azure.ValidateResourceID,
},

"gateway_manager_etag": {
Type: pluginsdk.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -228,20 +251,38 @@ func resourceExpressRouteCircuitPeeringCreateUpdate(d *pluginsdk.ResourceData, m

parameters := network.ExpressRouteCircuitPeering{
ExpressRouteCircuitPeeringPropertiesFormat: &network.ExpressRouteCircuitPeeringPropertiesFormat{
PeeringType: network.ExpressRoutePeeringType(id.PeeringName),
SharedKey: utils.String(sharedKey),
PrimaryPeerAddressPrefix: utils.String(primaryPeerAddressPrefix),
SecondaryPeerAddressPrefix: utils.String(secondaryPeerAddressPrefix),
AzureASN: utils.Int32(int32(azureASN)),
PeerASN: utils.Int64(int64(peerASN)),
VlanID: utils.Int32(int32(vlanId)),
PeeringType: network.ExpressRoutePeeringType(id.PeeringName),
SharedKey: utils.String(sharedKey),
AzureASN: utils.Int32(int32(azureASN)),
PeerASN: utils.Int64(int64(peerASN)),
VlanID: utils.Int32(int32(vlanId)),
GatewayManagerEtag: utils.String(d.Get("gateway_manager_etag").(string)),
},
}

ipv4Enabled := d.Get("ipv4_enabled").(bool)
if ipv4Enabled {
parameters.ExpressRouteCircuitPeeringPropertiesFormat.State = network.ExpressRoutePeeringStateEnabled
} else {
parameters.ExpressRouteCircuitPeeringPropertiesFormat.State = network.ExpressRoutePeeringStateDisabled
}

if !strings.EqualFold(primaryPeerAddressPrefix, "") {
parameters.PrimaryPeerAddressPrefix = utils.String(primaryPeerAddressPrefix)
}

if !strings.EqualFold(secondaryPeerAddressPrefix, "") {
parameters.SecondaryPeerAddressPrefix = utils.String(secondaryPeerAddressPrefix)
}

if strings.EqualFold(id.PeeringName, string(network.ExpressRoutePeeringTypeMicrosoftPeering)) {
peerings := d.Get("microsoft_peering_config").([]interface{})
if len(peerings) == 0 {
return fmt.Errorf("`microsoft_peering_config` must be specified when `peering_type` is set to `MicrosoftPeering`")
if len(peerings) == 0 && primaryPeerAddressPrefix != "" {
return fmt.Errorf("`microsoft_peering_config` must be specified when config for Ipv4 and `peering_type` is set to `MicrosoftPeering`")
}

if len(peerings) != 0 && (primaryPeerAddressPrefix == "" || secondaryPeerAddressPrefix == "") {
return fmt.Errorf("`primary_peer_address_prefix, secondary_peer_address_prefix` must be specified when config for Ipv4")
}

peeringConfig := expandExpressRouteCircuitPeeringMicrosoftConfig(peerings)
Expand All @@ -252,23 +293,20 @@ func resourceExpressRouteCircuitPeeringCreateUpdate(d *pluginsdk.ResourceData, m
ID: utils.String(route_filter_id),
}
}
} else if route_filter_id != "" {
return fmt.Errorf("`route_filter_id` may only be specified when `peering_type` is set to `MicrosoftPeering`")
}

ipv6Peering := d.Get("ipv6").([]interface{})
ipv6PeeringConfig, err := expandExpressRouteCircuitIpv6PeeringConfig(ipv6Peering)
if err != nil {
return err
}
parameters.ExpressRouteCircuitPeeringPropertiesFormat.Ipv6PeeringConfig = ipv6PeeringConfig
} else {
if route_filter_id != "" {
return fmt.Errorf("`route_filter_id` may only be specified when `peering_type` is set to `MicrosoftPeering`")
}
ipv6Peering := d.Get("ipv6").([]interface{})
if len(ipv6Peering) != 0 && id.PeeringName == string(network.ExpressRoutePeeringTypeAzurePublicPeering) {
return fmt.Errorf("`ipv6` may only be specified when `peering_type` is `MicrosoftPeering` or `AzurePrivatePeering`")
}

ipv6Peering := d.Get("ipv6").([]interface{})
if len(ipv6Peering) != 0 {
return fmt.Errorf("`ipv6` may only be specified when `peering_type` is set to `MicrosoftPeering`")
}
ipv6PeeringConfig, err := expandExpressRouteCircuitIpv6PeeringConfig(ipv6Peering)
if err != nil {
return err
}
parameters.ExpressRouteCircuitPeeringPropertiesFormat.Ipv6PeeringConfig = ipv6PeeringConfig

future, err := client.CreateOrUpdate(ctx, id.ResourceGroup, id.ExpressRouteCircuitName, id.PeeringName, parameters)
if err != nil {
Expand Down Expand Up @@ -315,6 +353,8 @@ func resourceExpressRouteCircuitPeeringRead(d *pluginsdk.ResourceData, meta inte
d.Set("primary_peer_address_prefix", props.PrimaryPeerAddressPrefix)
d.Set("secondary_peer_address_prefix", props.SecondaryPeerAddressPrefix)
d.Set("vlan_id", props.VlanID)
d.Set("gateway_manager_etag", props.GatewayManagerEtag)
d.Set("ipv4_enabled", props.State == network.ExpressRoutePeeringStateEnabled)

routeFilterId := ""
if props.RouteFilter != nil && props.RouteFilter.ID != nil {
Expand Down Expand Up @@ -388,10 +428,24 @@ func expandExpressRouteCircuitIpv6PeeringConfig(input []interface{}) (*network.I

v := input[0].(map[string]interface{})
peeringConfig := network.Ipv6ExpressRouteCircuitPeeringConfig{
PrimaryPeerAddressPrefix: utils.String(v["primary_peer_address_prefix"].(string)),
SecondaryPeerAddressPrefix: utils.String(v["secondary_peer_address_prefix"].(string)),
MicrosoftPeeringConfig: expandExpressRouteCircuitPeeringMicrosoftConfig(v["microsoft_peering"].([]interface{})),
MicrosoftPeeringConfig: expandExpressRouteCircuitPeeringMicrosoftConfig(v["microsoft_peering"].([]interface{})),
State: network.ExpressRouteCircuitPeeringStateEnabled,
}

primaryPeerAddressPrefix := v["primary_peer_address_prefix"].(string)
secondaryPeerAddressPrefix := v["secondary_peer_address_prefix"].(string)
if !strings.EqualFold(primaryPeerAddressPrefix, "") {
peeringConfig.PrimaryPeerAddressPrefix = utils.String(primaryPeerAddressPrefix)
}
if !strings.EqualFold(secondaryPeerAddressPrefix, "") {
peeringConfig.SecondaryPeerAddressPrefix = utils.String(secondaryPeerAddressPrefix)
}

ipv6Enabled := v["enabled"].(bool)
if !ipv6Enabled {
peeringConfig.State = network.ExpressRouteCircuitPeeringStateDisabled
}

routeFilterId := v["route_filter_id"].(string)
if routeFilterId != "" {
if _, err := parse.RouteFilterID(routeFilterId); err != nil {
Expand Down Expand Up @@ -448,6 +502,7 @@ func flattenExpressRouteCircuitIpv6PeeringConfig(input *network.Ipv6ExpressRoute
"primary_peer_address_prefix": primaryPeerAddressPrefix,
"secondary_peer_address_prefix": secondaryPeerAddressPrefix,
"route_filter_id": routeFilterId,
"enabled": input.State == network.ExpressRouteCircuitPeeringStateEnabled,
},
}
}
66 changes: 60 additions & 6 deletions website/docs/r/express_route_circuit_peering.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ resource "azurerm_express_route_circuit_peering" "example" {
peer_asn = 100
primary_peer_address_prefix = "123.0.0.0/30"
secondary_peer_address_prefix = "123.0.0.4/30"
ipv4_enabled = true
vlan_id = 300
microsoft_peering_config {
Expand All @@ -54,6 +55,7 @@ resource "azurerm_express_route_circuit_peering" "example" {
ipv6 {
primary_peer_address_prefix = "2002:db01::/126"
secondary_peer_address_prefix = "2003:db01::/126"
enabled = true
microsoft_peering {
advertised_public_prefixes = ["2002:db01::/126"]
Expand All @@ -62,6 +64,52 @@ resource "azurerm_express_route_circuit_peering" "example" {
}
```

## Example Usage (Creating Azure Private Peering)

```hcl
resource "azurerm_resource_group" "example" {
name = "exprtTest"
location = "West Europe"
}
resource "azurerm_express_route_circuit" "example" {
name = "expressRoute1"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
service_provider_name = "Equinix"
peering_location = "Silicon Valley"
bandwidth_in_mbps = 50
sku {
tier = "Standard"
family = "MeteredData"
}
allow_classic_operations = false
tags = {
environment = "Production"
}
}
resource "azurerm_express_route_circuit_peering" "example" {
peering_type = "AzurePrivatePeering"
express_route_circuit_name = azurerm_express_route_circuit.example.name
resource_group_name = azurerm_resource_group.example.name
peer_asn = 100
primary_peer_address_prefix = "123.0.0.0/30"
secondary_peer_address_prefix = "123.0.0.4/30"
ipv4_enabled = true
vlan_id = 300
ipv6 {
primary_peer_address_prefix = "2002:db01::/126"
secondary_peer_address_prefix = "2003:db01::/126"
enabled = true
}
}
```

## Argument Reference

The following arguments are supported:
Expand All @@ -74,17 +122,19 @@ The following arguments are supported:

* `resource_group_name` - (Required) The name of the resource group in which to create the Express Route Circuit Peering. Changing this forces a new resource to be created.

* `primary_peer_address_prefix` - (Required) A `/30` subnet for the primary link.
* `vlan_id` - (Required) A valid VLAN ID to establish this peering on.

* `secondary_peer_address_prefix` - (Required) A `/30` subnet for the secondary link.
* `primary_peer_address_prefix` - (Optional) A `/30` subnet for the primary link. Required when config for IPv4.

* `vlan_id` - (Required) A valid VLAN ID to establish this peering on.
* `secondary_peer_address_prefix` - (Optional) A `/30` subnet for the secondary link. Required when config for IPv4.

* `ipv4_enabled` - (Optional) A boolean value indicating whether the IPv4 peering is enabled. Defaults to `true`.

* `shared_key` - (Optional) The shared key. Can be a maximum of 25 characters.

* `peer_asn` - (Optional) The Either a 16-bit or a 32-bit ASN. Can either be public or private.

* `microsoft_peering_config` - (Optional) A `microsoft_peering_config` block as defined below. Required when `peering_type` is set to `MicrosoftPeering`.
* `microsoft_peering_config` - (Optional) A `microsoft_peering_config` block as defined below. Required when `peering_type` is set to `MicrosoftPeering` and config for IPv4.

* `ipv6` - (Optional) A `ipv6` block as defined below.

Expand All @@ -104,14 +154,18 @@ A `microsoft_peering_config` block contains:

A `ipv6` block contains:

* `microsoft_peering` - (Required) A `microsoft_peering` block as defined below.

* `primary_peer_address_prefix` - (Required) A subnet for the primary link.

* `secondary_peer_address_prefix` - (Required) A subnet for the secondary link.

* `enabled` - (Optional) A boolean value indicating whether the IPv6 peering is enabled. Defaults to `true`.

* `microsoft_peering` - (Optional) A `microsoft_peering` block as defined below.

* `route_filter_id` - (Optional) The ID of the Route Filter. Only available when `peering_type` is set to `MicrosoftPeering`.

~> **NOTE:** `ipv6` can be specified when `peering_type` is `MicrosoftPeering` or `AzurePrivatePeering`

---

A `microsoft_peering` block contains:
Expand Down

0 comments on commit ebd138d

Please sign in to comment.