<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Marcin Jan Puhacz</title>
    <description>The latest articles on Forem by Marcin Jan Puhacz (@mpuhacz).</description>
    <link>https://forem.com/mpuhacz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F352887%2Fe8765ad3-4489-46d6-83d5-7e13c47694a7.jpg</url>
      <title>Forem: Marcin Jan Puhacz</title>
      <link>https://forem.com/mpuhacz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mpuhacz"/>
    <language>en</language>
    <item>
      <title>The right way of accessing Azure services from inside your Azure Kubernetes Cluster</title>
      <dc:creator>Marcin Jan Puhacz</dc:creator>
      <pubDate>Fri, 20 Mar 2020 19:41:32 +0000</pubDate>
      <link>https://forem.com/mpuhacz/the-right-way-of-accessing-azure-services-from-inside-your-azure-kubernetes-cluster-4p8d</link>
      <guid>https://forem.com/mpuhacz/the-right-way-of-accessing-azure-services-from-inside-your-azure-kubernetes-cluster-4p8d</guid>
      <description>&lt;p&gt;Often applications running on Azure need to access other Azure resources, like storage accounts, CosmosDB or, KeyVault instances. When it seems like an easy task using &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview"&gt;managed identities&lt;/a&gt;, it gets a little bit more complicated in the context of the AKS cluster. Nodes are shared across different pods, and we need to keep fine-grained access policies at the pod level rather than the node level.&lt;/p&gt;

&lt;p&gt;If you are coming from AWS space, you might be aware of projects like &lt;a href="https://github.com/zalando-incubator/kube-aws-iam-controller"&gt;Zalando's IAM controller for K8S&lt;/a&gt; or &lt;a href="https://github.com/uswitch/kiam"&gt;kiam&lt;/a&gt;. Azure has &lt;a href="https://github.com/Azure/aad-pod-identity/"&gt;AAD Pod Identity&lt;/a&gt; which, you can consider equivalent to the projects mentioned above.&lt;/p&gt;

&lt;p&gt;In this article, I walk you through the process of setting up  Azure Access Directory Pod Identities inside your cluster. The article is split into four parts&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The problem we want to solve&lt;/li&gt;
&lt;li&gt;Concepts behind AAD Pod Identity&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Deployment steps&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Let's say a pod with an application X needs to have read access to data inside a blob storage container. There are several ways of achieving this, examples are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;EnvironmentCredential&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Will read environment variables and then authenticate as a service principal or a user.&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.identity&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;EnvironmentCredential&lt;/span&gt;

    &lt;span class="n"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EnvironmentCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BlobServiceClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Storage Account Keys&lt;/p&gt;

&lt;p&gt;Think about it as a root password to your storage account. You probably don't want to risk using it in any of your applications. (I won't even show you a code example :))&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SAS Token (Shared Access Signature)&lt;/p&gt;

&lt;p&gt;A string that you can provide to your application to grant granular temporary access to storage resources: e.g., container, single blob.&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.storage.blob&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BlockBlobService&lt;/span&gt;

    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"?sv=2019-02-02&amp;amp;ss=b&amp;amp;srt=co&amp;amp;sp=r&amp;amp;se=2020-03-19T00:50:10Z&amp;amp;st=2020-03-18T16:50:10Z&amp;amp;spr=https&amp;amp;sig=XXX%3D"&lt;/span&gt;

    &lt;span class="n"&gt;blob_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BlockBlobService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;account_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"storagaccountname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sas_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Each of these options requires us to have a certain value like the token above, or environmental variables set on the target machine. Those values could be defined inside the container image, injected as a K8S secret, or maybe set as env variable in the deployment YAML. For a token, we need to make sure we rotate it regularly; env variables need to be delivered to target pod. &lt;/p&gt;

&lt;p&gt;Ideally, we would like to get rid of this requirement and use something that streamlines the whole process. We want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;make sure our application access only necessary resources&lt;/li&gt;
&lt;li&gt;apply none or minimal code changes to our application&lt;/li&gt;
&lt;li&gt;get an access token automatically, rather than using fixed credentials&lt;/li&gt;
&lt;li&gt;the token should have its life span and be valid only for our application&lt;/li&gt;
&lt;li&gt;the token should be rotated automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does it work
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Managed identities
&lt;/h4&gt;

&lt;p&gt;Managed identity allows authenticating to any service that supports Azure AD authentication without attaching credentials to your application. Once the identity is created, you need to attach a role that defines what the identity can do with a particular resource.&lt;/p&gt;

&lt;p&gt;Let's have a look at the sample code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.identity&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ManagedIdentityCredential&lt;/span&gt;

&lt;span class="n"&gt;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ManagedIdentityCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BlobServiceClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It looks almost like the &lt;code&gt;EnvironmentCredential&lt;/code&gt; example above, but there is one subtle difference. &lt;code&gt;ManagedIdentityCredential&lt;/code&gt; creates an access token in real-time without any additional data attached to your app as opposed to &lt;code&gt;EnvironmentCredential&lt;/code&gt; that requires you to set env variables with secrets.&lt;/p&gt;

&lt;h4&gt;
  
  
  AAD Pod Identity
&lt;/h4&gt;

&lt;p&gt;When you deploy AAD Pod Identity to your cluster, you get two components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Managed Identity Controller (MIC)&lt;/p&gt;

&lt;p&gt;A pod that watches for changes and when detects a relevant one (e.g., pod or identity bindings modified) attaches or removes assigned identities.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Node Managed Identity (NMI)&lt;/p&gt;

&lt;p&gt;A Daemon set which hijacks each call of &lt;code&gt;ManagedIdentityCredential&lt;/code&gt; to node metadata.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Under the hood
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fzZ80v7j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/umh8e1r9bvurnglbnhlb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fzZ80v7j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/umh8e1r9bvurnglbnhlb.png" alt="AAD Pod Identity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Inside your pod, the &lt;code&gt;ManagedIdentityCredential&lt;/code&gt; instance sends a request to Azure Instance Metadata Service (IMDS)&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://169.254.169.254/metadata/identity/oauth2/token
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The request gets intercepted by the NMI. The NMI then checks which identity is assigned to the source pod by querying the MIC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The MIC checks for Azure identity mappings in your AKS cluster. If such exists, it returns it to the NMI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The NMI server requests an access token from AD based on the pod's identity mapping returned in the step above&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AD passes the token to the NMI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The NMI transfers the token to the app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The app queries Azure service using the token&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;Before we deploy anything, it is vital to understand the potential security risks behind it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reusing selector binding
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rNaH3uvA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jkbxfjh89943d9k4einj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rNaH3uvA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jkbxfjh89943d9k4einj.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
MIC identifies pods by &lt;code&gt;aadpodidbinding&lt;/code&gt; label. If any other pod in the cluster reuses &lt;code&gt;aadpodidbinding&lt;/code&gt; it also accesses to the associated identity binding. For a cluster with a single project, it's unlikely to happen, but still, you need to be cautious, especially if the cluster is logically shared across teams/projects.&lt;/p&gt;

&lt;p&gt;By default, AAD Pod Identity maps pods with identities across namespaces. If the cluster is shared, it is crucial to deploy AAD Pod Identities, &lt;a href="https://github.com/Azure/aad-pod-identity/blob/master/docs/readmes/README.namespaced.md"&gt;forcing namespace matching&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  NMI intercepts all connections to the instance metadata endpoint
&lt;/h4&gt;

&lt;p&gt;By default, the NMI component captures all requests to IMDS inside your cluster. That might not be sufficient for some of the use cases. The easiest way to is to create &lt;code&gt;AzurePodIdentityException&lt;/code&gt; resource in the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aadpodidentity.k8s.io/v1"&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AzurePodIdentityException&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aad-identity-exception&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;PodLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;noaad&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then, for every app we don't want to use AAD Pod Identity, we simply specify &lt;code&gt;spec.template.metadata.labels&lt;/code&gt; to &lt;code&gt;noaad: true&lt;/code&gt;. Of course, you can use your custom label.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing AAD Pod Identity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Deploy aad-pod-identity to your cluster
&lt;/h3&gt;

&lt;p&gt;Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that the deployment will go to the &lt;code&gt;default&lt;/code&gt; namespace.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create a new managed identity and assign a role to it
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;az identity create &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;your_resource_group&amp;gt;"&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;your_managed_identity_name&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The command should return the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"clientId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"00000000-0000-0000-0000-000000000000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"clientSecretUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://control-westeurope.identity.azure.net/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/&amp;lt;your_resource_group&amp;gt;/providers/Microsoft.ManagedIdentity/userAssignedIdentities/&amp;lt;your_managed_identity_name&amp;gt;/credentials?tid=00000000-0000-0000-0000-000000000000&amp;amp;oid=00000000-0000-0000-0000-000000000000&amp;amp;aid=00000000-0000-0000-0000-000000000000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/myresourcegroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/&amp;lt;your_managed_identity_name&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"westeurope"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your_managed_identity_name&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"principalId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"00000000-0000-0000-0000-000000000000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resourceGroup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your_resource_group&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tenantId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"00000000-0000-0000-0000-000000000000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Microsoft.ManagedIdentity/userAssignedIdentities"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now it's time to assign a role. Here I'm using &lt;code&gt;Storage Blob Data Reader&lt;/code&gt;. This will enable reading data from a blob storage account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;az role assignment create &lt;span class="nt"&gt;--role&lt;/span&gt; &lt;span class="s2"&gt;"Storage Blob Data Reader"&lt;/span&gt; &lt;span class="nt"&gt;--assignee&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;the managed identity id returned previously&amp;gt;"&lt;/span&gt; &lt;span class="nt"&gt;--scope&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;your resource id&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Hint 1&lt;/em&gt;: You can find more roles &lt;a href="https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles"&gt;here&lt;/a&gt;. If you are looking for something more specific you might &lt;a href="https://docs.microsoft.com/en-us/azure/role-based-access-control/custom-roles"&gt;want to create a custom role&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hint 2&lt;/em&gt;: If you don't know your resource id you can fetch it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;az resource list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Create an Azure identity in you cluster
&lt;/h3&gt;

&lt;p&gt;Create a file &lt;code&gt;aadpodidentity.yaml&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aadpodidentity.k8s.io/v1"&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AzureIdentity&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your_managed_identity_name&amp;gt;&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="na"&gt;ResourceID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;the managed identity id returned previously&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;ClientID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;the managed identity clientId returned previously&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Apply it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f aadpodidentity.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Bind the Azure Identity to your pod selector
&lt;/h3&gt;

&lt;p&gt;Create another manifest file named &lt;code&gt;aadpodidentitybinding.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aadpodidentity.k8s.io/v1"&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AzureIdentityBinding&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp-azure-identity-binding&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;AzureIdentity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your_managed_identity_name from the previous step&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;Selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your_app_selector_name&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Deploy it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; aadpodidentitybinding.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now the MIC knows that, whenever a pod with a particular selector appears in the cluster, it needs to bind the previously created identity to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Managed Identity Controller (MIC) permissions
&lt;/h3&gt;

&lt;p&gt;The MIC needs to read information about the managed identity we just created. Since it is using AKS service principal to query Azure resources we need to assign a specific role to our AKS service principal.&lt;/p&gt;

&lt;p&gt;First of all, you need to find the service principal id:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;az aks show &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;aks_resource_group&amp;gt;"&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;aks_cluster_name&amp;gt;"&lt;/span&gt; &lt;span class="nt"&gt;--query&lt;/span&gt; servicePrincipalProfile.clientId &lt;span class="nt"&gt;-o&lt;/span&gt; tsv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now simply assign the &lt;code&gt;Managed Identity Operator&lt;/code&gt; role to the AKS service principal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;az role assignment create &lt;span class="nt"&gt;--role&lt;/span&gt; &lt;span class="s2"&gt;"Managed Identity Operator"&lt;/span&gt; &lt;span class="nt"&gt;--assignee&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;result of the previous command&amp;gt;"&lt;/span&gt; &lt;span class="nt"&gt;--scope&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;the “id” field of az identity create command executed previously&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Update your deployment manifest
&lt;/h3&gt;

&lt;p&gt;The last step is to update your deployment manifest. In the &lt;code&gt;spec.template.metadata.labels&lt;/code&gt; add a new label called &lt;code&gt;aadpodidbinding&lt;/code&gt; with the selector name you've chosen in step 4.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;aadpodidbinding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your_selector_name&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Congratulations, you are ready to use your managed identities with apps running inside your AKS cluster. &lt;/p&gt;

&lt;p&gt;I hope you find this useful. Let me know if you have any questions or like to hear about some other topics.&lt;/p&gt;




&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@doctortinieblas"&gt;Benjamin Massello&lt;/a&gt; on &lt;a href="https://unsplash.com/"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>kubernetes</category>
      <category>security</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
