Configure credentials for Azure Blob remote storage

Set up Azure Blob credentials for the App Framework.

Configure credentials for Azure Blob storage using Managed Identity, Workload Identity, or Kubernetes secrets.

Compare Azure Managed Identity and Workload Identity

Feature Managed Identity Workload Identity
Scope Tied to the Azure resource (for example, AKS node) Tied to Kubernetes Service Accounts
Credential Management Azure manages credentials Kubernetes manages Service Account credentials
Flexibility Limited to Azure resources More flexible, integrates with Kubernetes-native identities
Granularity Role assignments at Azure resource level Role assignments at Kubernetes namespace or service account level
Use Cases Simple scenarios where workloads share identities Complex scenarios requiring granular access controls

When to use which:

Managed Identity
Suitable for scenarios where workloads are tightly coupled with specific Azure resources and require straightforward IAM access.
Workload Identity
Ideal for Kubernetes-native environments where fine-grained access control and integration with Kubernetes Service Accounts are essential.

Set up Azure Blob access with Managed Identity

Note:
  • Familiarize yourself with AKS managed identity concepts (Use managed identities in Azure Kubernetes Service).
  • The names used below are for example purposes only. Change them to match your setup.
  • These steps cover creating a resource group and AKS cluster; skip them if you already have them created.
  1. Create an Azure Resource Group:

    CODE
    az group create --name splunkOperatorResourceGroup --location westus2
  2. Create an AKS cluster with Managed Identity enabled:

    CODE
    az aks create -g splunkOperatorResourceGroup -n splunkOperatorCluster --enable-managed-identity
  3. Get credentials to access the cluster:

    CODE
    az aks get-credentials --resource-group splunkOperatorResourceGroup --name splunkOperatorCluster
  4. Get the Kubelet User Managed Identity. Run az identity list and find the entry where name is your-cluster-name-agentpool. Example JSON output:

    JSON
    {
      "clientId": "a5890776-24e6-4f5b-9b6c-**************",
      "id": "/subscriptions/<subscription-id>/resourceGroups/MC_splunkOperatorResourceGroup_splunkOperatorCluster_westus2/providers/Microsoft.ManagedIdentity/userAssignedIdentities/splunkOperatorCluster-agentpool",
      "location": "westus2",
      "name": "splunkOperatorCluster-agentpool",
      "principalId": "f0f04120-6a36-49bc--**************",
      "resourceGroup": "MC_splunkOperatorResourceGroup_splunkOperatorCluster_westus2",
      "tags": {},
      "tenantId": "8add7810-b62a--**************",
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
    }

    Extract the principalId. Alternative command:

    CODE
    az identity show --name <identityName> --resource-group "<resourceGroup>" --query 'principalId' --output tsv

    Example:

    CODE
    principalId=$(az identity show --name splunkOperatorCluster-agentpool --resource-group "MC_splunkOperatorResourceGroup_splunkOperatorCluster_westus2" --query 'principalId' --output tsv)
    echo $principalId

    Output example: f0f04120-6a36-49bc--**************

  5. Assign read access for the Kubelet User Managed Identity to the storage account:

    CODE
    az role assignment create --assignee "<principalId>" --role 'Storage Blob Data Reader' --scope /subscriptions/<subscription_id>/resourceGroups/<storageAccountResourceGroup>/providers/Microsoft.Storage/storageAccounts/<storageAccountName>

    Example:

    CODE
    az role assignment create --assignee "f0f04120-6a36-49bc--**************" --role 'Storage Blob Data Reader' --scope /subscriptions/f428689e-c379-4712--**************/resourceGroups/splunkOperatorResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount

    After this, you can use the App Framework for Azure Blob without secrets.

Set up Azure Blob access with Workload Identity

Note:
  • Familiarize yourself with Azure AD Workload Identity concepts (Azure AD Workload Identity overview).
  • Names are examples only. Change them to match your setup.
  • These steps cover creating a resource group and AKS cluster with Azure Workload Identity enabled; skip them if you already created them.
  1. Create an Azure Resource Group:

    CODE
    az group create --name splunkOperatorWorkloadIdentityRG --location westus2
  2. Create an AKS cluster with Azure Workload Identity enabled:

    CODE
    az aks create -g splunkOperatorWorkloadIdentityRG -n splunkOperatorWICluster --enable-oidc-issuer --enable-managed-identity

    The --enable-oidc-issuer parameter enables the OIDC issuer for Workload Identity. The --enable-managed-identity parameter enables managed identity for the cluster.

  3. Get credentials:

    CODE
    az aks get-credentials --resource-group splunkOperatorWorkloadIdentityRG --name splunkOperatorWICluster
  4. Install Azure AD Workload Identity in Kubernetes using helm:

    CODE
    helm repo add azure-workload-identity https://azure.github.io/azure-workload-identity/charts
    helm repo update
    kubectl create namespace workload-identity-system
    helm install azure-workload-identity azure-workload-identity/azure-workload-identity \
      --namespace workload-identity-system \
      --set azureIdentityBindingSelector="splunk-operator"
  5. Create a user-assigned managed identity:

    CODE
    az identity create --name splunkOperatorWIIdentity --resource-group splunkOperatorWorkloadIdentityRG --location westus2

    Retrieve details:

    JSON
    az identity show --name splunkOperatorWIIdentity --resource-group splunkOperatorWorkloadIdentityRG --query "{clientId: clientId, principalId: principalId, id: id}" --output json
  6. Assign the Storage Blob Data Contributor role:

    CODE
    az role assignment create --assignee <clientId> --role "Storage Blob Data Contributor" --scope /subscriptions/<subscription-id>/resourceGroups/<storageAccountResourceGroup>/providers/Microsoft.Storage/storageAccounts/<storageAccountName>
  7. Create a Kubernetes Service Account. Example YAML:

    CODE
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bucket-admin-test-wi
      namespace: your-splunk-operator-namespace
      labels:
        azure.workload.identity/client-id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

    Apply the manifest:

    CODE
    kubectl apply -f splunk-operator-wi-serviceaccount.yaml
  8. Create AzureIdentity and AzureIdentityBinding resources.

    AzureIdentity:

    CODE
    apiVersion: workloadidentity.azure.com/v1alpha1
    kind: AzureIdentity
    metadata:
      name: splunkOperatorWIIdentity
      namespace: workload-identity-system
    spec:
      type: 0
      resourceID: /subscriptions/<subscription-id>/resourceGroups/splunkOperatorWorkloadIdentityRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/splunkOperatorWIIdentity
      clientID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

    AzureIdentityBinding:

    CODE
    apiVersion: workloadidentity.azure.com/v1alpha1
    kind: AzureIdentityBinding
    metadata:
      name: splunkOperatorWIIdentityBinding
      namespace: workload-identity-system
    spec:
      azureIdentity: splunkOperatorWIIdentity
      selector: splunk-operator-wi

    Apply the manifests:

    CODE
    kubectl apply -f azureidentity-wi.yaml
    kubectl apply -f azureidentitybinding-wi.yaml
  9. Annotate the Kubernetes Service Account to use Workload Identity. Update the deployment YAML:

    CODE
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: splunk-operator
      namespace: your-splunk-operator-namespace
      labels:
        app: splunk-operator
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: splunk-operator
      template:
        metadata:
          labels:
            app: splunk-operator
          annotations:
            azure.workload.identity/use: "true"
        spec:
          serviceAccountName: bucket-admin-test-wi
          containers:
          - name: splunk-operator
            image: your-splunk-operator-image

    Apply the manifest:

    CODE
    kubectl apply -f splunk-operator-deployment-wi.yaml
  10. Verify the setup:

    • Check pod annotations:

      CODE
      kubectl get pods -n your-splunk-operator-namespace -o jsonpath='{.items[*].metadata.annotations}'
    • Test Azure Blob Storage access from the pod:

      CODE
      kubectl exec -it <splunk-operator-pod> -n your-splunk-operator-namespace -- /bin/bash
      az storage blob list --account-name mystorageaccount --container-name mycontainer --output table
    Note: Ensure that the Azure CLI is installed in the pod or use appropriate Azure SDK commands within your application code.

    Check logs:

    CODE
    kubectl logs deployment/splunk-operator -n your-splunk-operator-namespace

Set up Azure Blob access with Kubernetes secrets

Create a Kubernetes Secret object with static storage credentials.

Example:

CODE
kubectl create secret generic azureblob-secret --from-literal=azure_sa_name=mystorageaccount --from-literal=azure_sa_secret_key=wJalrXUtnFEMI/K7MDENG/EXAMPLE_AZURE_SHARED_ACCESS_KEY

Azure Blob authorization recommendations

  1. Granular access. Azure allows Managed Identity assignment at the storage account level and at specific container (bucket) levels. A managed identity assigned read permissions at the storage account level has read access for all containers within that storage account. As a good security practice, assign the managed identity only to the specific containers it needs to access, rather than the entire storage account.

  2. Avoid shared access keys. Azure allows shared access keys configurable only at the storage account level. When you use the secretRef configuration in the CRD, the underlying secret key allows both read and write access to the storage account and all containers within it. Based on your security needs, consider using Managed Identities instead of secrets. There is no automated way to rotate the secret key, so if you use these keys, rotate them regularly (for example, every 90 days).

  3. Secure service accounts. Restrict Kubernetes Service Accounts used with Workload Identity to only the necessary namespaces and roles.