<?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>DEV Community: Martin</title>
    <description>The latest articles on DEV Community by Martin (@gjoshevski).</description>
    <link>https://dev.to/gjoshevski</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%2F16317%2Fd723bd8b-1750-4fe0-8ddb-870d6c88d1c5.jpeg</url>
      <title>DEV Community: Martin</title>
      <link>https://dev.to/gjoshevski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gjoshevski"/>
    <language>en</language>
    <item>
      <title>Container-Based Applications on Azure - Simple and Kubernetesless</title>
      <dc:creator>Martin</dc:creator>
      <pubDate>Fri, 10 Jun 2022 08:09:27 +0000</pubDate>
      <link>https://dev.to/gjoshevski/container-based-applications-on-azure-simple-and-kubernetesless-2glj</link>
      <guid>https://dev.to/gjoshevski/container-based-applications-on-azure-simple-and-kubernetesless-2glj</guid>
      <description>&lt;p&gt;The justified popularity of containers due to their compactness and portability has opened many opportunities for stacking them into flexible solutions but not seldom with quite complex arrangements.&lt;/p&gt;

&lt;p&gt;The search for the best tools to run code placed into a container and then arrange and orchestrate these containers is certainly an interesting one to follow, and the exploration is far from done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o7zKQgHx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AcSXNIz2atQtVnPx7" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o7zKQgHx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AcSXNIz2atQtVnPx7" alt="img" width="612" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Containers on Azure
&lt;/h2&gt;

&lt;p&gt;Architects and builders are exposed to the dilemma of where and how to deploy their containerized applications on Azure. Azure is very flexible and offers many container options to run your workloads.&lt;br&gt;
A quick search will return you the following options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Kubernetes Service&lt;/li&gt;
&lt;li&gt;Azure App Service&lt;/li&gt;
&lt;li&gt;Azure Container Instances&lt;/li&gt;
&lt;li&gt;Azure Spring Cloud&lt;/li&gt;
&lt;li&gt;Azure Red Hat OpenShift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As the ancient manuscripts say:&lt;br&gt;
"There's no silver bullet. There is no single solution for every use case and every team."&lt;/p&gt;

&lt;p&gt;A short visit to the Azure Architecture Centre will give you a great flowchart, which can greatly simplify your decision-making process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p-KWnVZS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.microsoft.com/en-us/azure/architecture/guide/technology-choices/images/compute-choices.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p-KWnVZS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.microsoft.com/en-us/azure/architecture/guide/technology-choices/images/compute-choices.png" alt="Choose an Azure compute service - Azure Architecture Center | Microsoft Docs" width="880" height="1020"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I must admit that Kubernetes, in most cases, is my default choice for orchestrating containers, but if you are starting or migrating a project a lot of times, you might have an application that does not require all of the features Kubernetes offers. Therefore, in this blog, we will go slightly deeper into services that, as of now, allow you to run simple container-based applications, which do not require full-fledged orchestration:&lt;/p&gt;

&lt;p&gt;a) Azure Container Instances&lt;br&gt;
b) Azure App Service&lt;br&gt;
c) Azure Container Apps&lt;/p&gt;

&lt;h2&gt;
  
  
  a) Azure Container Instances
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h6PKun6K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AvmwQ4pyNKwWxN7_R.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h6PKun6K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AvmwQ4pyNKwWxN7_R.png" alt="img" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Azure Container Instances (ACI) is a serverless container offer which provides a single pod of Hyper-V isolated containers on demand. ACI offer highly versatile sizing, allowing you to select the exact amount of memory and vCPUs your application requires. Concepts like scale, load balancing, and certificates are not provided with ACI containers.&lt;/p&gt;

&lt;p&gt;For example, to scale to five container instances, you create five distinct container instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use it?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small-scale batch processing​&lt;/li&gt;
&lt;li&gt;CI/CD agents​&lt;/li&gt;
&lt;li&gt;Simple web apps&lt;/li&gt;
&lt;li&gt;Task automation​&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The good things:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A super-Fast and effortless way to run a container in the cloud, from any container registry.&lt;/li&gt;
&lt;li&gt;No need to manage Infra/VMs/OS&lt;/li&gt;
&lt;li&gt;Per-second billing based on resource requirements (CPU + Memory)​&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Considerations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No orchestration capabilities (Auto-scaling, Integrated load balancing, Rolling upgrades, Service discovery, Affinity/anti-affinity …)&lt;/li&gt;
&lt;li&gt;Azure Container Instances do not expose direct access to the underlying infrastructure that hosts container groups. This includes access to the Docker API running on the container's host and running privileged containers. If you require Docker interaction, check the REST reference documentation to see what the ACI API supports. If there is something missing, submit a request on the ACI feedback forums.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  b) Azure App Service
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z0MGFQ5R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AvCj_p-n7pV78ofWQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z0MGFQ5R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AvCj_p-n7pV78ofWQ.png" alt="img" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Azure App Service provides fully managed hosting for web applications including websites and web APIs. These web applications may be deployed using code or containers. Azure App Service is optimized for web applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use it?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running Web Applications&lt;/li&gt;
&lt;li&gt;Deploying long-running containers/services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The good things:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managed production environment - App Service automatically patches and maintains the OS and language frameworks for you. Spend time writing great apps and let Azure worry about the platform.&lt;/li&gt;
&lt;li&gt;DevOps optimization - Set up continuous integration and deployment with Azure DevOps, GitHub, BitBucket, Docker Hub, or Azure Container Registry. Promote updates through test and staging environments. Manage your apps in App Service by using Azure PowerShell or the cross-platform command-line interface (CLI).&lt;/li&gt;
&lt;li&gt;Global-scale with high availability - Scale up or out manually or automatically. Host your apps anywhere in Microsoft's global data center infrastructure, and the App Service SLA promises high availability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more please check: &lt;a href="https://docs.microsoft.com/en-us/azure/app-service/overview#why-use-app-service"&gt;Overview - Azure App Service&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Considerations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you run multiple containers into a shared App Service plan, and some of the containers have unpredictable resource-intensive usage, you might experience the Noisy Neighbor antipattern. Isolating these containers into a new Service Plan is recommended in this case.&lt;/li&gt;
&lt;li&gt;To avoid underutilization, understand your CPU, Memory, disk size and disk IOPS requirements of your application to determine the most optimal size of your App Service Plan.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  c) Azure Container Apps
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pB5ejUun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A2ARdKdz3Yj1xBj3P.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pB5ejUun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A2ARdKdz3Yj1xBj3P.png" alt="img" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Azure Container Apps (ACA)allows you to build Kubernetes-style applications and is greatly simplifying the deployment and management aspects. ACA has an opinion on how things should be done, which is not necessarily bad, since this opinion is based on Azure and Cloud Native best practices, which makes this offer quite appealing to people that want to move fast, have powerful orchestration options, but are not necessarily familiar or big fans of kubectl.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Powered by Kubernetes and open-source technologies like Dapr, KEDA, and envoy.&lt;/li&gt;
&lt;li&gt;Supports Kubernetes-style apps and microservices with features like service discovery and traffic splitting.&lt;/li&gt;
&lt;li&gt;Enables event-driven application architectures by supporting scale based on traffic and pulling from event sources like queues, including scale to zero.&lt;/li&gt;
&lt;li&gt;Support of long-running processes and can run background tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to use it?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploying API endpoints&lt;/li&gt;
&lt;li&gt;Hosting background processing applications&lt;/li&gt;
&lt;li&gt;Handling event-driven processing&lt;/li&gt;
&lt;li&gt;Running microservices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Considerations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Container Apps doesn't provide direct access to the underlying Kubernetes APIs, which means that you can't just take your existing Kubernetes YAML or Helm charts and use them.&lt;/li&gt;
&lt;li&gt;Despite being very flexible ACA is opinionated, it is integrated with services like Envoy for ingress, KEDA for scaling, Log Analytics for monitoring etc.&lt;/li&gt;
&lt;li&gt;Currently supports only Linux containers, no support for Windows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summa Summarum
&lt;/h2&gt;

&lt;p&gt;You have already greatly improved the portability and ease of deploying your applications just by dockerizing them.&lt;/p&gt;

&lt;p&gt;The decision on where and how to deploy your docker images does not have to be a binary decision. Start with your, your team's experience and the application`s resource and operational requirements. Luckily today most cloud providers offer a variety of services that make "Choosing the right tool for the right job" possible and simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/architecture/guide/technology-choices/compute-decision-tree"&gt;Choose an Azure compute service - Azure Architecture Center | Microsoft Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-gb/azure/container-instances/container-instances-tutorial-deploy-app"&gt;Tutorial - Deploy container application to container instance - Azure Container Instances | Microsoft Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/app-service/tutorial-custom-container?pivots=container-linux"&gt;Tutorial: Build and run a custom image in Azure App Service - Azure App Service | Microsoft Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-gb/azure/container-apps/get-started?tabs=bash"&gt;Quickstart: Deploy your first container app | Microsoft Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>azure</category>
      <category>docker</category>
      <category>cloud</category>
      <category>containers</category>
    </item>
    <item>
      <title>Use Azure AD workload identity to securely access Azure services or resource from your Kubernetes cluster</title>
      <dc:creator>Martin</dc:creator>
      <pubDate>Tue, 19 Apr 2022 12:24:38 +0000</pubDate>
      <link>https://dev.to/gjoshevski/use-azure-ad-workload-identity-to-securely-access-azure-services-or-resource-from-your-kubernetes-cluster-51d4</link>
      <guid>https://dev.to/gjoshevski/use-azure-ad-workload-identity-to-securely-access-azure-services-or-resource-from-your-kubernetes-cluster-51d4</guid>
      <description>&lt;p&gt;A common challenge architects and developers face when designing a Kubernetes solution is how to grant containerized workload permissions to access an Azure service or resource.&lt;/p&gt;

&lt;p&gt;To avoid the need for developers to manage credentials, recommended way is to use Managed identities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-gb/azure/active-directory/managed-identities-azure-resources/overview" rel="noopener noreferrer"&gt;Managed identities&lt;/a&gt; provide an identity for applications to use when connecting to resources that support Azure Active Directory (Azure AD) authentication. Applications may use the managed identity to obtain Azure AD tokens.&lt;/p&gt;

&lt;p&gt;Besides eliminating the need for managing credentials, Managed identities provide additional benefits like using managed identities to authenticate to any resource that supports Azure AD authentication, including your own applications.&lt;/p&gt;

&lt;p&gt;It is worth mentioning that Managed identities can be used without any additional cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure AD workload identity
&lt;/h2&gt;

&lt;p&gt;Azure AD Workload Identity for Kubernetes is an open-source project that integrates with the capabilities native to Kubernetes to federate with external identity providers.  It leverages the public preview capability of &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation" rel="noopener noreferrer"&gt;Azure AD workload identity federation&lt;/a&gt;. With this project, developers can use native Kubernetes concepts of &lt;a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/" rel="noopener noreferrer"&gt;service accounts&lt;/a&gt; and federation to access Azure AD protected resources, such as Azure and Microsoft Graph, without needing secrets.&lt;/p&gt;

&lt;p&gt;The existing &lt;a href="https://github.com/Azure/aad-pod-identity" rel="noopener noreferrer"&gt;Azure AD Pod Identity project&lt;/a&gt; addresses this need. However, the Azure AD workload identity approach is simpler to use and deploy, and overcomes several limitations in Azure AD Pod Identity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removes the scale and performance issues that existed for identity assignment.&lt;/li&gt;
&lt;li&gt;Supports Kubernetes clusters hosted in any cloud.&lt;/li&gt;
&lt;li&gt;Supports both Linux and Windows workloads.&lt;/li&gt;
&lt;li&gt;Removes the need for Custom Resource Definitions and pods that intercept IMDS (Instance Metadata Service) traffic.&lt;/li&gt;
&lt;li&gt;Avoids the complication and error-prone installation steps such as cluster role assignment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;In this model, the Kubernetes cluster becomes a token issuer, issuing tokens to Kubernetes Service Accounts. These service account tokens can be configured to be trusted on Azure AD applications. Workload can exchange a service account token projected to its volume for an Azure AD access token using the Azure Identity SDKs or the Microsoft Authentication Library (MSAL).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fhow-it-works-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fhow-it-works-diagram.png" alt="How it works"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To read more please following this &lt;a href="https://azure.github.io/azure-workload-identity/docs/introduction.html" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample overview
&lt;/h2&gt;

&lt;p&gt;This sample can be found at:&lt;br&gt;
&lt;a href="https://github.com/Azure-Samples/azure-workload-identity-nodejs-aks-terraform" rel="noopener noreferrer"&gt;Azure-Samples/azure-workload-identity-nodejs-aks-terraform (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Application
&lt;/h3&gt;

&lt;p&gt;In this sample we will deploy our Node.js application that provides information regarding the pod in which it runs and lists all of the roles it has assigned. The roles assigned give us view in the permissions this app has and which services it can connect to and use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fapp-screenshot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fapp-screenshot.png" alt="App"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Source code
&lt;/h4&gt;

&lt;p&gt;The main logic of the sample application can be found in &lt;code&gt;App/routes/index.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we examine the &lt;em&gt;getAppRoleAssignments()&lt;/em&gt; function we can see that the application uses the &lt;a href="https://www.npmjs.com/package/@azure/identity" rel="noopener noreferrer"&gt;@azure/identity&lt;/a&gt; library to perform the authorization.&lt;/p&gt;

&lt;p&gt;In order to use the &lt;em&gt;AuthorizationManagementClient&lt;/em&gt; and obtain the role assignments for our application we need to provide credentials.&lt;/p&gt;

&lt;p&gt;The credentials are obtained by simply using the constructor without any need for the developer to provide the  &lt;em&gt;client id&lt;/em&gt; or &lt;em&gt;client secret&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This credentials are exposed to the application through the workload identity hook.&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function getAppRoleAssignments() {

    const credential = new DefaultAzureCredential();
    const client = new AuthorizationManagementClient(credential, subscriptionId);

    return client.roleAssignments.listForScope(`subscriptions/${subscriptionId}`, { filter: `assignedTo('{${servicePrincipalObjectId}}')` });

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;`&lt;/p&gt;
&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;p&gt;All of the required components  to run the application and leverage the Azure Workload Identity project are part of the &lt;em&gt;main.tf&lt;/em&gt; template in the Infra folder. On the below diagram you can see the main components created by our terraform template:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Finfra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Finfra.png" alt="Infra"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Walkthrough
&lt;/h2&gt;

&lt;p&gt;This quick start demonstrate how Azure AD Workload Identity works with AKS cluster. We will use Terraform to provision all of the resources required for our Node.js application to run and connect to other Azure services.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;For this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an Azure account - &lt;a href="https://azure.microsoft.com/en-gb/free/" rel="noopener noreferrer"&gt;get one for free&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;installed &lt;a href="https://docs.microsoft.com/en-us/cli/azure/" rel="noopener noreferrer"&gt;Azure CLI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;installed &lt;a href="https://kubernetes.io/docs/tasks/tools/" rel="noopener noreferrer"&gt;kubectl&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;installed &lt;a href="https://learn.hashicorp.com/tutorials/terraform/install-cli" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  A) Validate Azure CLI and enable the EnableOIDCIssuerPreview feature
&lt;/h4&gt;

&lt;p&gt;The Azure CLI's default authentication method for logins uses a web browser and access token to sign in. To login with other methods follow the &lt;a href="https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the login command.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;az login&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the below command and verify that the correct subscription is being used. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;az account show&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To switch to a different subscription, use &lt;a href="https://docs.microsoft.com/en-us/cli/azure/account?view=azure-cli-latest#az-account-set" rel="noopener noreferrer"&gt;az account set&lt;/a&gt; with the subscription ID or name you want to switch to.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To use the OIDC Issuer feature, you must enable the EnableOIDCIssuerPreview feature flag on your subscription.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;az feature register --name EnableOIDCIssuerPreview --namespace Microsoft.ContainerService&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  B) Initialize Terraform
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;In your terminal, clone the following repository, if you haven't already.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
git clone https://github.com/gjoshevski/tf-workload-identity&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the &lt;em&gt;Infra&lt;/em&gt; directory. And initialize your Terraform workspace, which will download the providers and initialize them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;terraform init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make sure the init was successful and you get output similar to the one below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;azureuser@TF-Test:~/tf-workload-identity/Infra$ terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/random from the dependency lock file
- Reusing previous version of hashicorp/kubernetes from the dependency lock file
- Reusing previous version of hashicorp/helm from the dependency lock file
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Reusing previous version of hashicorp/azuread from the dependency lock file
- Installing hashicorp/azuread v2.20.0...
- Installed hashicorp/azuread v2.20.0 (signed by HashiCorp)
- Installing hashicorp/random v3.1.2...
- Installed hashicorp/random v3.1.2 (signed by HashiCorp)
- Installing hashicorp/kubernetes v2.10.0...
- Installed hashicorp/kubernetes v2.10.0 (signed by HashiCorp)
- Installing hashicorp/helm v2.5.1...
- Installed hashicorp/helm v2.5.1 (signed by HashiCorp)
- Installing hashicorp/azurerm v3.1.0...
- Installed hashicorp/azurerm v3.1.0 (signed by HashiCorp)

Terraform has made some changes to the provider dependency selections recorded
in the .terraform.lock.hcl file. Review those changes and commit them to your
version control system if they represent changes you intended to make.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
azureuser@TF-Test:~/tf-workload-identity/Infra$

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  C) Provision the resources
&lt;/h4&gt;

&lt;p&gt;In your initialized directory, run &lt;code&gt;terraform apply&lt;/code&gt; and review the planned actions. Your terminal output should indicate the plan is running and what resources will be created.&lt;/p&gt;

&lt;h4&gt;
  
  
  D) Validate the deployment
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;In the outputs in your cli you will see the assigned name tou your cluster. Like for example
&lt;code&gt;
kubernetes_cluster_name = "still-shiner-aks"
&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The name is auto generated using the random provider for terraform.&lt;/p&gt;

&lt;p&gt;Navigate to your Azure Portal where you should see the new AKS cluster created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Faks-cluster.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Faks-cluster.png" alt="aks-cluster.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the name of the cluster and then under &lt;em&gt;Kubernetes resources&lt;/em&gt; click on &lt;em&gt;Services and ingresses&lt;/em&gt;. Here you will see the &lt;em&gt;External IP&lt;/em&gt;, which you can use to access the web app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Faks-external-ip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Faks-external-ip.png" alt="aks-external-ip.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the External IP in your browser. You will see the web app that will display stats about your pod and in the &lt;em&gt;App Role Assignments&lt;/em&gt; you will see a list of all of the roles that this pod can use to call Azure services. At this point you will see that there is only one role in the list. This is a custom role created by our terraform deployment and gives permissions to the application to list all of the assigned roles. &lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;To see the definition of this role go to the &lt;em&gt;Infra/main.tf&lt;/em&gt; and check line 222:&lt;br&gt;
  &lt;code&gt;resource "azurerm_role_definition" "azurerm_custom_role"&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fapp-ok.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fapp-ok.png" alt="app-ok.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let's navigate back to the Azure portal and grant additional access to this application. 
In this example we will grant the application Read access so it can view all the resources of the AKS cluster. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Navigate to the AKS cluster and open the &lt;em&gt;Access control (IAM)&lt;/em&gt; page.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Faks-access-control.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Faks-access-control.png" alt="aks-access-control.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;em&gt;Add &amp;gt; Add role assignment&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;On the Roles tab, select a role &lt;em&gt;Reader&lt;/em&gt; and click &lt;em&gt;Next&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;On the Members tab, select User, group, or service principal to assign the selected role&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;+Select members&lt;/em&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fmembers.png" alt="members.png"&gt;
&lt;/li&gt;
&lt;li&gt;In the list find the service principal, that will have the same pet name as you AKS cluster, but it will end with the &lt;em&gt;-app&lt;/em&gt; suffix.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/.%2Fselect-members.png" alt="select-members.png"&gt;
&lt;/li&gt;
&lt;li&gt;After selecting it, click on &lt;em&gt;Review + assign&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;After the Role assignment is created navigate back to the web application.
Now you will see the new role that we assigned in the list. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fselect-members.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fselect-members.png" alt="role-assignemnts-after.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pod description&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you check the kubernetes_deployment that we use you will notice that we set only 2 env vars, &lt;em&gt;AZURE_SUBSCRIPTION_ID&lt;/em&gt; and &lt;em&gt;AZURE_SERVICE_PRINCIPAL_OBJECT_ID&lt;/em&gt; which are requred to call the API that returns the roles assigned to a specific principal. &lt;/p&gt;

&lt;p&gt;But we do not provide any keys which we can use to authenticate.&lt;/p&gt;

&lt;p&gt;Navigate to the &lt;em&gt;Workloads&lt;/em&gt; page. &lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fworkloads.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fworkloads.png" alt="workloads.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Expand the &lt;em&gt;app-example&lt;/em&gt; workload and then expand one of the pods from the list below.&lt;/p&gt;

&lt;p&gt;Then examine the YAML definition of this pod.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fpod-yaml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fgjoshevski%2Ftf-workload-identity%2Fraw%2Fmaster%2Fmedia%2Fpod-yaml.png" alt="pod-yaml.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the container specs, you will notice that there are 3 env vars exposed &lt;em&gt;AZURE_TENANT_ID, AZURE_FEDERATED_TOKEN_FILE, AZURE_AUTHORITY_HOST&lt;/em&gt;, by the Azure AD Workload Identity for Kubernetes.&lt;/p&gt;

&lt;p&gt;If this env vars are not present your application will not be able to authenticate!&lt;/p&gt;

&lt;p&gt;In the case when the env vars are not present, follow the next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;verify that &lt;em&gt;azure-workload-identity&lt;/em&gt; helm chart was successfully created&lt;/li&gt;
&lt;li&gt;the &lt;em&gt;azure-wi-webhook-controller-manager&lt;/em&gt; pods are running without any errors&lt;/li&gt;
&lt;li&gt;redeploy the &lt;em&gt;app-example&lt;/em&gt; deployment and verify if the new pods got populated with the env vars&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Clean up your workspace
&lt;/h3&gt;

&lt;p&gt;Congratulations, you have provisioned an AKS cluster, deployed the application and managed to get access to Azure services using the Azure AD workload identity. &lt;/p&gt;

&lt;p&gt;To clean the resources please run: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;terraform destroy&lt;/code&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>aks</category>
      <category>terraform</category>
      <category>node</category>
    </item>
  </channel>
</rss>
