diff --git a/nsxt/resource_nsxt_policy_tier0_gateway.go b/nsxt/resource_nsxt_policy_tier0_gateway.go index 568750a19..1c9dda910 100644 --- a/nsxt/resource_nsxt_policy_tier0_gateway.go +++ b/nsxt/resource_nsxt_policy_tier0_gateway.go @@ -109,6 +109,16 @@ func resourceNsxtPolicyTier0Gateway() *schema.Resource { Computed: true, ForceNew: true, // Modification of transit subnet not allowed after Tier-0 deployment }, + "vrf_transit_subnets": { + Type: schema.TypeList, + Description: "VRF transit subnets in CIDR format", + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validateCidr(), + }, + Optional: true, + Computed: true, + }, "ipv6_ndra_profile_path": getIPv6NDRAPathSchema(), "ipv6_dad_profile_path": getIPv6DadPathSchema(), "edge_cluster_path": getPolicyEdgeClusterPathSchema(), @@ -721,6 +731,7 @@ func policyTier0GatewayResourceToInfraStruct(context utl.SessionContext, d *sche revision := int64(d.Get("revision").(int)) internalSubnets := interfaceListToStringList(d.Get("internal_transit_subnets").([]interface{})) transitSubnets := interfaceListToStringList(d.Get("transit_subnets").([]interface{})) + vrfTransitSubnets := interfaceListToStringList(d.Get("vrf_transit_subnets").([]interface{})) ipv6ProfilePaths := getIpv6ProfilePathsFromSchema(d) vrfConfig := getPolicyVRFConfigFromSchema(d) dhcpPath := d.Get("dhcp_config_path").(string) @@ -752,6 +763,10 @@ func policyTier0GatewayResourceToInfraStruct(context utl.SessionContext, d *sche t0Struct.RdAdminField = rdAdminField } + if nsxVersionHigherOrEqual("4.1.0") { + t0Struct.VrfTransitSubnets = vrfTransitSubnets + } + if len(d.Id()) > 0 { // This is update flow t0Struct.Revision = &revision @@ -912,6 +927,7 @@ func resourceNsxtPolicyTier0GatewayRead(d *schema.ResourceData, m interface{}) e d.Set("force_whitelisting", obj.ForceWhitelisting) d.Set("internal_transit_subnets", obj.InternalTransitSubnets) d.Set("transit_subnets", obj.TransitSubnets) + d.Set("vrf_transit_subnets", obj.VrfTransitSubnets) d.Set("revision", obj.Revision) if nsxVersionHigherOrEqual("3.0.0") { d.Set("rd_admin_address", obj.RdAdminField) diff --git a/nsxt/resource_nsxt_policy_tier0_gateway_test.go b/nsxt/resource_nsxt_policy_tier0_gateway_test.go index e4f14b68c..2cbabdc20 100644 --- a/nsxt/resource_nsxt_policy_tier0_gateway_test.go +++ b/nsxt/resource_nsxt_policy_tier0_gateway_test.go @@ -129,6 +129,35 @@ func TestAccResourceNsxtPolicyTier0Gateway_withSubnets(t *testing.T) { }) } +func TestAccResourceNsxtPolicyTier0Gateway_withVrfSubnets(t *testing.T) { + // Also set vrf_transit_subnet. Needs NSX 4.1.0 or above. + name := getAccTestResourceName() + testResourceName := "nsxt_policy_tier0_gateway.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccOnlyLocalManager(t); testAccPreCheck(t); testAccNSXVersion(t, "4.1.0") }, + Providers: testAccProviders, + CheckDestroy: func(state *terraform.State) error { + return testAccNsxtPolicyTier0CheckDestroy(state, name) + }, + Steps: []resource.TestStep{ + { + Config: testAccNsxtPolicyTier0SubnetsWithVrfTemplate(name), + Check: resource.ComposeTestCheckFunc( + testAccNsxtPolicyTier0Exists(testResourceName), + resource.TestCheckResourceAttr(testResourceName, "display_name", name), + resource.TestCheckResourceAttr(testResourceName, "description", "Acceptance Test"), + resource.TestCheckResourceAttr(testResourceName, "tag.#", "1"), + resource.TestCheckResourceAttr(realizationResourceName, "state", "REALIZED"), + resource.TestCheckResourceAttr(testResourceName, "internal_transit_subnets.#", "1"), + resource.TestCheckResourceAttr(testResourceName, "transit_subnets.#", "1"), + resource.TestCheckResourceAttr(testResourceName, "vrf_transit_subnets.#", "1"), + ), + }, + }, + }) +} + func TestAccResourceNsxtPolicyTier0Gateway_withDHCP(t *testing.T) { name := getAccTestResourceName() testResourceName := "nsxt_policy_tier0_gateway.test" @@ -689,6 +718,32 @@ data "nsxt_policy_realization_info" "realization_info" { }`, name) } +func testAccNsxtPolicyTier0SubnetsWithVrfTemplate(name string) string { + return fmt.Sprintf(` +resource "nsxt_policy_tier0_gateway" "test" { + display_name = "%s" + description = "Acceptance Test" + failover_mode = "NON_PREEMPTIVE" + default_rule_logging = "false" + enable_firewall = "true" + force_whitelisting = "true" + ha_mode = "ACTIVE_STANDBY" + ipv6_dad_profile_path = "/infra/ipv6-dad-profiles/default" + internal_transit_subnets = ["102.64.0.0/16"] + transit_subnets = ["101.64.0.0/16"] + vrf_transit_subnets = ["103.64.0.0/28"] + + tag { + scope = "scope3" + tag = "tag3" + } +} + +data "nsxt_policy_realization_info" "realization_info" { + path = nsxt_policy_tier0_gateway.test.path +}`, name) +} + func testAccNsxtPolicyTier0WithVRFTemplate(name string, targets bool, rdAdmin bool, withBGP bool) string { var routeTargets string diff --git a/website/docs/r/policy_tier0_gateway.html.markdown b/website/docs/r/policy_tier0_gateway.html.markdown index caa9cfd48..782c0235b 100644 --- a/website/docs/r/policy_tier0_gateway.html.markdown +++ b/website/docs/r/policy_tier0_gateway.html.markdown @@ -24,6 +24,7 @@ resource "nsxt_policy_tier0_gateway" "tier0_gw" { ha_mode = "ACTIVE_STANDBY" internal_transit_subnets = ["102.64.0.0/16"] transit_subnets = ["101.64.0.0/16"] + vrf_transit_subnets = ["100.64.0.0/16"] edge_cluster_path = data.nsxt_policy_edge_cluster.EC.path rd_admin_address = "192.168.0.2" @@ -133,6 +134,7 @@ The following arguments are supported: * `ha_mode` - (Optional) High-availability Mode for Tier-0. Valid values are `ACTIVE_ACTIVE` and `ACTIVE_STANDBY`. * `internal_transit_subnets` - (Optional) Internal transit subnets in CIDR format. At most 1 CIDR. * `transit_subnets` - (Optional) Transit subnets in CIDR format. +* `vrf_transit_subnets` - (Optional) VRF transit subnets in CIDR format. Maximum 1 item allowed in the list. * `dhcp_config_path` - (Optional) Policy path to DHCP server or relay configuration to use for this gateway. * `rd_admin_address` - (Optional) Route distinguisher administrator address. If using EVPN service, then this attribute should be defined if auto generation of route distinguisher on VRF configuration is needed. * `bgp_config` - (Optional) The BGP configuration for the Tier-0 gateway. When enabled a valid `edge_cluster_path` must be set on the Tier-0 gateway. This clause is not applicable for Global Manager - use `nsxt_policy_bgp_config` resource instead.