<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Shivam Mahajan's blog]]></title><description><![CDATA[Thanks for stopping by, and I hope you enjoy reading my blog! If you have any questions or feedback, feel free to reach out to me.]]></description><link>https://shivammahajan.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 21 Jun 2026 15:09:47 GMT</lastBuildDate><atom:link href="https://shivammahajan.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Add and Manage Multiple GKE Clusters with ArgoCD]]></title><description><![CDATA[ArgoCD is a powerful Continuous Delivery (CD) tool that simplifies the deployment and management of applications in Kubernetes clusters. It allows users to define the desired state of their applications in Git repositories and automatically ensures t...]]></description><link>https://shivammahajan.hashnode.dev/add-and-manage-multiple-gke-clusters-with-argocd</link><guid isPermaLink="true">https://shivammahajan.hashnode.dev/add-and-manage-multiple-gke-clusters-with-argocd</guid><category><![CDATA[ArgoCD]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[Devops]]></category><category><![CDATA[gitops]]></category><category><![CDATA[How to Add and Manage Multiple GKE Clusters with ArgoCD]]></category><dc:creator><![CDATA[Shivam Mahajan]]></dc:creator><pubDate>Mon, 31 Jul 2023 09:12:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1690794574658/1babe35c-21e1-476b-81ab-187be34b048e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>ArgoCD is a powerful Continuous Delivery (CD) tool that simplifies the deployment and management of applications in Kubernetes clusters. It allows users to define the desired state of their applications in Git repositories and automatically ensures that the clusters match that state. One of the key features of ArgoCD is its ability to manage applications across multiple Kubernetes clusters from a single ArgoCD instance. In this blog, we will explore the step-by-step process of adding multiple Kubernetes clusters to ArgoCD.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>Before proceeding, make sure you have the following prerequisites in place</p>
<ol>
<li><p>A running ArgoCD server</p>
</li>
<li><p>Kubernetes clusters that you want to connect to ArgoCD</p>
</li>
</ol>
<h3 id="heading-how-to-setup-argocd-and-connect-to-private-github-repo">How to setup ArgoCD and connect to private github repo</h3>
<p>In my previous blog I have covered this topic for setup ArgoCD and connect to private github repo you will also get their sample code to perform this blogs tutorial that is important please do checkout before this blog</p>
<p><a target="_blank" href="https://shivammahajan.hashnode.dev/part-1-setting-up-cicd-using-github-actions-sonarcloud-and-argocd-on-google-kubernetes-engine">Part-1: Setting Up CI/CD using GitHub Actions, SonarCloud, and ArgoCD on Google Kubernetes Engine</a></p>
<h3 id="heading-gke-clusters-set-up">GKE Clusters Set-Up</h3>
<ol>
<li>Create 2 gke clusters ( you can create multiple clusters as per your comfort )</li>
</ol>
<pre><code class="lang-bash">gcloud container clusters create dev --num-nodes=2 --zone=us-central1<span class="hljs-_">-a</span>
gcloud container clusters create prod --num-nodes=1 --zone=us-central1<span class="hljs-_">-a</span>
</code></pre>
<p>Note: Make sure argoCD server should be installed on dev cluster</p>
<ol>
<li>Get config entry in Cloud shell for dev cluster</li>
</ol>
<pre><code class="lang-bash">gcloud container clusters get-credentials dev --zone=us-central1<span class="hljs-_">-a</span>
gcloud container clusters get-credentials prod --zone=us-central1<span class="hljs-_">-a</span>
</code></pre>
<p>dev cluster is the one where we will install argoCD CLI</p>
<h3 id="heading-install-argocd-cli">Install ArgoCD CLI</h3>
<ol>
<li>The ArgoCD CLI (argocd) is a command-line tool that allows you to interact with the ArgoCD server. If you haven't already installed it, download the CLI from the official ArgoCD releases page and ensure it is in your system's PATH.</li>
</ol>
<pre><code class="lang-bash">curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/<span class="hljs-built_in">local</span>/bin/argocd
rm argocd-linux-amd64
</code></pre>
<ol>
<li>Connect to ArgoCD Server To interact with the ArgoCD server, use the <code>argocd login</code> command. Replace <code>&lt;ARGOCD_SERVER_ADDRESS&gt;</code>, <code>&lt;USERNAME&gt;</code>, and <code>&lt;PASSWORD&gt;</code> (or <code>&lt;TOKEN&gt;</code>) with the appropriate values for your ArgoCD instance.</li>
</ol>
<p><code>&lt;ARGOCD_SERVER_ADDRESS&gt;</code> don't include https or http just keep IP only</p>
<pre><code class="lang-bash">argocd login &lt;ARGOCD_SERVER_ADDRESS&gt; --username &lt;USERNAME&gt; --password &lt;PASSWORD&gt;
<span class="hljs-comment"># or use token-based authentication:</span>
<span class="hljs-comment"># argocd login &lt;ARGOCD_SERVER_ADDRESS&gt; --username &lt;USERNAME&gt; --token &lt;TOKEN&gt;</span>
</code></pre>
<ol>
<li>Get context names</li>
</ol>
<pre><code class="lang-bash">kubectl config get-contexts
</code></pre>
<p>copy context name for prod cluster <code>&lt;CLUSTER_CONTEXT_NAME&gt;</code></p>
<ol>
<li>Add Cluster Contexts Use the <code>argocd cluster add</code> command to add Kubernetes cluster as a context to ArgoCD. For example:</li>
</ol>
<pre><code class="lang-bash">argocd cluster add &lt;CLUSTER_CONTEXT_NAME&gt;
</code></pre>
<ol>
<li>Verify Connected Clusters You can verify the clusters connected to ArgoCD using the following command:</li>
</ol>
<pre><code class="lang-bash">argocd cluster list
</code></pre>
<p>This will list all the clusters that are connected to your ArgoCD instance.</p>
<ol>
<li>Open argoCD UI and check under setting &gt;&gt; cluster you will see your second cluster is added but status will be <code>unknown</code> don't worry just deploy app it will show <code>successful</code></li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690553506610/be378da6-8104-40df-895a-54305f3cceed.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Create Applications With the clusters connected, you can now create applications in ArgoCD that deploy resources to specific clusters , and how to create application. I have covered in my previous blog on argocd</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690553652542/d3ea1160-c4ae-4866-8171-1c998b8adbef.png" alt class="image--center mx-auto" /></p>
<p>app in the dev cluster</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690553727771/2833a295-3ff7-4526-850e-122dfb247708.png" alt class="image--center mx-auto" /></p>
<p>app in the prod cluster</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690553753602/8a030c2d-b403-46e9-b117-db25b418fbf9.png" alt class="image--center mx-auto" /></p>
<p>Sync Applications ArgoCD will automatically sync the applications with their respective clusters based on the specified context and Git repository.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>By following these steps, you can easily add multiple Kubernetes clusters to ArgoCD and manage your applications across various clusters from a single ArgoCD instance. ArgoCD's ability to handle multiple clusters simplifies the process of deploying applications in complex multi-cluster environments. Embrace the power of ArgoCD to streamline your application deployments and manage your Kubernetes clusters efficiently. Happy deploying!</p>
]]></content:encoded></item><item><title><![CDATA[Part-2: Building CI/CD using GitHub Actions, SonarCloud, and ArgoCD on Google Kubernetes Engine]]></title><description><![CDATA[In Part 2 of this series, we'll explore the tools and techniques to streamline your development process and deliver high-quality software with ease. Building a robust CI/CD pipeline can help you automate the deployment process, ensure the quality of ...]]></description><link>https://shivammahajan.hashnode.dev/part-2-building-cicd-using-github-actions-sonarcloud-and-argocd-on-google-kubernetes-engine</link><guid isPermaLink="true">https://shivammahajan.hashnode.dev/part-2-building-cicd-using-github-actions-sonarcloud-and-argocd-on-google-kubernetes-engine</guid><category><![CDATA[CI/CD]]></category><category><![CDATA[GCP]]></category><category><![CDATA[GCP DevOps]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[ArgoCD]]></category><dc:creator><![CDATA[Shivam Mahajan]]></dc:creator><pubDate>Wed, 19 Apr 2023 10:56:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681568853058/44711501-cbd8-4ea3-b746-f1f835695084.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Part 2 of this series, we'll explore the tools and techniques to streamline your development process and deliver high-quality software with ease. Building a robust CI/CD pipeline can help you automate the deployment process, ensure the quality of your code through code analysis and testing, and achieve faster and more reliable deployments to production.</p>
<p>We'll cover topics such as setting up GitHub Actions workflows for building, testing, and deploying your application, integrating SonarCloud for code quality analysis, and leveraging ArgoCD for automated deployment of your application to Google Kubernetes Engine (GKE).</p>
<p>With this comprehensive guide, you'll be able to optimize your development workflow, ensure code quality, and achieve efficient and reliable deployments to production.</p>
<p>Note: If you haven't checkout part-1 , please check the first <a target="_blank" href="https://shivammahajan.hashnode.dev/part-1-setting-up-cicd-using-github-actions-sonarcloud-and-argocd-on-google-kubernetes-engine">Link</a>.</p>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<ul>
<li><p>Sonarcloud account</p>
</li>
<li><p>GitHub public repositories ( works with Sonarcloud free plan)</p>
</li>
<li><p>Slack (Optional)</p>
</li>
</ul>
<h3 id="heading-why-sonarcloud-and-github-actions">Why SonarCloud and GitHub Actions?</h3>
<p>SonarCloud is a go-to choice for devs when it comes to code analysis and quality management, thanks to its awesome features and support for a bunch of programming languages like Java, JavaScript, C#, C++, Python, and more. It's got some powerful code analysis tools, like detecting code smells, security vulnerabilities, code duplication, and analyzing code coverage, which helps teams spot and fix issues early in the dev process. On the flip side, GitHub Actions is a super handy automation tool that lets devs automate all sorts of tasks, like continuous integration (CI), continuous delivery (CD), and code quality checks, right within their GitHub repos. GitHub Actions offers a flexible and customizable way to automate workflows and create automated pipelines for software development projects.</p>
<p>Combining SonarCloud and GitHub Actions can provide a seamless and automated way to incorporate code quality checks into the software development workflow, enabling developers to catch and fix code issues before they make their way into production.</p>
<p>Setting up SonarCloud and GitHub Actions: Here's a step-by-step guide on how to set up SonarCloud and GitHub Actions for code quality checks in your GitHub repositories:</p>
<h3 id="heading-sonarcloud-setup">Sonarcloud Setup</h3>
<ol>
<li><p>Sign up and configure SonarCloud Sign up for a free account on SonarCloud (<a target="_blank" href="https://sonarcloud.io/"><strong>https://sonarcloud.io/</strong></a>).</p>
</li>
<li><p>Create a new project for your GitHub repository or import organization.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681647232957/dba33aa2-8245-4873-af8f-28597676b8b3.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Click on the imported repo and choose analysis method Github actions. copy token, as they will be needed in the GitHub Actions workflow.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681649442166/d3b7f6d2-a45b-42b8-b538-0af9288a0056.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Add the above token to Github actions secrets</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681648447570/f2af83cf-b4c9-4d80-a394-e832966b5b4d.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Generate one more Github token or take from part-1 <strong>API_TOKEN_GITHUB</strong></li>
</ol>
<h3 id="heading-github-actions-workflow">GitHub Actions workflow</h3>
<ol>
<li><p>Create a <a target="_blank" href="http://sonar-project.properties"><strong>sonar-project.properties</strong></a> file in the main repo and configure it.</p>
<p> sonar.projectKey=<mark>&lt;&lt;ADD PROJECT KEY&gt;&gt;</mark></p>
<p> sonar.organization=<mark>&lt;&lt;organization name&gt;&gt;</mark></p>
<p> sonar.projectName= <mark>&lt;ADD project NAME&gt;</mark></p>
</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-string">sonar.projectKey=&lt;&lt;ADD</span> <span class="hljs-string">PROJECT</span> <span class="hljs-string">KEY&gt;&gt;</span>
<span class="hljs-string">sonar.organization=shivam779823</span>
<span class="hljs-string">sonar.python.coverage.reportPaths=*coverage*.xml</span>
<span class="hljs-string">sonar.python.xunit.reportPath=*output*.xml</span> 
<span class="hljs-string">sonar.coverage.dtdVerification=false</span>
<span class="hljs-comment">#sonar.inclusions=*.py</span>

<span class="hljs-comment"># This is the name and version displayed in the SonarCloud UI.</span>
<span class="hljs-string">sonar.projectName=</span> <span class="hljs-string">&lt;ADD</span> <span class="hljs-string">project</span> <span class="hljs-string">NAME&gt;</span>
<span class="hljs-comment">#sonar.projectVersion=1.0</span>
<span class="hljs-string">sonar.python.version</span> <span class="hljs-string">=</span> <span class="hljs-number">3</span>

<span class="hljs-comment"># Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.</span>
<span class="hljs-string">sonar.sources=.</span>


<span class="hljs-comment"># Encoding of the source code. Default is default system encoding</span>
<span class="hljs-string">sonar.sourceEncoding=UTF-8</span>
</code></pre>
<ol>
<li>Establish the steps for your GitHub Actions workflow, incorporating essential code quality checks. These may consist of checking out the code, installing dependencies, running tests, and performing SonarCloud analysis. Below is a GitHub Actions workflow YAML file featuring SonarCloud analysis for a Python project</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-comment">#################################################</span>
<span class="hljs-comment"># MAINTAINED BY: SHIVAM</span>
<span class="hljs-comment">#################################################</span>

<span class="hljs-attr">name:</span> <span class="hljs-string">ArgoCD</span> <span class="hljs-string">CI</span> <span class="hljs-string">Pipeline</span> 
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">workflow_dispatch:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">main</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">test</span>
  <span class="hljs-attr">pull_request:</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">main</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">test</span>
<span class="hljs-attr">env:</span>     
  <span class="hljs-attr">IMAGE:</span> <span class="hljs-string">mywebsite</span>
  <span class="hljs-attr">DOCKERHUB_USERNAME:</span> <span class="hljs-string">&lt;username&gt;</span> 

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">build:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">strategy:</span>
      <span class="hljs-attr">matrix:</span>
        <span class="hljs-attr">python-version:</span> [<span class="hljs-string">"3.9"</span>,]

    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">code</span> <span class="hljs-string">Checkout</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v3</span>
        <span class="hljs-attr">with:</span>
           <span class="hljs-attr">fetch-depth:</span> <span class="hljs-number">0</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Set</span> <span class="hljs-string">up</span> <span class="hljs-string">Python</span> <span class="hljs-string">${{</span> <span class="hljs-string">matrix.python-version</span> <span class="hljs-string">}}</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/setup-python@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">python-version:</span> <span class="hljs-string">${{</span> <span class="hljs-string">matrix.python-version</span> <span class="hljs-string">}}</span>

<span class="hljs-comment">#       #STEP 1 python install</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">install</span> <span class="hljs-string">dependencies</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          python -m pip install --upgrade pip
          pip install pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi  
</span><span class="hljs-comment">#       #STEP 2 Pytest        </span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Test</span> <span class="hljs-string">with</span> <span class="hljs-string">pytest</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          pytest --cov=main test_main.py --junitxml=./output.xml 
          python3 -m coverage xml
          ls
          cat coverage.xml
          pwd
</span>        <span class="hljs-comment">#STEP 3 Sonarcloud</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">SonarCloud</span> <span class="hljs-string">Scan</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">SonarSource/sonarcloud-github-action@master</span>
        <span class="hljs-attr">env:</span>
            <span class="hljs-attr">GITHUB_TOKEN:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">}}</span>  <span class="hljs-comment"># Needed to get PR information, if any</span>
            <span class="hljs-attr">SONAR_TOKEN:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.SONAR_TOKEN</span> <span class="hljs-string">}}</span>   

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">SonarQube</span> <span class="hljs-string">Quality</span> <span class="hljs-string">Gate</span> <span class="hljs-string">check</span>
        <span class="hljs-attr">id:</span> <span class="hljs-string">sonarqube-quality-gate-check</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">sonarsource/sonarqube-quality-gate-action@master</span>
      <span class="hljs-comment"># Force to fail step after specific time.</span>
        <span class="hljs-attr">timeout-minutes:</span> <span class="hljs-number">1</span>
        <span class="hljs-attr">env:</span>
          <span class="hljs-attr">SONAR_TOKEN:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.SONAR_TOKEN</span> <span class="hljs-string">}}</span> 

<span class="hljs-comment">#       #STEP 4 Dockerhub login</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Login</span> <span class="hljs-string">to</span> <span class="hljs-string">Docker</span> <span class="hljs-string">Hub</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">docker/login-action@v2</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">username:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.DOCKERHUB_USERNAME</span> <span class="hljs-string">}}</span>
          <span class="hljs-attr">password:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.DOCKERHUB_TOKEN</span> <span class="hljs-string">}}</span>

<span class="hljs-comment">#       #STEP 5 Build and Push</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">and</span> <span class="hljs-string">push</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">docker/build-push-action@v3</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">context:</span> <span class="hljs-string">.</span>
          <span class="hljs-attr">file:</span> <span class="hljs-string">./Dockerfile</span>
          <span class="hljs-attr">push:</span> <span class="hljs-literal">true</span>
          <span class="hljs-attr">tags:</span> <span class="hljs-string">${{env.DOCKERHUB_USERNAME}}/${{env.IMAGE}}:${{github.run_number}}</span> 

<span class="hljs-comment">#       #STEP 6  Invoke deployment action     </span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Invoke</span> <span class="hljs-string">deployment</span> <span class="hljs-string">GitOps</span> <span class="hljs-string">pipe</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          curl -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{secrets.API_TOKEN_GITHUB}}" \
          --request POST \
          --data '{"event_type": "update-deployment", "client_payload": { "buildnumber": "'"${{github.run_number}}"'" }}' \
          https://api.github.com/repos/shivam779823/argocd-deployment/dispatches</span>
</code></pre>
<p>In this example, the workflow is triggered on push and pull request events for the main branch.</p>
<p><em>Github APP repo</em>: <a target="_blank" href="https://github.com/shivam779823/ArgoCD-CICD-app-repo"><strong>ArgoCD-CICD-app-repo</strong></a></p>
<h3 id="heading-github-secrets"><strong>Github Secrets</strong></h3>
<p>Add all secrets to GitHub secrets</p>
<p>DOCKERHUB_USERNAME :</p>
<p>API_GITHUB_TOKEN:</p>
<p>DOCKERHUB_TOKEN:</p>
<p>SONAR_TOKEN:</p>
<ol>
<li>Configure sonar Quality Gates as per your requirements.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681650464700/7aada92f-a22c-4144-b885-6dd069b63093.png" alt class="image--center mx-auto" /></p>
<p>Try to push or add a commit run CI/CD you will see code analysis on Sonarcloud UI</p>
<p>The next step is Slack integration this is optional you can add whatever tool you like for notifications</p>
<h3 id="heading-slack-integrations">Slack Integrations</h3>
<ol>
<li><p>Create a Slack workspace: If you don't already have a Slack workspace, you'll need to create one. You can sign up for a free account on the Slack website (<a target="_blank" href="https://slack.com/"><strong>https://slack.com/</strong></a>) and create a new workspace for your team or organization.</p>
</li>
<li><p>Add the GitHub app to Slack: In your Slack workspace, you can search for the GitHub app in the Slack App Directory and add it to your workspace. The GitHub app allows you to receive notifications and updates from your GitHub repositories directly in Slack.</p>
</li>
<li><p>Configure GitHub integration settings: Once the GitHub app is added to your Slack workspace, you'll need to configure the integration settings. This usually involves authorizing the app to access your GitHub repositories and selecting the repositories for which you want to receive notifications in Slack.</p>
</li>
<li><p>Customize notifications: You can customize the notifications that you want to receive in Slack from GitHub. For example, you can choose to receive notifications for new pull requests, code reviews, commits, and other GitHub events. You can also configure the format and content of the notifications, such as the channel where notifications are posted, the message template, and the level of detail in the notifications.</p>
</li>
<li><p>Set up Slack webhooks: Slack also supports webhooks, which allow you to receive custom notifications and events from GitHub in Slack. You can set up webhooks in GitHub to send notifications to a specific Slack channel or user when certain events occur, such as new pull requests or issues being opened or closed.</p>
</li>
<li><p>Use Slack commands for GitHub actions: Slack also supports custom slash commands, which allow you to trigger GitHub actions directly from Slack. For example, you can create custom slash commands to create new issues, comment on pull requests, or close issues in GitHub, all from within Slack.</p>
</li>
<li><p>Collaborate with team members: Once the Slack and GitHub integration is set up, you can collaborate with your team members in Slack by discussing code changes, reviewing pull requests, and coordinating code reviews. Slack notifications can help you stay up-to-date with the latest changes in your GitHub repositories, and you can use Slack commands to take actions on GitHub directly from Slack, making it a seamless and efficient way to collaborate on code development and reviews.</p>
</li>
</ol>
<h3 id="heading-summary">Summary</h3>
<p>building a CI/CD pipeline using GitHub Actions, SonarCloud, and ArgoCD on GKE. These tools enable developers to automate code quality analysis, build, and deployment processes, resulting in faster and more reliable software development cycles. By implementing a robust CI/CD pipeline, teams can achieve higher code quality, faster release cycles, and improved collaboration among team members, ultimately leading to more successful and efficient software development projects.</p>
<p>In conclusion, this blog provides a comprehensive guide on how to build a CI/CD pipeline using GitHub Actions, SonarCloud, and ArgoCD on GKE, empowering teams to deliver high-quality software with increased speed, reliability, and scalability.</p>
]]></content:encoded></item><item><title><![CDATA[Linux commands that every DevOps engineer should know]]></title><description><![CDATA[As a DevOps engineer, your job is to manage servers and infrastructure, automate tasks, and deploy applications. One of the essential skills for any DevOps engineer is a good knowledge of Linux commands. Linux is a powerful and flexible operating sys...]]></description><link>https://shivammahajan.hashnode.dev/linux-commands-that-every-devops-engineer-should-know</link><guid isPermaLink="true">https://shivammahajan.hashnode.dev/linux-commands-that-every-devops-engineer-should-know</guid><category><![CDATA[Linux]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Kubernetes]]></category><dc:creator><![CDATA[Shivam Mahajan]]></dc:creator><pubDate>Thu, 13 Apr 2023 03:16:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/4Mw7nkQDByk/upload/dc146dc4431227096792cc4d79c7d9aa.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a DevOps engineer, your job is to manage servers and infrastructure, automate tasks, and deploy applications. One of the essential skills for any DevOps engineer is a good knowledge of Linux commands. Linux is a powerful and flexible operating system that is widely used in the server and cloud computing industries. In this blog post, we'll cover some of the top Linux commands that every DevOps engineer should know.</p>
<h3 id="heading-cd">cd</h3>
<p><code>cd</code>: Change directory</p>
<p>The <code>cd</code> command is used to navigate between directories. It allows you to move to a different directory within the file system. For example, to move to the home directory, you can type <code>cd ~</code>.</p>
<h3 id="heading-ls">ls</h3>
<p><code>ls</code>: List contents of a directory</p>
<p>The <code>ls</code> command is used to list the contents of a directory. It displays the files and directories in the current directory. You can use the <code>-l</code> option to display more detailed information about the files, such as their permissions, owner, and size.</p>
<h3 id="heading-mkdir">mkdir</h3>
<p><code>mkdir</code>: Make directory</p>
<p>The <code>mkdir</code> command is used to create a new directory. You can create a new directory by typing <code>mkdir directory_name</code>. For example, to create a new directory called "my_folder", you can type <code>mkdir my_folder</code>.</p>
<h3 id="heading-rm">rm</h3>
<p><code>rm</code>: Remove files or directories</p>
<p>The <code>rm</code> command is used to delete files or directories. Be careful when using this command as it can permanently delete files and directories. To delete a file, you can type <code>rm file_name</code>. To delete a directory and its contents, you can use the <code>-r</code> option, which stands for "recursive". For example, to delete a directory called "my_folder" and its contents, you can type <code>rm -r my_folder</code>.</p>
<h3 id="heading-cp">cp</h3>
<p><code>cp</code>: Copy files or directories</p>
<p>The <code>cp</code> command is used to make a copy of a file or directory. To copy a file, you can type <code>cp file_name new_file_name</code>. To copy a directory and its contents, you can use the <code>-r</code> option. For example, to copy a directory called "my_folder" to a new directory called "new_folder", you can type <code>cp -r my_folder new_folder</code>.</p>
<h3 id="heading-mv">mv</h3>
<p><code>mv</code>: Move files or directories</p>
<p>The <code>mv</code> command is used to move files or directories. It can also be used to rename files or directories. To move a file or directory, you can type <code>mv file_or_directory_name new_directory_name</code>. For example, to move a file called "my_file.txt" to a new directory called "my_folder", you can type <code>mv my_file.txt my_folder/</code>.</p>
<h3 id="heading-grep">grep</h3>
<p><code>grep</code>: Search for a pattern in a file</p>
<p>The <code>grep</code> command is used to search for a specific string or pattern in a file. It can be used to search for a word, a phrase, or a regular expression. For example, to search for the word "error" in a log file called "my_log.txt", you can type <code>grep error my_log.txt</code>.</p>
<h3 id="heading-top">top</h3>
<p><code>top</code>: Display system information</p>
<p>The <code>top</code> command is used to display information about system processes and resource usage. It shows the processes that are currently running on the system, as well as their CPU and memory usage. It's a useful command for monitoring system performance and troubleshooting issues.</p>
<h3 id="heading-netstat">netstat</h3>
<p><code>netstat</code>: Display network information</p>
<p>The <code>netstat</code> command is used to display network connections, routing tables, and interface statistics. It can be used to troubleshoot network issues and monitor network activity. For example, to display all active network connections, you can type <code>netstat -a</code>.</p>
<h3 id="heading-ssh">ssh</h3>
<p><code>ssh</code>: Secure Shell</p>
<p>The SSH command is used to establish a secure shell connection between a client and a server. Here's an example of how to use the SSH command</p>
<p>ssh <code>username@server_ip_address</code></p>
<p><code>username</code> is the username you use to log in to the server, and <code>server_ip_address</code> is the IP address or domain name of the server you want to connect to.</p>
<h3 id="heading-ping">ping</h3>
<p><code>ping</code>: Check network connectivity</p>
<p>The <code>ping</code> command is used to check network connectivity. It sends packets to a remote host and waits for a response. If the host is reachable, it will respond with a packet. The <code>ping</code> command can be used to test the connectivity of a remote host or troubleshoot network issues. For example, to ping a host called "<a target="_blank" href="http://google.com">google.com</a>", you can type <code>ping</code> <a target="_blank" href="http://google.com"><code>google.com</code></a>.</p>
<h3 id="heading-ifconfig">ifconfig</h3>
<p><code>ifconfig</code>: Display network interface configuration</p>
<p>The <code>ifconfig</code> command is used to display the configuration of network interfaces on the system. It shows information such as the IP address, netmask, and MAC address of each interface. It can be used to troubleshoot network issues and configure network settings.</p>
<h3 id="heading-ps">ps</h3>
<p><code>ps</code>: Display running processes</p>
<p>The <code>ps</code> command is used to display information about running processes on the system. It shows the process ID, CPU and memory usage, and other information about each process. It can be used to monitor system performance and troubleshoot issues.</p>
<h3 id="heading-kill">kill</h3>
<p><code>kill</code>: Stop a running process</p>
<p>The <code>kill</code> command is used to stop a running process. It sends a signal to the process to terminate it. You can use the <code>kill</code> command to stop a process that has become unresponsive or is consuming too much resources. For example, to stop a process with a process ID of 1234, you can type <code>kill 1234</code>.</p>
<h3 id="heading-tar">tar</h3>
<p><code>tar</code>: Create and extract compressed archives</p>
<p>The <code>tar</code> command is used to create and extract compressed archives. It can be used to compress and archive files and directories for backup or transfer. For example, to create a compressed archive of a directory called "my_folder", you can type <code>tar -czvf my_folder.tar.gz my_folder/</code>. To extract the contents of a compressed archive, you can use the <code>tar -xvf</code> command.</p>
<h3 id="heading-curl">curl</h3>
<p><code>curl</code>: Transfer data from or to a server</p>
<p>The <code>curl</code> command is used to transfer data from or to a server using a variety of protocols, including HTTP, FTP, SMTP, and more. It can be used to test API endpoints, download files, or upload data to a server. For example, to download a file from a URL, you can type <code>curl -O</code> <a target="_blank" href="http://example.com/file.txt"><code>http://example.com/file.txt</code></a>.</p>
<h3 id="heading-sed">sed</h3>
<p><code>sed</code>: Stream editor for text files</p>
<p>The <code>sed</code> command is used to perform text transformations on a file or stream. It can be used to find and replace text, delete lines, or perform other operations. For example, to replace the word "foo" with "bar" in a file called "my_file.txt", you can type <code>sed 's/foo/bar/g' my_file.txt</code>.</p>
<h3 id="heading-awk">awk</h3>
<p><code>awk</code>: Pattern scanning and processing language</p>
<p>The <code>awk</code> command is used to perform text processing and manipulation. It can be used to extract specific fields from a file, perform calculations, or apply transformations to text. For example, to print the first column of a CSV file called "data.csv", you can type <code>awk -F, '{print $1}' data.csv</code>.</p>
<h3 id="heading-iptables">iptables</h3>
<p><code>iptables</code>: Firewall configuration</p>
<p>The <code>iptables</code> command is used to configure the Linux firewall. It can be used to allow or deny traffic based on IP address, port, or protocol. It is an essential tool for securing servers and preventing unauthorized access. For example, to allow incoming traffic on port 80, you can type <code>iptables -A INPUT -p tcp --dport 80 -j ACCEPT</code>.</p>
<h3 id="heading-summary">summary</h3>
<p>By mastering these Linux commands, one can increase efficiency and productivity as a DevOps engineer. Many other Linux commands can be useful in your work, but these commands are a good starting point. With practice and experience, you can become proficient in using the Linux command line to manage servers and infrastructure.</p>
]]></content:encoded></item><item><title><![CDATA[Setup GCP Compute Engine with Bastion Host]]></title><description><![CDATA[GCP Compute Engine with Bastion Host is a commonly used security configuration for providing secure access to virtual machines (VMs) in GCP. A bastion host is a special-purpose VM that acts as an intermediary between your local computer and the VMs y...]]></description><link>https://shivammahajan.hashnode.dev/setup-gcp-compute-engine-with-bastion-host</link><guid isPermaLink="true">https://shivammahajan.hashnode.dev/setup-gcp-compute-engine-with-bastion-host</guid><category><![CDATA[ssh]]></category><category><![CDATA[Devops]]></category><category><![CDATA[GCP]]></category><category><![CDATA[compute engine]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Shivam Mahajan]]></dc:creator><pubDate>Sat, 08 Apr 2023 10:37:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680598129948/f34225dd-6aa6-48dd-a8d1-3f8cfee99a59.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>GCP Compute Engine with Bastion Host is a commonly used security configuration for providing secure access to virtual machines (VMs) in GCP. A bastion host is a special-purpose VM that acts as an intermediary between your local computer and the VMs you want to access.</p>
<h3 id="heading-ssh">SSH</h3>
<p>Secure Shell (SSH) is a widely used protocol for accessing remote servers and computing resources. Google Cloud Platform (GCP) Compute Engine provides a powerful platform for deploying virtual machines in the cloud. In this blog post, we will explore how to SSH into a GCP Compute Engine instance using a Bastion host.</p>
<h3 id="heading-what-is-a-bastion-host">What is a Bastion Host?</h3>
<p>A bastion host is a secure intermediary server that acts as a gateway for remote access to a private network. In the context of GCP Compute Engine, a bastion host is used to provide secure access to instances running in a Virtual Private Cloud (VPC).</p>
<h3 id="heading-benefits-of-using-a-bastion-host-for-accessing-vms-in-gcp">Benefits of using a bastion host for accessing VMs in GCP</h3>
<ol>
<li><p>Enhanced security: A bastion host acts as a secure gateway to your VMs, reducing the surface area for attacks.</p>
</li>
<li><p>Centralized access control: With a bastion host, you can centralize access control and log for all SSH connections to your VMs.</p>
</li>
<li><p>Simplified management: A bastion host can reduce the complexity of managing SSH keys for multiple VMs.</p>
</li>
</ol>
<h3 id="heading-steps-to-set-up-bastion-host">Steps to set up Bastion Host</h3>
<ol>
<li>Create a VPC network: Create a VPC network in GCP, which will be used to host your VMs and a bastion host.</li>
</ol>
<pre><code class="lang-bash">gcloud compute networks create bastion-vpc \
--subnet-mode=custom
</code></pre>
<ol>
<li>Create two subnets in the VPC network</li>
</ol>
<pre><code class="lang-bash">gcloud compute networks subnets create subnet-a --network=bastion-vpc --region=us-central1 --range=10.250.40.0/27
</code></pre>
<pre><code class="lang-bash">gcloud compute networks subnets create subnet-b --network=bastion-vpc --region=us-central1 --range=10.250.41.0/9
</code></pre>
<p>Note: Delete your default vpc before running the above commands</p>
<ol>
<li>Create a bastion host VM: Create a new Compute Engine instance that will act as the bastion host. Ensure that this VM is in the same VPC network as your target VMs.</li>
</ol>
<pre><code class="lang-bash">gcloud compute instances create bastion  \
--network=bastion-vpc \
--zone=us-central1<span class="hljs-_">-a</span> \
--subnet=subnet-a \
--tags=bastion
</code></pre>
<ol>
<li>Create a private VM with no external IP</li>
</ol>
<pre><code class="lang-bash">gcloud compute instances create private-vm  \
--network=bastion-vpc \
--zone=us-central1<span class="hljs-_">-a</span> \
--subnet=subnet-b \
--tags=private-vm \
--no-address
</code></pre>
<p>Create a Firewall rule to allow ssh to Bastion host with your IP address</p>
<pre><code class="lang-bash">gcloud compute firewall-rules create allow-ssh-bastion \
--allow=tcp:22 \
--network=bastion-vpc \
--target-tags=bastion \
--source-ranges=[YOUR IP_RANGE]
</code></pre>
<p>Create a Firewall rule to allow traffic from the bastion to all other instances</p>
<pre><code class="lang-bash">gcloud compute firewall-rules create bastion-fwd-private-vm \
--allow=tcp:22 \
--network=bastion-vpc \
--source-tags=bastion \
--target-tags=private-vm
</code></pre>
<p>SSH into bastion host and run below command to access private vm</p>
<pre><code class="lang-bash">gcloud compute ssh private-vm --internal-ip
</code></pre>
<p>Note: Make sure your bastion vm service accountt have Read/Write permissions.</p>
<p>That's it! You can now securely access your VMs in GCP using a Bastion host.</p>
<p>Conclusion</p>
<p>In this blog post, we have explored how to SSH into a GCP Compute Engine instance using a Bastion host. By following these steps, you can establish a secure connection to your instances running in a VPC. It is important to note that using a bastion host adds an extra layer of security to your system by providing an additional barrier against unauthorized access.</p>
]]></content:encoded></item><item><title><![CDATA[Part-1: Setting Up CI/CD using GitHub Actions, SonarCloud, and ArgoCD on Google Kubernetes Engine]]></title><description><![CDATA[Learn how to automate your software development workflows and deploy applications seamlessly to Google Kubernetes Engine (GKE) using the powerful combination of GitHub Actions, SonarCloud, and ArgoCD. In this tutorial, i will guide you through settin...]]></description><link>https://shivammahajan.hashnode.dev/part-1-setting-up-cicd-using-github-actions-sonarcloud-and-argocd-on-google-kubernetes-engine</link><guid isPermaLink="true">https://shivammahajan.hashnode.dev/part-1-setting-up-cicd-using-github-actions-sonarcloud-and-argocd-on-google-kubernetes-engine</guid><category><![CDATA[CI/CD]]></category><category><![CDATA[GCP]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[GitHub Actions]]></category><category><![CDATA[ArgoCD]]></category><dc:creator><![CDATA[Shivam Mahajan]]></dc:creator><pubDate>Tue, 04 Apr 2023 04:22:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681567582550/8b6d6a92-6f27-4119-8550-e4fbef756967.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Learn how to automate your software development workflows and deploy applications seamlessly to Google Kubernetes Engine (GKE) using the powerful combination of GitHub Actions, SonarCloud, and ArgoCD. In this tutorial, i will guide you through setting up a robust CI/CD pipeline using GitHub Actions and ArgoCD for managing Kubernetes applications. With step-by-step instructions, you'll be able to leverage the full potential of these tools to streamline your software development process and deploy your applications with ease.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>Before proceeding , you should have the following:</p>
<ul>
<li><p>A GitHub account</p>
</li>
<li><p>A Google Cloud Platform account</p>
</li>
<li><p>A Google Kubernetes Engine cluster</p>
</li>
<li><p>ArgoCD installed on the cluster</p>
</li>
<li><p>A sample application that you want to deploy</p>
</li>
</ul>
<h3 id="heading-architecture">Architecture</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680496288843/cac811a4-00c8-4063-9446-b66e269a6538.png" alt class="image--center mx-auto" /></p>
<p>I have two GitHub repositories: one for app code and another for deployment. The app code repository stores our application code, utilizing a continuous integration GitHub workflow. Meanwhile, the deployment repository houses a workflow for managing changes in deployment.yaml files. Additionally, you can integrate third-party tools for notifications.</p>
<h3 id="heading-setting-up-github-actions-cicd">Setting up GitHub Actions CI/CD</h3>
<p>The first step is to set up GitHub Actions to build and test the application. Create a new file in the root directory of your application code repo named .github/workflows/Argocd-ci.yaml. This file will contain the following configuration for your CI/CD workflow.</p>
<p>Note: SonarCloud Integration and Slack we will See In the next part</p>
<pre><code class="lang-yaml"><span class="hljs-comment">#################################################</span>
<span class="hljs-comment"># MAINTAINED BY: SHIVAM</span>
<span class="hljs-comment">#################################################</span>

<span class="hljs-attr">name:</span> <span class="hljs-string">ArgoCD</span> <span class="hljs-string">CI</span> <span class="hljs-string">Pipeline</span> 
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">workflow_dispatch:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">main</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">test</span>
  <span class="hljs-attr">pull_request:</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">main</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">test</span>
<span class="hljs-attr">env:</span>     
  <span class="hljs-attr">IMAGE:</span> <span class="hljs-string">mywebsite</span>
  <span class="hljs-attr">DOCKERHUB_USERNAME:</span> <span class="hljs-string">&lt;username&gt;</span> 

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">build:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">strategy:</span>
      <span class="hljs-attr">matrix:</span>
        <span class="hljs-attr">python-version:</span> [<span class="hljs-string">"3.9"</span>,]

    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">code</span> <span class="hljs-string">Checkout</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v3</span>
        <span class="hljs-attr">with:</span>
           <span class="hljs-attr">fetch-depth:</span> <span class="hljs-number">0</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Set</span> <span class="hljs-string">up</span> <span class="hljs-string">Python</span> <span class="hljs-string">${{</span> <span class="hljs-string">matrix.python-version</span> <span class="hljs-string">}}</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/setup-python@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">python-version:</span> <span class="hljs-string">${{</span> <span class="hljs-string">matrix.python-version</span> <span class="hljs-string">}}</span>

<span class="hljs-comment">#       #STEP 1 python install</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">install</span> <span class="hljs-string">dependencies</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          python -m pip install --upgrade pip
          pip install pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi  
</span><span class="hljs-comment">#       #STEP 2 Pytest        </span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Test</span> <span class="hljs-string">with</span> <span class="hljs-string">pytest</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          pytest --cov=main test_main.py --junitxml=./output.xml 
          python3 -m coverage xml
          ls
          cat coverage.xml
          pwd
</span><span class="hljs-comment">#       #STEP 3 Lint</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Linting</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          find . -name \*.py | xargs pylint -f parseable | tee pylint.log
</span>

<span class="hljs-comment">#       #STEP 4 Dockerhub login</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Login</span> <span class="hljs-string">to</span> <span class="hljs-string">Docker</span> <span class="hljs-string">Hub</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">docker/login-action@v2</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">username:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.DOCKERHUB_USERNAME</span> <span class="hljs-string">}}</span>
          <span class="hljs-attr">password:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.DOCKERHUB_TOKEN</span> <span class="hljs-string">}}</span>

<span class="hljs-comment">#       #STEP 5 Build and Push</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">and</span> <span class="hljs-string">push</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">docker/build-push-action@v3</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">context:</span> <span class="hljs-string">.</span>
          <span class="hljs-attr">file:</span> <span class="hljs-string">./Dockerfile</span>
          <span class="hljs-attr">push:</span> <span class="hljs-literal">true</span>
          <span class="hljs-attr">tags:</span> <span class="hljs-string">${{env.DOCKERHUB_USERNAME}}/${{env.IMAGE}}:${{github.run_number}}</span> 



      <span class="hljs-comment"># - name: kuberntest manifest</span>
      <span class="hljs-comment">#   run: |</span>
      <span class="hljs-comment">#     sed -i 's/mywebsite:latest/mywebsite:${{github.run_number}}/g' ${{ github.workspace }}/k8s/deployment.yaml</span>

<span class="hljs-comment">#       #STEP 6  Invoke deployment action     </span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Invoke</span> <span class="hljs-string">deployment</span> <span class="hljs-string">GitOps</span> <span class="hljs-string">pipe</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          curl -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{secrets.API_TOKEN_GITHUB}}" \
          --request POST \
          --data '{"event_type": "update-deployment", "client_payload": { "buildnumber": "'"${{github.run_number}}"'" }}' \
          https://api.github.com/repos/shivam779823/argocd-deployment/dispatches</span>
</code></pre>
<p><em>Github APP repo</em>: <a target="_blank" href="https://github.com/shivam779823/ArgoCD-CICD-app-repo">ArgoCD-CICD-app-repo</a></p>
<p>Now create separate Github repo for Deployment files</p>
<p>Github Deployment repo: <a target="_blank" href="https://github.com/shivam779823/ArgoCD-CICD-deployment-repo">ArgoCD-CICD-deployment-repo</a></p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Deployment</span> <span class="hljs-string">to</span> <span class="hljs-string">GKE</span> 

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">repository_dispatch:</span>
     <span class="hljs-attr">types:</span> <span class="hljs-string">update-deployment</span>   
<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">Deploy:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v3</span>
      <span class="hljs-attr">with:</span>
        <span class="hljs-attr">persist-credentials:</span> <span class="hljs-literal">false</span> <span class="hljs-comment"># otherwise, the token used is the GITHUB_TOKEN, instead of your personal token</span>
        <span class="hljs-attr">fetch-depth:</span> <span class="hljs-number">0</span>

    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Update</span> <span class="hljs-string">Image</span> <span class="hljs-string">Version</span>
      <span class="hljs-attr">id:</span> <span class="hljs-string">imgupd</span>
      <span class="hljs-attr">uses:</span> <span class="hljs-string">mikefarah/yq@master</span>
      <span class="hljs-attr">with:</span>
        <span class="hljs-attr">cmd:</span> <span class="hljs-string">yq</span> <span class="hljs-string">eval</span> <span class="hljs-string">'.spec.template.spec.containers[0].image = "shiva9921/mywebsite:$<span class="hljs-template-variable">{{ github.event.client_payload.buildnumber }}</span>"'</span> <span class="hljs-string">-i</span> <span class="hljs-string">k8s/deployment.yaml</span>

    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Update</span> <span class="hljs-string">the</span> <span class="hljs-string">Build</span> <span class="hljs-string">number</span>
      <span class="hljs-attr">run:</span> <span class="hljs-string">|
        echo "Updating the Build Number: ${{github.event.client_payload.buildnumber}}"
</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Commit</span> <span class="hljs-string">&amp;</span> <span class="hljs-string">Push</span> <span class="hljs-string">changes</span>
      <span class="hljs-attr">uses:</span> <span class="hljs-string">actions-js/push@master</span>
      <span class="hljs-attr">with:</span>
        <span class="hljs-attr">github_token:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.API_GITHUB_TOKEN</span> <span class="hljs-string">}}</span>
        <span class="hljs-attr">message:</span> <span class="hljs-string">"Updating the Build Number: $<span class="hljs-template-variable">{{github.event.client_payload.buildnumber}}</span>"</span>
</code></pre>
<h3 id="heading-github-secrets">Github Secrets</h3>
<p>Add all secrets to GitHub secrets</p>
<p>DOCKERHUB_USERNAME :</p>
<p>API_GITHUB_TOKEN:</p>
<p>DOCKERHUB_TOKEN:</p>
<h3 id="heading-steup-gke-and-argocd">Steup GKE and ArgoCD</h3>
<p>as of now I am creating only one cluster you are free to create multiple cluster and how to add it in single argocd we will see in separate blog.</p>
<ol>
<li>Run in Cloud shell to spin GKE Cluster.</li>
</ol>
<pre><code class="lang-bash">gcloud container clusters create dev --num-nodes=2 --zone=us-central1<span class="hljs-_">-a</span>
</code></pre>
<ol>
<li>Get config entry in Cloud shell.</li>
</ol>
<pre><code class="lang-bash">gcloud container clusters get-credentials dev --zone=us-central1<span class="hljs-_">-a</span>
</code></pre>
<ol>
<li>clone repo</li>
</ol>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/shivam779823/ArgoCD-CICD-app-repo.git
<span class="hljs-built_in">cd</span> ArgoCD-CICD-app-repo
</code></pre>
<ol>
<li>Create a namespace and Install ArgoCD</li>
</ol>
<pre><code class="lang-bash">kubectl create ns argocd

kubectl -n argocd apply -f install.yaml
</code></pre>
<ol>
<li>Get argocd password and username "Admin" by default</li>
</ol>
<pre><code class="lang-bash">kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath=<span class="hljs-string">"{.data.password}"</span> | base64 -d; <span class="hljs-built_in">echo</span>
</code></pre>
<ol>
<li>Open Load balancer ip in the browser for argocd server</li>
</ol>
<pre><code class="lang-plaintext">kubectl -n argocd get svc
</code></pre>
<h3 id="heading-argo-cd-github-private-repo-integration">Argo CD Github Private repo integration</h3>
<p>Remember that this repository is used for these tutorials are public for obvious reasons, so if you want to follow this tutorial, you are free to fork it to a private repository and adjust the repository URLs there.</p>
<p>There are two possibilities for ArgoCD to communicate with GitHub to check for changes. One is via HTTPS using a username and password. The other and recommended way is using SSH using a private-public key-pair</p>
<ol>
<li>we need an SSH key to use. We can easily create a new SSH key pair using the following command.</li>
</ol>
<pre><code class="lang-bash">ssh-keygen -t ed25519 -C <span class="hljs-string">"some comment"</span>
</code></pre>
<pre><code class="lang-bash">cat ~/.ssh/id_ed25519.pub
</code></pre>
<ol>
<li>Copy the public key and Add the Public key to GitHub.</li>
</ol>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/1*lwJrE-Tonyg-8GilBNNGLg.png" alt /></p>
<ol>
<li>Go to settings in argoCD UI , Click on Repository, select auth method SSH</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690550542746/f6a52c10-36e3-41dc-abde-e5da8828aeb7.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Add the GitHub ssh url and Paste the private key that we generated.</li>
</ol>
<h3 id="heading-argocd-application-deployments-config">ArgoCD application deployments config</h3>
<p>Go to argocd and click on create new app and fill the details . ( you can change the details as per your github repo configurations)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690551314603/f526aad8-29cb-42d9-91fd-8135cbedd72f.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690551110414/a96a122a-ee05-4239-8230-b9f58a4accf4.png" alt class="image--center mx-auto" /></p>
<p>finally, we are done with deployment of application ..............you can play around and explore UI</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690551331981/f947ec96-ef2e-4290-aead-e7b09c21c5c0.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-summary"><strong>Summary</strong></h3>
<p>This tutorial taught us a few steps to create GitHub actions CI/CD using ArgoCD with our private GitHub repository. If you are pretty new to it, it might be a bit overwhelming, but you should get quickly into it, and with this tutorial, you should get a quick start on getting up and running fast 😊.</p>
<h3 id="heading-additional-resources">Additional resources</h3>
<p>ArgoCD: <a target="_blank" href="https://spacelift.io/blog/argocd">https://spacelift.io/blog/argocd</a></p>
<p>GitHub actions: <a target="_blank" href="https://docs.github.com/en/actions">https://docs.github.com/en/actions</a></p>
<p>Part 2 : <a target="_blank" href="https://shivammahajan.hashnode.dev/part-2-building-cicd-using-github-actions-sonarcloud-and-argocd-on-google-kubernetes-engine">part-2-building-cicd-using-github-actions-sonarcloud-and-argocd-on-google-kubernetes-engine</a></p>
]]></content:encoded></item></channel></rss>