Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VNet Peering enhancements #1078

Closed
Closed
Show file tree
Hide file tree
Changes from all 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
63 changes: 40 additions & 23 deletions src/Farmer/Arm/Network.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Farmer.Arm.Network

open System.Net.Mail
open Farmer
open Farmer.Arm
open Farmer.Network
open Farmer.ExpressRoute
open Farmer.Route
open Farmer.RouteServer
Expand Down Expand Up @@ -33,10 +33,10 @@ let serviceEndpointPolicies =
ResourceType("Microsoft.Network/serviceEndpointPolicies", "2020-07-01")

let subnets =
ResourceType("Microsoft.Network/virtualNetworks/subnets", "2020-07-01")
ResourceType("Microsoft.Network/virtualNetworks/subnets", "2023-04-01")

let virtualNetworks =
ResourceType("Microsoft.Network/virtualNetworks", "2020-07-01")
ResourceType("Microsoft.Network/virtualNetworks", "2023-04-01")

let virtualNetworkGateways =
ResourceType("Microsoft.Network/virtualNetworkGateways", "2020-05-01")
Expand All @@ -50,7 +50,7 @@ let privateEndpoints =
ResourceType("Microsoft.Network/privateEndpoints", "2021-05-01")

let virtualNetworkPeering =
ResourceType("Microsoft.Network/virtualNetworks/virtualNetworkPeerings", "2020-05-01")
ResourceType("Microsoft.Network/virtualNetworks/virtualNetworkPeerings", "2023-04-01")

let routeTables = ResourceType("Microsoft.Network/routeTables", "2021-01-01")
let routes = ResourceType("Microsoft.Network/routeTables/routes", "2021-01-01")
Expand Down Expand Up @@ -973,27 +973,32 @@ type PrivateEndpoint =
|}
|}

type GatewayTransit =
| UseRemoteGateway
| UseLocalGateway
| GatewayTransitDisabled

type PeerAccess =
| AccessDenied
| AccessOnly
| ForwardOnly
| AccessAndForward

type NetworkPeering =
{
Location: Location
DoNotVerifyRemoteGateways: bool option
OwningVNet: LinkedResource
PeeringState: PeeringState option
PeeringSyncLevel: PeeringSyncLevel option
RemoteVNet: LinkedResource
RemoteAccess: PeerAccess
RemoteAddressSpace: IPAddressCidr list
RemoteVirtualNetworkAddressSpace: IPAddressCidr list
GatewayTransit: GatewayTransit
DependsOn: ResourceId Set
}

/// Emits the prefix list in the addressPrefixes field if there are any, but empty list will be null
/// so the serializer won't emit anything.
static member private prefixListArmJson(addressPrefixes: IPAddressCidr list) =
if addressPrefixes.IsEmpty then
null
else
box
{|
addressPrefixes = addressPrefixes |> Seq.map IPAddressCidr.format
|}

member this.Name = this.OwningVNet.Name / $"peering-%s{this.RemoteVNet.Name.Value}"

interface IArmResource with
Expand All @@ -1014,11 +1019,6 @@ type NetworkPeering =
{| virtualNetworkPeering.Create(this.Name, this.Location, deps) with
properties =
{|
allowVirtualNetworkAccess =
match this.RemoteAccess with
| AccessOnly
| AccessAndForward -> true
| _ -> false
allowForwardedTraffic =
match this.RemoteAccess with
| ForwardOnly
Expand All @@ -1029,17 +1029,34 @@ type NetworkPeering =
| UseLocalGateway
| UseRemoteGateway -> true
| _ -> false
useRemoteGateways =
match this.GatewayTransit with
| UseRemoteGateway -> true
allowVirtualNetworkAccess =
match this.RemoteAccess with
| AccessOnly
| AccessAndForward -> true
| _ -> false
doNotVerifyRemoteGateways =
this.DoNotVerifyRemoteGateways |> Option.map box |> Option.defaultValue null
peeringState =
this.PeeringState
|> Option.map (fun p -> p.ArmValue)
|> Option.defaultValue null
peeringSyncLevel =
this.PeeringSyncLevel
|> Option.map (fun p -> p.ArmValue)
|> Option.defaultValue null
remoteAddressSpace = this.RemoteAddressSpace |> NetworkPeering.prefixListArmJson
remoteVirtualNetwork =
{|
id =
match this.RemoteVNet with
| Managed id
| Unmanaged id -> id.ArmExpression.Eval()
|}
remoteVirtualNetworkAddressSpace = this.RemoteAddressSpace |> NetworkPeering.prefixListArmJson
useRemoteGateways =
match this.GatewayTransit with
| UseRemoteGateway -> true
| _ -> false
|}
|}

Expand Down
103 changes: 81 additions & 22 deletions src/Farmer/Builders/Builders.VirtualNetwork.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ open Farmer.Builders
open Farmer.Network
open Farmer.Arm.Network

type PeeringMode =
| TwoWay
| OneWayToRemote
| OneWayFromRemote

type SubnetConfig =
{
Name: ResourceName
Expand Down Expand Up @@ -477,11 +472,21 @@ type AddressSpaceBuilder() =

let addressSpace = AddressSpaceBuilder()

type PeeringMode =
| TwoWay
| OneWayToRemote
| OneWayFromRemote

type VNetPeeringSpec =
{
RemoteVNet: LinkedResource
DoNotVerifyRemoteGateways: bool option
Direction: PeeringMode
Access: PeerAccess
PeeringState: PeeringState option
PeeringSyncLevel: PeeringSyncLevel option
RemoteAddressSpace: IPAddressCidr list
RemoteVirtualNetworkAddressSpace: IPAddressCidr list
Transit: GatewayTransit
DependsOn: ResourceId Set
}
Expand Down Expand Up @@ -514,40 +519,44 @@ type VirtualNetworkConfig =
Subnets = this.Subnets |> List.map (fun subnetConfig -> subnetConfig.AsSubnetResource)
Tags = this.Tags
}
for {
RemoteVNet = remote
Direction = direction
Access = access
Transit = transit
DependsOn = deps
} in this.Peers do
match direction with
for peering in this.Peers do
match peering.Direction with
| OneWayToRemote
| TwoWay ->
{
Location = location
DoNotVerifyRemoteGateways = None
OwningVNet = Managed this.ResourceId
RemoteVNet = remote
RemoteAccess = access
GatewayTransit = transit
DependsOn = deps
PeeringState = peering.PeeringState
PeeringSyncLevel = peering.PeeringSyncLevel
RemoteVNet = peering.RemoteVNet
RemoteAccess = peering.Access
RemoteAddressSpace = peering.RemoteAddressSpace
RemoteVirtualNetworkAddressSpace = peering.RemoteVirtualNetworkAddressSpace
GatewayTransit = peering.Transit
DependsOn = peering.DependsOn
}
| _ -> ()

match direction with
match peering.Direction with
| OneWayFromRemote
| TwoWay ->
{
Location = location
OwningVNet = remote
DoNotVerifyRemoteGateways = None
OwningVNet = peering.RemoteVNet
PeeringState = peering.PeeringState
PeeringSyncLevel = peering.PeeringSyncLevel
RemoteVNet = Managed this.ResourceId
RemoteAccess = access
RemoteAccess = peering.Access
RemoteAddressSpace = peering.RemoteAddressSpace
RemoteVirtualNetworkAddressSpace = peering.RemoteVirtualNetworkAddressSpace
GatewayTransit =
match transit with
match peering.Transit with
| UseRemoteGateway -> UseLocalGateway
| UseLocalGateway -> UseRemoteGateway
| GatewayTransitDisabled -> GatewayTransitDisabled
DependsOn = deps
DependsOn = peering.DependsOn
}
| _ -> ()
]
Expand Down Expand Up @@ -594,6 +603,11 @@ type VirtualNetworkBuilder() =
Direction = direction
Access = AccessAndForward
Transit = GatewayTransitDisabled
DoNotVerifyRemoteGateways = None
PeeringState = None
PeeringSyncLevel = None
RemoteAddressSpace = []
RemoteVirtualNetworkAddressSpace = []
DependsOn = Set.empty
}

Expand Down Expand Up @@ -700,6 +714,11 @@ type VNetPeeringSpecBuilder() =
Direction = TwoWay
Access = AccessAndForward
Transit = GatewayTransitDisabled
DoNotVerifyRemoteGateways = None
PeeringState = None
PeeringSyncLevel = None
RemoteAddressSpace = []
RemoteVirtualNetworkAddressSpace = []
DependsOn = Set.empty
}

Expand All @@ -711,12 +730,52 @@ type VNetPeeringSpecBuilder() =
RemoteVNet = Managed vnet.ResourceId
}

[<CustomOperation "do_not_verify_remote_gateways">]
member _.DoNotVerifyRemoteGateways(state: VNetPeeringSpec, doNotVerify: bool) =
{ state with
DoNotVerifyRemoteGateways = Some doNotVerify
}

[<CustomOperation "direction">]
member _.Mode(state: VNetPeeringSpec, direction) = { state with Direction = direction }

[<CustomOperation "access">]
member _.Access(state: VNetPeeringSpec, access) = { state with Access = access }

[<CustomOperation "peering_state">]
member _.PeeringState(state: VNetPeeringSpec, peeringState: PeeringState) =
{ state with
PeeringState = Some peeringState
}

[<CustomOperation "peering_sync_level">]
member _.PeeringSyncLevel(state: VNetPeeringSpec, peeringSyncLevel: PeeringSyncLevel) =
{ state with
PeeringSyncLevel = Some peeringSyncLevel
}

[<CustomOperation "add_remote_address_space_prefixes">]
member _.AddRemoteAddressSpacePrefixes(state: VNetPeeringSpec, remoteAddressSpacePrefixes: IPAddressCidr list) =
{ state with
RemoteAddressSpace = state.RemoteAddressSpace @ remoteAddressSpacePrefixes
}

member this.AddRemoteAddressSpacePrefixes(state: VNetPeeringSpec, remoteAddressSpacePrefixes: string list) =
this.AddRemoteAddressSpacePrefixes(state, remoteAddressSpacePrefixes |> List.map IPAddressCidr.parse)

[<CustomOperation "add_remote_vnet_address_space_prefixes">]
member _.AddRemoteVnetAddressSpacePrefixes
(
state: VNetPeeringSpec,
remoteVnetAddressSpacePrefixes: IPAddressCidr list
) =
{ state with
RemoteAddressSpace = state.RemoteVirtualNetworkAddressSpace @ remoteVnetAddressSpacePrefixes
}

member this.AddRemoteVnetAddressSpacePrefixes(state: VNetPeeringSpec, remoteVnetAddressSpacePrefixes: string list) =
this.AddRemoteVnetAddressSpacePrefixes(state, remoteVnetAddressSpacePrefixes |> List.map IPAddressCidr.parse)

[<CustomOperation "transit">]
member _.GatewayTransit(state: VNetPeeringSpec, transit) = { state with Transit = transit }

Expand Down
34 changes: 34 additions & 0 deletions src/Farmer/Common.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2914,6 +2914,40 @@ module Network =
/// Microsoft.Web
static member Web = EndpointServiceType "Microsoft.Web"

type GatewayTransit =
| UseRemoteGateway
| UseLocalGateway
| GatewayTransitDisabled

type PeerAccess =
| AccessDenied
| AccessOnly
| ForwardOnly
| AccessAndForward

type PeeringState =
| Connected
| Disconnected
| Initiated

member this.ArmValue =
match this with
| Connected -> "Connected"
| Disconnected -> "Disconnected"
| Initiated -> "Initiated"

type PeeringSyncLevel =
| FullyInSync
| LocalAndRemoteNotInSync
| LocalNotInSync
| RemoteNotInSync

member this.ArmValue =
match this with
| FullyInSync -> "FullyInSync"
| LocalAndRemoteNotInSync -> "LocalAndRemoteNotInSync"
| LocalNotInSync -> "LocalNotInSync"
| RemoteNotInSync -> "RemoteNotInSync"

module NetworkSecurity =
type Operation =
Expand Down
Loading
Loading