<?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: Lester Diaz Perez</title>
    <description>The latest articles on DEV Community by Lester Diaz Perez (@sharker3312).</description>
    <link>https://dev.to/sharker3312</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%2F1299900%2F7a42a784-c654-4960-8111-01c210d63003.jpg</url>
      <title>DEV Community: Lester Diaz Perez</title>
      <link>https://dev.to/sharker3312</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sharker3312"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Sun, 22 Jun 2025 00:46:42 +0000</pubDate>
      <link>https://dev.to/sharker3312/-4bhb</link>
      <guid>https://dev.to/sharker3312/-4bhb</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/sharker3312/azure-devops-build-push-docker-micro-services-to-azure-container-registry-3c5b" class="crayons-story__hidden-navigation-link"&gt;Azure DevOps: build &amp;amp; push docker micro-services to Azure Container Registry&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/sharker3312" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F1299900%2F7a42a784-c654-4960-8111-01c210d63003.jpg" alt="sharker3312 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/sharker3312" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Lester Diaz Perez
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Lester Diaz Perez
                
              
              &lt;div id="story-author-preview-content-2584934" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/sharker3312" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F1299900%2F7a42a784-c654-4960-8111-01c210d63003.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Lester Diaz Perez&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/sharker3312/azure-devops-build-push-docker-micro-services-to-azure-container-registry-3c5b" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 21 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/sharker3312/azure-devops-build-push-docker-micro-services-to-azure-container-registry-3c5b" id="article-link-2584934"&gt;
          Azure DevOps: build &amp;amp; push docker micro-services to Azure Container Registry
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/azure"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;azure&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cicd"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cicd&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/docker"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;docker&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/sharker3312/azure-devops-build-push-docker-micro-services-to-azure-container-registry-3c5b" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/sharker3312/azure-devops-build-push-docker-micro-services-to-azure-container-registry-3c5b#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>azure</category>
      <category>devops</category>
      <category>cicd</category>
      <category>docker</category>
    </item>
    <item>
      <title>Deploying ArgoCD on an Azure Kubernetes Cluster for GitOps</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Sat, 21 Jun 2025 19:10:09 +0000</pubDate>
      <link>https://dev.to/sharker3312/deploying-argocd-on-an-azure-kubernetes-cluster-for-gitops-4cp0</link>
      <guid>https://dev.to/sharker3312/deploying-argocd-on-an-azure-kubernetes-cluster-for-gitops-4cp0</guid>
      <description>&lt;h1&gt;
  
  
  Azure Kubernetes Service (AKS) Cluster Setup ☸️
&lt;/h1&gt;

&lt;p&gt;This document outlines the steps to create an Azure Kubernetes Service (AKS) cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Prerequisites: Equipping Your Toolkit 🛠️
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;  An active Azure subscription 💳.&lt;/li&gt;
&lt;li&gt;  Azure CLI installed and configured. If not, follow the &lt;a href="https://docs.microsoft.com/cli/azure/install-azure-cli" rel="noopener noreferrer"&gt;official Azure CLI installation guide&lt;/a&gt; 💻.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;kubectl&lt;/code&gt; installed. If not, follow the &lt;a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/" rel="noopener noreferrer"&gt;official kubectl installation guide&lt;/a&gt;
## 2. Create AKS Cluster: Setting up Your Kubernetes Environment 🔥➡️☸️&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Time to create your AKS cluster.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Sign in to Azure Portal&lt;/strong&gt;: Navigate to &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;portal.azure.com&lt;/a&gt; 🔑.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Search for AKS&lt;/strong&gt;: In the search bar, type "Azure Kubernetes Service" and select it 🔍.&lt;/li&gt;
&lt;/ol&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%2Fwm7rcz6yeph134362uua.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%2Fwm7rcz6yeph134362uua.png" alt=" " width="510" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Initiate Cluster Creation&lt;/strong&gt;: Click "Create" and then "Create Kubernetes cluster" ✨.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Configure Basic Settings&lt;/strong&gt; ⚙️:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Project details&lt;/strong&gt;: Select your Azure subscription and resource group 📂.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cluster details&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Kubernetes cluster name&lt;/strong&gt;: Enter a unique name for your cluster 🏷️.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Region&lt;/strong&gt;: Choose the Azure region for your cluster 🌍.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Availability zones&lt;/strong&gt;: Select zones for high availability if needed 🏞️.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;AKS pricing tier&lt;/strong&gt;: Standard is recommended for production 💰.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Kubernetes version&lt;/strong&gt;: Choose a recent, stable version ✅.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Primary node pool&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Node size&lt;/strong&gt;: Select an appropriate VM size 🖥️. &lt;code&gt;Standard_B2s&lt;/code&gt; is a good starting point for dev/test. For production, consider &lt;code&gt;Standard_D2s_v3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Scale method&lt;/strong&gt;: Choose "Autoscale" for flexibility ⚖️.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Node count&lt;/strong&gt;: Set the initial number of nodes #️⃣.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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%2Fsaztl4nj2n2d0e10rug8.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%2Fsaztl4nj2n2d0e10rug8.png" alt=" " width="800" height="660"&gt;&lt;/a&gt;&lt;br&gt;
.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Review and Create&lt;/strong&gt;: Carefully review all settings 👀. Once confirmed, click "Create". Cluster deployment may take several minutes ⏳. (Perfect time for a coffee! ☕)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  3. Connect to Your AKS Cluster: Establishing Communication 🔮
&lt;/h2&gt;

&lt;p&gt;After the cluster is deployed, connect to it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Azure CLI (if not already done)&lt;/strong&gt;:&lt;br&gt;
Ensure Azure CLI is installed 💻.&lt;br&gt;
Verify installation:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;az &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Login to Azure&lt;/strong&gt; 🔑:&lt;br&gt;
&lt;/p&gt;

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



&lt;p&gt;Follow the prompts to authenticate.&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Get Cluster Credentials&lt;/strong&gt; 📜:&lt;br&gt;
This command configures &lt;code&gt;kubectl&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;az aks get-credentials &lt;span class="nt"&gt;--resource-group&lt;/span&gt; &amp;lt;your-resource-group&amp;gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;your-cluster-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Verify Connection&lt;/strong&gt; ✅:&lt;br&gt;
Check if your nodes are ready.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;You should see your nodes listed with a &lt;code&gt;Ready&lt;/code&gt; status.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                                STATUS   ROLES   AGE     VERSION
aks-systempool-12345678-vmss000000   Ready    agent   5m16s   v1.28.5
aks-systempool-12345678-vmss000001   Ready    agent   5m17s   v1.28.5
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  4. Install ArgoCD using Helm: Your GitOps Companion 🧙‍♂️⛵📦
&lt;/h2&gt;

&lt;p&gt;ArgoCD will manage your deployments based on your Git repository.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add ArgoCD Helm Repository&lt;/strong&gt; ➕:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add argo https://argoproj.github.io/argo-helm
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update Helm Repositories&lt;/strong&gt; 🔄:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install ArgoCD&lt;/strong&gt; 🚀:&lt;br&gt;
This installs ArgoCD into the &lt;code&gt;argocd&lt;/code&gt; namespace.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;argocd argo/argo-cd &lt;span class="nt"&gt;--namespace&lt;/span&gt; argocd &lt;span class="nt"&gt;--create-namespace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Access ArgoCD UI (via Port Forwarding)&lt;/strong&gt; 🖥️➡️🚪:&lt;br&gt;
Access the ArgoCD dashboard.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; argocd
&lt;span class="c"&gt;# Wait for argocd-server to be Running&lt;/span&gt;
kubectl port-forward svc/argocd-server &lt;span class="nt"&gt;-n&lt;/span&gt; argocd 8080:https
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&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%2Fau7sgxrgk1ol7d4tzqry.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%2Fau7sgxrgk1ol7d4tzqry.png" alt=" " width="800" height="404"&gt;&lt;/a&gt;&lt;br&gt;
    Open &lt;code&gt;https://localhost:8080&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Get Initial Admin Password&lt;/strong&gt; 🤫🔑:&lt;br&gt;
"Keep it secret, keep it safe!" (Okay, just one for the road! 😉)&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; argocd get secret argocd-initial-admin-secret &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{.data.password}"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  5. Next Steps: The Journey Continues... ➡️👣
&lt;/h2&gt;

&lt;p&gt;Your AKS and ArgoCD setup is complete!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Connect Git repositories to ArgoCD 🔗.&lt;/li&gt;
&lt;li&gt;  Define applications for ArgoCD to manage 📝.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>gitops</category>
      <category>azure</category>
      <category>devops</category>
    </item>
    <item>
      <title>Azure DevOps: build &amp; push docker micro-services to Azure Container Registry</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Sat, 21 Jun 2025 19:08:05 +0000</pubDate>
      <link>https://dev.to/sharker3312/azure-devops-build-push-docker-micro-services-to-azure-container-registry-3c5b</link>
      <guid>https://dev.to/sharker3312/azure-devops-build-push-docker-micro-services-to-azure-container-registry-3c5b</guid>
      <description>&lt;h2&gt;
  
  
  🦆 Prerequisites: Get Your Ducks in a Row
&lt;/h2&gt;

&lt;p&gt;Before we dive in:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Why You Need It&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✅ &lt;strong&gt;Azure subscription&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Need Credits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ &lt;strong&gt;Docker basics&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Containerization knowledge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ &lt;strong&gt;Git workflows&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Version control fundamentals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ &lt;strong&gt;GitHub repo&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/dockersamples/example-voting-app" rel="noopener noreferrer"&gt;Fork this repo&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;☕ &lt;strong&gt;Coffee&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Optional but highly recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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%2F2udvz60ngc1rx0bsroe2.gif" 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%2F2udvz60ngc1rx0bsroe2.gif" alt="Let's Go!" width="480" height="202"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Microservices Architecture:&lt;/strong&gt;&lt;/p&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%2F7c2jxgkmfrcunbt31cna.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%2F7c2jxgkmfrcunbt31cna.png" alt=" " width="800" height="742"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Step 1: Azure DevOps Foundation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Azure DevOps?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔥 &lt;strong&gt;Industry standard&lt;/strong&gt; for enterprise CI/CD&lt;/li&gt;
&lt;li&gt;💎 &lt;strong&gt;Free private repos&lt;/strong&gt; (up to 5 users)&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Seamless Azure integration&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Setup:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;🌐 Head to &lt;a href="https://dev.azure.com" rel="noopener noreferrer"&gt;Azure DevOps&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🆕 Create new project&lt;/li&gt;
&lt;li&gt;🔗 Link your forked &lt;code&gt;example-voting-app&lt;/code&gt; repo&lt;/li&gt;
&lt;/ol&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%2F5th922k8tq98whbrcffg.jpg" 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%2F5th922k8tq98whbrcffg.jpg" alt=" " width="576" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🏪 Step 2: Container Registry - Your Image Vault
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Solution: Azure Container Registry (ACR)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔒 &lt;strong&gt;Private &amp;amp; secure&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Geo-replication&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Native Azure integration&lt;/strong&gt;
&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%2F96d223ak09tu7rjm333f.jpg" 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%2F96d223ak09tu7rjm333f.jpg" alt=" " width="526" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Think of ACR as:&lt;/strong&gt; Your private, VIP parking garage for containers! &lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Create:
&lt;/h3&gt;

&lt;p&gt;Navigate to Container Registry → Create&lt;/p&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%2Fqstudlcvun556kd4n4o5.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%2Fqstudlcvun556kd4n4o5.png" alt=" " width="793" height="712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oops! 🤦‍♂️&lt;/strong&gt; Need a Resource Group first. Let's fix that...&lt;/p&gt;




&lt;h2&gt;
  
  
  📁 Step 3: Resource Group - Organization Master
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Think digital folder that keeps all your Azure resources organized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💰 &lt;strong&gt;Cost tracking&lt;/strong&gt; per project&lt;/li&gt;
&lt;li&gt;🗂️ &lt;strong&gt;Easy cleanup&lt;/strong&gt; (delete group = delete everything)&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Access management&lt;/strong&gt; in one place&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%2Fo7r3inr3r7316r0i6xh2.jpg" 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%2Fo7r3inr3r7316r0i6xh2.jpg" alt=" " width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Naming convention:&lt;/strong&gt; &lt;code&gt;rg-voting-app-prod&lt;/code&gt; (descriptive + environment)&lt;/p&gt;




&lt;h2&gt;
  
  
  🤖 Step 4: Self-Hosted Agent - Your Build Butler
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hosted vs Self-Hosted: The Truth
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hosted Agents&lt;/th&gt;
&lt;th&gt;Self-Hosted Agents&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;💸 Pay per minute&lt;/td&gt;
&lt;td&gt;💰 &lt;strong&gt;Free after VM cost&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🐌 Queue times&lt;/td&gt;
&lt;td&gt;⚡ &lt;strong&gt;Instant builds&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔒 Limited customization&lt;/td&gt;
&lt;td&gt;🔧 &lt;strong&gt;Full control&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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%2Fmedy0perb7rvhynl6mtj.gif" 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%2Fmedy0perb7rvhynl6mtj.gif" alt="Let's Go!" width="398" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup Process:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;🖥️ Create Ubuntu VM in Azure&lt;/li&gt;
&lt;li&gt;⚙️ &lt;strong&gt;Azure DevOps&lt;/strong&gt; → Project Settings → Agent Pools → Add pool&lt;/li&gt;
&lt;li&gt;📋 Follow installation steps&lt;/li&gt;
&lt;/ol&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%2Fofwjdiezqni2mofu2dtf.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%2Fofwjdiezqni2mofu2dtf.png" alt=" " width="800" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Security: Personal Access Token (PAT)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why PAT?&lt;/strong&gt; Secure communication between agent and Azure DevOps.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Profile picture → &lt;strong&gt;Personal Access Tokens&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create token with required scopes&lt;/li&gt;
&lt;/ol&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%2Fa6t6kadnqcmh4rgqb0g7.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%2Fa6t6kadnqcmh4rgqb0g7.png" alt=" " width="703" height="498"&gt;&lt;/a&gt;&lt;/p&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%2Fjg5yxjozozh0o9kqe7p4.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%2Fjg5yxjozozh0o9kqe7p4.png" alt=" " width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Note:&lt;/strong&gt; Full access scope = demo only. Production = minimal required permissions! ⚠️&lt;/p&gt;




&lt;h2&gt;
  
  
  💍 Step 5: Crafting My Preciouuuuss Pipeline
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;"One pipeline to build them all, one pipeline to find them, one pipeline to bring them all, and in the registry bind them."&lt;/em&gt; – DevOps Gandalf&lt;/p&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%2F83o2mg400gj699es9mud.gif" 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%2F83o2mg400gj699es9mud.gif" alt="DevOps Sauron" width="400" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pipeline Creation Magic ✨
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Azure DevOps makes this stupid easy:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pipelines&lt;/strong&gt; → New Pipeline&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure Repos Git&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Select repository&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker - build and push to ACR&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;!&lt;br&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%2Fumnawdfycj2s4hrnleta.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%2Fumnawdfycj2s4hrnleta.png" alt=" " width="800" height="421"&gt;&lt;/a&gt;&lt;/p&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%2F5oqg9neyqffhi3quanu1.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%2F5oqg9neyqffhi3quanu1.png" alt=" " width="800" height="655"&gt;&lt;/a&gt;&lt;br&gt;
Look at all the infinity of tasks available! Probably all frequently used tasks are already developed here. But you know, if something's missing, you can always create it yourself!&lt;/p&gt;
&lt;h2&gt;
  
  
  Dockerize and Push Our Vote Microservice
&lt;/h2&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%2Faedn0j6qo9qbl0ejz6vn.jpg" 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%2Faedn0j6qo9qbl0ejz6vn.jpg" alt=" " width="800" height="743"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  🐳 Creating the Vote Pipeline
&lt;/h3&gt;

&lt;p&gt;Now let's create a dedicated pipeline for our vote microservice. This pipeline will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Trigger only on vote/ changes&lt;/strong&gt; (efficient builds)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Build the Python Flask app&lt;/strong&gt; using Docker&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Push to Azure Container Registry&lt;/strong&gt; securely&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Tag with build number&lt;/strong&gt; for version tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pipeline Configuration:&lt;/strong&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="na"&gt;paths&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;vote/*&lt;/span&gt;  &lt;span class="c1"&gt;# Only triggers when vote microservice changes&lt;/span&gt;

&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;self&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;dockerRegistryServiceConnection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2833cab0-ae52-474d-97fd-43a2db870ebe'&lt;/span&gt;
  &lt;span class="na"&gt;imageRepository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;vote'&lt;/span&gt; &lt;span class="c1"&gt;# For each service one repository (worker, result)&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;sharker3312.azurecr.io'&lt;/span&gt;
  &lt;span class="na"&gt;dockerfilePath&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.SourcesDirectory)/vote/Dockerfile'&lt;/span&gt; &lt;span class="c1"&gt;# Dockerfile PATH&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;pool&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="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;self-host'&lt;/span&gt;  &lt;span class="c1"&gt;# Using our self-hosted agent&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;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push stage&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;Build&lt;/span&gt;
    &lt;span class="na"&gt;displayName&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;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;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push an image to container registry&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;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;buildAndPush&lt;/span&gt;
        &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$(imageRepository)&lt;/span&gt;
        &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$(dockerfilePath)&lt;/span&gt;
        &lt;span class="na"&gt;containerRegistry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$(dockerRegistryServiceConnection)&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="s"&gt;latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚨 &lt;strong&gt;REALITY CHECK: When Things Go BOOM!&lt;/strong&gt; 💥
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Because let's be honest - your first pipeline run is going to fail spectacularly, and that's perfectly normal!&lt;/em&gt; 😅&lt;/p&gt;

&lt;h3&gt;
  
  
  🔥 &lt;strong&gt;THE MOMENT OF TRUTH&lt;/strong&gt; 🔥
&lt;/h3&gt;

&lt;p&gt;You hit that "Run Pipeline" button with all the confidence in the world, and then...&lt;/p&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%2Fji0676g1ie9crf9dsuio.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%2Fji0676g1ie9crf9dsuio.png" alt=" " width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem Solved:&lt;/strong&gt; Our agent needs Docker to build those containers! Let's fix that:&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;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; apt-transport-https ca-certificates curl software-properties-common
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/docker-archive-keyring.gpg
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [arch=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;--print-architecture&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; docker-ce docker-ce-cli containerd.io

&lt;span class="c"&gt;# Add agent user to docker group (no sudo needed for docker)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Don't worry about errors - they're just DevOps giving you a chance to learn something new! 🧠&lt;/p&gt;

&lt;h3&gt;
  
  
  🏷️ Tagging Strategy Explained:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tag&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build ID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vote:12345&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specific version tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vote:latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Always points to newest build&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🔄 Step 7: Worker &amp;amp; Result Microservices
&lt;/h2&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%2Fe2dvzbsa6i9vly8ux3fr.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%2Fe2dvzbsa6i9vly8ux3fr.png" alt=" " width="800" height="742"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  👷‍♂️ The Worker Pipeline
&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;imageRepository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;worker'&lt;/span&gt; &lt;span class="c1"&gt;# Changed from 'vote'&lt;/span&gt;
  &lt;span class="na"&gt;dockerfilePath&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.SourcesDirectory)/worker/Dockerfile'&lt;/span&gt; &lt;span class="c1"&gt;# Changed path&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Also update your trigger path:&lt;/strong&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="na"&gt;paths&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;worker/*&lt;/span&gt;  &lt;span class="c1"&gt;# Only triggers when worker microservice changes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📊 The Result Pipeline
&lt;/h3&gt;

&lt;p&gt;Same story, different microservice! For the Result app, just modify:&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;imageRepository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;result'&lt;/span&gt; &lt;span class="c1"&gt;# Changed from 'vote'&lt;/span&gt;
  &lt;span class="na"&gt;dockerfilePath&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.SourcesDirectory)/result/Dockerfile'&lt;/span&gt; &lt;span class="c1"&gt;# Changed path&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And update your trigger:&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;paths&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;result/*&lt;/span&gt;  &lt;span class="c1"&gt;# Only triggers when result microservice changes &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; 🧙‍♂️ With this approach, each microservice has its own dedicated pipeline that only triggers when that specific service changes! Talk about efficiency!&lt;/p&gt;

&lt;p&gt;At this moment we've got all our pipelines functioning beautifully:&lt;/p&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%2F8nthyyamh7s3fyi0hvq6.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%2F8nthyyamh7s3fyi0hvq6.png" alt=" " width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 Step 8: Redis &amp;amp; PostgreSQL - The Missing Pieces
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🤔 What about Redis and PostgreSQL?
&lt;/h3&gt;

&lt;p&gt;No need to reinvent the wheel! For these components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🐘 &lt;strong&gt;PostgreSQL&lt;/strong&gt; - Using official public image from Docker Hub&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Redis&lt;/strong&gt; - Using official public image from Docker Hub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why use public images?&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🏆 &lt;strong&gt;Production-ready&lt;/strong&gt; containers maintained by experts&lt;/li&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Security updates&lt;/strong&gt; automatically rolled out &lt;/li&gt;
&lt;li&gt;💰 &lt;strong&gt;Cost-efficient&lt;/strong&gt; - no need to maintain our own images&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚢 What's Next?
&lt;/h2&gt;

&lt;p&gt;But the real question is: What do we do with these container images once they're in our registry?&lt;/p&gt;

&lt;p&gt;Well, this is just the beginning of our DevOps journey! Now we need a way to manage these containers through a single orchestration service.&lt;/p&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%2Fvqry628jsua3lml3ar73.gif" 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%2Fvqry628jsua3lml3ar73.gif" alt="Kubernetes Excitement" width="480" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe &lt;strong&gt;Kubernetes&lt;/strong&gt; - the container orchestration superhero! 🦸‍♂️&lt;/p&gt;

</description>
      <category>azure</category>
      <category>devops</category>
      <category>cicd</category>
      <category>docker</category>
    </item>
    <item>
      <title>🏗️ Provision AWS EC2 Instances with Terraform and Set Up Docker via User Data</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Thu, 09 Jan 2025 15:34:14 +0000</pubDate>
      <link>https://dev.to/sharker3312/provision-aws-ec2-instances-with-terraform-and-set-up-docker-via-user-data-2ik7</link>
      <guid>https://dev.to/sharker3312/provision-aws-ec2-instances-with-terraform-and-set-up-docker-via-user-data-2ik7</guid>
      <description>&lt;h1&gt;
  
  
  📋Workflow
&lt;/h1&gt;

&lt;p&gt;1️⃣ 📁 Structure&lt;br&gt;
2️⃣ 🌱 Root module&lt;br&gt;
3️⃣ 💻 EC2 module&lt;br&gt;
4️⃣ 🛡️ Security Group module&lt;/p&gt;

&lt;p&gt;🔗&lt;a href="https://github.com/Sharker3312/AWS-Projects/tree/main/TerraTraefik" rel="noopener noreferrer"&gt;Link to project&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  1️⃣ 📁 Structure
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;├── dev.tfvars
├── main.tf
├── provider.tf
├── modules
│   ├── ec2
│   │   ├── install_docker.sh
│   │   ├── main.tf
│   │   ├── output.tf
│   │   └── variables.tf
│   └── security_group
│       ├── igw.tf
│       ├── output.tf
│       ├── rt.tf
│       ├── sg.tf
│       ├── subnet.tf
│       └── vpc.tf

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

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Why it's important to split terraform into modules?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;🔄 Code reuse&lt;/li&gt;
&lt;li&gt;📈 Improved scalability&lt;/li&gt;
&lt;li&gt;🧩 Modularity and abstraction&lt;/li&gt;
&lt;li&gt;👥 Clear separation of responsibilities.&lt;/li&gt;
&lt;li&gt;🛠️ Simplified maintenance&lt;/li&gt;
&lt;li&gt;📖 Improved readability&lt;/li&gt;
&lt;li&gt;🔄 Efficient version control&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  2️⃣ 🌱 Root module
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.tf&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ami"&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;"instance_type"&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;"key_name"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;


&lt;span class="c1"&gt;#Replace the resource with a module&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"ec2_instance"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;#References file location of new module&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/ec2"&lt;/span&gt;

  &lt;span class="nx"&gt;ami&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;ami&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&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;instance_type&lt;/span&gt;
  &lt;span class="nx"&gt;key_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;key_name&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subnet_id&lt;/span&gt;  &lt;span class="c1"&gt;# Call the name of variable output &lt;/span&gt;

  &lt;span class="nx"&gt;sg_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sg_id&lt;/span&gt;


&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Specify the name for the security group&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"security_group"&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/security_group"&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#provider.tf&lt;/span&gt;
&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&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;"hashicorp/aws"&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;"~&amp;gt; 5.52.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&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-2"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# dev.tfvars&lt;/span&gt;
&lt;span class="nx"&gt;ami&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0b4624933067d393a"&lt;/span&gt; &lt;span class="c1"&gt;# each ami is region specific &lt;/span&gt;
&lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="err"&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="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ec2_key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  3️⃣ 💻 EC2 module
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# modules/ec2/main.tf&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ami"&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;"instance_type"&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;"key_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;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"ec2"&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="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ami&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&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;instance_type&lt;/span&gt;
  &lt;span class="nx"&gt;key_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;key_name&lt;/span&gt;

  &lt;span class="nx"&gt;vpc_security_group_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;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sg_id&lt;/span&gt;&lt;span class="p"&gt;]&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;user_data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${file("&lt;/span&gt;&lt;span class="p"&gt;./&lt;/span&gt;&lt;span class="nx"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;install_docker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sh&lt;/span&gt;&lt;span class="s2"&gt;")}"&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;"traefik-demo"&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# modules/ec2/variables.tf&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"sg_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Security Group ID"&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&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;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Subnet ID"&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;🔑 Key points.&lt;br&gt;
The &lt;strong&gt;EC2 module&lt;/strong&gt; requires two essential fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛡️ Security Group ID.&lt;/li&gt;
&lt;li&gt;🌐 Subnet ID
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# modules/ec2/output.tf&lt;/span&gt;
&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"instance_id"&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;ec2&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;output&lt;/span&gt; &lt;span class="s2"&gt;"public_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;ec2&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;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;# Update and install Docker&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum update &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; jq docker


&lt;span class="c"&gt;# Enable Docker service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;service docker start
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-G&lt;/span&gt; docker ec2-user

&lt;span class="c"&gt;# Get the latest version of Docker Compose &lt;/span&gt;
&lt;span class="nv"&gt;DOCKER_COMPOSE_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.github.com/repos/docker/compose/releases/latest | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .tag_name&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Install Docker Compose&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/docker/compose/releases/download/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOCKER_COMPOSE_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/docker-compose-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/local/bin/docker-compose
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; +x /usr/local/bin/docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  4️⃣ 🛡️ Security Group module
&lt;/h2&gt;

&lt;p&gt;vpc.tf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#modules/security_group/vpc.tf&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_vpc"&lt;/span&gt; &lt;span class="s2"&gt;"traefik_vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_block&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="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;"main-vpc"&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#modules/security_group/subnet.tf&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_subnet"&lt;/span&gt; &lt;span class="s2"&gt;"traefik_subnet"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;vpc_id&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_vpc&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;cidr_block&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="nx"&gt;map_public_ip_on_launch&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;"example-subnet"&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#modules/security_group/sg.tf&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"traefik_sg"&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;"traefik-security-group"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_vpc&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;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow HTTP and HTTPS traffic"&lt;/span&gt;

  &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Allow ssh from internet&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;egress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"-1"&lt;/span&gt; &lt;span class="c1"&gt;# Allow all traffic&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&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;"traefik_sg"&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#modules/security_group/rt.tf&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route_table"&lt;/span&gt; &lt;span class="s2"&gt;"traefik_route_table"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_vpc&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;route&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_block&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;
    &lt;span class="nx"&gt;gateway_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_internet_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_igw&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;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;"route_table"&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;"aws_route_table_association"&lt;/span&gt; &lt;span class="s2"&gt;"a"&lt;/span&gt; &lt;span class="p"&gt;{&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;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_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;route_table_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_route_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_route_table&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#modules/security_group/igw.tf&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_internet_gateway"&lt;/span&gt; &lt;span class="s2"&gt;"traefik_igw"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_vpc&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;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;"traefik_IGW"&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;#modules/security_group/output.tf&lt;/span&gt;
&lt;span class="nx"&gt;output&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;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_subnet&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;output&lt;/span&gt; &lt;span class="s2"&gt;"sg_id"&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_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;traefik_sg&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🏗️ Terraform deploy
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; terraform init
 terraform validate &lt;span class="nt"&gt;--var-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev.tfvars
 terraform plan &lt;span class="nt"&gt;--var-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev.tfvars
 terraform apply &lt;span class="nt"&gt;--var-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev.tfvars &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>terraform</category>
      <category>docker</category>
      <category>network</category>
    </item>
    <item>
      <title>☁️ AWS - Email notification system</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Mon, 17 Jun 2024 20:13:55 +0000</pubDate>
      <link>https://dev.to/sharker3312/aws-email-notification-system-2clo</link>
      <guid>https://dev.to/sharker3312/aws-email-notification-system-2clo</guid>
      <description>&lt;h1&gt;
  
  
  Technologies:
&lt;/h1&gt;

&lt;p&gt;☁️ AWS: 🪣 S3 bucket, ⚡️ lambda function, 🔔 SNS, 📬 SQS&lt;br&gt;
🤖 IaC: 🏗️ Terraform&lt;br&gt;
🔄 CD: 🛠️ GitLab&lt;/p&gt;

&lt;p&gt;Project resume: Email notification system developed in AWS. Once a file is uploaded to an s3 bucket it triggers an event which calls a lambda function and notifies service subscribers that a file has been uploaded.&lt;/p&gt;
&lt;h2&gt;
  
  
  📌Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AWS &lt;a href="https://aws.amazon.com/free/" rel="noopener noreferrer"&gt;account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;VsCode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/users/sign_in" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🎯Workflow
&lt;/h2&gt;

&lt;p&gt;1️⃣ Source code 📄&lt;br&gt;
2️⃣ Lambda function ⚡️&lt;br&gt;
3️⃣ Deploy to AWS through GitLab 🚀&lt;/p&gt;


&lt;h2&gt;
  
  
  1️⃣ Source code 📄
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/sharker2/AWS-Projects/-/tree/main/Notification-system?ref_type=heads" rel="noopener noreferrer"&gt;Gitlab project&lt;/a&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform
└── terraform
    ├── bucket
    │   ├── main.tf
    │   └── output.tf
    │   └── variables.tf
    ├── lambda
    │   ├── main.tf
    │   └── output.tf
    │   └── variables.tf
    │   └── lambda_assume_role_policy.json
    │   └── lambda_policy.json
    │   └── lambda_function.py
    │   └── lambda_function.zip
    ├── sns
    │   ├── main.tf
    │   └── output.tf
    │   └── variables.tf
    ├── sqs
    │   ├── main.tf
    │   └── output.tf
    │   └── variables.tf
    ├── main.tf
    └── providers.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is organized into modules dedicated to different AWS services, each designed to serve a specific purpose and facilitate the management and scalability of the cloud environment.In addition, using Terraform to orchestrate these modules ensures a consistent and controlled deployment of the infrastructure, aligned with best practices for configuration management and agile development in the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  2️⃣ Lambda function ⚡️
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize AWS clients
&lt;/span&gt;&lt;span class="n"&gt;s3_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sns_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sns&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sqs_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sqs&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Define SNS topic ARN and SQS queue URL
&lt;/span&gt;    &lt;span class="n"&gt;sns_topic_arn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;arn:aws:sns:us-east-2:087243254862:notifcationsystem-bucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="n"&gt;sqs_queue_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://sqs.us-east-2.amazonaws.com/087243254862/notification&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="c1"&gt;# Process S3 event records
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Records&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="c1"&gt;# Print the entire event for debugging purposes
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Extract S3 bucket and object information from the event record
&lt;/span&gt;        &lt;span class="n"&gt;s3_bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;s3_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="c1"&gt;# Example: Prepare metadata to send to SQS
&lt;/span&gt;        &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s3_bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s3_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;eventTime&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;# Send metadata to SQS queue
&lt;/span&gt;        &lt;span class="n"&gt;sqs_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqs_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;QueueUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sqs_queue_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;MessageBody&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Example: Prepare notification message to send to SNS
&lt;/span&gt;        &lt;span class="n"&gt;notification_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;New file uploaded to S3 bucket &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s3_bucket&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; with key &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s3_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;

        &lt;span class="c1"&gt;# Publish notification message to SNS topic
&lt;/span&gt;        &lt;span class="n"&gt;sns_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sns_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;TopicArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sns_topic_arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;notification_message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;File Upload Notification&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Return a success response
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;statusCode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Processing complete&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;3️⃣ GitLab workflow 🚀&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add pipeline&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%2Fgtohuu18oh7o1h1gtm66.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%2Fgtohuu18oh7o1h1gtm66.png" alt="Click pipeline" width="316" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🔑Add access key from AWS into secrets in GitLab(Create a User for this purpose)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;▶️ Run&lt;/p&gt;&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%2Fainli13x389z5nz0bmv6.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%2Fainli13x389z5nz0bmv6.png" alt="running pipeline" width="800" height="113"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://linkedin.com/in/lesterdprez" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94940866c98cb4fca5783c4e8ac95776d2f52df6bbf3d5ab9e30d76836f30ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d2532333030373742352e7376673f6c6f676f3d6c696e6b6564696e266c6f676f436f6c6f723d7768697465" alt="LinkedIn" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>aws</category>
      <category>python</category>
      <category>devops</category>
    </item>
    <item>
      <title>Ansible: The Swiss Army Knife of Automation</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Fri, 26 Apr 2024 02:11:12 +0000</pubDate>
      <link>https://dev.to/sharker3312/ansible-the-swiss-army-knife-of-automation-5d0c</link>
      <guid>https://dev.to/sharker3312/ansible-the-swiss-army-knife-of-automation-5d0c</guid>
      <description>&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%2Ftaufq48h7ztu34md9fma.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%2Ftaufq48h7ztu34md9fma.png" alt=" " width="512" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📌Prerequisites:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://docs.ansible.com/ansible/latest/installation_guide/installation_distros.html" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;Vscode&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯Workflow
&lt;/h2&gt;

&lt;p&gt;1️⃣What we need to deploy the application❓&lt;br&gt;
2️⃣Structure of the Project👷&lt;br&gt;
3️⃣File Descriptions📂&lt;br&gt;
4️⃣Playbook✏&lt;br&gt;
5️⃣Check connectivity🌐 &amp;amp; Install Docker🐳&lt;br&gt;
6️⃣Run docker app🚀&lt;/p&gt;


&lt;h2&gt;
  
  
  1️⃣What we need to deploy the application❓
&lt;/h2&gt;

&lt;p&gt;Well, as the application is dockerized, the only thing we have to do is to &lt;strong&gt;install docker&lt;/strong&gt; in the ec2 instance.&lt;/p&gt;
&lt;h2&gt;
  
  
  2️⃣Structure of the Project👷
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible/
│
├── ansible.cfg
├── inventory.ini
│
├── key/
│   └── ec2_key.pem
│  
├── playbooks/
│   └── install_docker.yml
│   └── run_image.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;ansible.cfg&lt;/em&gt;📋 : &lt;em&gt;Defines the global configuration for running Ansible tasks in an environment.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;inventary.ini📋: Define the list of hosts on which Ansible tasks will run. This file can contain groups of hosts and variables associated with those groups or individual hosts.&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;/key/ec2_key.pem : This file will only be available on our localhost and contains the ssh key. Later I will add it as an environment variable.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;/playbooks/install_docker📋 : This file contain all the tasks to execute the docker installation&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  3️⃣File Descriptions📂
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;ansible.cfg&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;defaults]
inventory &lt;span class="o"&gt;=&lt;/span&gt; inventory.ini
host_key_checking &lt;span class="o"&gt;=&lt;/span&gt; False  &lt;span class="c"&gt;# optional: removes the SSH prompt &lt;/span&gt;
&lt;span class="nv"&gt;deprecation_warnings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False  &lt;span class="c"&gt;# optional: removes deprecation warning in playbooks&lt;/span&gt;
remote_user &lt;span class="o"&gt;=&lt;/span&gt; ubuntu
&lt;span class="c"&gt;#private_key_file = ./key/ec2_key.pem&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;inventory.ini&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;all]
node &lt;span class="nv"&gt;ansible_host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;x.x.x.x &lt;span class="nv"&gt;ansible_user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ubuntu &lt;span class="nv"&gt;ansible_ssh_private_key_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./key/ec2_key.pem 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;key/ec2_key.pem&lt;br&gt;
 alerta bla blA&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4️⃣Playbook✏
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;playbooks/install_docker.yml&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&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 docker&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="kc"&gt;true&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 docker dependencies&lt;/span&gt;
      &lt;span class="na"&gt;ansible.builtin.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="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt-transport-https&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ca-certificates&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;curl&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gnupg-agent&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;software-properties-common&lt;/span&gt;
        &lt;span class="na"&gt;update_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;Add docker gpg key&lt;/span&gt;
      &lt;span class="na"&gt;ansible.builtin.apt_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://download.docker.com/linux/ubuntu/gpg&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="na"&gt;keyring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/apt/keyrings/docker.gpg&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;Add docker repository&lt;/span&gt;
      &lt;span class="na"&gt;ansible.builtin.apt_repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker&lt;/span&gt;
        &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ansible_lsb.codename | lower }} stable&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;Install docker engine&lt;/span&gt;
      &lt;span class="na"&gt;ansible.builtin.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="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker-ce&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker-ce-cli&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;containerd.io&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker-buildx-plugin&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker-scan-plugin&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker-compose-plugin&lt;/span&gt;
        &lt;span class="na"&gt;update_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;Add user permissions&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;usermod&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-aG&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;docker&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ubuntu"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5️⃣Check connectivity🌐
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ansible -i inventory.ini -m ping all&lt;/code&gt;&lt;/p&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%2F1bkbf4p6u4ntpp8j7vpl.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%2F1bkbf4p6u4ntpp8j7vpl.png" alt=" " width="800" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, install docker🐳 on the host&lt;br&gt;
&lt;code&gt;ansible-playbook -i inventory.ini playbooks/install_docker.yml&lt;/code&gt;&lt;br&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%2F7eylj7zyuonftap3tnjw.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%2F7eylj7zyuonftap3tnjw.png" alt=" " width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  6️⃣Run docker app🚀
&lt;/h2&gt;

&lt;p&gt;This is the playbook to pull and run the docker image&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="nt"&gt;---&lt;/span&gt;
- name: Download and run sharker3312/nodeapp:latest
  hosts: all
  become: &lt;span class="nb"&gt;true

  &lt;/span&gt;tasks:
    - name: Download Docker image
      ansible.builtin.docker_image:
        name: sharker3312/nodeapp:latest
        &lt;span class="nb"&gt;source&lt;/span&gt;: pull

    - name: Run Docker container
      ansible.builtin.docker_container:
        name: nodeapp
        image: sharker3312/nodeapp:latest
        state: started
        detach: &lt;span class="nb"&gt;yes
        &lt;/span&gt;ports:
          - &lt;span class="s2"&gt;"8000:8000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ansible-playbook -i inventory.ini playbooks/run_image.yml&lt;/code&gt;&lt;/p&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%2F48h3ivorbu0lulftwhdt.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%2F48h3ivorbu0lulftwhdt.png" alt=" " width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The web site: &lt;/p&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%2Fzf3r1ng6fm78ccuxapfs.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%2Fzf3r1ng6fm78ccuxapfs.png" alt=" " width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The purpose of using anisble software is to fully automate daily tasks. In this blog we observed how without having an interactive shell on the EC2 instance we were able to deploy a docker image.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://linkedin.com/in/lesterdprez" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94940866c98cb4fca5783c4e8ac95776d2f52df6bbf3d5ab9e30d76836f30ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d2532333030373742352e7376673f6c6f676f3d6c696e6b6564696e266c6f676f436f6c6f723d7768697465" alt="LinkedIn" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ansible</category>
      <category>aws</category>
      <category>docker</category>
    </item>
    <item>
      <title>Working Less, Automating More: Simplifying AWS Management with Terraform and GitHub Actions</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Sat, 13 Apr 2024 02:39:45 +0000</pubDate>
      <link>https://dev.to/sharker3312/automating-aws-with-terraform-i9p</link>
      <guid>https://dev.to/sharker3312/automating-aws-with-terraform-i9p</guid>
      <description>&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%2Fjl16no7t3h0xcfeoexos.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%2Fjl16no7t3h0xcfeoexos.png" alt=" " width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📌Prerequisites:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AWS &lt;a href="https://aws.amazon.com/free/" rel="noopener noreferrer"&gt;account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;VsCode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯Workflow
&lt;/h2&gt;

&lt;p&gt;1️⃣Create IAM user👤&lt;br&gt;
2️⃣Save🔒 Acces &amp;amp; Secret &lt;br&gt;
3️⃣Key Pair for ssh🔑&lt;br&gt;
4️⃣Terraform Pipeline📝&lt;br&gt;
5️⃣Job from Github Actions📝&lt;/p&gt;


&lt;h3&gt;
  
  
  1️⃣Create IAM user👤
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Login AWS &lt;/li&gt;
&lt;li&gt;IAM -&amp;gt; Users -&amp;gt; &lt;strong&gt;Create user&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Name of user whatever as you wish&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;Attach policies directly&lt;/strong&gt; -&amp;gt; Select &lt;strong&gt;AmazonEC2FullAccess&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;It's not❌ the best practice, but it's simple for this purpose&lt;/em&gt;&lt;/p&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%2Fatgiy0pu90wa8if2bnfu.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%2Fatgiy0pu90wa8if2bnfu.png" alt=" " width="187" height="41"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;User created successfully✅&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Create Credentials&lt;/u&gt;&lt;/p&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%2F10te4wc0g83rzvsjzcrr.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%2F10te4wc0g83rzvsjzcrr.png" alt=" " width="592" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create Access Key&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Third-party service&lt;/strong&gt;
&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%2Fh1ludf49956vflp0n2ym.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%2Fh1ludf49956vflp0n2ym.png" alt=" " width="460" height="84"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2️⃣Save🔒 Acces &amp;amp; Secret
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to Github repository&lt;/li&gt;
&lt;li&gt;Settings -&amp;gt; Secrets &amp;amp; Variables -&amp;gt; Actions&lt;/li&gt;
&lt;li&gt;Save as a &lt;strong&gt;Secret&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; &lt;code&gt;TF_USER_AWS_SECRET&lt;/code&gt;&lt;br&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%2Fnmyzqchfyvpes0v105s3.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%2Fnmyzqchfyvpes0v105s3.png" alt=" " width="692" height="89"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3️⃣Create Key Pair for ssh
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Just go here and name it.Is simple&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The key will download⬇ automatically&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&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%2F5vezsj0239fpafayvd36.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%2F5vezsj0239fpafayvd36.png" alt=" " width="800" height="117"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  4️⃣Terraform Pipeline📝
&lt;/h3&gt;

&lt;p&gt;Create a new directory in the root &lt;a href="https://github.com/Sharker3312/Node-App" rel="noopener noreferrer"&gt;project&lt;/a&gt;&lt;br&gt;
🔰Name: terraform&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is a very simple pipeline. Remember this is a tutorial. I will soon make📍 a Terraform series.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;provider "aws" {&lt;/span&gt;
  &lt;span class="s"&gt;region = "us-east-2"&lt;/span&gt; &lt;span class="c1"&gt;#Region as you wish&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="s"&gt;resource "aws_instance" "nodeapp" {&lt;/span&gt;
  &lt;span class="s"&gt;ami           = "ami-00cda30cf72311684"&lt;/span&gt; &lt;span class="c1"&gt;#Check the AMI list for free tier&lt;/span&gt;
  &lt;span class="s"&gt;instance_type = "t2.micro"&lt;/span&gt; &lt;span class="c1"&gt;#Well... very intuitive -_-&lt;/span&gt;
  &lt;span class="s"&gt;key_name = "ec2_key"&lt;/span&gt; &lt;span class="c1"&gt;#Name of key pair created in step 3&lt;/span&gt;
  &lt;span class="s"&gt;vpc_security_group_ids = [aws_security_group.nodeapp.id]&lt;/span&gt; &lt;span class="c1"&gt;# ID security group&lt;/span&gt;


  &lt;span class="s"&gt;tags = {&lt;/span&gt;
    &lt;span class="s"&gt;Name = "Nodeapp"&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#Security Group&lt;/span&gt;
&lt;span class="s"&gt;resource "aws_security_group" "nodeapp" {&lt;/span&gt;
  &lt;span class="s"&gt;name        = "ec2_ecurity-group"&lt;/span&gt; &lt;span class="c1"&gt;#Whatever name&lt;/span&gt;
  &lt;span class="s"&gt;description = "Allow inbound traffic on port 8080 and SSH"&lt;/span&gt; &lt;span class="c1"&gt;#The app expose port  8080&lt;/span&gt;




  &lt;span class="s"&gt;ingress {&lt;/span&gt;
    &lt;span class="s"&gt;from_port   = &lt;/span&gt;&lt;span class="m"&gt;22&lt;/span&gt;
    &lt;span class="s"&gt;to_port     = &lt;/span&gt;&lt;span class="m"&gt;22&lt;/span&gt;
    &lt;span class="s"&gt;protocol    = "tcp"&lt;/span&gt;
    &lt;span class="s"&gt;cidr_blocks = ["0.0.0.0/0"]&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;

  &lt;span class="s"&gt;ingress {&lt;/span&gt;
    &lt;span class="s"&gt;from_port   = &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;
    &lt;span class="s"&gt;to_port     = &lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;
    &lt;span class="s"&gt;protocol    = "tcp"&lt;/span&gt;
    &lt;span class="s"&gt;cidr_blocks = ["0.0.0.0/0"]&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5️⃣Job from Github Actions📝
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;name: Deploy Node app 

on:
  push:
    branches:
      - master

&lt;span class="nb"&gt;jobs&lt;/span&gt;:
  tf-aws:
    name: Deploy Node app to AWS
    runs-on: ubuntu-latest

    defaults:
      run:
        working-directory: terraform &lt;span class="c"&gt;#Path directory&lt;/span&gt;

    steps:

      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.AWS_ACCESS_KEY_ID &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          aws-secret-access-key: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.AWS_SECRET_ACCESS_KEY &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          aws-region: us-east-2

      - name: Setup Terraform CLI
        uses: hashicorp/setup-terraform@v3

      - name: Terraform Init
        run: terraform init

      - name: Terraform Validate
        run: terraform validate

      - name: Terraform Plan
        run: terraform plan 

      - name: Terraform Apply
        run: terraform apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🎬 Run the job&lt;/p&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%2Fqr2mw28qe2iforh4dg6t.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%2Fqr2mw28qe2iforh4dg6t.png" alt="job done" width="566" height="167"&gt;&lt;/a&gt;&lt;br&gt;
✅&lt;/p&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%2Fipj6aoheimiz0ksb8cd2.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%2Fipj6aoheimiz0ksb8cd2.png" alt="ec2_nodeapp" width="800" height="148"&gt;&lt;/a&gt;&lt;/p&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%2Fi0wj8xm7yaoi3d93adzj.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%2Fi0wj8xm7yaoi3d93adzj.png" alt="security group" width="800" height="172"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://linkedin.com/in/lesterdprez" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94940866c98cb4fca5783c4e8ac95776d2f52df6bbf3d5ab9e30d76836f30ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d2532333030373742352e7376673f6c6f676f3d6c696e6b6564696e266c6f676f436f6c6f723d7768697465" alt="LinkedIn" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>github</category>
      <category>aws</category>
      <category>terraform</category>
    </item>
    <item>
      <title>Integrating a CodeQuality Scanner into Github Actions</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Tue, 02 Apr 2024 20:41:21 +0000</pubDate>
      <link>https://dev.to/sharker3312/integrating-a-codequality-scanner-into-github-actions-52e7</link>
      <guid>https://dev.to/sharker3312/integrating-a-codequality-scanner-into-github-actions-52e7</guid>
      <description>&lt;h2&gt;
  
  
  🎯Workflow
&lt;/h2&gt;

&lt;p&gt;1️⃣Search🔍 the CodeQuality scanner tool&lt;br&gt;
2️⃣Hands On✍&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣Search🔍 the CodeQuality scanner tool
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;As always Let's go to the 🛒&lt;a href="https://github.com/marketplace" rel="noopener noreferrer"&gt;marketplace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Looking for a Codequality scanner🐞&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%2F13gufggm6lji7mh2rb8p.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%2F13gufggm6lji7mh2rb8p.png" alt=" " width="266" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Well, the &lt;strong&gt;SonarCloud&lt;/strong&gt; is very used&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%2Fxicrg964ojjuh3boeopa.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%2Fxicrg964ojjuh3boeopa.png" alt=" " width="361" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣Hands On✍
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Select SonarCloud and complete✅ the process&lt;/li&gt;
&lt;li&gt;Just select the current repository in which you are working&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%2F2pfsjllehtfdhxq2y4x4.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%2F2pfsjllehtfdhxq2y4x4.png" alt=" " width="411" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You will be redirected to login📌 of the web SonarCloud(Just continue with your github account)&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%2Fi0v26jt057j7vp8uuq2f.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%2Fi0v26jt057j7vp8uuq2f.png" alt=" " width="367" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create Organization👥&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2️⃣Hands On✍
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Inside the web ,get the SONAR_TOKEN&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%2F9iihbi2vsr2qzc3mopn3.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%2F9iihbi2vsr2qzc3mopn3.png" alt=" " width="713" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✏Save the SONAR_TOKEN as a secret in the repository&lt;/li&gt;
&lt;li&gt;Create this file🗒 at the root directory
&amp;gt;sonar-project.properties
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sonar.projectKey=sharker_sharker
sonar.organization=sharker
sonar.host.url=https://sonarcloud.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add ➕ this job to the Workflow
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; sonarcloud:
    name: SonarCloud
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0  &lt;span class="c"&gt;# Shallow clones should be disabled for a better relevancy of analysis&lt;/span&gt;
      - name: SonarCloud Scan
        uses: SonarSource/sonarcloud-github-action@master
        &lt;span class="nb"&gt;env&lt;/span&gt;:
          &lt;span class="c"&gt;# This Token is automatically generated by Github&lt;/span&gt;
          GITHUB_TOKEN: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.GITHUB_TOKEN &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;  &lt;span class="c"&gt;# Needed to get PR information, if any&lt;/span&gt;
          SONAR_TOKEN: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.SONAR_TOKEN &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎬Run The Action&lt;/p&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%2Flaioqet8ds5fig14rwzh.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%2Flaioqet8ds5fig14rwzh.png" alt=" " width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done 🚀&lt;/p&gt;




&lt;p&gt;&lt;a href="https://linkedin.com/in/lesterdprez" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94940866c98cb4fca5783c4e8ac95776d2f52df6bbf3d5ab9e30d76836f30ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d2532333030373742352e7376673f6c6f676f3d6c696e6b6564696e266c6f676f436f6c6f723d7768697465" alt="LinkedIn" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>codequality</category>
      <category>github</category>
      <category>devops</category>
    </item>
    <item>
      <title>Add Slack notifications into Github Actions</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Tue, 02 Apr 2024 20:39:02 +0000</pubDate>
      <link>https://dev.to/sharker3312/add-slack-notifications-into-github-actions-486p</link>
      <guid>https://dev.to/sharker3312/add-slack-notifications-into-github-actions-486p</guid>
      <description>&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%2F7072pp6013k50wzjz4fp.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%2F7072pp6013k50wzjz4fp.png" alt=" " width="267" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯Workflow
&lt;/h2&gt;

&lt;p&gt;1️⃣Search🔍 the Slack-Notifications in the marketplace🛒&lt;br&gt;
2️⃣Configure📋 the Webhook&lt;br&gt;
3️⃣Configure📋 the Job&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣Search🔍 the Slack-Notifications in the marketplace🛒
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to github action &lt;a href="https://github.com/marketplace" rel="noopener noreferrer"&gt;marketplace&lt;/a&gt;
&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%2F89kzampatl3iyy3q427y.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%2F89kzampatl3iyy3q427y.png" alt=" " width="725" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select Slack-Notify🔔&lt;/li&gt;
&lt;li&gt;Read📖 the doc&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2️⃣ Configure 📋 the Webhook
&lt;/h3&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%2Fjh6o6xtw8e1jse3tm4ls.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%2Fjh6o6xtw8e1jse3tm4ls.png" alt=" " width="217" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;For communication between Slack and Github we need a &lt;strong&gt;Slack webhook&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login in Slack&lt;/li&gt;
&lt;li&gt;Enter here to add the &lt;a href="https://api.slack.com/incoming-webhooks" rel="noopener noreferrer"&gt;incoming webhook&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You will be asked❓ to enter your team URL&lt;/li&gt;
&lt;li&gt;Select the channel📱 to which you want to post&lt;/li&gt;
&lt;li&gt;Save the URL generated as a &lt;strong&gt;Webhook&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3️⃣Configure📋 the Job
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add ➕ a Slack Notification Job to the &lt;a href="https://github.com/Sharker3312/Node-App/blob/master/.github/workflows/node.js.yml" rel="noopener noreferrer"&gt;pipeline&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; Slack-Notify:
    runs-on: ubuntu-latest
    &lt;span class="c"&gt;#Wait for test job ending&lt;/span&gt;
    needs: &lt;span class="nb"&gt;test&lt;/span&gt;
    &lt;span class="c"&gt;#If the test job is wrong, this job will still be executed &lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;:  always&lt;span class="o"&gt;()&lt;/span&gt;
    steps:
    - uses: actions/checkout@v2
    - name: Slack Notification
      uses: rtCamp/action-slack-notify@v2
      &lt;span class="nb"&gt;env&lt;/span&gt;:
        &lt;span class="c"&gt;#Settings-&amp;gt;Secrets &amp;amp; Variables-&amp;gt;Actions-&amp;gt;New Secret&lt;/span&gt;
        &lt;span class="c"&gt;#Paste here your secret webhook &lt;/span&gt;
        SLACK_WEBHOOK: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.SLACK_WEBHOOK &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="c"&gt;# The variable needs.test.result print the result of the test job &lt;/span&gt;
        SLACK_COLOR: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ needs.test.result &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
        SLACK_CHANNEL: general
        SLACK_USERNAME: &lt;span class="s1"&gt;'Node-Bot'&lt;/span&gt;
        SLACK_TITLE: Workflow &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ needs.test.result &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
        SLACK_MESSAGE_ON_SUCCESS: &lt;span class="s1"&gt;'✅'&lt;/span&gt;
        SLACK_MESSAGE_ON_FAILURE: &lt;span class="s1"&gt;'❌'&lt;/span&gt;
        SLACK_FOOTER: By Sharker3312


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

&lt;/div&gt;



&lt;p&gt;🚨🚨🚨:&lt;em&gt;It is likely that you only want to send notifications when an error occurs, in this case just substitute this line&lt;/em&gt;&lt;br&gt;
&lt;code&gt;if: ${{ always() &amp;amp;&amp;amp; (needs.failing-job.result == 'failure' || needs.failing-job.result == 'timed_out') }}&lt;/code&gt;&lt;/p&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%2F7qyhblpdiju4m4ijwk17.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%2F7qyhblpdiju4m4ijwk17.png" alt=" " width="441" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done✅🚀&lt;/p&gt;




&lt;p&gt;&lt;a href="https://linkedin.com/in/lesterdprez" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94940866c98cb4fca5783c4e8ac95776d2f52df6bbf3d5ab9e30d76836f30ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d2532333030373742352e7376673f6c6f676f3d6c696e6b6564696e266c6f676f436f6c6f723d7768697465" alt="LinkedIn" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>devops</category>
      <category>github</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Leveraging GitHub Actions, Docker, Code Quality, and Slack Integration</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Mon, 01 Apr 2024 03:53:30 +0000</pubDate>
      <link>https://dev.to/sharker3312/leveraging-github-actions-docker-code-quality-and-slack-integration-501g</link>
      <guid>https://dev.to/sharker3312/leveraging-github-actions-docker-code-quality-and-slack-integration-501g</guid>
      <description>&lt;p&gt;&lt;strong&gt;📌Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Dockerhub account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Web repository for dockerize&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The web repository could be any of you wish&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🎯Workflow
&lt;/h2&gt;

&lt;p&gt;1️⃣Build🧱 &amp;amp; Test🧪 &lt;br&gt;
2️⃣Dockerize🐳 the web project&lt;br&gt;
3️⃣Upload💹 image to your docker hub account&lt;/p&gt;


&lt;h2&gt;
  
  
  1️⃣Build🧱 &amp;amp; Test🧪
&lt;/h2&gt;

&lt;p&gt;Why do what others have already done?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Github Actions has a marketplace where you can find🔎 any pipeline that any other developer has developed.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Writing✏ the pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inside repo -&amp;gt; Click in &lt;strong&gt;Actions&lt;/strong&gt;
&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%2Ffph6szm4dyh79mb9b37r.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%2Ffph6szm4dyh79mb9b37r.png" alt=" " width="763" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create the workflow -&amp;gt; Enter &lt;strong&gt;New workflow&lt;/strong&gt;&lt;br&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%2Flyc563l7v5tiyf8yy0f5.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%2Flyc563l7v5tiyf8yy0f5.png" alt=" " width="320" height="195"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for a NodeJs pipeline&lt;/p&gt;&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%2F9haxwuf6dwpazhhgyemq.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%2F9haxwuf6dwpazhhgyemq.png" alt=" " width="294" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adjust the pipeline to your needs
An example of my &lt;a href="https://github.com/Sharker3312/Node-App/actions/runs/8445740088/workflow" rel="noopener noreferrer"&gt;pipeline &lt;/a&gt;stages&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%2Fjnve0nb5tchopev8szhx.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%2Fjnve0nb5tchopev8szhx.png" alt=" " width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2️⃣Dockerize🐳 the web project
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;So, if you want to contain the application, you just have to write a dockerfile&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🚨 Packing the NodeJs project&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;em&gt;dockerfile.ci&lt;/em&gt;  at the root project directory
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM node:18-alpine
WORKDIR /usr/src/app

COPY package.json package-lock.json ./
COPY app.js ./
COPY views ./views/

RUN npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="c"&gt;#web port&lt;/span&gt;
EXPOSE 8000
CMD &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;, &lt;span class="s2"&gt;"app.js"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  3️⃣Upload💹 image to your docker hub account
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go to github &lt;a href="https://github.com/marketplace" rel="noopener noreferrer"&gt;marketplace&lt;/a&gt;🛒&lt;/li&gt;
&lt;li&gt;Looking for build and push dockerhub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I like this pipeline&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="c"&gt;#Name of Job&lt;/span&gt;
 to_dockerhub:
    runs-on: ubuntu-latest
    &lt;span class="c"&gt;#Wait for ending test process&lt;/span&gt;
    needs: &lt;span class="nb"&gt;test

    &lt;/span&gt;steps:

    - uses: actions/checkout@v3
      name: Check out code

    - uses: mr-smithers-excellent/docker-build-push@v6
      name: Build &amp;amp; push Docker image
      with:
        &lt;span class="c"&gt;#Name's dockerhub / Name as you want&lt;/span&gt;
        image: sharker3312/nodeapp
        tags: v1, latest
        registry: docker.io
        dockerfile: Dockerfile
        username: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.DOCKER_USERNAME &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
        password: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.DOCKER_PASSWORD &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create the secret for login&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to Settings&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%2Fz54j9j18hhh2abh49g6h.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%2Fz54j9j18hhh2abh49g6h.png" alt=" " width="781" height="52"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In left panel Click &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets and Variables&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Actions&lt;/strong&gt;
&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%2F4yw4u45qctdtjnw72l1l.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%2F4yw4u45qctdtjnw72l1l.png" alt=" " width="331" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter the secrets&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%2Fznmhirglzykbjo18an9h.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%2Fznmhirglzykbjo18an9h.png" alt=" " width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🎬Run the workflow&lt;/p&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%2Fjwwd7xmy5o40topbv1gj.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%2Fjwwd7xmy5o40topbv1gj.png" alt=" " width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🔦Check the dockerhub repository&lt;/p&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%2Fo7meqqs2z7lwdkqtpqjt.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%2Fo7meqqs2z7lwdkqtpqjt.png" alt=" " width="693" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done✅🚀&lt;/p&gt;




&lt;p&gt;&lt;a href="https://linkedin.com/in/lesterdprez" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94940866c98cb4fca5783c4e8ac95776d2f52df6bbf3d5ab9e30d76836f30ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d2532333030373742352e7376673f6c6f676f3d6c696e6b6564696e266c6f676f436f6c6f723d7768697465" alt="LinkedIn" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tutorial</category>
      <category>docker</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Manual Approval and Telegram Notifications in Jenkins</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Mon, 11 Mar 2024 01:43:08 +0000</pubDate>
      <link>https://dev.to/sharker3312/manual-approval-and-telegram-notifications-in-jenkins-1l7a</link>
      <guid>https://dev.to/sharker3312/manual-approval-and-telegram-notifications-in-jenkins-1l7a</guid>
      <description>&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%2Fm39s07p2q1ihbha75flz.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%2Fm39s07p2q1ihbha75flz.png" alt=" " width="707" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use a manual approval step in the deploy code?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Manual approval in Jenkins provides a mechanism to ensure quality, security and compliance in software development and deployment processes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Manual approval&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add this stage to the pipeline
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Approval'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        steps &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nb"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;: 15, unit: &lt;span class="s2"&gt;"MINUTES"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        input message: &lt;span class="s1"&gt;'Do you want to approve the deployment?'&lt;/span&gt;, ok: &lt;span class="s1"&gt;'Yes'&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;

                    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Initiating 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;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%2Fx0awadb72xwbig89urew.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%2Fx0awadb72xwbig89urew.png" alt=" " width="260" height="86"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Telegram Notifications
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To send notifications we need two things&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;First&lt;/strong&gt;: HTTP_API of bot&lt;br&gt;
&lt;strong&gt;Second&lt;/strong&gt;: CHAT_ID&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;HTTP_API of bot&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create telegram bot&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;BotFather in Telegram (&lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Send /newbot command&lt;/li&gt;
&lt;li&gt;Enter bot name and bot username&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;u&gt;token-http-api&lt;/u&gt;&lt;/p&gt;
&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%2Fb3berv927qnf987ggm45.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%2Fb3berv927qnf987ggm45.png" alt=" " width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;CHAT_ID&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
    1. Go to @myidbot &lt;br&gt;
    2. Enter: /start -&amp;gt; /getid&lt;br&gt;
    3. Save your chat_ID&lt;/p&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%2F9qugr3zi80agdi7k9c9j.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%2F9qugr3zi80agdi7k9c9j.png" alt=" " width="329" height="552"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Creating Jenkins Global Credentials
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Manage Jenkins&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Credentials&lt;/strong&gt; -&amp;gt; &lt;strong&gt;System&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Global credentials (unrestricted)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Add Crediantials(CHAT_ID &amp;amp; TELEGRAM_API)&lt;/li&gt;
&lt;/ol&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%2Fih5pvksqgy6o2thho82j.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%2Fih5pvksqgy6o2thho82j.png" alt=" " width="800" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configurig pipeline&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;_At the top of the &lt;a href="https://github.com/Sharker3312/Node-App/blob/master/Jenkinsfile" rel="noopener noreferrer"&gt;pipeline&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;environment &lt;span class="o"&gt;{&lt;/span&gt;
        // Telegram configuration
        TOKEN &lt;span class="o"&gt;=&lt;/span&gt; credentials&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'telegram-api'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        CHAT_ID &lt;span class="o"&gt;=&lt;/span&gt; credentials&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'telegram_chatid'&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;blockquote&gt;
&lt;p&gt;&lt;em&gt;Declare two variables which contain the tokens&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; post &lt;span class="o"&gt;{&lt;/span&gt;
        success &lt;span class="o"&gt;{&lt;/span&gt;
            script &lt;span class="o"&gt;{&lt;/span&gt;
                sh &lt;span class="s2"&gt;"curl -X POST -H 'Content-Type: application/json' -d '{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;chat_id&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CHAT_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;JOB_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: #&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BUILD_NUMBER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;✅ Deploy succeeded! &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;disable_notification&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: false}' &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;https://api.telegram.org/bot&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/sendMessage&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        failure &lt;span class="o"&gt;{&lt;/span&gt;
            script &lt;span class="o"&gt;{&lt;/span&gt;
                sh &lt;span class="s2"&gt;"curl -X POST -H 'Content-Type: application/json' -d '{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;chat_id&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CHAT_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;JOB_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: #&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BUILD_NUMBER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;❌Deploy failure!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;disable_notification&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: false}' &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;https://api.telegram.org/bot&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/sendMessage&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

       aborted &lt;span class="o"&gt;{&lt;/span&gt;
            script &lt;span class="o"&gt;{&lt;/span&gt;
                sh &lt;span class="s2"&gt;"curl -X POST -H 'Content-Type: application/json' -d '{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;chat_id&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CHAT_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;JOB_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: #&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BUILD_NUMBER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;❌Deploy aborted!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;disable_notification&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: false}' &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;https://api.telegram.org/bot&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/sendMessage&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&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;&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%2Flbdku9p3yglchktuwwcy.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%2Flbdku9p3yglchktuwwcy.png" alt=" " width="192" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope helpful!!  &lt;/p&gt;




&lt;p&gt;&lt;a href="https://linkedin.com/in/lesterdprez" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94940866c98cb4fca5783c4e8ac95776d2f52df6bbf3d5ab9e30d76836f30ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d2532333030373742352e7376673f6c6f676f3d6c696e6b6564696e266c6f676f436f6c6f723d7768697465" alt="LinkedIn" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>cloud</category>
      <category>devops</category>
      <category>jenkins</category>
    </item>
    <item>
      <title>Integrating SonarQube into Your CI/CD Pipeline: Elevating Code Quality and Security</title>
      <dc:creator>Lester Diaz Perez</dc:creator>
      <pubDate>Mon, 26 Feb 2024 01:23:40 +0000</pubDate>
      <link>https://dev.to/sharker3312/integrating-sonarqube-into-your-cicd-pipeline-elevating-code-quality-and-security-4111</link>
      <guid>https://dev.to/sharker3312/integrating-sonarqube-into-your-cicd-pipeline-elevating-code-quality-and-security-4111</guid>
      <description>&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%2Fa32riwzaz5p69monxai5.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%2Fa32riwzaz5p69monxai5.png" alt=" " width="365" height="138"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Adding Sonarqube into our workflow, code and security analysis.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-requisites&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the 1st part&lt;/li&gt;
&lt;li&gt;Ngrok app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For clarification&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I tried to install it on the t2.micro instance but Sonarqube requires 2 gb ram&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&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%2Fcdf7th06el2zc26p85ma.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%2Fcdf7th06el2zc26p85ma.png" alt="Requirementes of Sonarqube" width="705" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;We will install it on our local machine to do everything for free at least in this test environment, but in AWS a t2.medium is recommended (it is not free tier).&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Deploy Sonarqube&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sonarqube &lt;a href="https://github.com/Sharker3312/Devops-Projects/blob/main/CD_pipeline_for_an_app/sonarqube.yml" rel="noopener noreferrer"&gt;compose&lt;/a&gt; file&lt;/li&gt;
&lt;li&gt;cd /path(compose file)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;In sonarqube it is typical to find this error when deploying the container.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&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%2Fhrwatyk5zucz3w4krrgb.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%2Fhrwatyk5zucz3w4krrgb.png" alt=" " width="800" height="14"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The solution is simple paste into the CLI the next code&lt;/em&gt;&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;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; vm.max_map_count&lt;span class="o"&gt;=&lt;/span&gt;262144
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Opening Sonarqube Web -&amp;gt; &lt;em&gt;&lt;a href="http://localhost:9000" rel="noopener noreferrer"&gt;http://localhost:9000&lt;/a&gt;&lt;/em&gt;&lt;/p&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%2Fqf6tphhulsfa5os2slhp.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%2Fqf6tphhulsfa5os2slhp.png" alt=" " width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Well as sonarqube is in our localhost now we will expose it to the internet&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tunneling app to internet through &lt;a href="https://ngrok.com/docs/getting-started/" rel="noopener noreferrer"&gt;Ngrok&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&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%2F72lmlp6rhxjrqcmjiceb.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%2F72lmlp6rhxjrqcmjiceb.png" alt=" " width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Our Sonarqube is now exposed to the internet&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Configure Jenkins to add Sonarqube&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Jenkins&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Manage&lt;/strong&gt; Jenkins -&amp;gt; &lt;strong&gt;Plugins&lt;/strong&gt; -&amp;gt;&lt;strong&gt;Available&lt;/strong&gt; plugins&lt;/li&gt;
&lt;li&gt;Install &lt;strong&gt;SonarQube Scanner&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Now we configure the plugin&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Manage Jenkins -&amp;gt; &lt;strong&gt;System&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Search &lt;strong&gt;SonarQube servers&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Click&lt;/strong&gt; Environment variables&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&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%2F4ev1mzugttmtywjfc8cu.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%2F4ev1mzugttmtywjfc8cu.png" alt=" " width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to SonarQube Web&lt;/li&gt;
&lt;li&gt;Click in &lt;strong&gt;Administration&lt;/strong&gt; bar -&amp;gt; &lt;strong&gt;Security&lt;/strong&gt;-&amp;gt; &lt;strong&gt;Users&lt;/strong&gt;
&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%2Fzjilsbpt550owcvcx1eu.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%2Fzjilsbpt550owcvcx1eu.png" alt=" " width="800" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click Token and name it
&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%2Fddlpfqkzq5mhppc2l8hu.png" alt=" " width="800" height="255"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Now copy the token into the jenkins configuration variable&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Press Add&lt;/li&gt;
&lt;li&gt;Kind= Secret text
&lt;em&gt;ID and description name them as you wish&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&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%2Fgly83wk3t4nmqxjd6hqj.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%2Fgly83wk3t4nmqxjd6hqj.png" alt=" " width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change Server authentication token&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%2Flud6kjr60ec45bazy7lh.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%2Flud6kjr60ec45bazy7lh.png" alt=" " width="634" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  CodeQuality Stage
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Take a look to the pipeline &lt;a href="https://github.com/Sharker3312/sonar-test" rel="noopener noreferrer"&gt;project&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&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%2Fx60ey2o15bgum5rgtq1m.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%2Fx60ey2o15bgum5rgtq1m.png" alt=" " width="409" height="336"&gt;&lt;/a&gt;&lt;br&gt;
&lt;u&gt;tools: maven 3.9.6&lt;/u&gt;&lt;br&gt;
Go to &lt;strong&gt;Manage Jenkins&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Tools&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Maven&lt;/strong&gt;&lt;/p&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%2Fqbsn2wu5kzf876zt3xfi.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%2Fqbsn2wu5kzf876zt3xfi.png" alt=" " width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ready to run the job&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build the job&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;New Item&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Pipeline&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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%2Fr06jgrlvzph8n9j8lih0.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%2Fr06jgrlvzph8n9j8lih0.png" alt=" " width="800" height="359"&gt;&lt;/a&gt;&lt;br&gt;
&lt;u&gt;Check the correct branch&lt;/u&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;run&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&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%2Fdc7uv4o1ph2awkr9cyj5.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%2Fdc7uv4o1ph2awkr9cyj5.png" alt=" " width="161" height="19"&gt;&lt;/a&gt;&lt;/p&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%2F2fyzo0ozgk5ckt90wtxt.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%2F2fyzo0ozgk5ckt90wtxt.png" alt=" " width="408" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pulsa sobre el icono de sonarqube en la web, y haz click en el proyecto demo&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%2Fjlxzi71t9ym9c8xfnr40.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%2Fjlxzi71t9ym9c8xfnr40.png" alt=" " width="537" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quality Gate&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What is a quality gate for?&lt;/em&gt; &lt;br&gt;
This function is used to wait for a certain time until the code analysis is completed&lt;br&gt;
It's simple to use, just add the next code to the &lt;strong&gt;pipeline&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;stage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Quality Gate"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      steps &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;: 2, unit: &lt;span class="s1"&gt;'MINUTES'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          waitForQualityGate abortPipeline: &lt;span class="nb"&gt;true&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;&lt;a href="https://linkedin.com/in/lesterdprez" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d94940866c98cb4fca5783c4e8ac95776d2f52df6bbf3d5ab9e30d76836f30ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c696e6b6564496e2d2532333030373742352e7376673f6c6f676f3d6c696e6b6564696e266c6f676f436f6c6f723d7768697465" alt="LinkedIn" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>codequality</category>
      <category>tutorial</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
