<?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: Akash Roy</title>
    <description>The latest articles on Forem by Akash Roy (@akash_roy_3bc76e473db5e40).</description>
    <link>https://forem.com/akash_roy_3bc76e473db5e40</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%2F2845820%2F0cf7a272-2a30-4639-b66e-72c1391c3eb3.jpg</url>
      <title>Forem: Akash Roy</title>
      <link>https://forem.com/akash_roy_3bc76e473db5e40</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/akash_roy_3bc76e473db5e40"/>
    <language>en</language>
    <item>
      <title>Deploy to Azure Kubernetes Service (AKS) using Azure Pipelines</title>
      <dc:creator>Akash Roy</dc:creator>
      <pubDate>Wed, 08 Oct 2025 08:55:32 +0000</pubDate>
      <link>https://forem.com/akash_roy_3bc76e473db5e40/deploy-to-azure-kubernetes-service-aks-using-azure-pipelines-3127</link>
      <guid>https://forem.com/akash_roy_3bc76e473db5e40/deploy-to-azure-kubernetes-service-aks-using-azure-pipelines-3127</guid>
      <description>&lt;p&gt;If you’ve already built your first Azure Pipeline, this next step will show you how to take your code all the way to production — deploying automatically to an Azure Kubernetes Service (AKS) cluster.&lt;/p&gt;

&lt;p&gt;This post is a simple walkthrough for anyone who wants to see their containerized app running on Azure, without deep Kubernetes expertise.&lt;/p&gt;




&lt;h2&gt;
  
  
  What We’ll Do
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Containerize a sample app
&lt;/li&gt;
&lt;li&gt;Push the image to Azure Container Registry (ACR)
&lt;/li&gt;
&lt;li&gt;Create a YAML-based pipeline to deploy it on AKS
&lt;/li&gt;
&lt;li&gt;Validate the deployment
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1: Prepare Your App and ACR
&lt;/h2&gt;

&lt;p&gt;Let’s assume you have a simple Node.js or Python app.&lt;br&gt;&lt;br&gt;
Create a &lt;code&gt;Dockerfile&lt;/code&gt; in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:18&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, build and push this image to Azure Container Registry (ACR):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az acr build &lt;span class="nt"&gt;--registry&lt;/span&gt; &amp;lt;your-acr-name&amp;gt; &lt;span class="nt"&gt;--image&lt;/span&gt; sampleapp:v1 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Connect Azure DevOps with ACR and AKS
&lt;/h2&gt;

&lt;p&gt;In your Azure DevOps project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;Project Settings → Service Connections&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create two connections:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Azure Resource Manager&lt;/strong&gt; (for AKS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker Registry&lt;/strong&gt; (for ACR)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;These connections will authenticate your pipeline securely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Create a Deployment YAML
&lt;/h2&gt;

&lt;p&gt;Add &lt;code&gt;deployment.yaml&lt;/code&gt; in your repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;sampleapp&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;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sampleapp&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;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sampleapp&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;containers&lt;/span&gt;&lt;span class="pi"&gt;:&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;sampleapp&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your-acr-name&amp;gt;.azurecr.io/sampleapp:v1&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Build the Azure Pipeline
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;.azure-pipelines/aks-deploy.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;vmImage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;imageName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sampleapp&lt;/span&gt;
  &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(Build.BuildId)'&lt;/span&gt;

&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
  &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;BuildImage&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Docker@2&lt;/span&gt;
      &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;containerRegistry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;acr-connection'&lt;/span&gt;
        &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(imageName)'&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;buildAndPush'&lt;/span&gt;
        &lt;span class="na"&gt;Dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/Dockerfile'&lt;/span&gt;
        &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;$(tag)&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
  &lt;span class="na"&gt;dependsOn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
  &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DeployToAKS&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;KubernetesManifest@1&lt;/span&gt;
      &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
        &lt;span class="na"&gt;kubernetesServiceConnection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;aks-connection'&lt;/span&gt;
        &lt;span class="na"&gt;manifests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/deployment.yaml'&lt;/span&gt;
        &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;$(imageName)=$(imageName):$(tag)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit and push this YAML file to your main branch.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Run and Verify
&lt;/h2&gt;

&lt;p&gt;Once the pipeline completes, verify the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
kubectl get svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll see your app live on AKS — deployed automatically through Azure DevOps!&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;You’ve just connected CI/CD to a live Kubernetes cluster. From here, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add health checks or rolling updates
&lt;/li&gt;
&lt;li&gt;Integrate Helm for versioned deployments
&lt;/li&gt;
&lt;li&gt;Set up Blue-Green or Canary strategies
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This forms the core of a modern cloud deployment pipeline — repeatable, automated, and secure.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Next up:&lt;/strong&gt; I’ll write about securing pipelines using Azure Key Vault for secret management — stay tuned.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>devops</category>
      <category>cicd</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Build Your First Azure Pipeline (YAML-based CI/CD)</title>
      <dc:creator>Akash Roy</dc:creator>
      <pubDate>Sat, 17 May 2025 14:13:11 +0000</pubDate>
      <link>https://forem.com/akash_roy_3bc76e473db5e40/build-your-first-azure-pipeline-yaml-based-cicd-39fg</link>
      <guid>https://forem.com/akash_roy_3bc76e473db5e40/build-your-first-azure-pipeline-yaml-based-cicd-39fg</guid>
      <description>&lt;p&gt;Now that you’ve seen how Azure DevOps works and what role pipelines play in the DevOps lifecycle, it’s time to get hands-on. In this blog, we’ll walk through creating a complete CI/CD pipeline using &lt;strong&gt;YAML in Azure Pipelines&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a new Azure DevOps project&lt;/li&gt;
&lt;li&gt;Connecting your Git repo&lt;/li&gt;
&lt;li&gt;Writing your first YAML pipeline&lt;/li&gt;
&lt;li&gt;Running and debugging your build&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s go step-by-step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a New Project in Azure DevOps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://dev.azure.com/" rel="noopener noreferrer"&gt;https://dev.azure.com/&lt;/a&gt; and sign in.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;New Project&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter project name (e.g., &lt;code&gt;my-first-pipeline&lt;/code&gt;), select &lt;strong&gt;Private&lt;/strong&gt;, and click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 2: Push Code to Azure Repos (or Connect GitHub)
&lt;/h2&gt;

&lt;p&gt;You can either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push your local project to the Azure Repo created automatically, &lt;strong&gt;OR&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Connect an external GitHub repo (from Pipelines &amp;gt; New Pipeline &amp;gt; GitHub)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure your repo has a basic project setup — for example, a Node.js or Python app with tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Create Your First Pipeline
&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    Go to &lt;strong&gt;Pipelines &amp;gt; New Pipeline&lt;/strong&gt;.
    &lt;p&gt;
      &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9mbt6qvck7e290rkd9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9mbt6qvck7e290rkd9g.png" alt="New Pipeline button" width="350" height="673"&gt;&lt;/a&gt;
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Choose your source (Azure Repos Git or GitHub).
    &lt;p&gt;
      &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9eww3pyjthtwwb46wqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9eww3pyjthtwwb46wqa.png" alt="Select source" width="673" height="474"&gt;&lt;/a&gt;
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Select your repository.
    &lt;p&gt;
      &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnlbibs5qt1ht5mpf8yjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnlbibs5qt1ht5mpf8yjb.png" alt="Choose repository" width="800" height="347"&gt;&lt;/a&gt;
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Azure will try to auto-detect a starter pipeline. You can use it or paste your own.
    &lt;p&gt;
      &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8i6smfbsy3ojwdyfhvl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8i6smfbsy3ojwdyfhvl.png" alt="Starter pipeline suggestion" width="735" height="362"&gt;&lt;/a&gt;
    &lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 4: Write the YAML for CI
&lt;/h2&gt;

&lt;p&gt;Here’s a basic CI pipeline for a Node.js project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;vmImage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ubuntu-latest'&lt;/span&gt;

&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodeTool@0&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;versionSpec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;18.x'&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Install&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Node.js'&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="s"&gt;npm test&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Install&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;dependencies&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests'&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Build&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;application'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;vmImage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ubuntu-latest'&lt;/span&gt;

&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UsePythonVersion@0&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;versionSpec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.x'&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;pip install -r requirements.txt&lt;/span&gt;
      &lt;span class="s"&gt;pytest&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Install&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;deps&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Run the Pipeline
&lt;/h2&gt;

&lt;p&gt;Once committed, the pipeline will automatically run.&lt;/p&gt;

&lt;p&gt;You’ll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each step’s status (success/failure)&lt;/li&gt;
&lt;li&gt;Logs for every command&lt;/li&gt;
&lt;li&gt;Artifacts (if any) saved from the build&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 6: Debug Failures
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use the logs tab to inspect each task output&lt;/li&gt;
&lt;li&gt;Common issues: missing dependencies, wrong version, permission errors&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 7: Add Deployment to Azure and Set Up an Azure Service Connection (Optional)
&lt;/h2&gt;

&lt;p&gt;Before your pipeline can deploy to Azure resources, it needs a secure way to authenticate. Azure DevOps handles this using &lt;strong&gt;Service Connections&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To create one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your Azure DevOps project&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Project Settings &amp;gt; Service connections&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;New service connection&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Azure Resource Manager&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Service principal (automatic)&lt;/strong&gt; (recommended)&lt;/li&gt;
&lt;li&gt;Choose your subscription and authorize access&lt;/li&gt;
&lt;li&gt;Give it a recognizable name (e.g., &lt;code&gt;MyServiceConnection&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This connection will be referenced in your pipeline YAML to authorize deployments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AzureWebApp@1&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;azureSubscription&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;MyServiceConnection'&lt;/span&gt;
      &lt;span class="na"&gt;appName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-web-app'&lt;/span&gt;
      &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(System.DefaultWorkingDirectory)/**/*.zip'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use separate pipelines for CI (build/test) and CD (deploy)&lt;/li&gt;
&lt;li&gt;Store your pipeline YAML in the root of your repo (&lt;code&gt;azure-pipelines.yml&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Protect your main branch with build validation policies&lt;/li&gt;
&lt;li&gt;Use variable groups and secrets via Azure Key Vault&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;In the next blog, we’ll look at using &lt;strong&gt;Terraform with Azure DevOps&lt;/strong&gt; to provision infrastructure as code. We’ll start by writing a basic Terraform script to deploy a resource group, and run it from a pipeline.&lt;/p&gt;

&lt;p&gt;From pipelines to infrastructure — this is where DevOps gets powerful.&lt;/p&gt;

</description>
      <category>azuredevops</category>
      <category>cicd</category>
      <category>devops</category>
    </item>
    <item>
      <title>Inside Azure DevOps: Boards, Repos, Pipelines, and Artifacts</title>
      <dc:creator>Akash Roy</dc:creator>
      <pubDate>Thu, 08 May 2025 04:51:32 +0000</pubDate>
      <link>https://forem.com/akash_roy_3bc76e473db5e40/inside-azure-devops-boards-repos-pipelines-and-artifacts-2l9</link>
      <guid>https://forem.com/akash_roy_3bc76e473db5e40/inside-azure-devops-boards-repos-pipelines-and-artifacts-2l9</guid>
      <description>&lt;p&gt;Azure DevOps is one of the most complete DevOps platforms out there — and it's heavily adopted across enterprises. But if you're new to it, all the moving parts can be a little confusing.&lt;/p&gt;

&lt;p&gt;In this post, we’ll break down the four major services you’ll be working with most: &lt;strong&gt;Boards, Repos, Pipelines, and Artifacts&lt;/strong&gt; — and explain how they fit together in a real DevOps lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Azure DevOps?
&lt;/h2&gt;

&lt;p&gt;Azure DevOps is a suite of services from Microsoft that supports the entire software development lifecycle (SDLC). It includes tools for planning, version control, CI/CD, package management, and more — all integrated under one roof.&lt;/p&gt;

&lt;p&gt;The four core services we’ll focus on are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Azure Boards&lt;/strong&gt; – Track work items like epics, user stories, bugs, and tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure Repos&lt;/strong&gt; – Git-based source code management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure Pipelines&lt;/strong&gt; – CI/CD pipelines for building, testing, and deploying code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure Artifacts&lt;/strong&gt; – Package and dependency management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lgalznbjqx8vu9wx84v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lgalznbjqx8vu9wx84v.png" alt="Core components of Azure DevOps" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s explore them one by one.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Azure Boards
&lt;/h2&gt;

&lt;p&gt;Boards help you &lt;strong&gt;plan, track, and discuss work&lt;/strong&gt; across teams. It’s fully integrated with Git commits, pull requests, and pipeline deployments.&lt;/p&gt;

&lt;p&gt;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work item types: Epic, Feature, User Story, Task, Bug&lt;/li&gt;
&lt;li&gt;Kanban boards and backlogs&lt;/li&gt;
&lt;li&gt;Sprint planning and burndown charts&lt;/li&gt;
&lt;li&gt;Queries and dashboards for visibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're using Agile or Scrum, Azure Boards can be your centralized hub for project management.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Azure Repos
&lt;/h2&gt;

&lt;p&gt;Azure Repos offers &lt;strong&gt;cloud-hosted Git repositories&lt;/strong&gt; for your source code.&lt;/p&gt;

&lt;p&gt;Features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Branch policies (e.g., require PR review, build pass before merge)&lt;/li&gt;
&lt;li&gt;Code search, diff, blame, and history&lt;/li&gt;
&lt;li&gt;Integration with Boards and Pipelines&lt;/li&gt;
&lt;li&gt;Pull request workflows with discussion threads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Azure Repos is comparable to GitHub or GitLab in terms of capabilities but shines in enterprise scenarios due to tight integration with Azure AD and Azure Pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Azure Pipelines
&lt;/h2&gt;

&lt;p&gt;Pipelines provide &lt;strong&gt;CI/CD automation&lt;/strong&gt; for your projects. You can build and deploy apps written in any language, to any platform.&lt;/p&gt;

&lt;p&gt;Highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;YAML-based and classic editor&lt;/li&gt;
&lt;li&gt;Microsoft-hosted or self-hosted agents&lt;/li&gt;
&lt;li&gt;Support for containers, VMs, Kubernetes, serverless, and more&lt;/li&gt;
&lt;li&gt;Built-in integration with GitHub, Repos, Artifacts, and Key Vault&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code pushed to Git → Pipeline triggers → Build &amp;amp; test → Deploy to staging or production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll build a working pipeline using Azure Pipelines in the next blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Azure Artifacts
&lt;/h2&gt;

&lt;p&gt;Artifacts is your &lt;strong&gt;in-house package management system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NuGet, npm, Maven, Python, and Universal Packages&lt;/li&gt;
&lt;li&gt;Versioned and scoped feeds for dev, test, prod&lt;/li&gt;
&lt;li&gt;Retention policies and clean-up rules&lt;/li&gt;
&lt;li&gt;Integrated with CI/CD pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use it to store and share internal libraries or build outputs between stages.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It All Ties Together
&lt;/h2&gt;

&lt;p&gt;Here's how the services connect in a DevOps workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Plan features in &lt;strong&gt;Boards&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Code in &lt;strong&gt;Repos&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Trigger CI/CD in &lt;strong&gt;Pipelines&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use or publish packages with &lt;strong&gt;Artifacts&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every commit, pull request, and release can be linked to work items — giving you end-to-end traceability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use service connections with appropriate permissions for security&lt;/li&gt;
&lt;li&gt;Define pipeline as code (YAML) for versioning&lt;/li&gt;
&lt;li&gt;Link PRs and commits to work items in Boards&lt;/li&gt;
&lt;li&gt;Automate deployment of packages using Artifacts feeds&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;Now that you know the building blocks of Azure DevOps, we’ll use them to create your &lt;strong&gt;first end-to-end CI/CD pipeline&lt;/strong&gt; with source control, builds, and deployment in the next blog.&lt;/p&gt;

&lt;p&gt;Time to get your hands dirty.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>devops</category>
      <category>cicd</category>
      <category>git</category>
    </item>
    <item>
      <title>CI/CD 101: From Code Commit to Production</title>
      <dc:creator>Akash Roy</dc:creator>
      <pubDate>Wed, 07 May 2025 07:08:40 +0000</pubDate>
      <link>https://forem.com/akash_roy_3bc76e473db5e40/cicd-101-from-code-commit-to-production-3bii</link>
      <guid>https://forem.com/akash_roy_3bc76e473db5e40/cicd-101-from-code-commit-to-production-3bii</guid>
      <description>&lt;p&gt;In the world of modern software delivery, speed and reliability are everything. Users expect features to roll out fast — without downtime or drama. That’s where &lt;strong&gt;CI/CD&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;In this blog, we’ll break down what CI/CD really is, how it powers DevOps, and walk through a real example so you can see it in action.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CI/CD?
&lt;/h2&gt;

&lt;p&gt;CI/CD stands for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Integration (CI)&lt;/strong&gt; – Automating the build and test process every time code is committed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Delivery (CD)&lt;/strong&gt; – Automating the release of that tested code to staging or production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You commit code → It’s built and tested → If successful, it’s deployed automatically&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This approach avoids the nightmare of last-minute integration hell, ensures bugs are caught early, and allows teams to ship smaller, safer changes more frequently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of CI/CD
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster deployments&lt;/strong&gt;: Shipping becomes routine, not a big event.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved quality&lt;/strong&gt;: Automated testing catches issues early.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shorter feedback loops&lt;/strong&gt;: Stakeholders see progress faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced risk&lt;/strong&gt;: Small, incremental changes are easier to roll back.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Typical CI/CD Flow
&lt;/h2&gt;

&lt;p&gt;Here’s a high-level look at what happens in a CI/CD pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developer pushes code to a Git repository&lt;/li&gt;
&lt;li&gt;CI pipeline triggers:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Runs tests&lt;/li&gt;
&lt;li&gt;Lints code&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Builds artifacts (e.g., a Docker image or compiled binary)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If all steps pass, CD pipeline triggers:&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploys to staging environment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optionally runs automated integration tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promotes to production&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tools Involved in CI/CD
&lt;/h2&gt;

&lt;p&gt;Depending on your stack, you might use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source Control&lt;/strong&gt;: GitHub, Azure Repos, GitLab&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Engines&lt;/strong&gt;: Azure Pipelines, GitHub Actions, GitLab CI, Jenkins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artifacts&lt;/strong&gt;: Azure Artifacts, GitHub Packages, JFrog Artifactory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environments&lt;/strong&gt;: Azure App Service, AKS, App Center, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our upcoming blogs, we’ll focus on &lt;strong&gt;Azure Pipelines&lt;/strong&gt; and &lt;strong&gt;GitHub Actions&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: CI/CD for a Node.js App Using Azure Pipelines
&lt;/h2&gt;

&lt;p&gt;Let’s say you have a simple Node.js app in a Git repo. You want every push to the &lt;code&gt;main&lt;/code&gt; branch to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install dependencies&lt;/li&gt;
&lt;li&gt;Run unit tests&lt;/li&gt;
&lt;li&gt;Build the app&lt;/li&gt;
&lt;li&gt;Deploy to Azure App Service (if all goes well)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s what a basic YAML pipeline could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;vmImage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ubuntu-latest'&lt;/span&gt;

&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodeTool@0&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;versionSpec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;18.x'&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Node.js'&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="s"&gt;npm run test&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Install&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Test'&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Build&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Application'&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AzureWebApp@1&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;azureSubscription&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Your-Service-Connection-Name'&lt;/span&gt;
      &lt;span class="na"&gt;appName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;your-app-service-name'&lt;/span&gt;
      &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(System.DefaultWorkingDirectory)/**/*.zip'&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Azure'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a minimal setup. Real-world pipelines often include linting, code coverage checks, approval gates, infrastructure provisioning, and rollback mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep builds fast — under 10 minutes ideally&lt;/li&gt;
&lt;li&gt;Fail fast: stop pipeline early if a key step fails&lt;/li&gt;
&lt;li&gt;Store pipeline definitions in code (YAML, not UI)&lt;/li&gt;
&lt;li&gt;Use secrets for credentials (never hardcode passwords or tokens)&lt;/li&gt;
&lt;li&gt;Protect production branches with approvals or checks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;Now that you understand the value of CI/CD and how it works, we’re ready to build one ourselves.&lt;/p&gt;

&lt;p&gt;In the next blog, we’ll create your first Azure DevOps Project and link it to a Git repo. From there, we’ll configure a working pipeline for real deployment.&lt;/p&gt;

&lt;p&gt;Time to get hands-on.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>devops</category>
      <category>azure</category>
      <category>git</category>
    </item>
    <item>
      <title>Azure 101: Getting Started with Azure Cloud</title>
      <dc:creator>Akash Roy</dc:creator>
      <pubDate>Tue, 06 May 2025 12:24:20 +0000</pubDate>
      <link>https://forem.com/akash_roy_3bc76e473db5e40/azure-101-getting-started-with-azure-cloud-3j64</link>
      <guid>https://forem.com/akash_roy_3bc76e473db5e40/azure-101-getting-started-with-azure-cloud-3j64</guid>
      <description>&lt;p&gt;If you’re diving into DevOps, sooner or later you’ll find yourself working with cloud infrastructure. And when it comes to enterprises, Azure is one of the biggest players in the game. But for many newcomers, Azure can feel like a maze of services, menus, and jargon.&lt;/p&gt;

&lt;p&gt;This post breaks down &lt;strong&gt;how to get started with Azure practically&lt;/strong&gt; — with just enough context to understand what's happening, and a CLI-driven walkthrough to create your first resource group.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Azure?
&lt;/h2&gt;

&lt;p&gt;At its core, &lt;strong&gt;Microsoft Azure is a cloud computing platform&lt;/strong&gt; that offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On-demand access to computing, storage, networking, and AI services&lt;/li&gt;
&lt;li&gt;A pay-as-you-go model&lt;/li&gt;
&lt;li&gt;Massive global scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you’re hosting a web app, spinning up Kubernetes clusters, or building a DevOps pipeline — Azure has a service for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Concepts in Azure (You’ll Hear These Everywhere)
&lt;/h2&gt;

&lt;p&gt;Before we dive in, let’s get clear on a few building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subscription&lt;/strong&gt;: Your billing boundary. Everything you create lives inside a subscription.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Group (RG)&lt;/strong&gt;: A logical container that holds related resources like VMs, databases, storage, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Region&lt;/strong&gt;: The physical data center location where your resources live (e.g., East US, West Europe).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt;: Actual services like Azure VM, App Service, or Key Vault.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Azure Portal vs CLI vs Infrastructure as Code
&lt;/h2&gt;

&lt;p&gt;Azure gives you multiple ways to interact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Azure Portal&lt;/strong&gt;: GUI in the browser for manual control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure CLI (&lt;code&gt;az&lt;/code&gt;)&lt;/strong&gt;: Fast, scriptable command-line tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ARM Templates / Bicep / Terraform&lt;/strong&gt;: Infrastructure as Code options for automating deployments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this series, we’ll focus mostly on &lt;strong&gt;CLI and Terraform&lt;/strong&gt; — because repeatability and automation are DevOps cornerstones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hands-On: Set Up Azure CLI and Create a Resource Group
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install the Azure CLI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;macOS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;azure-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ubuntu/Debian&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sL&lt;/span&gt; https://aka.ms/InstallAzureCLIDeb | &lt;span class="nb"&gt;sudo &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;br&gt;
Use the official MSI installer:&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/cli/azure/install-azure-cli" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/cli/azure/install-azure-cli&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 2: Login to Azure
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This opens a browser window and logs you in with your Microsoft account.&lt;/p&gt;

&lt;p&gt;For CI/CD service principals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az login &lt;span class="nt"&gt;--service-principal&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;appId&amp;gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;password&amp;gt; &lt;span class="nt"&gt;--tenant&lt;/span&gt; &amp;lt;tenantId&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 3: Check and Set Your Subscription
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az account list &lt;span class="nt"&gt;--output&lt;/span&gt; table
az account &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--subscription&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;subscription-name-or-id&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 4: Create Your First Resource Group
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az group create &lt;span class="nt"&gt;--name&lt;/span&gt; devops-rg &lt;span class="nt"&gt;--location&lt;/span&gt; eastus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 5: List and Delete (Optional)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az group list &lt;span class="nt"&gt;--output&lt;/span&gt; table
az group delete &lt;span class="nt"&gt;--name&lt;/span&gt; devops-rg &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Best Practices for Beginners
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use consistent naming conventions: &lt;code&gt;project-env-type-region&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stick to a primary region for experiments (e.g., &lt;code&gt;eastus&lt;/code&gt; or &lt;code&gt;centralindia&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Use a separate dev/test subscription from production if possible&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;Now that you’ve installed Azure CLI and created your first resource group, you're ready to start deploying real infrastructure.&lt;/p&gt;

&lt;p&gt;In the next post, we’ll explore &lt;strong&gt;CI/CD concepts from a DevOps perspective&lt;/strong&gt; — from Git push to production deployment.&lt;/p&gt;

&lt;p&gt;Let’s get some pipelines flowing.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>devops</category>
      <category>cloud</category>
      <category>azuredevops</category>
    </item>
    <item>
      <title>What is DevOps? Why It Matters in Modern Software Development</title>
      <dc:creator>Akash Roy</dc:creator>
      <pubDate>Tue, 06 May 2025 11:39:20 +0000</pubDate>
      <link>https://forem.com/akash_roy_3bc76e473db5e40/what-is-devops-why-it-matters-in-modern-software-development-46bb</link>
      <guid>https://forem.com/akash_roy_3bc76e473db5e40/what-is-devops-why-it-matters-in-modern-software-development-46bb</guid>
      <description>&lt;p&gt;Let’s be real — "DevOps" gets thrown around a lot.&lt;/p&gt;

&lt;p&gt;Some think it's just about automating deployments. Others think it’s just a fancy job title with no clear definition. And if you're just getting started, it’s easy to get overwhelmed by all the tools, pipelines, YAML files, and buzzwords.&lt;/p&gt;

&lt;p&gt;So let’s strip it all down and talk about what DevOps actually is — and why you need to care if you're building anything in the cloud today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dev + Ops = DevOps? Not Quite
&lt;/h2&gt;

&lt;p&gt;At face value, "DevOps" combines Development and Operations. But it’s more than just two teams collaborating. It’s a cultural shift in how software gets built, shipped, and maintained.&lt;/p&gt;

&lt;p&gt;Back in the day, developers would write code, toss it over the wall, and the operations team would figure out how to run it in production. Naturally, this led to finger-pointing, delays, and a ton of miscommunication.&lt;/p&gt;

&lt;p&gt;DevOps breaks that wall. It’s about developers and ops folks working together, continuously, with shared goals and responsibilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  What DevOps Actually Means (in simple terms)
&lt;/h2&gt;

&lt;p&gt;At its heart, DevOps is about these key things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration&lt;/strong&gt; — No more silos between dev, QA, and ops.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation&lt;/strong&gt; — From code push to production, everything is streamlined.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Everything&lt;/strong&gt; — Integration, delivery, deployment, testing — happening all the time.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and Feedback&lt;/strong&gt; — Not just deploying, but observing, learning, improving.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of DevOps as the muscle that gets your app from laptop to live — safely and repeatedly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DevOps Became So Important
&lt;/h2&gt;

&lt;p&gt;Software today is no longer shipped once every 6 months. Businesses want updates daily, sometimes hourly.&lt;/p&gt;

&lt;p&gt;Here's what the old way looked like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code freeze for weeks
&lt;/li&gt;
&lt;li&gt;Manual testing
&lt;/li&gt;
&lt;li&gt;Panic deployments at 2 AM
&lt;/li&gt;
&lt;li&gt;"It worked on my machine" excuses
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now compare that to DevOps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated testing and deployments
&lt;/li&gt;
&lt;li&gt;Small, frequent releases
&lt;/li&gt;
&lt;li&gt;Rollbacks when something breaks
&lt;/li&gt;
&lt;li&gt;Real-time monitoring and feedback loops
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DevOps makes software delivery smoother, safer, and faster — which is exactly what businesses need in a cloud-first world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Should You Learn DevOps?
&lt;/h2&gt;

&lt;p&gt;Whether you're a developer, tester, or just curious about cloud technologies — DevOps is the common ground that connects it all. Knowing DevOps means you understand how real-world software is built and maintained.&lt;/p&gt;

&lt;p&gt;You'll also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build confidence in working with tools like Azure DevOps, GitHub Actions, Terraform, and Docker
&lt;/li&gt;
&lt;li&gt;Understand modern deployment strategies like blue-green, rolling, and canary
&lt;/li&gt;
&lt;li&gt;Be better prepared for certifications like AZ-400 and real-world SRE roles
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Coming Up Next
&lt;/h2&gt;

&lt;p&gt;In the next blog, we’ll roll up our sleeves and get into Azure basics — setting up your first cloud account, creating a resource group, and understanding how Azure structures your infrastructure.&lt;/p&gt;

&lt;p&gt;Stick with this series. By the end, you’ll be confidently deploying real apps to the cloud with clarity and purpose. No fluff. Just practical knowledge.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>azure</category>
      <category>cicd</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Create a Virtual Machine on Azure Using a Reusable Terraform Script</title>
      <dc:creator>Akash Roy</dc:creator>
      <pubDate>Sun, 20 Apr 2025 09:11:14 +0000</pubDate>
      <link>https://forem.com/akash_roy_3bc76e473db5e40/how-to-create-a-virtual-machine-on-azure-using-a-reusable-terraform-script-18e1</link>
      <guid>https://forem.com/akash_roy_3bc76e473db5e40/how-to-create-a-virtual-machine-on-azure-using-a-reusable-terraform-script-18e1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Deploying infrastructure shouldn't be a copy-paste headache. Here's how to make your Azure VM setup repeatable and clean using Terraform.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I started using Terraform to manage infrastructure on Azure, one thing became clear very quickly: &lt;strong&gt;writing the same Terraform config every time gets old fast&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, I'm going to show you how to &lt;strong&gt;create an Azure Virtual Machine using a reusable Terraform script&lt;/strong&gt;. By the end of this post, you'll have a modular setup you can use across projects—without rewriting the whole thing each time.&lt;/p&gt;




&lt;h3&gt;
  
  
  What You’ll Need
&lt;/h3&gt;

&lt;p&gt;Before we begin, make sure you’ve got the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/downloads" rel="noopener noreferrer"&gt;Terraform installed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Azure CLI installed and logged in (&lt;code&gt;az login&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 1: Create the Folder Structure
&lt;/h3&gt;

&lt;p&gt;Let’s keep things clean.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;terraform-azure-vm
&lt;span class="nb"&gt;cd &lt;/span&gt;terraform-azure-vm

&lt;span class="nb"&gt;mkdir &lt;/span&gt;modules
&lt;span class="nb"&gt;mkdir &lt;/span&gt;modules/vm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll keep our reusable VM code inside &lt;code&gt;modules/vm&lt;/code&gt; and the environment-specific code in the root folder.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Build the Reusable VM Module
&lt;/h3&gt;

&lt;p&gt;Inside &lt;code&gt;modules/vm/&lt;/code&gt;, create these files:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;main.tf&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"azurerm_network_interface"&lt;/span&gt; &lt;span class="s2"&gt;"nic"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.vm_name}-nic"&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;
  &lt;span class="nx"&gt;resource_group_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource_group_name&lt;/span&gt;

  &lt;span class="nx"&gt;ip_configuration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;                           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"internal"&lt;/span&gt;
    &lt;span class="nx"&gt;subnet_id&lt;/span&gt;                      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subnet_id&lt;/span&gt;
    &lt;span class="nx"&gt;private_ip_address_allocation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dynamic"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"azurerm_windows_virtual_machine"&lt;/span&gt; &lt;span class="s2"&gt;"vm"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm_name&lt;/span&gt;
  &lt;span class="nx"&gt;resource_group_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource_group_name&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;
  &lt;span class="nx"&gt;size&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm_size&lt;/span&gt;
  &lt;span class="nx"&gt;admin_username&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;admin_username&lt;/span&gt;
  &lt;span class="nx"&gt;admin_password&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;admin_password&lt;/span&gt;
  &lt;span class="nx"&gt;network_interface_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;azurerm_network_interface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;os_disk&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;caching&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ReadWrite"&lt;/span&gt;
    &lt;span class="nx"&gt;storage_account_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Standard_LRS"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;source_image_reference&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;publisher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"MicrosoftWindowsServer"&lt;/span&gt;
    &lt;span class="nx"&gt;offer&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"WindowsServer"&lt;/span&gt;
    &lt;span class="nx"&gt;sku&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2019-Datacenter"&lt;/span&gt;
    &lt;span class="nx"&gt;version&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"latest"&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;h4&gt;
  
  
  &lt;code&gt;variables.tf&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"vm_name"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"resource_group_name"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"location"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"vm_size"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"admin_username"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"admin_password"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 3: Use the Module in Your Environment
&lt;/h3&gt;

&lt;p&gt;Go to the root folder and create:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;main.tf&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"azurerm"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;features&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"vm"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./modules/vm"&lt;/span&gt;
  &lt;span class="nx"&gt;vm_name&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-vm"&lt;/span&gt;
  &lt;span class="nx"&gt;resource_group_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;azurerm_resource_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;azurerm_resource_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_id&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;azurerm_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;vm_size&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Standard_B1s"&lt;/span&gt;
  &lt;span class="nx"&gt;admin_username&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"azureuser"&lt;/span&gt;
  &lt;span class="nx"&gt;admin_password&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"MySecureP@ssw0rd123"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"azurerm_resource_group"&lt;/span&gt; &lt;span class="s2"&gt;"rg"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-rg"&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"East US"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"azurerm_virtual_network"&lt;/span&gt; &lt;span class="s2"&gt;"vnet"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-vnet"&lt;/span&gt;
  &lt;span class="nx"&gt;address_space&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.0.0/16"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;azurerm_resource_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;
  &lt;span class="nx"&gt;resource_group_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;azurerm_resource_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"azurerm_subnet"&lt;/span&gt; &lt;span class="s2"&gt;"subnet"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-subnet"&lt;/span&gt;
  &lt;span class="nx"&gt;resource_group_name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;azurerm_resource_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;virtual_network_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;azurerm_virtual_network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;address_prefixes&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.1.0/24"&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;h3&gt;
  
  
  Step 4: Don’t Forget the Backend (Optional but recommended)
&lt;/h3&gt;

&lt;p&gt;For team use or remote state management, configure a &lt;code&gt;backend.tf&lt;/code&gt; file using Azure Storage Account.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 5: Deploy It!
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
terraform plan
terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done! Your Azure VM is up and running.&lt;/p&gt;




&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;With this modular approach, the next time you need a VM? Just tweak a few inputs. No more rewriting long scripts or fighting with syntax every time.&lt;/p&gt;

&lt;p&gt;Let me know in the comments if you'd like to see a Linux version, auto-shutdown scripts, or cost-saving tricks next!&lt;/p&gt;




&lt;p&gt;Happy Terraforming!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
      <category>azure</category>
      <category>virtualmachine</category>
    </item>
  </channel>
</rss>
