Skip to content

Commit

Permalink
Merge pull request #1039 from Huaxinli123/farmerSupportForNI
Browse files Browse the repository at this point in the history
Farmer support for network interface
  • Loading branch information
ninjarobot authored Jun 5, 2023
2 parents 594e986 + b473fad commit e616e34
Show file tree
Hide file tree
Showing 5 changed files with 411 additions and 0 deletions.
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Release Notes
=============
## 1.7.24
* Network Interface: Adds support for network interface creation.

## 1.7.23
* Route server: Adds support for route server creation.
* Storage Accounts: Fixes scope of role assignments.
Expand Down
77 changes: 77 additions & 0 deletions docs/content/api-overview/resources/network-interface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: "Network Interface"
chapter: false
weight: 5
---

#### Overview
The `networkInterface` builder allows you to create network interfaces (NIC) so that Azure virtual machine (VM) can
communicate with internet, Azure, and on-premises resources. To learn more about routeServer, reference to
[Azure Docs](https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-network-interface?tabs=azure-portal)

* NetworkInterface (`Microsoft.Network/networkInterfaces`)

#### Builder Keywords

| Applies To | Keyword | Purpose |
|-|------------------|-------------------------------------------------------------------------------------------------------|
| networkInterface | name | Name of the network interface resource |
| networkInterface | link_to_subnet | Link to existing subnet. If not provided, need to specify the subnet name and prefix for a new subnet |
| networkInterface | subnet_name | Sets the name of the vnet subnet for network interface |
| networkInterface | subnet_prefix | Sets the prefix of the vnet subnet for network interface |
| networkInterface | link_to_vnet | Link to existing vnet or to vnet managed by Farmer |
| networkInterface | add_static_ip | Use static ip for the network interface. If not provided, ip will be dynamically allocated |
| networkInterface | accelerated_networking_flag | The accelerated networking flag for the network interface. Default is false |
| networkInterface | ip_forwarding_flag | The ip forwarding flag for the network interface. Default is false |

#### Example

```fsharp
#r "nuget:Farmer"
open Farmer
open Farmer.Builders
open Farmer.Builders.NetworkInterface
arm {
location Location.EastUS
add_resources
[
vnet {
name "test-vnet"
add_address_spaces [ "10.0.0.0/16" ]
}
networkInterface {
name "my-network-interface"
subnet_name "my-subnet"
subnet_prefix "10.0.100.0/24"
link_to_vnet (virtualNetworks.resourceId "test-vnet")
add_static_ip "10.0.100.10"
accelerated_networking_flag false
ip_forwarding_flag false
}
]
}
```

#### Example using existing vnet and subnet with dynamic ip allocation

```fsharp
#r "nuget:Farmer"
open Farmer
open Farmer.Builders
open Farmer.Builders.NetworkInterface
arm {
location Location.EastUS
add_resources
[
networkInterface {
name "my-network-interface"
link_to_subnet "test-subnet"
link_to_vnet "test-vnet"
}
]
}
```
181 changes: 181 additions & 0 deletions src/Farmer/Builders/Builders.NetworkInterface.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
module Farmer.Builders.NetworkInterface

open Farmer
open Farmer.Arm
open Farmer
open Farmer.Builders
open Farmer.Network
open Farmer.Arm.Network

type NetworkInterfaceConfig =
{
Name: ResourceName
AcceleratedNetworkingflag: FeatureFlag option
IpForwarding: FeatureFlag option
IsPrimary: bool option
VirtualNetwork: LinkedResource option
SubnetName: string option
SubnetPrefix: IPAddressCidr option
LinkedSubnet: LinkedResource option
PrivateIpAddress: AllocationMethod
Tags: Map<string, string>
}

interface IBuilder with
member this.ResourceId = networkInterfaces.resourceId this.Name

member this.BuildResources location =
[
//vnet
let vnetId =
this.VirtualNetwork
|> Option.defaultWith (fun _ -> raiseFarmer "Must set 'vnet' for network interface")

match this.LinkedSubnet with
| Some subnet ->
//ipConfig
let subnetIpConfigs =
[
{
SubnetName = subnet.Name
LoadBalancerBackendAddressPools = []
PublicIpAddress = None
PrivateIpAllocation = Some(this.PrivateIpAddress)
Primary = this.IsPrimary
}
]

//network interface
{
Name = this.Name
Location = location
EnableAcceleratedNetworking =
this.AcceleratedNetworkingflag |> Option.map (fun f -> f.AsBoolean)
EnableIpForwarding = this.IpForwarding |> Option.map (fun f -> f.AsBoolean)
IpConfigs = subnetIpConfigs
Primary = this.IsPrimary
VirtualNetwork = vnetId
NetworkSecurityGroup = None
Tags = this.Tags
}

| None ->
match this.SubnetName, this.SubnetPrefix with
| Some subnetName, Some subnetPrefix ->
//subnet
{
Subnet.Name = ResourceName subnetName
Prefix = IPAddressCidr.format subnetPrefix
VirtualNetwork = Some(vnetId)
NetworkSecurityGroup = None
Delegations = []
NatGateway = None
ServiceEndpoints = []
AssociatedServiceEndpointPolicies = []
PrivateEndpointNetworkPolicies = None
PrivateLinkServiceNetworkPolicies = None
}

//ipConfig
let subnetIpConfigs =
[
{
SubnetName = ResourceName subnetName
LoadBalancerBackendAddressPools = []
PublicIpAddress = None
PrivateIpAllocation = Some(this.PrivateIpAddress)
Primary = this.IsPrimary
}
]

//network interface
{
Name = this.Name
Location = location
EnableAcceleratedNetworking =
this.AcceleratedNetworkingflag |> Option.map (fun f -> f.AsBoolean)
EnableIpForwarding = this.IpForwarding |> Option.map (fun f -> f.AsBoolean)
IpConfigs = subnetIpConfigs
Primary = this.IsPrimary
VirtualNetwork = vnetId
NetworkSecurityGroup = None
Tags = this.Tags
}
| _ ->
raiseFarmer
$"subnetName and subnetPrefix must be specified for a new subnet if no existing subnet provided."
]

type NetworkInterfaceBuilder() =
member _.Yield _ =
{
Name = ResourceName.Empty
AcceleratedNetworkingflag = None
IpForwarding = None
IsPrimary = None
VirtualNetwork = None
SubnetName = None
SubnetPrefix = None
LinkedSubnet = None
PrivateIpAddress = AllocationMethod.DynamicPrivateIp
Tags = Map.empty
}

[<CustomOperation "name">]
member _.Name(state: NetworkInterfaceConfig, name: string) = { state with Name = ResourceName name }

[<CustomOperation "accelerated_networking_flag">]
member _.AcceleratedNetworkingflag(state: NetworkInterfaceConfig, flag: bool) =
{ state with
AcceleratedNetworkingflag = Some(FeatureFlag.ofBool flag)
}

[<CustomOperation "ip_forwarding_flag">]
member _.IpForwarding(state: NetworkInterfaceConfig, flag: bool) =
{ state with
IpForwarding = Some(FeatureFlag.ofBool flag)
}

[<CustomOperation "is_primary">]
member _.IsPrimary(state: NetworkInterfaceConfig, isPrimary: bool) =
{ state with
IsPrimary = Some(isPrimary)
}

// linked to managed vnet created by Farmer and linked by user
[<CustomOperation "link_to_vnet">]
member _.LinkToVNetId(state: NetworkInterfaceConfig, vnetId: ResourceId) =
{ state with
VirtualNetwork = Some(Managed vnetId)
}

// linked to external existing vnet
member _.LinkToVNetId(state: NetworkInterfaceConfig, vnetName: string) =
{ state with
VirtualNetwork = Some(Unmanaged(virtualNetworks.resourceId (ResourceName vnetName)))
}

// create subnet through Farmer. Need to specify subnet_name and subnet_prefix
[<CustomOperation "subnet_name">]
member _.SubnetName(state: NetworkInterfaceConfig, name) = { state with SubnetName = Some(name) }

[<CustomOperation "subnet_prefix">]
member _.SubnetPrefix(state: NetworkInterfaceConfig, prefix) =
{ state with
SubnetPrefix = Some(IPAddressCidr.parse prefix)
}

// linked to external existing subnet
[<CustomOperation "link_to_subnet">]
member _.LinkToSubnet(state: NetworkInterfaceConfig, name: string) =
{ state with
LinkedSubnet = Some(Unmanaged(subnets.resourceId (ResourceName name)))
}

[<CustomOperation "add_static_ip">]
member _.StaticIpAllocation(state: NetworkInterfaceConfig, addr) =
{ state with
PrivateIpAddress = AllocationMethod.StaticPrivateIp(System.Net.IPAddress.Parse addr)
}

let networkInterface = NetworkInterfaceBuilder()
1 change: 1 addition & 0 deletions src/Farmer/Farmer.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
<Compile Include="Builders\Builders.PrivateEndpoint.fs" />
<Compile Include="Builders\Builders.RouteTable.fs" />
<Compile Include="Builders\Builders.HostGroup.fs" />
<Compile Include="Builders\Builders.NetworkInterface.fs" />
<Compile Include="Builders\Builders.RouteServer.fs" />
<Compile Include="Aliases.fs" />
</ItemGroup>
Expand Down
Loading

0 comments on commit e616e34

Please sign in to comment.