Search code examples
azure-aksazure-bicep

How can I refer to a subnet created in a module from a bicep AKS configuration


I am trying to create an Azure Kubernetes Service cluster to an existing virtual network. I need to use CNI networking, so I need a predefined subnet. The subnet is in a different resource group.

My solution was to use a module to create the subnet, then load it as an existing resource:

@description('Resource group with the vNet')
param vnetRG string

@description('The vNet that will have the subnet')
param vNet string

param location string = resourceGroup().location

param otherParameter string

param sshPubKey string

module subnet 'subnet.bicep' = {
  name: '${deployment().name}-subnet'
  scope: resourceGroup( vnetRG )
  params: {
    virtualNetworkName: vNet
  }
}

resource subnetFromModule 'Microsoft.Network/virtualNetworks/subnets@2022-07-01' existing = {
  name: subnet.outputs.subnetName
  scope: resourceGroup( vnetRG )
}

// The Azure Kubernetes Service cluster.
resource aks 'Microsoft.ContainerService/managedClusters@2022-05-02-preview' = {
  name: otherParameter
  location: location
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    dnsPrefix: 'dummy'
    publicNetworkAccess: 'Enabled'
    networkProfile: {
      networkPlugin: 'azure'
    }
    agentPoolProfiles: [
      {
        name: 'lnxnod'
        osDiskSizeGB: 60
        count: 3
        vmSize: 'Standard_D2s_v3'
        osType: 'Linux'
        mode: 'System'
        vnetSubnetID: subnetFromModule.id
      }
    ]
    linuxProfile: {
      adminUsername: otherParameter
      ssh: {
        publicKeys: [
          {
            keyData: sshPubKey
          }
        ]
      }
    }
  }
}

output subnetId string = subnetFromModule.id

But trying to apply this template resulted in the error: InvalidTemplateDeploymentError - Provisioning of resource(s) for container service lsdkf in resource group testclusterthing failed. Message: Provisioning of resource(s) for container service lsdkf in resource group GLRclusterRG failed. Message: Deployment template validation failed: 'The template parameter 'vnetRG' is not found. Please see https://aka.ms/arm-syntax-parameters for usage details.'.. Details: . Details:. What am I doing wrong?


Solution

  • I figured out the problem. At first I thought the error was coming from the module declaration, because replacing the parameter with a literal value there fixed the problem. But then I tried deleting everything after the module reference, and that fixed the issue as well. I was finally able to pin down the issue to vnetSubnetID: subnetFromModule.id in agentPoolProfiles. For some reason a reference to the existing resource created by the module failed here.

    I worked around the issue by not using existing to load the subnet resource. Instead I just returned all the relevant metadata as outputs from the module:

    @description('Resource group with the vNet')
    param vnetRG string
    
    @description('The vNet that will have the subnet')
    param vNet string
    
    param location string = resourceGroup().location
    
    param otherParameter string
    
    param sshPubKey string
    
    module subnet 'subnet.bicep' = {
      name: '${deployment().name}-subnet'
      scope: resourceGroup( vnetRG )
      params: {
        virtualNetworkName: vNet
      }
    }
    
    // The Azure Kubernetes Service cluster.
    resource aks 'Microsoft.ContainerService/managedClusters@2022-05-02-preview' = {
      name: otherParameter
      location: location
      identity: {
        type: 'SystemAssigned'
      }
      properties: {
        dnsPrefix: 'dummy'
        publicNetworkAccess: 'Enabled'
        networkProfile: {
          networkPlugin: 'azure'
        }
        agentPoolProfiles: [
          {
            name: 'lnxnod'
            osDiskSizeGB: 60
            count: 3
            vmSize: 'Standard_D2s_v3'
            osType: 'Linux'
            mode: 'System'
            vnetSubnetID: subnet.outputs.subnetId
          }
        ]
        linuxProfile: {
          adminUsername: otherParameter
          ssh: {
            publicKeys: [
              {
                keyData: sshPubKey
              }
            ]
          }
        }
      }
    }
    
    output subnetId string = subnet.outputs.subnetId