Azure / bicep-registry-modules

Bicep registry modules
MIT License
481 stars 336 forks source link

[AVM Module Issue]: load-balancer: fails on redeploy attempting to to modify backendAddressPool #3395

Open geoffklee opened 6 days ago

geoffklee commented 6 days ago

Check for previous/existing GitHub issues

Issue Type?

Bug

Module Name

avm/res/network/load-balancer

(Optional) Module Version

0.4.0

Description

I'm not 100% sure I'm not doing something wrong here, but I have a test case that consistently demonstrates this behaviour. In my reduced test case, I am creating a load balancer with a single backend pool containing a single NIC. Initial deployment is ok, but subsequent attempts to redeploy without modification result in the following error:

"Operation on backend pool /subscriptions/cc754c70-48de-4db0-a402-f26e3851e0f3/resourceGroups/rg-uos-sandbox-ciscofwtest/providers/Microsoft.Network/loadBalancers/testlb1/backendAddressPools/backendAddressPool1 not allowed since it adds/modifies/deletes backend address pool members that are specified with a network interface IP configuration."

to be clear, this is with no change to the code between initial deployment and redeployment. If I create the same load balancer as a resource directly, without using the module, it works as expected. Sample code below:

This works as expected:

resource externalLB 'Microsoft.Network/loadBalancers@2023-11-01' = {
  name: 'testlb1'
  location: resourceGroup().location
  sku: { name:'Standard', tier:'Regional' }
  properties: {
    frontendIPConfigurations: [
      {
        name: 'publicIPConfig1'
        properties: {
          publicIPAddress: {
            id: loadBalancerPublicIPAddress.id
          }
        }
      }
    ]
    backendAddressPools: [
      {
        name: 'backendAddressPool1'
      }
    ]
  }
}

resource vmNicDataInt 'Microsoft.Network/networkInterfaces@2020-04-01' = {
  name: 'nic-test'
  location: resourceGroup().location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig_int'
        properties: {
          privateIPAllocationMethod: 'Static'
          privateIPAddress: '10.12.0.40'
          subnet: {
            id: subnetMgtRef.id
          }

          //Add load balancer address pools for this NIC to be a member of
          loadBalancerBackendAddressPools: [ 
            {
               id: externalLB.properties.backendAddressPools[0].id
            }
          ]
        }
      }
    ]
    enableAcceleratedNetworking: true
    enableIPForwarding: true
  }
}

This, OTOH, creates the resources initially but fails on redeployment:

module externalLB './modules/load-balancer/main.bicep' = {
  name: 'lbi-test-1'
  params: {
    name: 'testlb1'
    frontendIPConfigurations: [
      {
        name: 'publicIPConfig1'
        publicIPAddressId: loadBalancerPublicIPAddress.id
      }
    ]
    // Non-required parameters
    backendAddressPools: [
      {
        name: 'backendAddressPool1'
      }
    ]
  }
}

resource vmNicDataInt 'Microsoft.Network/networkInterfaces@2020-04-01' = {
  name: 'nic-test'
  location: resourceGroup().location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig_int'
        properties: {
          privateIPAllocationMethod: 'Static'
          privateIPAddress: '10.12.0.40'
          subnet: {
            id: subnetMgtRef.id
          }

          //Add load balancer address pools for this NIC to be a member of
          loadBalancerBackendAddressPools: [ 
            {
              id: externalLB.outputs.backendpools[0].id
            }
          ]
        }
      }
    ]
    enableAcceleratedNetworking: true
    enableIPForwarding: true
  }
}

It appears that the module causes an empty loadBalancerBackendAddresses[]` property to be set on the backendAddressPool resource, and this has the effect of trying to modify a read-only resource.

(Optional) Correlation Id

No response

avm-team-linter[bot] commented 6 days ago

@geoffklee, thanks for submitting this issue for the avm/res/network/load-balancer module!

[!IMPORTANT] A member of the @Azure/avm-res-network-loadbalancer-module-owners-bicep or @Azure/avm-res-network-loadbalancer-module-contributors-bicep team will review it soon!

geoffklee commented 6 days ago

I investigated this a bit more and managed to provoke the failure by creating the backend pool as a separate resource rather than a property of the load balancer (the same approach as the module takes). So this exhibits the same failure as at the top of my original report:

resource externalLB 'Microsoft.Network/loadBalancers@2023-11-01' = {
  name: 'testlb1'
  location: resourceGroup().location
  sku: { name:'Standard', tier:'Regional' }
  properties: {
    frontendIPConfigurations: [
      {
        name: 'publicIPConfig1'
        properties: {
          publicIPAddress: {
            id: loadBalancerPublicIPAddress.id
          }
        }
      }
    ]
  }
}

resource backendAddressPool 'Microsoft.Network/loadBalancers/backendAddressPools@2023-11-01' = {
  name: 'backendAddressPool1'
  properties: {
  }
  parent: externalLB
}

ie, initial deployment works as expected but subsequent deployments produce this error:

"details":[{"code":"ModificationOfNICIpConfigBackendPoolNotSupported","message":"Operation on backend pool /subscriptions/cc754c70-48de-4db0-a402-f26e3851e0f3/resourceGroups/rg-uos-sandbox-ciscofwtest/providers/Microsoft.Network/loadBalancers/testlb1/backendAddressPools/backendAddressPool1 not allowed since it adds/modifies/deletes backend address pool members that are specified with a network interface IP configuration."

So perhaps not an issue with the module per se but I'd appreciate the thoughts of someone who understands this stuff properly!

arnoldna commented 1 day ago

Thanks @geoffklee for reporting this. Let me take a look.