<?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: Shankar Thejaswi</title>
    <description>The latest articles on DEV Community by Shankar Thejaswi (@shankarthejaswi).</description>
    <link>https://dev.to/shankarthejaswi</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%2F2820623%2F7daac2d3-64dd-4428-a19c-f9ce1288baff.jpg</url>
      <title>DEV Community: Shankar Thejaswi</title>
      <link>https://dev.to/shankarthejaswi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shankarthejaswi"/>
    <language>en</language>
    <item>
      <title>Building and Releasing Dockerized Applications using Azure Pipelines</title>
      <dc:creator>Shankar Thejaswi</dc:creator>
      <pubDate>Wed, 11 Jun 2025 07:54:41 +0000</pubDate>
      <link>https://dev.to/shankarthejaswi/building-and-releasing-dockerized-applications-using-azure-pipelines-1mpa</link>
      <guid>https://dev.to/shankarthejaswi/building-and-releasing-dockerized-applications-using-azure-pipelines-1mpa</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As containerized applications become the norm in modern DevOps workflows, having an automated CI/CD pipeline to build, test, and deploy Docker images is essential. Azure Pipelines — a part of Azure DevOps — provides a powerful, cloud-native platform to manage the entire lifecycle of your Docker applications, from source control to deployment.&lt;/p&gt;

&lt;p&gt;In this blog, you'll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build Docker images in Azure Pipelines&lt;/li&gt;
&lt;li&gt;Push them to Azure Container Registry (ACR) or Docker Hub&lt;/li&gt;
&lt;li&gt;Deploy them to services like Azure Kubernetes Service (AKS) &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Git repository (Azure Repos or GitHub)&lt;/li&gt;
&lt;li&gt;Dockerfile in your app's root directory&lt;/li&gt;
&lt;li&gt;Azure DevOps organization and project&lt;/li&gt;
&lt;li&gt;Azure Container Registry (or Docker Hub) created&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Create an Azure Pipeline (YAML)
&lt;/h2&gt;

&lt;p&gt;In your repo, create a &lt;code&gt;azure-pipelines.yml&lt;/code&gt; file to define your pipeline steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Pipeline to Build and Push Docker Image to Azure Container Registry (ACR):
&lt;/h3&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;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;myapp&lt;/span&gt;
  &lt;span class="na"&gt;registry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myacr.azurecr.io&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;DockerBuild&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;checkout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;self&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;DockerInstaller@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;dockerVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20.10.7'&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;MyACRServiceConnection'&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;latest&lt;/span&gt;
          &lt;span class="s"&gt;$(Build.BuildId)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;MyACRServiceConnection&lt;/code&gt; with a valid Azure DevOps service connection to your ACR.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;registry&lt;/code&gt; variable to your ACR login server (&lt;code&gt;myacr.azurecr.io&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 2: Configure Azure Container Registry Service Connection
&lt;/h2&gt;

&lt;p&gt;To allow Azure DevOps to push images to ACR:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Project Settings → Service connections&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ New service connection → Docker Registry&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Azure Container Registry&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Authenticate using Azure Resource Manager and select your ACR&lt;/li&gt;
&lt;li&gt;Name it (e.g., &lt;code&gt;MyACRServiceConnection&lt;/code&gt;) and save&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 3: (Optional) Deploy to Azure Kubernetes Service
&lt;/h2&gt;

&lt;p&gt;You can extend the pipeline to deploy your Docker image to AKS.&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;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;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;Kubernetes@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;connectionType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Azure&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Resource&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Manager'&lt;/span&gt;
        &lt;span class="na"&gt;azureSubscriptionEndpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;MyAzureRMConnection'&lt;/span&gt;
        &lt;span class="na"&gt;azureResourceGroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;myResourceGroup'&lt;/span&gt;
        &lt;span class="na"&gt;kubernetesCluster&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;myAKSCluster'&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apply&lt;/span&gt;
        &lt;span class="na"&gt;useConfigurationFile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;configuration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;manifests/deployment.yaml'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure your Kubernetes deployment YAML (&lt;code&gt;manifests/deployment.yaml&lt;/code&gt;) pulls the latest Docker image from ACR using the same tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With Azure Pipelines, you can easily build and release Dockerized applications to any container registry or hosting environment. This CI/CD workflow ensures consistency, scalability, and speed in your software delivery process.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Automating AWS Deployments with GitHub and CodePipeline using Jenkins</title>
      <dc:creator>Shankar Thejaswi</dc:creator>
      <pubDate>Tue, 25 Feb 2025 15:22:12 +0000</pubDate>
      <link>https://dev.to/shankarthejaswi/automating-aws-deployments-with-github-and-codepipeline-using-jenkins-2j5c</link>
      <guid>https://dev.to/shankarthejaswi/automating-aws-deployments-with-github-and-codepipeline-using-jenkins-2j5c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Continuous Integration and Continuous Deployment (CI/CD) is a fundamental practice in DevOps that automates the deployment process, reducing manual work and improving efficiency. AWS CodePipeline is a managed CI/CD service that automates code changes to application deployment. Combined with GitHub and Jenkins, you can create a robust deployment workflow to AWS services such as S3, ECS, Lambda, or EC2.&lt;/p&gt;

&lt;p&gt;In this blog, we'll walk through setting up a CI/CD pipeline using GitHub, Jenkins, and AWS CodePipeline to deploy an application to AWS.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Setting Up AWS CodePipeline
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ** Create an S3 Bucket for Artifacts**
&lt;/h3&gt;

&lt;p&gt;AWS CodePipeline requires an S3 bucket to store artifacts during deployment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the AWS Console → S3 → Create a new bucket.&lt;/li&gt;
&lt;li&gt;Ensure you disable Block all public access (artifacts do not need to be public).&lt;/li&gt;
&lt;li&gt;Note the bucket name for later use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ** Create an IAM Role for CodePipeline**
&lt;/h3&gt;

&lt;p&gt;AWS CodePipeline needs permissions to access GitHub, deploy applications, and interact with AWS services.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to IAM → Roles → Create Role.&lt;/li&gt;
&lt;li&gt;Select AWS Service → Choose CodePipeline.&lt;/li&gt;
&lt;li&gt;Attach the following policies:

&lt;ul&gt;
&lt;li&gt;AWSCodePipelineFullAccess&lt;/li&gt;
&lt;li&gt;AmazonS3FullAccess&lt;/li&gt;
&lt;li&gt;AWSCodeBuildAdminAccess&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Name the role and create it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ** Create a CodePipeline**
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to AWS CodePipeline → Create a new pipeline.&lt;/li&gt;
&lt;li&gt;Choose GitHub as the source provider and connect your repository.&lt;/li&gt;
&lt;li&gt;Add Jenkins as the build provider.&lt;/li&gt;
&lt;li&gt;Deploy using AWS CodeDeploy (for EC2/ECS) or another AWS service as needed.&lt;/li&gt;
&lt;li&gt;Click Create Pipeline.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 2: Configuring GitHub and Jenkins for AWS Deployment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ** Install and Configure Jenkins**
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install Jenkins on an AWS EC2 instance or a local server.&lt;/li&gt;
&lt;li&gt;Install necessary plugins:

&lt;ul&gt;
&lt;li&gt;AWS CodePipeline Plugin&lt;/li&gt;
&lt;li&gt;Git Plugin&lt;/li&gt;
&lt;li&gt;Pipeline Plugin&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set up credentials for AWS within Jenkins.&lt;/li&gt;
&lt;li&gt;Create a new Jenkins Pipeline Job that fetches code from GitHub and triggers deployments.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ** Add AWS Credentials to Jenkins**
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In Jenkins, go to Manage Jenkins → Manage Credentials.&lt;/li&gt;
&lt;li&gt;Add AWS credentials (&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;, &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;) under Global Credentials.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ** Create a Jenkinsfile**
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;Jenkinsfile&lt;/code&gt; in your repository to define the build and deployment stages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'AWS_ACCESS_KEY_ID'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'AWS_SECRET_ACCESS_KEY'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;stages&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Checkout Code'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="nl"&gt;branch:&lt;/span&gt; &lt;span class="s1"&gt;'main'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;url:&lt;/span&gt; &lt;span class="s1"&gt;'https://github.com/your-repo.git'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Build'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'echo Building application...'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Deploy to AWS'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'aws s3 sync . s3://my-bucket-name --delete'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;my-bucket-name&lt;/code&gt; with your actual S3 bucket name.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Deploying an Application to AWS
&lt;/h2&gt;

&lt;p&gt;Depending on your target AWS service, modify the &lt;code&gt;Jenkinsfile&lt;/code&gt; to deploy accordingly:&lt;/p&gt;

&lt;h3&gt;
  
  
  ** Deploy to AWS ECS (Dockerized Applications)**
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Deploy to ECS'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'''
                aws ecr get-login-password | docker login --username AWS --password-stdin &amp;lt;AWS_ACCOUNT_ID&amp;gt;.dkr.ecr.&amp;lt;AWS_REGION&amp;gt;.amazonaws.com
                docker build -t my-app .
                docker tag my-app:latest &amp;lt;AWS_ACCOUNT_ID&amp;gt;.dkr.ecr.&amp;lt;AWS_REGION&amp;gt;.amazonaws.com/my-app:latest
                docker push &amp;lt;AWS_ACCOUNT_ID&amp;gt;.dkr.ecr.&amp;lt;AWS_REGION&amp;gt;.amazonaws.com/my-app:latest
                aws ecs update-service --cluster my-cluster --service my-service --force-new-deployment
                '''&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Automating Rollbacks and Monitoring
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ** Enable Rollbacks in CodeDeploy**
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;CodeDeploy Deployment Configs&lt;/strong&gt; (&lt;code&gt;CodeDeployDefault.OneAtATime&lt;/code&gt;) to control rollout speed.&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;CloudWatch Alarms&lt;/strong&gt; to trigger rollbacks on failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ** Set Up Monitoring with CloudWatch**
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS CloudWatch Logs for debugging.&lt;/li&gt;
&lt;li&gt;Set up Amazon SNS Notifications for deployment alerts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ** Debugging and Troubleshooting**
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Check Jenkins build logs for errors.&lt;/li&gt;
&lt;li&gt;Use AWS CodePipeline Execution History to track failures.&lt;/li&gt;
&lt;li&gt;Review CloudWatch Logs for detailed error messages.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By integrating Jenkins, GitHub, and AWS CodePipeline, you can automate your deployment process, ensuring faster and more reliable application updates. This setup reduces manual intervention, improves development efficiency, and enhances security.&lt;/p&gt;




</description>
    </item>
    <item>
      <title>Automating EC2 Deployment with Terraform, Ansible, and Shell Script</title>
      <dc:creator>Shankar Thejaswi</dc:creator>
      <pubDate>Wed, 05 Feb 2025 16:50:42 +0000</pubDate>
      <link>https://dev.to/shankarthejaswi/automating-ec2-deployment-with-terraform-ansible-and-shell-script-3a75</link>
      <guid>https://dev.to/shankarthejaswi/automating-ec2-deployment-with-terraform-ansible-and-shell-script-3a75</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Infrastructure automation is key to efficient DevOps practices. Two of the most powerful tools for Infrastructure as Code (IaC) are &lt;strong&gt;Terraform&lt;/strong&gt; and &lt;strong&gt;Ansible&lt;/strong&gt;. Terraform is great for provisioning infrastructure, while Ansible excels at configuration management. In this blog, we'll see how to deploy an EC2 instance using Terraform and then configure it using Ansible—all orchestrated by a simple shell script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, ensure you have the following installed on your local machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS CLI&lt;/strong&gt; (configured with necessary credentials)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Terraform&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ansible&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH Key Pair&lt;/strong&gt; (for connecting to EC2 instance)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 1: Writing the Terraform Script&lt;/p&gt;

&lt;p&gt;Terraform will be used to provision the EC2 instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;main.tf&lt;/code&gt;
&lt;/h3&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;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&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;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"web"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c55b159cbfafe1f0"&lt;/span&gt; &lt;span class="c1"&gt;# Example AMI (Change as per requirement)&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;key_name&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"your-key-pair"&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&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;"Terraform-EC2"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"instance_ip"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;web&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public_ip&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Writing the Ansible Playbook&lt;/p&gt;

&lt;p&gt;Once the EC2 instance is up, Ansible will configure it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;playbook.yml&lt;/code&gt;
&lt;/h3&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure EC2 instance&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
  &lt;span class="na"&gt;tasks&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;Install Apache&lt;/span&gt;
      &lt;span class="na"&gt;apt&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;apache2&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&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;Start Apache&lt;/span&gt;
      &lt;span class="na"&gt;service&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;apache2&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;started&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Writing the Shell Script&lt;/p&gt;

&lt;p&gt;A shell script will automate Terraform execution and Ansible deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;deploy.sh&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Initialize Terraform&lt;/span&gt;
terraform init

&lt;span class="c"&gt;# Apply Terraform and capture instance IP&lt;/span&gt;
terraform apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; output.txt

&lt;span class="c"&gt;# Extract IP address&lt;/span&gt;
&lt;span class="nv"&gt;INSTANCE_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oP&lt;/span&gt; &lt;span class="s1"&gt;'(?&amp;lt;=instance_ip = )[^ ]+'&lt;/span&gt; output.txt&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"EC2 Instance IP: &lt;/span&gt;&lt;span class="nv"&gt;$INSTANCE_IP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Wait for instance to be ready&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;30

&lt;span class="c"&gt;# Add instance to Ansible inventory&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[web]"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; inventory
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INSTANCE_IP&lt;/span&gt;&lt;span class="s2"&gt; ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/your-key.pem"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; inventory

&lt;span class="c"&gt;# Run Ansible playbook&lt;/span&gt;
ansible-playbook &lt;span class="nt"&gt;-i&lt;/span&gt; inventory playbook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Running the Script&lt;br&gt;
Make the script executable and run it:&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;chmod&lt;/span&gt; +x deploy.sh
./deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
This setup automates EC2 provisioning with Terraform and configuration management with Ansible using a shell script. It eliminates manual intervention, ensuring a smooth, repeatable, and scalable deployment process. Happy automating!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>terraform</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
