How to fully provision AKS backups using Bicep

Tom Troughton 0 Reputation points
2024-11-21T19:11:52.1933333+00:00

I have an AKS cluster which I now want to add scheduled backups to using my Bicep-based provisioning pipeline.

I haven't found much guidance for this online but I've put together the following Bicep definitions for the various components. In addition to the cluster itself this provisions a backup vault, a backup policy (to run once every evening), a storage account with container for the backups, and adds the backup extension to my cluster. I had hoped this was all I'd need, but having waiting overnight nothing has happened. No backup and no evidence of a backup even being attempted. What am I missing?

Worth noting that if I try to perform a manual backup then I see the following warnings:

  • Extension MSI Role Permissions are missing for the associated storage account.
  • Trusted Access and/or Role Permissions are missing for the selected cluster.

I'm given the option of adding both these manually but I want to do everything by pipeline so it's repeatable. Could someone advise what precisely I need to provision in order to clear these warnings? Is there anything else I need to get these backups working?

Thanks in advance.

var aksClusterName = '${resourcePrefix}-cluster'

resource aks 'Microsoft.ContainerService/managedClusters@2024-08-01' = {
  name: aksClusterName
  location: location
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    dnsPrefix: useDnsPrefix
    oidcIssuerProfile: {
      enabled: true // Combines with securityProfile/workloadIdentity to enable workload identity
    }
    securityProfile: {
      workloadIdentity: {
        enabled: true
      }
    }
    autoUpgradeProfile: {
      upgradeChannel: 'stable'
    }
    agentPoolProfiles: [
      {
        name: 'agentpool'
        osDiskSizeGB: osDiskSizeGB
        count: agentCount
        vmSize: agentVMSize
        osType: 'Linux'
        mode: 'System'
        vnetSubnetID: subnetId
        enableAutoScaling: true
        minCount: 1
        maxCount: maxNodes
      }
    ]
    linuxProfile: {
      adminUsername: linuxAdminUsername
      ssh: {
        publicKeys: [
          {
            keyData: sshPublicKey
          }
        ]
      }
    }
  }
}

var backupVaultName = '${resourcePrefix}-backup-vault'

resource backupVault 'Microsoft.DataProtection/backupVaults@2024-04-01' = {
  name: backupVaultName
  location: location
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    storageSettings: [
      {
        datastoreType: 'VaultStore'
        type: 'LocallyRedundant'
      }
    ]
    monitoringSettings: {
      azureMonitorAlertSettings: {
        alertsForAllJobFailures: 'Enabled'
      }
    }
  }
}

resource backupPolicy 'Microsoft.DataProtection/backupVaults/backupPolicies@2024-04-01' = {
  name: 'daily'
  parent: backupVault
  properties: {
    objectType: 'BackupPolicy'
    datasourceTypes: [ 
      'Microsoft.ContainerService/managedClusters'
    ]
    policyRules: [
      {
        objectType: 'AzureRetentionRule'
        name: 'Default'
        isDefault: true
        lifecycles: [
          {
            deleteAfter: {
              objectType: 'AbsoluteDeleteOption'
              duration: 'P7D'
            }
            sourceDataStore: {
                objectType: 'DataStoreInfoBase'
                dataStoreType: 'OperationalStore'
            }
          }
        ]
      }
      {
        name: 'BackupDaily'
        objectType: 'AzureBackupRule'
        backupParameters: {
          objectType: 'AzureBackupParams'
          backupType: 'Incremental'
        }
        trigger: {
          objectType: 'ScheduleBasedTriggerContext'
          schedule: {
            repeatingTimeIntervals: [
              'R/2024-11-19T23:00:00+00:00/P1D'
            ]
          }
          taggingCriteria: [
            {
              tagInfo: {
                tagName: 'Default'
              }
              taggingPriority: 99
              isDefault: true
            }
          ]
        }
        dataStore: {
          dataStoreType: 'OperationalStore'
          objectType: 'DataStoreInfoBase'
        }
      }
    ]
  }
}

var backupStorageAccountName = '${resourcePrefixShort}${locationShort}bkp'
var backupContainerName = '${resourcePrefix}-${location}-cluster-backup'

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = {
  location: location
  name: backupStorageAccountName
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  dependsOn: [
    aks
  ]
}

resource storageAccountBlobService 'Microsoft.Storage/storageAccounts/blobServices@2022-05-01' = {
  name: 'default'
  parent: storageAccount
  properties: {
    lastAccessTimeTrackingPolicy: {
      blobType: [
        'string'
      ]
      enable: true
      name: 'AccessTimeTracking'
      trackingGranularityInDays: 1
    }
  }
}

resource backupContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-04-01' = {
  parent: storageAccountBlobService
  name: backupContainerName
  properties: {
    publicAccess: 'None'
  }
}

var backupExtensionName = '${resourcePrefixShort}${locationShort}bkpext'

resource backupExtension 'Microsoft.KubernetesConfiguration/extensions@2023-05-01' = {
  name: backupExtensionName
  scope: aks
  properties: {
    extensionType: 'microsoft.dataprotection.kubernetes'
    configurationSettings: {
      'configuration.backupStorageLocation.bucket': backupContainerName
      'configuration.backupStorageLocation.config.storageAccount': backupStorageAccountName
      'configuration.backupStorageLocation.config.resourceGroup': resourceGroup().name
      'configuration.backupStorageLocation.config.subscriptionId': subscription().subscriptionId
      'credentials.tenantId': subscription().tenantId
    }
  }
  dependsOn: [
    backupContainer
  ]
}

Azure Backup
Azure Backup
An Azure backup service that provides built-in management at scale.
1,289 questions
Azure Kubernetes Service (AKS)
Azure Kubernetes Service (AKS)
An Azure service that provides serverless Kubernetes, an integrated continuous integration and continuous delivery experience, and enterprise-grade security and governance.
2,165 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.