Skip to content

Commit

Permalink
Merge pull request #1176 from CompositionalIT/arm_exp_params
Browse files Browse the repository at this point in the history
App Gateway SSL Support, ARM Expressions in NSG rules and Gallery Apps
  • Loading branch information
ninjarobot authored Jan 4, 2025
2 parents 0936a50 + fe36aff commit cc57024
Show file tree
Hide file tree
Showing 13 changed files with 404 additions and 58 deletions.
5 changes: 5 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Release Notes
=============

## 1.9.10
* Application Gateways: Adds SSL Certificates
* Network Security Groups: use ARM expressions in security rules
* Gallery Applications: `source_media_link` can be an ARM expression

## 1.9.9
* Virtual Machines: support for Azure Linux 3.0
* Virtual Machines: support for Standard SKU Public IP Address
Expand Down
44 changes: 27 additions & 17 deletions docs/content/api-overview/resources/application-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@ The Application Gateway builder is used to create Application Gateways.
#### Application Gateway Builder Keywords
The Application Gateway builder (`appGateway`) constructs Application Gateways.

| Keyword | Purpose |
|-|-|
| name | Sets the name of the Application Gateway. |
| sku_capacity | Sets the capacity for this SKU of Application Gateway. |
| add_identity | Assigns a managed identity to the Application Gateway. |
| add_ip_configs | Assigns one or more gateway IP configuration for the subnet where it should be created. |
| add_frontends | Assigns one or more frontend IP configuration for a public or private IP for the services accessible through the gateway. |
| add_frontend_ports | Assigns one or more frontend ports to listen |
| add_http_listeners | Assigns one or more http listeners. |
| add_backend_address_pools | Assigns one or more backend pools. |
| add_backend_http_settings_collection | Assigns HTTP settings for the listener. |
| add_request_routing_rules | Assigns routing rules between frontend IP configurations and ports and services in the backend pool. |
| add_probes | Assigns health probes to ensure backend services are healthy or removed from the pool. |
| Keyword | Purpose |
|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| name | Sets the name of the Application Gateway. |
| sku_capacity | Sets the capacity for this SKU of Application Gateway. |
| add_identity | Assigns a managed identity to the Application Gateway. |
| add_ip_configs | Assigns one or more gateway IP configuration for the subnet where it should be created. |
| add_frontends | Assigns one or more frontend IP configuration for a public or private IP for the services accessible through the gateway. |
| add_frontend_ports | Assigns one or more frontend ports to listen |
| add_http_listeners | Assigns one or more http listeners. |
| add_backend_address_pools | Assigns one or more backend pools. |
| add_backend_http_settings_collection | Assigns HTTP settings for the listener. |
| add_request_routing_rules | Assigns routing rules between frontend IP configurations and ports and services in the backend pool. |
| add_probes | Assigns health probes to ensure backend services are healthy or removed from the pool. |
| add_ssl_certificates | Assigns one or more SSL certificates to the App Gateway for use in httpListeners. |

#### Complete Example

Expand All @@ -45,7 +46,7 @@ let myNsg = nsg {
securityRule {
name "inet-gw"
description "Internet to gateway"
services [ "http", 80 ]
services [ "https", 443 ]
add_source_tag NetworkSecurity.TCP "Internet"
add_destination_network "10.28.0.0/24"
}
Expand Down Expand Up @@ -99,15 +100,17 @@ let myAppGateway =
}
let frontendPort =
frontendPort {
name "port-80"
port 80
name "port-443"
port 443
}
let listener =
httpListener {
name "http-listener"
name "https-listener"
frontend_ip frontendIp
frontend_port frontendPort
backend_pool backendPoolName.Value
protocol Protocol.Https
ssl_certificate "my-tls-cert"
}
let backendPool =
appGatewayBackendAddressPool {
Expand Down Expand Up @@ -153,6 +156,13 @@ let myAppGateway =
add_backend_http_settings_collection [ backendSettings ]
add_request_routing_rules [ routingRule ]
add_probes [ healthProbe ]
add_ssl_certificates [
sslCertificate {
name "my-tls-cert"
// Ensure App Gateway identity (MSI) has access to read this secret.
key_vault_secret_id "https://my-kv.vault.azure.net/secrets/app-gw-cert"
}
]
depends_on myNsg
depends_on net
}
Expand Down
49 changes: 26 additions & 23 deletions src/Farmer/Arm/ApplicationGateway.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,56 @@ open Farmer
open Farmer.ApplicationGateway
open Farmer.Identity

[<Literal>]
let private apiVersion = "2024-05-01"

let applicationGateways =
ResourceType("Microsoft.Network/applicationGateways", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways", apiVersion)

let applicationGatewayAuthenticationCertificates =
ResourceType("Microsoft.Network/applicationGateways/authenticationCertificates", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/authenticationCertificates", apiVersion)

let applicationGatewayBackendHttpSettingsCollection =
ResourceType("Microsoft.Network/applicationGateways/backendHttpSettingsCollection", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/backendHttpSettingsCollection", apiVersion)

let applicationGatewayBackendAddressPools =
ResourceType("Microsoft.Network/applicationGateways/backendAddressPools", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/backendAddressPools", apiVersion)

let applicationGatewayFrontendIPConfigurations =
ResourceType("Microsoft.Network/applicationGateways/frontendIPConfigurations", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/frontendIPConfigurations", apiVersion)

let applicationGatewayFrontendPorts =
ResourceType("Microsoft.Network/applicationGateways/frontendPorts", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/frontendPorts", apiVersion)

let applicationGatewayHttpListeners =
ResourceType("Microsoft.Network/applicationGateways/httpListeners", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/httpListeners", apiVersion)

let applicationGatewayPathRules =
ResourceType("Microsoft.Network/applicationGateways/pathRule", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/pathRule", apiVersion)

let ApplicationGatewayProbes =
ResourceType("Microsoft.Network/applicationGateways/probes", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/probes", apiVersion)

let applicationGatewayRedirectConfigurations =
ResourceType("Microsoft.Network/applicationGateways/redirectConfigurations", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/redirectConfigurations", apiVersion)

let applicationGatewayRequestRoutingRules =
ResourceType("Microsoft.Network/applicationGateways/requestRoutingRules", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/requestRoutingRules", apiVersion)

let applicationGatewayRewriteRuleSets =
ResourceType("Microsoft.Network/applicationGateways/rewriteRuleSets", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/rewriteRuleSets", apiVersion)

let applicationGatewaySslCertificates =
ResourceType("Microsoft.Network/applicationGateways/sslCertificates", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/sslCertificates", apiVersion)

let applicationGatewaySslProfiles =
ResourceType("Microsoft.Network/applicationGateways/sslProfiles", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/sslProfiles", apiVersion)

let applicationGatewayTrustedRootCertificates =
ResourceType("Microsoft.Network/applicationGateways/trustedRootCertificates", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/trustedRootCertificates", apiVersion)

let applicationGatewayUrlPathMaps =
ResourceType("Microsoft.Network/applicationGateways/urlPathMap", "2020-11-01")
ResourceType("Microsoft.Network/applicationGateways/urlPathMap", apiVersion)

type ApplicationGateway = {
Name: ResourceName
Expand All @@ -67,7 +70,7 @@ type ApplicationGateway = {
FrontendIpConfigs:
{|
Name: ResourceName
PrivateIpAllocationMethod: PrivateIpAddress.AllocationMethod
PrivateIpAllocationMethod: AllocationMethod
PublicIp: ResourceId option
|} list
BackendAddressPools:
Expand Down Expand Up @@ -209,7 +212,7 @@ type ApplicationGateway = {
{|
Name: ResourceName
Data: string option
KeyVaultSecretId: string
KeyVaultSecretId: string option
Password: string option
|} list
SslPolicy:
Expand Down Expand Up @@ -448,8 +451,8 @@ type ApplicationGateway = {
|> List.map (fun frontend ->
let allocationMethod, ip =
match frontend.PrivateIpAllocationMethod with
| PrivateIpAddress.DynamicPrivateIp -> "Dynamic", null
| PrivateIpAddress.StaticPrivateIp ip -> "Static", string ip
| DynamicPrivateIp -> "Dynamic", null
| StaticPrivateIp ip -> "Static", string ip

{|
name = frontend.Name.Value
Expand Down Expand Up @@ -521,7 +524,7 @@ type ApplicationGateway = {
|})
requestRoutingRules =
this.RequestRoutingRules
|> List.map (fun routingRule -> {|
|> List.mapi (fun idx routingRule -> {|
name = routingRule.Name.Value
properties = {|
backendAddressPool =
Expand All @@ -539,7 +542,7 @@ type ApplicationGateway = {
httpListener =
applicationGatewayHttpListeners.resourceId (this.Name, routingRule.HttpListener)
|> ResourceId.AsIdObject
priority = routingRule.Priority |> Option.toNullable
priority = routingRule.Priority |> Option.defaultValue (1000 + idx)
redirectConfiguration =
routingRule.RedirectConfiguration
|> Option.map (
Expand Down Expand Up @@ -614,7 +617,7 @@ type ApplicationGateway = {
name = cert.Name.Value
properties = {|
data = cert.Data |> Option.toObj
keyVaultSecretId = cert.KeyVaultSecretId
keyVaultSecretId = cert.KeyVaultSecretId |> Option.toObj
password = cert.Password |> Option.toObj
|}
|})
Expand Down
2 changes: 1 addition & 1 deletion src/Farmer/Arm/Gallery.fs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ type UserArtifactSettings = {

type UserArtifactSource = {
DefaultConfigurationLink: Uri option
MediaLink: Uri
MediaLink: string
} with

static member Empty = {
Expand Down
12 changes: 8 additions & 4 deletions src/Farmer/Arm/NetworkSecurityGroup.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ let (|SingleEndpoint|ManyEndpoints|) endpoints =
|> function
| Some(Tag tag) -> SingleEndpoint(Tag tag)
| None
| Some(AnyEndpoint | Network _ | Host _ | ApplicationSecurityGroup _) -> ManyEndpoints(List.ofSeq endpoints)
| Some(AnyEndpoint | Network _ | Host _ | ApplicationSecurityGroup _ | Expression _) ->
ManyEndpoints(List.ofSeq endpoints)

let private (|SinglePort|ManyPorts|) (ports: _ Set) =
if ports.Contains AnyPort then
Expand Down Expand Up @@ -57,6 +58,7 @@ module private EndpointWriter =

type SecurityRule = {
Name: ResourceName
Dependencies: ResourceId Set
Description: string option
SecurityGroup: LinkedResource
Protocol: NetworkProtocol
Expand All @@ -72,13 +74,14 @@ type SecurityRule = {
} with

/// Get any managed application security group resource IDs.
static member Dependencies securityRule =
static member internal AllDependencies securityRule =
securityRule.SourceApplicationSecurityGroups
@ securityRule.DestinationApplicationSecurityGroups
|> List.choose (function
| Managed id -> Some id
| _ -> None)
|> Set.ofList
|> Set.union securityRule.Dependencies

member this.PropertiesModel = {|
description = this.Description |> Option.toObj
Expand All @@ -103,7 +106,8 @@ type SecurityRule = {
member this.ResourceId = securityRules.resourceId (this.SecurityGroup.Name / this.Name)

member this.JsonModel =
let dependsOn = Set.empty |> LinkedResource.addToSetIfManaged this.SecurityGroup
let dependsOn =
this.Dependencies |> LinkedResource.addToSetIfManaged this.SecurityGroup

{|
securityRules.Create(this.SecurityGroup.Name / this.Name, dependsOn = dependsOn) with
Expand All @@ -125,7 +129,7 @@ type NetworkSecurityGroup = {
let dependencies =
[
this.Dependencies
yield! this.SecurityRules |> List.map SecurityRule.Dependencies
yield! this.SecurityRules |> List.map SecurityRule.AllDependencies
]
|> Set.unionMany

Expand Down
Loading

0 comments on commit cc57024

Please sign in to comment.