Skip to content

Commit cc57024

Browse files
authored
Merge pull request #1176 from CompositionalIT/arm_exp_params
App Gateway SSL Support, ARM Expressions in NSG rules and Gallery Apps
2 parents 0936a50 + fe36aff commit cc57024

13 files changed

+404
-58
lines changed

RELEASE_NOTES.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Release Notes
22
=============
33

4+
## 1.9.10
5+
* Application Gateways: Adds SSL Certificates
6+
* Network Security Groups: use ARM expressions in security rules
7+
* Gallery Applications: `source_media_link` can be an ARM expression
8+
49
## 1.9.9
510
* Virtual Machines: support for Azure Linux 3.0
611
* Virtual Machines: support for Standard SKU Public IP Address

docs/content/api-overview/resources/application-gateway.md

+27-17
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@ The Application Gateway builder is used to create Application Gateways.
1313
#### Application Gateway Builder Keywords
1414
The Application Gateway builder (`appGateway`) constructs Application Gateways.
1515

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

3031
#### Complete Example
3132

@@ -45,7 +46,7 @@ let myNsg = nsg {
4546
securityRule {
4647
name "inet-gw"
4748
description "Internet to gateway"
48-
services [ "http", 80 ]
49+
services [ "https", 443 ]
4950
add_source_tag NetworkSecurity.TCP "Internet"
5051
add_destination_network "10.28.0.0/24"
5152
}
@@ -99,15 +100,17 @@ let myAppGateway =
99100
}
100101
let frontendPort =
101102
frontendPort {
102-
name "port-80"
103-
port 80
103+
name "port-443"
104+
port 443
104105
}
105106
let listener =
106107
httpListener {
107-
name "http-listener"
108+
name "https-listener"
108109
frontend_ip frontendIp
109110
frontend_port frontendPort
110111
backend_pool backendPoolName.Value
112+
protocol Protocol.Https
113+
ssl_certificate "my-tls-cert"
111114
}
112115
let backendPool =
113116
appGatewayBackendAddressPool {
@@ -153,6 +156,13 @@ let myAppGateway =
153156
add_backend_http_settings_collection [ backendSettings ]
154157
add_request_routing_rules [ routingRule ]
155158
add_probes [ healthProbe ]
159+
add_ssl_certificates [
160+
sslCertificate {
161+
name "my-tls-cert"
162+
// Ensure App Gateway identity (MSI) has access to read this secret.
163+
key_vault_secret_id "https://my-kv.vault.azure.net/secrets/app-gw-cert"
164+
}
165+
]
156166
depends_on myNsg
157167
depends_on net
158168
}

src/Farmer/Arm/ApplicationGateway.fs

+26-23
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,56 @@ open Farmer
44
open Farmer.ApplicationGateway
55
open Farmer.Identity
66

7+
[<Literal>]
8+
let private apiVersion = "2024-05-01"
9+
710
let applicationGateways =
8-
ResourceType("Microsoft.Network/applicationGateways", "2020-11-01")
11+
ResourceType("Microsoft.Network/applicationGateways", apiVersion)
912

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

1316
let applicationGatewayBackendHttpSettingsCollection =
14-
ResourceType("Microsoft.Network/applicationGateways/backendHttpSettingsCollection", "2020-11-01")
17+
ResourceType("Microsoft.Network/applicationGateways/backendHttpSettingsCollection", apiVersion)
1518

1619
let applicationGatewayBackendAddressPools =
17-
ResourceType("Microsoft.Network/applicationGateways/backendAddressPools", "2020-11-01")
20+
ResourceType("Microsoft.Network/applicationGateways/backendAddressPools", apiVersion)
1821

1922
let applicationGatewayFrontendIPConfigurations =
20-
ResourceType("Microsoft.Network/applicationGateways/frontendIPConfigurations", "2020-11-01")
23+
ResourceType("Microsoft.Network/applicationGateways/frontendIPConfigurations", apiVersion)
2124

2225
let applicationGatewayFrontendPorts =
23-
ResourceType("Microsoft.Network/applicationGateways/frontendPorts", "2020-11-01")
26+
ResourceType("Microsoft.Network/applicationGateways/frontendPorts", apiVersion)
2427

2528
let applicationGatewayHttpListeners =
26-
ResourceType("Microsoft.Network/applicationGateways/httpListeners", "2020-11-01")
29+
ResourceType("Microsoft.Network/applicationGateways/httpListeners", apiVersion)
2730

2831
let applicationGatewayPathRules =
29-
ResourceType("Microsoft.Network/applicationGateways/pathRule", "2020-11-01")
32+
ResourceType("Microsoft.Network/applicationGateways/pathRule", apiVersion)
3033

3134
let ApplicationGatewayProbes =
32-
ResourceType("Microsoft.Network/applicationGateways/probes", "2020-11-01")
35+
ResourceType("Microsoft.Network/applicationGateways/probes", apiVersion)
3336

3437
let applicationGatewayRedirectConfigurations =
35-
ResourceType("Microsoft.Network/applicationGateways/redirectConfigurations", "2020-11-01")
38+
ResourceType("Microsoft.Network/applicationGateways/redirectConfigurations", apiVersion)
3639

3740
let applicationGatewayRequestRoutingRules =
38-
ResourceType("Microsoft.Network/applicationGateways/requestRoutingRules", "2020-11-01")
41+
ResourceType("Microsoft.Network/applicationGateways/requestRoutingRules", apiVersion)
3942

4043
let applicationGatewayRewriteRuleSets =
41-
ResourceType("Microsoft.Network/applicationGateways/rewriteRuleSets", "2020-11-01")
44+
ResourceType("Microsoft.Network/applicationGateways/rewriteRuleSets", apiVersion)
4245

4346
let applicationGatewaySslCertificates =
44-
ResourceType("Microsoft.Network/applicationGateways/sslCertificates", "2020-11-01")
47+
ResourceType("Microsoft.Network/applicationGateways/sslCertificates", apiVersion)
4548

4649
let applicationGatewaySslProfiles =
47-
ResourceType("Microsoft.Network/applicationGateways/sslProfiles", "2020-11-01")
50+
ResourceType("Microsoft.Network/applicationGateways/sslProfiles", apiVersion)
4851

4952
let applicationGatewayTrustedRootCertificates =
50-
ResourceType("Microsoft.Network/applicationGateways/trustedRootCertificates", "2020-11-01")
53+
ResourceType("Microsoft.Network/applicationGateways/trustedRootCertificates", apiVersion)
5154

5255
let applicationGatewayUrlPathMaps =
53-
ResourceType("Microsoft.Network/applicationGateways/urlPathMap", "2020-11-01")
56+
ResourceType("Microsoft.Network/applicationGateways/urlPathMap", apiVersion)
5457

5558
type ApplicationGateway = {
5659
Name: ResourceName
@@ -67,7 +70,7 @@ type ApplicationGateway = {
6770
FrontendIpConfigs:
6871
{|
6972
Name: ResourceName
70-
PrivateIpAllocationMethod: PrivateIpAddress.AllocationMethod
73+
PrivateIpAllocationMethod: AllocationMethod
7174
PublicIp: ResourceId option
7275
|} list
7376
BackendAddressPools:
@@ -209,7 +212,7 @@ type ApplicationGateway = {
209212
{|
210213
Name: ResourceName
211214
Data: string option
212-
KeyVaultSecretId: string
215+
KeyVaultSecretId: string option
213216
Password: string option
214217
|} list
215218
SslPolicy:
@@ -448,8 +451,8 @@ type ApplicationGateway = {
448451
|> List.map (fun frontend ->
449452
let allocationMethod, ip =
450453
match frontend.PrivateIpAllocationMethod with
451-
| PrivateIpAddress.DynamicPrivateIp -> "Dynamic", null
452-
| PrivateIpAddress.StaticPrivateIp ip -> "Static", string ip
454+
| DynamicPrivateIp -> "Dynamic", null
455+
| StaticPrivateIp ip -> "Static", string ip
453456

454457
{|
455458
name = frontend.Name.Value
@@ -521,7 +524,7 @@ type ApplicationGateway = {
521524
|})
522525
requestRoutingRules =
523526
this.RequestRoutingRules
524-
|> List.map (fun routingRule -> {|
527+
|> List.mapi (fun idx routingRule -> {|
525528
name = routingRule.Name.Value
526529
properties = {|
527530
backendAddressPool =
@@ -539,7 +542,7 @@ type ApplicationGateway = {
539542
httpListener =
540543
applicationGatewayHttpListeners.resourceId (this.Name, routingRule.HttpListener)
541544
|> ResourceId.AsIdObject
542-
priority = routingRule.Priority |> Option.toNullable
545+
priority = routingRule.Priority |> Option.defaultValue (1000 + idx)
543546
redirectConfiguration =
544547
routingRule.RedirectConfiguration
545548
|> Option.map (
@@ -614,7 +617,7 @@ type ApplicationGateway = {
614617
name = cert.Name.Value
615618
properties = {|
616619
data = cert.Data |> Option.toObj
617-
keyVaultSecretId = cert.KeyVaultSecretId
620+
keyVaultSecretId = cert.KeyVaultSecretId |> Option.toObj
618621
password = cert.Password |> Option.toObj
619622
|}
620623
|})

src/Farmer/Arm/Gallery.fs

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ type UserArtifactSettings = {
297297

298298
type UserArtifactSource = {
299299
DefaultConfigurationLink: Uri option
300-
MediaLink: Uri
300+
MediaLink: string
301301
} with
302302

303303
static member Empty = {

src/Farmer/Arm/NetworkSecurityGroup.fs

+8-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ let (|SingleEndpoint|ManyEndpoints|) endpoints =
2626
|> function
2727
| Some(Tag tag) -> SingleEndpoint(Tag tag)
2828
| None
29-
| Some(AnyEndpoint | Network _ | Host _ | ApplicationSecurityGroup _) -> ManyEndpoints(List.ofSeq endpoints)
29+
| Some(AnyEndpoint | Network _ | Host _ | ApplicationSecurityGroup _ | Expression _) ->
30+
ManyEndpoints(List.ofSeq endpoints)
3031

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

5859
type SecurityRule = {
5960
Name: ResourceName
61+
Dependencies: ResourceId Set
6062
Description: string option
6163
SecurityGroup: LinkedResource
6264
Protocol: NetworkProtocol
@@ -72,13 +74,14 @@ type SecurityRule = {
7274
} with
7375

7476
/// Get any managed application security group resource IDs.
75-
static member Dependencies securityRule =
77+
static member internal AllDependencies securityRule =
7678
securityRule.SourceApplicationSecurityGroups
7779
@ securityRule.DestinationApplicationSecurityGroups
7880
|> List.choose (function
7981
| Managed id -> Some id
8082
| _ -> None)
8183
|> Set.ofList
84+
|> Set.union securityRule.Dependencies
8285

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

105108
member this.JsonModel =
106-
let dependsOn = Set.empty |> LinkedResource.addToSetIfManaged this.SecurityGroup
109+
let dependsOn =
110+
this.Dependencies |> LinkedResource.addToSetIfManaged this.SecurityGroup
107111

108112
{|
109113
securityRules.Create(this.SecurityGroup.Name / this.Name, dependsOn = dependsOn) with
@@ -125,7 +129,7 @@ type NetworkSecurityGroup = {
125129
let dependencies =
126130
[
127131
this.Dependencies
128-
yield! this.SecurityRules |> List.map SecurityRule.Dependencies
132+
yield! this.SecurityRules |> List.map SecurityRule.AllDependencies
129133
]
130134
|> Set.unionMany
131135

0 commit comments

Comments
 (0)