diff --git a/internal/services/network/virtual_hub_connection_resource.go b/internal/services/network/virtual_hub_connection_resource.go index 8d01e41bb2fc..00a9a2501290 100644 --- a/internal/services/network/virtual_hub_connection_resource.go +++ b/internal/services/network/virtual_hub_connection_resource.go @@ -89,6 +89,18 @@ func resourceVirtualHubConnectionSchema() map[string]*pluginsdk.Schema { AtLeastOneOf: []string{"routing.0.associated_route_table_id", "routing.0.propagated_route_table", "routing.0.static_vnet_route"}, }, + "inbound_route_map_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validate.RouteMapID, + }, + + "outbound_route_map_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validate.RouteMapID, + }, + "propagated_route_table": { Type: pluginsdk.TypeList, Optional: true, @@ -122,6 +134,17 @@ func resourceVirtualHubConnectionSchema() map[string]*pluginsdk.Schema { AtLeastOneOf: []string{"routing.0.associated_route_table_id", "routing.0.propagated_route_table", "routing.0.static_vnet_route"}, }, + "static_vnet_local_route_override_criteria": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Default: string(network.VnetLocalRouteOverrideCriteriaContains), + ValidateFunc: validation.StringInSlice([]string{ + string(network.VnetLocalRouteOverrideCriteriaContains), + string(network.VnetLocalRouteOverrideCriteriaEqual), + }, false), + }, + //lintignore:XS003 "static_vnet_route": { Type: pluginsdk.TypeList, @@ -304,7 +327,15 @@ func expandVirtualHubConnectionRouting(input []interface{}) *network.RoutingConf } v := input[0].(map[string]interface{}) - result := network.RoutingConfiguration{} + + result := &network.RoutingConfiguration{ + VnetRoutes: &network.VnetRoute{ + StaticRoutes: expandVirtualHubConnectionVnetStaticRoute(v["static_vnet_route"].([]interface{})), + StaticRoutesConfig: &network.StaticRoutesConfig{ + VnetLocalRouteOverrideCriteria: network.VnetLocalRouteOverrideCriteria(v["static_vnet_local_route_override_criteria"].(string)), + }, + }, + } if associatedRouteTableId := v["associated_route_table_id"].(string); associatedRouteTableId != "" { result.AssociatedRouteTable = &network.SubResource{ @@ -312,15 +343,23 @@ func expandVirtualHubConnectionRouting(input []interface{}) *network.RoutingConf } } - if vnetStaticRoute := v["static_vnet_route"].([]interface{}); len(vnetStaticRoute) != 0 { - result.VnetRoutes = expandVirtualHubConnectionVnetStaticRoute(vnetStaticRoute) + if inboundRouteMapId := v["inbound_route_map_id"].(string); inboundRouteMapId != "" { + result.InboundRouteMap = &network.SubResource{ + ID: utils.String(inboundRouteMapId), + } + } + + if outboundRouteMapId := v["outbound_route_map_id"].(string); outboundRouteMapId != "" { + result.OutboundRouteMap = &network.SubResource{ + ID: utils.String(outboundRouteMapId), + } } if propagatedRouteTable := v["propagated_route_table"].([]interface{}); len(propagatedRouteTable) != 0 { result.PropagatedRouteTables = expandVirtualHubConnectionPropagatedRouteTable(propagatedRouteTable) } - return &result + return result } func expandVirtualHubConnectionPropagatedRouteTable(input []interface{}) *network.PropagatedRouteTable { @@ -343,9 +382,9 @@ func expandVirtualHubConnectionPropagatedRouteTable(input []interface{}) *networ return &result } -func expandVirtualHubConnectionVnetStaticRoute(input []interface{}) *network.VnetRoute { +func expandVirtualHubConnectionVnetStaticRoute(input []interface{}) *[]network.StaticRoute { if len(input) == 0 { - return &network.VnetRoute{} + return nil } results := make([]network.StaticRoute, 0) @@ -374,9 +413,7 @@ func expandVirtualHubConnectionVnetStaticRoute(input []interface{}) *network.Vne results = append(results, result) } - return &network.VnetRoute{ - StaticRoutes: &results, - } + return &results } func expandIDsToSubResources(input []interface{}) *[]network.SubResource { @@ -401,11 +438,29 @@ func flattenVirtualHubConnectionRouting(input *network.RoutingConfiguration) []i associatedRouteTableId = *input.AssociatedRouteTable.ID } + inboundRouteMapId := "" + if input.InboundRouteMap != nil && input.InboundRouteMap.ID != nil { + inboundRouteMapId = *input.InboundRouteMap.ID + } + + outboundRouteMapId := "" + if input.OutboundRouteMap != nil && input.OutboundRouteMap.ID != nil { + outboundRouteMapId = *input.OutboundRouteMap.ID + } + + staticVnetLocalRouteOverrideCriteria := "" + if input.VnetRoutes != nil && input.VnetRoutes.StaticRoutesConfig != nil && input.VnetRoutes.StaticRoutesConfig.VnetLocalRouteOverrideCriteria != "" { + staticVnetLocalRouteOverrideCriteria = string(input.VnetRoutes.StaticRoutesConfig.VnetLocalRouteOverrideCriteria) + } + return []interface{}{ map[string]interface{}{ - "associated_route_table_id": associatedRouteTableId, - "propagated_route_table": flattenVirtualHubConnectionPropagatedRouteTable(input.PropagatedRouteTables), - "static_vnet_route": flattenVirtualHubConnectionVnetStaticRoute(input.VnetRoutes), + "associated_route_table_id": associatedRouteTableId, + "inbound_route_map_id": inboundRouteMapId, + "outbound_route_map_id": outboundRouteMapId, + "propagated_route_table": flattenVirtualHubConnectionPropagatedRouteTable(input.PropagatedRouteTables), + "static_vnet_route": flattenVirtualHubConnectionVnetStaticRoute(input.VnetRoutes), + "static_vnet_local_route_override_criteria": staticVnetLocalRouteOverrideCriteria, }, } } diff --git a/internal/services/network/virtual_hub_connection_resource_test.go b/internal/services/network/virtual_hub_connection_resource_test.go index b749e68d7b68..988f11283c36 100644 --- a/internal/services/network/virtual_hub_connection_resource_test.go +++ b/internal/services/network/virtual_hub_connection_resource_test.go @@ -257,6 +257,22 @@ func TestAccVirtualHubConnection_updateRoutingConfiguration(t *testing.T) { }) } +func TestAccVirtualHubConnection_routeMapAndStaticVnetLocalRouteOverrideCriteria(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_virtual_hub_connection", "test") + r := VirtualHubConnectionResource{} + nameSuffix := randString() + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.routeMapAndStaticVnetLocalRouteOverrideCriteria(data, nameSuffix), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func (t VirtualHubConnectionResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { id, err := parse.HubVirtualNetworkConnectionID(state.ID) if err != nil { @@ -576,3 +592,77 @@ resource "azurerm_virtual_hub_connection" "test" { } `, r.template(data), data.RandomInteger) } + +func (r VirtualHubConnectionResource) routeMapAndStaticVnetLocalRouteOverrideCriteria(data acceptance.TestData, nameSuffix string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_route_map" "test" { + name = "acctestrm-%[2]s" + virtual_hub_id = azurerm_virtual_hub.test.id + + rule { + name = "rule1" + next_step_if_matched = "Continue" + + action { + type = "Add" + + parameter { + as_path = ["22334"] + } + } + + match_criterion { + match_condition = "Contains" + route_prefix = ["10.0.0.0/8"] + } + } +} + +resource "azurerm_route_map" "test2" { + name = "acctestrmn-%[2]s" + virtual_hub_id = azurerm_virtual_hub.test.id + + rule { + name = "rule1" + next_step_if_matched = "Continue" + + action { + type = "Add" + + parameter { + as_path = ["22334"] + } + } + + match_criterion { + match_condition = "Contains" + route_prefix = ["10.0.0.0/8"] + } + } +} + +resource "azurerm_virtual_hub_connection" "test" { + name = "acctest-vhubconn-%[3]d" + virtual_hub_id = azurerm_virtual_hub.test.id + remote_virtual_network_id = azurerm_virtual_network.test.id + + routing { + inbound_route_map_id = azurerm_route_map.test.id + outbound_route_map_id = azurerm_route_map.test2.id + static_vnet_local_route_override_criteria = "Equal" + + propagated_route_table { + labels = ["label3"] + } + + static_vnet_route { + name = "testvnetroute6" + address_prefixes = ["10.0.6.0/24", "10.0.7.0/24"] + next_hop_ip_address = "10.0.6.5" + } + } +} +`, r.template(data), nameSuffix, data.RandomInteger) +} diff --git a/website/docs/r/virtual_hub_connection.html.markdown b/website/docs/r/virtual_hub_connection.html.markdown index b5c059221168..8b76dae2c933 100644 --- a/website/docs/r/virtual_hub_connection.html.markdown +++ b/website/docs/r/virtual_hub_connection.html.markdown @@ -68,8 +68,14 @@ A `routing` block supports the following: * `associated_route_table_id` - (Optional) The ID of the route table associated with this Virtual Hub connection. +* `inbound_route_map_id` - (Optional) The resource ID of the Route Map associated with this Routing Configuration for inbound learned routes. + +* `outbound_route_map_id` - (Optional) The resource ID of the Route Map associated with this Routing Configuration for outbound advertised routes. + * `propagated_route_table` - (Optional) A `propagated_route_table` block as defined below. +* `static_vnet_local_route_override_criteria` - (Optional) The static VNet local route override criteria that is used to determine whether NVA in spoke VNet is bypassed for traffic with destination in spoke VNet. Possible values are `Contains` and `Equal`. Defaults to `Contains`. Changing this forces a new resource to be created. + * `static_vnet_route` - (Optional) A `static_vnet_route` block as defined below. ---