Reputation: 23
I'm currently working with a solution that uses an Azure Application Gateway deployed with ARM/Bicep. Over time, other applications are deployed that use this AppGw, so rules/backend pools/listeners are created for those applications at their deployment time via Az CLI (outside of the central infra IaC pipeline/process). When it comes to redeploying/updating the central AppGw, I have the classic problem of the ARM/Bicep template overwriting all of these extra additions, as the AppGw is a single resource and as the changes are not in the ARM/Bicep file they are removed.
I have worked around this problem in the past by checking for AppGw existence, outputting the existing rules/pools/etc. and then incorporating them into the ARM/Bicep JSON before it is redeployed. This has worked fine but the AppGw is now getting so large/complex that I am hitting Bash character limits when deploying updates via Azure Devops build pipelines. As such, I am looking for a better way to handle this issue. I have also tried outputting the existing config to file and ingesting via file load in Azure Bicep, but I need to deploy multiple AppGws across the globe with different configs so due to compile time file reference restrictions in Bicep, this doesn't work for me.
I need to ensure that my baseline template file for the AppGw, which sets core things like TLS level or diagnostic settings, is honoured in some way while not overwriting the amendments that happen from separate deployment processes.
My question is whether I can incorporate/merge the state of this existing AppGw with my baseline template, either using Azure Bicep or retooling to something like Pulumi/Terraform if this exposes the functionality. The kind of approach I was thinking of would be:
I am aware, but not experienced with, Pulumi's concept of ignoreChanges and transformations. I wasn't sure if that covered the use case here. What I am trying to achieve here may be in conflict with the purpose of these declarative languages, but just thought I'd ask to see if someone else had any thoughts.
Thanks very much in advance!
Upvotes: 1
Views: 822
Reputation: 29482
Using Bicep, you could always retrieve existing configuration if the app gateway already exists.
Here is a sample using httpListeners
.
You could define a app-gateway.bicep
module like that:
param appGatewayName string
param location string = resourceGroup().location
...
param httpListeners array
resource appGateway 'Microsoft.Network/applicationGateways@2020-11-01' = {
name: appGatewayName
location: location
...
properties: {
...
httpListeners: httpListeners
}
}
Then from your main.bicep
file, use the default or existing config:
param appGateWayExists bool
param appGatewayName string
...
// Get existing app gateway if existing
resource existing 'Microsoft.Network/applicationGateways@2020-11-01' existing = if (appGateWayExists) {
name: appGatewayName
}
// Deploy app gateway
module appgateway './app-gateway.bicep' = {
name: 'app-gateway'
params: {
appGatewayName: appGatewayName
...
// Use existing configuration if exists
httpListeners: appGateWayExists ? existing.properties.httpListeners : [
{
// default listener configuration
}
]
}
}
Then you could invoke it like that:
$appGatewayName = "<app-gateway-name>"
$appGatewayExists = (az resource list --name "$appGatewayName" --query '[].[id]' | ConvertFrom-Json).Length -gt 0
az deployment group create `
--resource-group "<resource-group-name>" `
...
--parameters `
appGateWayExists=$appGatewayExists `
appGatewayName="$appGatewayName" `
...
Upvotes: 0