Jeevan Kumar -- Cloud Center of Excellence
Imagine you’re running a highly secure, private Kubernetes environment in Azure. Everything is well-architected, adhering to the best security practices, until your deployments from Azure DevOps start failing. Your namespaces aren’t loading, containers aren't pulling, and debugging feels like navigating a maze. This is the reality for many teams working with private Azure Kubernetes Service (AKS) clusters and Azure Container Registry (ACR) instances with restricted network access.
Deploying workloads to such restricted environments presents challenges, including authentication issues, service connection limitations, and network access constraints. However, with the right strategy, we can establish a secure, efficient deployment pipeline. In this blog, we’ll explore these challenges, break down the limitations of traditional service connections, and discuss a robust solution using Azure Resource Manager (ARM)-based authentication with the right IAM roles.
How Azure DevOps connects to Kubernetes
Azure DevOps supports three primary methods for creating service connections to deploy Kubernetes manifests:
Kubeconfig-based connection |
Service account-based connection |
Azure subscription-based connection |
Uses kubeconfig files with authentication details |
Uses a Kubernetes Service Account and associated credentials |
Leverages Azure credentials to connect using an Azure service principal |
For public AKS clusters, all three methods work seamlessly. However, the moment you introduce private networking, the landscape changes dramatically.
Authentication failures with Kubernetes 1.24+
Starting with Kubernetes 1.24, long-lived tokens are no longer created by default. Kubernetes recommends avoiding long-lived tokens altogether, which impacts authentication when using:
Kubeconfig-based connections |
Azure Subscription-based connections |
Relies on static tokens |
Lacks the necessary short-lived token support |
When these service connections fail, the ‘Loading namespaces’ dialog in Azure DevOps hangs indefinitely, preventing deployments.
Service account authentication issues
Service account-based connections also encounter authentication problems due to:
Role-Based Access Control (RBAC) restrictions in private clusters |
Missing Kubernetes secrets needed for authentication |
Inability to retrieve namespaces dynamically in Azure DevOps |
These limitations make service accounts unreliable for private AKS clusters.
Network restrictions impacting ACR access
In a private ACR setup, organizations often disable public network access to enhance security. However, this introduces challenges such as:
Azure DevOps services losing access to ACR |
Azure Security Center and other trusted services requiring exceptions |
Private endpoints preventing DevOps agent access |
Repository and tag listing restrictions |
Pipelines can no longer push/pull images. |
Security tools lose visibility unless network rules are explicitly modified. |
Managed Azure DevOps agents cannot access ACR over private endpoints. |
When public network access is disabled, you cannot view repositories via Azure CLI or Portal outside the virtual network. |
To overcome these roadblocks, we need an alternative authentication and networking strategy.
To maintain security without sacrificing functionality, we can leverage ARM-based authentication with dedicated IAM roles. This approach aligns with Kubernetes' best practices and avoids long-lived tokens while ensuring seamless connectivity.
Step 1: Create an ARM-based service connection in Azure DevOps
Instead of using static tokens or service accounts, create an ARM-based service connection in Azure DevOps. This method generates short-lived tokens dynamically, enhancing security and compliance with Kubernetes authentication guidelines.
|Assign the following IAM roles to the service principal used in the service connection:
Azure Kubernetes Service Cluster Admin Role |
Azure Kubernetes Service Cluster User Role |
Azure Kubernetes Service RBAC Cluster Admin Role |
Provides full control over the cluster |
Allows interaction with the cluster but with fewer privileges |
Ensures compatibility with Kubernetes RBAC settings |
Step 2: Enable Kubernetes local accounts for entra ID authentication
If your AKS cluster uses Microsoft Entra ID authentication, ensure the “Kubernetes local accounts” checkbox is enabled. This setting allows the creation of temporary credentials when needed, improving authentication flexibility.
Step 3: Use a self-hosted agent for private ACR access
Since Azure DevOps managed agents cannot access private endpoints, use a self-hosted agent deployed within your virtual network. This agent should have network line-of-sight to:
The private AKS cluster |
The private ACR instance |
By deploying a self-hosted agent, you ensure that deployments can push and pull container images without requiring public network access.
Step 4: Whitelist Azure DevOps public IP in ACR (If necessary)
If public network access is disabled on ACR, explicitly whitelist the Azure DevOps public IP to allow pipeline tasks to interact with the registry.
This can be configured via:
az acr network-rule add --name <ACR_NAME> --ip-address <DEVOPS_PUBLIC_IP> |
Step 5: Leverage short-lived tokens for Kubernetes authentication
One of the biggest advantages of ARM-based service connections is their ability to generate short-lived tokens dynamically. Each task execution in Azure DevOps receives a new token instead of relying on static credentials, ensuring:
Compliance with Kubernetes’ security best practices |
Reduced risk of credential leaks |
Automatic authentication renewal for every deployment |
Additional considerations for advanced scenarios
AKS Private Link Integration
For even greater security, integrate AKS with Azure Private Link to eliminate exposure over the public internet. This requires careful planning of:
Private DNS configurations |
Network peering strategies |
Firewall and NSG rules |
Automating IAM role assignment
To simplify role assignments for new service connections, consider automating the process using Azure CLI or Terraform. For example:
az role assignment create --assignee <SERVICE_PRINCIPAL_ID> --role "Azure Kubernetes Service Cluster Admin Role" --scope <RESOURCE_ID> |
Monitoring and troubleshooting
Monitor Kubernetes authentication and network connectivity using:
Azure monitor and log analytics for container insights |
kubectl logs and kubectl describe pod commands for debugging deployments |
Azure DevOps pipeline logs to capture service connection errors |
Building secure and efficient CI/CD pipelines
Deploying workloads to private AKS clusters and ACR instances presents unique challenges, but by leveraging ARM-based service connections, self-hosted agents, and proper IAM role assignments, we can achieve a secure, scalable, and efficient CI/CD pipeline.
TP is a Microsoft Azure Solutions Partner for Data & AI, highlighting our expertise in creating tailored analytics and AI solutions. We help businesses tackle challenges, boost efficiency, and gain valuable insights.
Visit our technology services page to learn more.