<?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: Atulpriya Sharma</title>
    <description>The latest articles on DEV Community by Atulpriya Sharma (@techmaharaj).</description>
    <link>https://dev.to/techmaharaj</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%2F795390%2F35203406-18d5-4552-9278-efec79836cfc.jpg</url>
      <title>DEV Community: Atulpriya Sharma</title>
      <link>https://dev.to/techmaharaj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/techmaharaj"/>
    <language>en</language>
    <item>
      <title>How To Run Static Analysis On Your CI/CD Pipelines Using AI</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Thu, 17 Oct 2024 07:27:57 +0000</pubDate>
      <link>https://dev.to/coderabbitai/how-to-run-static-analysis-on-your-cicd-pipelines-using-ai-3cl4</link>
      <guid>https://dev.to/coderabbitai/how-to-run-static-analysis-on-your-cicd-pipelines-using-ai-3cl4</guid>
      <description>&lt;p&gt;&lt;em&gt;“An inadvertent misconfiguration during a setup left a data field blank, which then triggered the system to automatically delete the account.” -&lt;/em&gt; was &lt;a href="https://www.business-standard.com/world-news/google-cloud-accidentally-deletes-125-billion-australian-pension-fund-124051800606_1.html" rel="noopener noreferrer"&gt;Google's explanation for accidentally deleting a pension fund's entire account&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Incidents like these highlight the importance of configuration accuracy in modern software systems. A simple misconfiguration can have devastating consequences, particularly in CI/CD pipelines. &lt;/p&gt;

&lt;p&gt;Ensuring configuration accuracy and managing the complexity of code reviews can be daunting for DevOps engineers. Teams often prioritize feature development, leaving configuration reviews as an afterthought. This can lead to unnoticed misconfigurations, causing production issues and downtime.&lt;/p&gt;

&lt;p&gt;CodeRabbit helps solve this by automating code reviews with AI-driven analysis and real-time feedback. Unlike other tools requiring complex setups, CodeRabbit integrates seamlessly into your pipeline, ensuring that static checks on configuration files are accurate and efficient.&lt;/p&gt;

&lt;p&gt;In this blog post, we will look at CodeRabbit and how it helps with static checking in CI/CD Pipelines, ensuring configuration quality and improving efficiency throughout the end-to-end deployment process. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Static Checking is Crucial in CI/CD Pipelines
&lt;/h2&gt;

&lt;p&gt;Configuration files are the backbone of CI/CD pipelines that control the deployment of infrastructure and applications.  Errors in these files can lead to costly outages and business disruptions, making early validation essential. Static checking is vital in mitigating security vulnerabilities, code quality issues, and operational disruptions.&lt;/p&gt;

&lt;p&gt;Below is an example of a Circle CI workflow configuration file that sets up a virtual environment, installs requirement dependencies, and executes linting commands.&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;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;circleci/python:3.9&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="s"&gt;checkout&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&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 Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;python -m venv venv&lt;/span&gt;
        &lt;span class="s"&gt;. venv/bin/activate&lt;/span&gt;
        &lt;span class="s"&gt;pip install flake8&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&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;Run Linting&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;. venv/bin/activate&lt;/span&gt;
        &lt;span class="s"&gt;flake8 .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If static checking didn’t happen in the above configuration, issues like unrecognized syntax or invalid configurations in the Python code could leak, causing the build to fail at later stages. For example, missing dependencies or improperly formatted code could lead to runtime errors that break deployment pipelines or introduce hard-to-trace bugs in production.&lt;/p&gt;

&lt;p&gt;Overall, static checking helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early error detection&lt;/strong&gt;: Static check identifies syntax errors and misconfigurations in code before execution, which reduces the likelihood of runtime failures. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enforce coding standards&lt;/strong&gt;: This ensures consistent code quality by enforcing style guidelines and best practices across code and configuration files, making it easier to maintain &amp;amp; review changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhancing Code quality&lt;/strong&gt;: Static checks help enforce criteria like passing tests or x% of code coverage, which must be met before any deployment, thus improving the overall quality.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using CodeRabbit For Static Checking
&lt;/h2&gt;

&lt;p&gt;CodeRabbit gives an edge by identifying common misconfigurations by integrating with your CI/CD workflows. This capability is crucial for maintaining the integrity of the deployment process and preventing disruptions that could affect end-users. &lt;/p&gt;

&lt;p&gt;In addition, it provides a distinctive benefit in executing static analysis and linting automatically, requiring no additional configuration. For DevOps teams, this functionality streamlines the setup process so they can concentrate on development rather than complicated settings. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It integrates with your CI/CD pipelines without causing any disruption and automatically runs linting and static analysis out of the box, requiring no additional configuration. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It supports integration with a wide range of tools across popular CI/CD platforms like GitHub, CircleCI, and GitLab, running checks such as &lt;a href="https://docs.coderabbit.ai/tools/actionlint" rel="noopener noreferrer"&gt;Actionlint&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/tools/yamllint" rel="noopener noreferrer"&gt;Yamllint&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/tools/shellcheck" rel="noopener noreferrer"&gt;ShellCheck&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/tools/circleci" rel="noopener noreferrer"&gt;CircleCI&lt;/a&gt; pipelines, etc. This simplifies setup, providing quick results without additional manual effort. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For tools like Jenkins and GitHub Actions, CodeRabbit continuously runs static analysis on every build or commit, catching misconfigurations early and improving workflow reliability.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let us look at CodeRabbit in action in the following section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detecting Misconfiguration with CodeRabbit and GitHub Actions Actionlint
&lt;/h2&gt;

&lt;p&gt;To demonstrate the functionality of CodeRabbit, let us look at how we integrate a GitHub Actions workflow into a project to automate the CI/CD pipeline. The repository has a configuration file with potential errors, which will be flagged and reported by CodeRabbit. &lt;/p&gt;

&lt;p&gt;Below is a diagram of the sequence of tasks in the workflow file we created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkzrygbuc1jlszvskv74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkzrygbuc1jlszvskv74.png" alt="CI/CD Pipeline Workflow" width="800" height="723"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By submitting a pull request, we allowed CodeRabbit to review the file and detect potential misconfigurations automatically. Once the repository is prepared, we &lt;a href="https://coderabbit.ai/blog/how-to-integrate-ai-code-review-into-your-devops-pipeline" rel="noopener noreferrer"&gt;integrate it with CodeRabbit&lt;/a&gt; to set up automated code reviews and generate a comprehensive, structured report consisting of the following key sections&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Summary&lt;/strong&gt; – A concise overview of the key changes detected in your code or configuration. This helps you quickly understand the main areas that need attention.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3j4rs06t1fqjni4dd3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3j4rs06t1fqjni4dd3x.png" alt="Summary By CodeRabbit" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Walkthrough&lt;/strong&gt; – A detailed, step-by-step analysis of the reviewed files, guiding you through specific issues, configurations, and recommendations.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Table of Changes&lt;/strong&gt; – A table listing all changes in each file and a change summary. This helps you quickly assess and prioritize necessary actions.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;You can customize these sections by tweaking the configuration file or using the &lt;a href="https://app.coderabbit.ai" rel="noopener noreferrer"&gt;CodeRabbit dashboard&lt;/a&gt;. Refer to our &lt;a href="https://docs.coderabbit.ai/configure-coderabbit" rel="noopener noreferrer"&gt;CodeRabbit configuration guide&lt;/a&gt; to learn more. &lt;/p&gt;

&lt;p&gt;Here a sample workflow.yaml config file, on which detailed insights and recommendations through CodeRabbit's review process.&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;development task&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;develop&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;staging&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;develop&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;staging&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&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;Lint workflow YAML files&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rhysd/actionlint@v1&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;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;18'&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 dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&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;Lint JavaScript code&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run lint&lt;/span&gt;

  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lint&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&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;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;18'&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 dependencies and cache&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/cache@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/.npm&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}&lt;/span&gt;
          &lt;span class="na"&gt;restore-keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;${{ runner.os }}-node-&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&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;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&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;Check for vulnerabilities&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm audit --production&lt;/span&gt;

  &lt;span class="na"&gt;terraform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&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;Setup Terraform&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hashicorp/setup-terraform@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;terraform_version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.5.0&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;Terraform init&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform init&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;infrastructure/&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;Terraform plan&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform plan&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;infrastructure/&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;Terraform apply (development)&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.ref == 'refs/heads/develop'&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform apply -auto-approve&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;infrastructure/&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;AWS_SECRET_ACCES_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET_ACCES_KEY }}&lt;/span&gt;

  &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&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;Login to AWS ECR&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;login-ecr&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/amazon-ecr-login@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&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;Build and tag Docker image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;IMAGE_TAG=${{ github.sha }}&lt;/span&gt;
          &lt;span class="s"&gt;docker build -t ${{ secrets.ECR_REGISTRY }}/my-app:latest .&lt;/span&gt;
          &lt;span class="s"&gt;echo "IMAGE_TAG=$IMAGE_TAG" &amp;gt;&amp;gt; $GITHUB_ENV&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;Push Docker image to AWS ECR&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;IMAGE_TAG=${{ env.IMAGE_TAG }}&lt;/span&gt;
          &lt;span class="s"&gt;docker push ${{ secrets.ECR_REGISTRY }}/my-app:$IMAGE_TAG&lt;/span&gt;

  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&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;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Development&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.ref == 'refs/heads/develop'&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "Deploying to development environment"&lt;/span&gt;
          &lt;span class="s"&gt;# Your deployment script here&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;Deploy to Staging&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.ref == 'refs/heads/staging'&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "Deploying to staging environment"&lt;/span&gt;
          &lt;span class="s"&gt;# Your deployment script here&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;Manual Approval for Production&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.ref == 'refs/head/main'&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hmarr/auto-approve-action@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;github-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&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;Deploy to Production&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.ref == 'refs/heads/main'&lt;/span&gt;
          &lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "Deploying to production environment"&lt;/span&gt;
          &lt;span class="s"&gt;# Your deployment script here&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Before getting into the code review, here’s a high-level overview of what the workflow file accomplishes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;triggers the CI/CD pipeline on pushes and pull requests to the main, develop, and staging branches, ensuring continuous integration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;executes a linting workflow that checks the syntax of the YAML configuration and installs the necessary dependencies for the application to ensure code quality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;sets up Terraform to manage and provision the cloud infrastructure needed for the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;executes tests to validate the functionality of the application and checks for vulnerabilities, ensuring the code is secure and stable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;builds and tags a Docker image for the application, preparing it for deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pushes the Docker image to AWS Elastic Container Registry (ECR), enabling easy access for deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;deploys the application to different environments (development, staging, and production) based on the branch, including a manual approval step for production deployments to ensure control and oversight.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having examined the workflow.yaml configuration file and its various components, we now delve into the individual section, starting with the summary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary 
&lt;/h3&gt;

&lt;p&gt;This summary serves as an essential first step in the review process, offering a clear and concise overview of the changes introduced in the latest commit. It provides a quick understanding of the key aspects covered, including new features, styling adjustments, configuration changes, and other relevant modifications raised in the pull request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp09d2vp965scjgx5tk86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp09d2vp965scjgx5tk86.png" alt="Summary By CodeRabbit" width="800" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above snippet highlights important maintenance tasks, including running the application in non-debug mode for improved performance and implementing an automated CI/CD pipeline to streamline code linting, building, and deployment processes.  &lt;/p&gt;

&lt;p&gt;This summary helps in understanding the key changes and enhancements made in the latest commit. &lt;/p&gt;

&lt;p&gt;After reviewing the key changes in the Summary, we can explore the Walkthrough section of the report, which provides a detailed breakdown of specific modifications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Walkthrough
&lt;/h3&gt;

&lt;p&gt;This section provides a comprehensive overview of the specific modifications made across different files in the latest commit. Each file is assessed for its unique contributions to the project, ensuring clarity on how these changes enhance the overall functionality and user experience.&lt;/p&gt;

&lt;p&gt;The Changes Table serves as a concise summary of specific modifications made across various files in the latest commit, allowing developers to quickly identify where changes have occurred within the codebase. &lt;/p&gt;

&lt;p&gt;Each row indicates an altered file, accompanied by a detailed description of the modifications in the Change Summary column. This includes updates related to styling in CSS files, application logic functionality adjustments, and CI/CD pipeline configuration enhancements.&lt;/p&gt;

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

&lt;p&gt;By presenting this information in a structured format, the table offers clarity and organization, making it easier for developers to digest and understand the impact of each change on the project. &lt;/p&gt;

&lt;p&gt;Overall, It acts as an essential reference for collaboration, enabling team members to focus on pertinent areas that may require further discussion or review while tracking the evolution of the codebase. To add some fun elements, it generates a poem for your errors. &lt;/p&gt;

&lt;h3&gt;
  
  
  Code Review
&lt;/h3&gt;

&lt;p&gt;The following section thoroughly examines the configuration file, identifying areas for enhancements. From improving caching strategies to optimizing deployment processes, these recommendations are designed specifically to code to enhance your GitHub Actions workflow's overall efficiency and robustness.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cjl62w3dvk1jfkhb14r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cjl62w3dvk1jfkhb14r.png" alt="Code Review" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It provides details and an overview of the &lt;strong&gt;actionable comments&lt;/strong&gt; about the review details, the configuration used, the review profile, the files selected for processing, and the additional context used. These can also include one-click commit suggestions.&lt;/p&gt;

&lt;p&gt;Let us look at the various review comments that CodeRabbit suggested for various sections of the workflow file. It automatically detects that the configuration file is a GitHub Actions workflow and uses actionlint to analyze it thoroughly. During the review, CodeRabbit provides valuable insights and suggestions for optimizing performance. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhelw2y0ngy5pi56nls3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhelw2y0ngy5pi56nls3e.png" alt="Code Review using actionlint" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our lint job it identified an opportunity to cache npm dependencies using &lt;code&gt;actions/cache@v3&lt;/code&gt;. By recommending the addition of a caching step before the linting process it helps reduce execution time for subsequent runs. This proactive feedback streamlines workflows without requiring manual intervention, ensuring a more efficient and optimized CI/CD pipeline.&lt;/p&gt;

&lt;p&gt;As it points out, the caching step is incorrectly structured. The run command (npm install) is placed within the uses block of the cache action, which could lead to improper execution.&lt;/p&gt;

&lt;p&gt;To resolve this, it suggests separating the caching and installation steps. The corrected version moves the cache logic into its own block and ensures the npm install command is executed independently in the next step, using &lt;code&gt;npm ci&lt;/code&gt; for a cleaner, faster installation of dependencies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjjzaxfnefarrmlgcrf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjjzaxfnefarrmlgcrf9.png" alt="Terraform Code Review" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Terraform section of the configuration, it detects a potential issue using a variable for the Terraform version. Additionally, AWS credentials too would cause an issue, especially in plan and apply steps. Lastly, it detects typos in &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;, as even minor mistakes can cause failures in your pipeline's execution.&lt;/p&gt;

&lt;p&gt;It suggests the changes in the configuration that fixes the typos, makes the Terraform version easily updatable, and ensures AWS credentials are available for all Terraform commands.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6xtdsk6n9k6qgjjq62r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6xtdsk6n9k6qgjjq62r.png" alt="Docker Job Code Review" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the docker job, it detects security vulnerabilities as the image is using the latest tag for the Docker image, which can be problematic for image versioning and rollbacks. It suggests configuration changes that consider both the latest tag and a specific version tag (e.g., git SHA) for better traceability and easier rollbacks. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3w6fds82o9os9gkt84h7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3w6fds82o9os9gkt84h7.png" alt="Docker job code review" width="800" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It also detected several potential issues in the deploy job that need attention. The manual approval step uses an auto-approve action, which defeats its purpose. Further, it finds a syntax error in the production deployment step, and the actual deployment scripts are missing, making the process incomplete. It suggests changes for these potential issues along with the required changes.&lt;/p&gt;

&lt;p&gt;CodeRabbit’s AI-powered analysis showed how configuration file issues were quickly identified, highlighted, and suggested changes. &lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Using CodeRabbit in CI/CD Pipelines
&lt;/h2&gt;

&lt;p&gt;By automating code reviews and providing precise feedback, CodeRabbit improves code quality and ensures that potential issues and vulnerabilities in your CI/CD pipeline are caught early, leading to smoother deployments and fewer errors. &lt;/p&gt;

&lt;p&gt;Let us look at some of the larger benefits of using CodeRabbit in CI/CD pipelines:&lt;/p&gt;

&lt;h3&gt;
  
  
  Enhanced Developer Productivity
&lt;/h3&gt;

&lt;p&gt;By performing automated static checking workflows, CodeRabbit reduces the need for manual reviews and enables DevOps engineers to focus on strategic tasks like optimizing infrastructure and deployment processes rather than fixing configuration issues. Its instant feedback loop ensures issues are detected quickly and addressed after every commit, allowing you to maintain a rapid development pace. &lt;/p&gt;

&lt;h3&gt;
  
  
  Improved Code Quality
&lt;/h3&gt;

&lt;p&gt;CodeRabbit enforces consistent configuration standards by automatically validating configuration files against the best practices and catching configuration errors early. The platform learns from the previous review, intelligently suppresses repetitive alerts and allows you to focus on the most critical issues, making code reviews more efficient without compromising on thoroughness. CodeRabbit can also provide one-click suggestions that you can quickly integrate into your configuration files. &lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;CodeRabbit helps DevOps engineers catch security vulnerabilities early, such as misconfigured access controls or insecure settings, reducing the chance of breaches. By integrating static checks into the CI/CD process, CodeRabbit prevents configuration errors from causing deployment failures, ensuring a more stable and reliable software delivery pipeline.&lt;/p&gt;

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

&lt;p&gt;We saw in this post how misconfigurations can lead to delays, security vulnerabilities, or even broken deployments, making it essential to test them just as rigorously as application code. &lt;/p&gt;

&lt;p&gt;Unlike traditional approaches that overlook the criticality of testing configuration files, &lt;a href="https://coderabbit.ai" rel="noopener noreferrer"&gt;CodeRabbit&lt;/a&gt; helps review CI/CD pipelines by automating code/config reviews, catching critical errors, and enhancing overall code quality. It significantly reduces manual review time, allowing DevOps teams to focus on strategic tasks and accelerate deployment cycles. &lt;/p&gt;

&lt;p&gt;Experience the impact of AI code review on your workflows – &lt;a href="https://coderabbit.ai/" rel="noopener noreferrer"&gt;start your free CodeRabbit trial today&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>cicd</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Treat Your Developers As Customers - Platform Engineering</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Thu, 22 Feb 2024 06:50:00 +0000</pubDate>
      <link>https://dev.to/techmaharaj/treat-your-developers-as-customers-platform-engineering-3gh8</link>
      <guid>https://dev.to/techmaharaj/treat-your-developers-as-customers-platform-engineering-3gh8</guid>
      <description>&lt;p&gt;Do you know what's common between apps like Zomato, Uber, Instagram and the likes? 🤔&lt;/p&gt;

&lt;p&gt;All these apps are built keeping their customers in mind.&lt;/p&gt;

&lt;p&gt;They collect tons of metrics, feedback, and understand usage patterns to decide the roadmap for their apps.&lt;br&gt;
The same analogy can be applied to Platform Engineering as well.&lt;/p&gt;

&lt;p&gt;Treat your developers as your customers and their requirements as features of your platform. 😮&lt;/p&gt;

&lt;p&gt;Understand what your developers do, from what tools they use to the processes they follow. &lt;/p&gt;

&lt;p&gt;These will help you build a customer-focused platform that your developers will like and use. 👨‍💻&lt;/p&gt;

&lt;p&gt;More importantly, enable feedback mechanisms that will help your developers pass on critical feedback that will be useful in shaping your platform. &lt;/p&gt;

&lt;p&gt;Customer-centricity is just one of the tenets of the Product Mindset for building platforms.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://www.infracloud.io/blogs/taking-product-approach-to-building-platforms/"&gt;this blog post&lt;/a&gt;, I've listed other tenets as part of the platform as a product mindset that you can incorporate.&lt;/p&gt;

&lt;p&gt;Follow me &lt;a href="https://twitter.com/TheTechMaharaj"&gt;@TheTechmaharaj&lt;/a&gt; on Twitter for more updates on platform engineering, DevOps, Kubernetes, and Cloud Native in general. &lt;/p&gt;

&lt;p&gt;For Food and Travel content, check out my blog [socialmaharaj.com](&lt;a href="https://socialmaharaj.com"&gt;https://socialmaharaj.com&lt;/a&gt;] or follow &lt;a href="https://instagram.com/Atulmaharaj"&gt;@Atulmaharaj&lt;/a&gt; on Instagram or &lt;a href="https://twitter.com/Atulmaharaj"&gt;@Atulmaharaj&lt;/a&gt; on Twitter.&lt;/p&gt;

</description>
      <category>platformenginering</category>
      <category>product</category>
      <category>developer</category>
    </item>
    <item>
      <title>NPCI Releases Falcon: An Open source Hyperledger Fabric Deployment Helper for Kubernetes</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Wed, 30 Aug 2023 04:42:39 +0000</pubDate>
      <link>https://dev.to/techmaharaj/npci-releases-falcon-an-open-source-hyperledger-fabric-deployment-helper-for-kubernetes-nak</link>
      <guid>https://dev.to/techmaharaj/npci-releases-falcon-an-open-source-hyperledger-fabric-deployment-helper-for-kubernetes-nak</guid>
      <description>&lt;p&gt;Hot off the press!&lt;/p&gt;

&lt;p&gt;National Payments Corporation Of India (NPCI) just jumped on the #OpenSource bandwagon by releasing Falcon - a Hyperledger Foundation Fabric Deployment Helper for #Kubernetes. It's a huge moment for India, open source &amp;amp; and #blockchain enthusiasts. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--veugYrCy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fvkyvcy9xyof4gbct0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--veugYrCy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fvkyvcy9xyof4gbct0m.png" alt="NPCI goes open source" width="641" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's understand what Falcon does in this short blog post.&lt;/p&gt;

&lt;p&gt;▶ But before that, what is Hyperledger? ⛓️&lt;/p&gt;

&lt;p&gt;Hosted by The Linux Foundation - Hyperledger is a hub for various blockchain frameworks, tools, and libraries designed for enterprise use cases. It has a range of projects that focus on creating, deploying, and operating distributed ledgers.&lt;/p&gt;

&lt;p&gt;▶ Kubernetes on the other hand comes with a suite of benefits in terms of scaling, high availability, resource management, and orchestration. So anything that runs on Kubernetes can take advantage of it. Hyperledger too can be deployed on Kubernetes, but has its own challenges.&lt;/p&gt;

&lt;p&gt;▶ Deploying any blockchain solution on Kubernetes is difficult due to:&lt;/p&gt;

&lt;p&gt;1️⃣ Complex Network Setup&lt;br&gt;
2️⃣ Data Persistence&lt;br&gt;
3️⃣ Consensus Mechanisms&lt;br&gt;
4️⃣ Distributed Ledger Scalability&lt;/p&gt;

&lt;p&gt;That's where Falcon comes in.&lt;/p&gt;

&lt;p&gt;▶ Falcon helps simplify setting up, configuring, and maintaining Fabric nodes, peers, orderers, and channels within a Kubernetes environment. Templatized and customizable helm charts help deploy Hyperledger networks easily.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Chaincode Lifecycle Management&lt;/li&gt;
&lt;li&gt;Channel Management&lt;/li&gt;
&lt;li&gt;Peer &amp;amp; Order Creation&lt;/li&gt;
&lt;li&gt;CA management and more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;▶ But wait, is this production ready?&lt;/p&gt;

&lt;p&gt;Well, Falcon is utilized across multiple #blockchain projects within NPCI.&lt;/p&gt;

&lt;p&gt;While most of us relate NPCI with #UPI, it's great to get a sneak peek into the cutting edge infra power it!&lt;/p&gt;

&lt;p&gt;Check out their repo for more details 👉 &lt;a href="https://github.com/npci/falcon"&gt;https://github.com/npci/falcon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS: They're open for contributions, so go ahead and leave a mark in making a global payment network that's second to none!&lt;/p&gt;

&lt;h1&gt;
  
  
  NPCI #UPI #Blockchain #Kubernetes #CloudNative #OpenSource #NewsUpdate #Falcon
&lt;/h1&gt;

</description>
      <category>blockchain</category>
      <category>kubernetes</category>
      <category>opensource</category>
      <category>news</category>
    </item>
    <item>
      <title>First Thoughts On Threads By Meta</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Thu, 06 Jul 2023 10:50:03 +0000</pubDate>
      <link>https://dev.to/techmaharaj/first-thoughts-on-threads-by-meta-3pdf</link>
      <guid>https://dev.to/techmaharaj/first-thoughts-on-threads-by-meta-3pdf</guid>
      <description>&lt;p&gt;While I was busy un-tangling the different threads at work and life in general, a new thread emerged today morning. If you don't know what I'm talking about, then you probably are living under a rock. &lt;/p&gt;

&lt;p&gt;Launched by Meta, Threads is a social media platform with a stark resemblance to Twitter. While Twitter is dealing with its share of problems, Threads is a refreshing take on Twitter with many features work in progress.&lt;/p&gt;

&lt;p&gt;And yes, like everyone else, I too searched for Threads on my Instagram app and joined Threads. &lt;/p&gt;

&lt;p&gt;A few things that I noticed after using it briefly:&lt;/p&gt;

&lt;p&gt;👍 The signup process is one of the simplest among any other platforms - Mastodon, Bluesky etc. Being tightly coupled with Instagram, it takes everything (Profile picture, bio, links, followers etc.) from your Instagram profile to sign you up on Threads. This seamless process makes user onboarding easier, and that's why it has had more than 11 Mn sign-ups within 4 hours of launch! &lt;/p&gt;

&lt;p&gt;📱 Currently only a mobile app, Threads is text-only. It does support photos, but no videos or GIFs at the moment. &lt;/p&gt;

&lt;p&gt;📝 Creating threads on the Thread app is super-easy, much easier than Twitter. If you've used Typefully on the web, you know this looks very similar to that.&lt;/p&gt;

&lt;p&gt;🎉 Ad-free at the moment, with no ads whatsoever on the feed.&lt;/p&gt;

&lt;p&gt;🤔 The interesting thing here is, Instagram has creators who mostly create video content nowadays. So how does onboarding them to a text-only platform work? Because their skill is video and not text and currently my feed is full of photos and links to reels.&lt;/p&gt;

&lt;p&gt;🤷‍♂️ Maybe creating a Reels app and making Instagram all about photos again, could have been better. Or make Threads a standalone platform without the integration with Instagram.&lt;/p&gt;

&lt;p&gt;🚨 PS: You cannot delete your Thread account. If you want to, you need to delete your Instagram account.&lt;/p&gt;

&lt;p&gt;PPS: You can follow me on Threads for more non-work content: &lt;a href="https://www.threads.net/@atulmaharaj"&gt;https://www.threads.net/@atulmaharaj&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also follow me on my blog at &lt;a href="https://socialmaharaj.com"&gt;https://socialmaharaj.com&lt;/a&gt; &lt;/p&gt;

</description>
      <category>socialmedia</category>
      <category>news</category>
    </item>
    <item>
      <title>Understanding Authentication &amp; Authorization in Istio</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Thu, 29 Jun 2023 09:07:24 +0000</pubDate>
      <link>https://dev.to/techmaharaj/understanding-authentication-authorization-in-istio-kbm</link>
      <guid>https://dev.to/techmaharaj/understanding-authentication-authorization-in-istio-kbm</guid>
      <description>&lt;p&gt;Modern organizations are increasingly adopting a distributed approach to application development, harnessing the power of microservices and leveraging Kubernetes for hosting. This paradigm shift offers unparalleled flexibility and scalability, aligning with evolving customer expectations. However, this transformation also introduces security concerns as numerous services interact, necessitating robust measures to safeguard sensitive data.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;service mesh,&lt;/strong&gt; which play a pivotal role in addressing these challenges. Not only do they streamline the management of microservices, relieving developers of operational complexities, but they also offer robust security features. Service mesh handles crucial tasks such as authentication, authorization, and routing, bolstering the security of your application.&lt;/p&gt;

&lt;p&gt;In this blog post, we will explore Istio, the service mesh tool we use, and how we leverage its capabilities to implement authentication and authorization policies, bolstering the security of our application."&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of security options in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Being one of the most preferred choices for container orchestration tools, Kubernetes provides a suite of security options out of the box. From the widely used &lt;a href="https://www.infracloud.io/blogs/role-based-access-kubernetes/"&gt;Role Based Access Control (RBAC)&lt;/a&gt; to &lt;a href="https://kubernetes.io/docs/concepts/security/pod-security-admission/"&gt;Pod Security Admission&lt;/a&gt; and &lt;a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/"&gt;Network Policies&lt;/a&gt;, Kubernetes does provide a basic level of security. &lt;/p&gt;

&lt;p&gt;Network policies allow organizations to define and enforce network-level rules within a cluster using ingress and egress rules. These allow for fine-grained control over the traffic flow between pods, namespaces, and other endpoints. These work at the IP address or port level - OSI Layer 3 or 4 to control the flow of traffic. By default, a pod allows all inbound and outbound connections and these can be controlled by using &lt;code&gt;to&lt;/code&gt; and &lt;code&gt;from&lt;/code&gt; selectors. Read more about &lt;a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/"&gt;network policies&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitations of Kubernetes network policies
&lt;/h3&gt;

&lt;p&gt;While network policies do provide a basic form of security, they lack some vital features that are required for production-grade deployments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network Policies in Kubernetes focus on controlling traffic between pods based on IP addresses, ports, and protocols. However, they do not provide a mechanism to force internal cluster traffic to go through a common gateway.&lt;/li&gt;
&lt;li&gt;Handling TLS-related tasks, such as SSL termination, certificate management, and encryption, is not a native feature of Network Policies. These do not directly handle TLS-related configurations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/#what-you-can-t-do-with-network-policies-at-least-not-yet"&gt;As recommended by Kubernetes&lt;/a&gt;, a service mesh emerges as a powerful solution to overcome the above limitations of network policies. It offers advanced traffic routing capabilities along with a comprehensive TLS approach. You can read our blog post on &lt;a href="https://www.infracloud.io/blogs/service-mesh-101/"&gt;demystifying service mesh&lt;/a&gt; to learn more about service meshes.&lt;/p&gt;

&lt;p&gt;Let’s see how service meshes differ from Kubernetes network policies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of service mesh over Kubernetes network policies
&lt;/h2&gt;

&lt;p&gt;While network policies primarily handle network-level segmentation, a service mesh goes beyond that, offering a more comprehensive solution for managing and securing microservice within a cluster. &lt;/p&gt;

&lt;p&gt;Let us examine the differences between a service mesh and Kubernetes network policies.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Kubernetes Network Policies&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Service Mesh&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Traffic Management&lt;/td&gt;
&lt;td&gt;Basic segmentation based on IP, ports, and protocols&lt;/td&gt;
&lt;td&gt;Advanced features like routing, load balancing, service discovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;Limited or no built-in observability&lt;/td&gt;
&lt;td&gt;Advanced observability and metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;No direct support for TLS&lt;/td&gt;
&lt;td&gt;Comprehensive TLS support and encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Granularity&lt;/td&gt;
&lt;td&gt;Pod-level network control&lt;/td&gt;
&lt;td&gt;Fine-grained control over service-to-service traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;Simpler configuration and management&lt;/td&gt;
&lt;td&gt;Additional complexity due to additional components (sidecar proxies)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ecosystem Integration&lt;/td&gt;
&lt;td&gt;Specific to Kubernetes ecosystem&lt;/td&gt;
&lt;td&gt;Works with any container orchestrator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When it comes to managing microservices communication and securing your Kubernetes environment, a service mesh offers distinct advantages over Kubernetes Network Policies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native support for mTLS and JWT authentication:&lt;/strong&gt; Most of the service meshes provide out-of-the-box support for mutual Transport Layer Security (mTLS) and JSON Web Token (JWT) authentication. This assures secure communication between microservices by encrypting data in transit along with secured authentication mechanisms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Control and visibility over network traffic:&lt;/strong&gt; A service mesh offers advanced traffic management capabilities, such as intelligent routing, load balancing, and circuit breaking. It provides fine-grained control over network traffic, allowing you to implement traffic-shaping strategies, and &lt;a href="https://www.infracloud.io/observability-consulting/"&gt;observability&lt;/a&gt; features like metrics, logs, and distributed tracing out of the box.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fine-grained access control through RBAC policies:&lt;/strong&gt; Service meshes also enable granular access control through Role-Based Access Control (RBAC) policies. You can write and enforce policies that govern which services can communicate with each other, based on specific criteria like service identity, namespace, or labels.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are different types of service meshes available today and most of them offer these capabilities. In the following section, we’ll shift our focus to Istio and learn about its authentication and authorization options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Istio - empowering authentication and authorization
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://istio.io"&gt;Istio&lt;/a&gt; is a popular open source service mesh that seamlessly integrates with Kubernetes. It unlocks advanced capabilities ranging from traffic management to observability and security. Istio acts as an infrastructure layer between application services – enabling transparent and intelligent communication between them. Service mesh enhances the control and reliability of your Kubernetes deployments. Its core features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Traffic management:&lt;/strong&gt; Istio enables fine-grained control over traffic routing, load balancing, and fault tolerance through intelligent routing rules. It offers capabilities like weighted routing, circuit breaking, and retries to optimize traffic flow and ensure robustness. One can also use &lt;a href="https://www.infracloud.io/blogs/progressive-delivery-service-mesh-argo-rollouts-istio/"&gt;Istio for progressive delivery&lt;/a&gt; and automate your application deployments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Observability:&lt;/strong&gt; Istio provides comprehensive observability through metrics, distributed tracing, and logging. You can monitor and analyze service-level performance, latency, and error rates to identify and resolve issues effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt; Istio strengthens the security of your Kubernetes environment by providing secure communication between services through automatic mutual TLS encryption. It also offers features like access control, authentication, and authorization through robust identity and security policies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These were just a few features of Istio. You can refer to &lt;a href="https://istio.io/latest/about/service-mesh/"&gt;Istio’s documentation&lt;/a&gt; for the complete list of features. &lt;/p&gt;

&lt;p&gt;Of all these, security is going to be the focus of our discussion going forward. We’ll understand the various options it provides from a security perspective.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;mTLS for service-to-service communication:&lt;/strong&gt; mTLS (mutual Transport Layer Security) is a security mechanism that ensures encrypted and authenticated communication between services. Istio provides native support for mTLS encryption, ensuring secure communication between services within the cluster. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authorization and authentication with JWT tokens:&lt;/strong&gt; Istio adds an additional layer of security by utilizing JSON Web Tokens (JWT) for authorization and authentication. Services can verify the authenticity of JWT tokens to grant access based on the claims contained within the token. This helps prevent unauthorized requests and enhances overall security.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Allow/Deny &amp;amp; custom policies:&lt;/strong&gt; Istio allows the creation of Allow/Deny policies to define which services are allowed or denied communication based on various criteria such as source, destination, and other attributes. Additionally, Istio enables the creation of custom policies to meet specific security requirements, providing granular control over service-to-service communication.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementing authentication and authorization policies in Istio
&lt;/h2&gt;

&lt;p&gt;In the preceding sections, we learned about various security features that Istio provides. We’ll now see how to implement these in a microservices-based application deployed on a Kubernetes cluster. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes cluster - &lt;em&gt;we’re using Minikube for this blog post&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Microservices-based application - &lt;em&gt;we’re using the &lt;a href="https://github.com/GoogleCloudPlatform/microservices-demo"&gt;Online Boutique application&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Setting up Istio
&lt;/h4&gt;

&lt;p&gt;Setting up Istio on our Kubernetes cluster is fairly simple and the official documentation is perfect for it. At a very high level, there are three things that need to be done:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://istio.io/latest/docs/setup/getting-started/#download"&gt;Download&lt;/a&gt; the latest version of Istio &amp;amp; configure &lt;code&gt;istioctl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://istio.io/latest/docs/setup/getting-started/#install"&gt;Install Istio&lt;/a&gt; using the &lt;a href="https://istio.io/latest/docs/setup/additional-setup/config-profiles/"&gt;demo profile&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Enable automatic sidecar injection for the default namespace using &lt;code&gt;kubectl label namespace default istio-injection=enabled&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this, we have configured Istio on our cluster and enabled automatic sidecar injection in the default namespace. Any application we now install to the default namespace will have the sidecar injected automatically.&lt;/p&gt;

&lt;h4&gt;
  
  
  Deploy online boutique application
&lt;/h4&gt;

&lt;p&gt;The next step is to deploy the Online Boutique application. &lt;/p&gt;

&lt;p&gt;Clone the repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://github.com/GoogleCloudPlatform/microservices-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy the application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; ./release/kubernetes-manifests.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify deployment&lt;br&gt;
&lt;/p&gt;

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

NAMESPACE    NAME                                   READY   STATUS  AGE
default      adservice-5f58d84d94-pjgsk             2/2     Running   2m34s
default      cartservice-58c4f996f5-jssdl           2/2     Running   2m34s
default      checkoutservice-65886cf7fb-mnxhv       2/2     Running   2m34s
default      currencyservice-645c6dd8-rz9pq         2/2     Running   2m34s
default      emailservice-7956996f78-2rtqt          2/2     Running   2m34s
default      frontend-78f8447ffd-fvx7j              2/2     Running   2m34s
default      loadgenerator-5cdd7f7bfc-dcgmg         2/2     Running   2m34s
default      paymentservice-767f89d888-pz7jc        2/2     Running   2m34s
default      productcatalogservice-5dbbcc58b6-fv8xh   2/2   Running   2m34s
default      recommendationservice-f5d756558-dxnwh  2/2     Running   2m34s
default      redis-cart-66fc6f5646-vrfds            2/2     Running   2m34s
default      shippingservice-9c9675994-rdr7v        2/2     Running   2m34s

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

&lt;/div&gt;



&lt;p&gt;We can see that the application is deployed successfully. If we observe closely, we see that every pod has 2 containers and that’s because of the automatic sidecar injection that we enabled.&lt;/p&gt;

&lt;p&gt;We can also access the application using the URL of the &lt;code&gt;frontend-external&lt;/code&gt; service. Type &lt;code&gt;minikube service list&lt;/code&gt; and click on the URL against the &lt;code&gt;frontend-external&lt;/code&gt; service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3EOeh5RS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ypitdsdns0nlzxwk5a6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3EOeh5RS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ypitdsdns0nlzxwk5a6h.png" alt="Deploying Online Boutique Store" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing mTLS
&lt;/h3&gt;

&lt;p&gt;By default all the communication that happens within the cluster is not encrypted i.e.: both TLS and plain text traffic are accepted. We can check that by accessing the &lt;code&gt;frontend&lt;/code&gt; service from a pod using a cURL request as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pod &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;productcatalogservice &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;.items..metadata.name&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; istio-proxy &lt;span class="nt"&gt;--&lt;/span&gt; curl http://frontend:80/ &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We can see that the response is &lt;code&gt;200&lt;/code&gt;, this means that the service is accessible without any authentication mechanism in place. &lt;/p&gt;

&lt;p&gt;We can implement mTLS per service or for the entire namespace. Use the following yaml file to enable &lt;code&gt;strict&lt;/code&gt; mTLS for the complete namespace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;security.istio.io/v1beta1"&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PeerAuthentication"&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default"&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default"&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mtls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;STRICT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply this configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; mtls-ns.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s execute the same that we used earlier to access the &lt;code&gt;frontend&lt;/code&gt; service from another pod.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pod &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;productcatalogservice &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;.items..metadata.name&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; istio-proxy &lt;span class="nt"&gt;--&lt;/span&gt; curl http://frontend:80/ &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt;
000
&lt;span class="nb"&gt;command &lt;/span&gt;terminated with &lt;span class="nb"&gt;exit &lt;/span&gt;code 56
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HTTP Response code is not 200. Instead, the command terminates with exit &lt;a href="https://curl.se/libcurl/c/libcurl-errors.html"&gt;code 56&lt;/a&gt;. This means that the request failed to receive any data and this is because there was no TLS certificate that was passed with the request. If you want to know more, read this thread on &lt;a href="https://discuss.istio.io/t/how-do-i-take-istio-mtls-tcpdump/9795/4"&gt;istio mTLS proof with tcpdump&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With this, we have enabled &lt;code&gt;strict&lt;/code&gt; mTLS for the entire namespace and every request has to be mTLS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If mTLS is set to &lt;code&gt;strict&lt;/code&gt; and your application is exposed using ingress controller, make sure to inject the Istio sidecar inside the Ingress controller as well else It won’t be able to communicate with the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing JWT authentication
&lt;/h3&gt;

&lt;p&gt;Istio also provides authentication mechanisms for secured access. We will now enable origin authentication using JWT tokens. We first need to create and apply a policy that will enforce JWT authentication. &lt;/p&gt;

&lt;p&gt;But before doing that we need to create a public-private key pair using which we will create JWT token that will be used. &lt;/p&gt;

&lt;h4&gt;
  
  
  Key generation
&lt;/h4&gt;

&lt;p&gt;Generate public/private keys using the following commands:&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="nv"&gt;$ &lt;/span&gt;openssl genrsa &lt;span class="nt"&gt;-des3&lt;/span&gt; &lt;span class="nt"&gt;-out&lt;/span&gt; private_encrypted.pem 2048
&lt;span class="nv"&gt;$ &lt;/span&gt;openssl rsa &lt;span class="nt"&gt;-pubout&lt;/span&gt; &lt;span class="nt"&gt;-in&lt;/span&gt; private_encrypted.pem &lt;span class="nt"&gt;-out&lt;/span&gt; public.pem
&lt;span class="nv"&gt;$ &lt;/span&gt;openssl rsa &lt;span class="nt"&gt;-in&lt;/span&gt; private_encrypted.pem &lt;span class="nt"&gt;-out&lt;/span&gt; private.pem &lt;span class="nt"&gt;-outform&lt;/span&gt; PEM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are different ways to generate a token, we’ll use a simple Python script to generate a token for us. All the Python files used here are placed in &lt;a href="https://github.com/infracloudio/Python-Key-Generation"&gt;this repo&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;authlib.jose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;

&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'alg'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'RS256'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'iss'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'admin@infracloud.io'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'sub'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'exp'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1685505001&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'private.pem'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'r'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'utf-8'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we provide the details like issuer, subject, and expiry time along with the private key. The code will generate a token.&lt;/p&gt;

&lt;p&gt;We then need to generate JWK that we’ll pass as a parameter in Istio’s policy configuration yaml. We’ll use another simple Python script to do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;authlib.jose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jwk&lt;/span&gt;
&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'public.pem'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'r'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'RSA'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass the public key file that we generated earlier and this will generate the JWK key that is required to create the Istio policy.&lt;/p&gt;

&lt;h4&gt;
  
  
  Policy creation
&lt;/h4&gt;

&lt;p&gt;We will create a yaml configuration file that will enforce JWT authentication for all incoming requests to the &lt;code&gt;frontend&lt;/code&gt; service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;security.istio.io/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RequestAuthentication&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;frontend&lt;/span&gt;
 &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;frontend&lt;/span&gt;
  &lt;span class="na"&gt;jwtRules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;forwardOriginalToken&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;issuer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin@infracloud.io&lt;/span&gt;
    &lt;span class="na"&gt;jwks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;{"keys": [{"n": "&amp;lt;actual-key&amp;gt;", "e": "AQAB", "kty": "RSA"}]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Replace &lt;code&gt;&amp;lt;actual-key&amp;gt;&lt;/code&gt; with your actual key.&lt;/p&gt;

&lt;p&gt;Apply the file to enforce the policy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; jwt.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let us make a request to the frontend by passing the authentication token. We can create a variable named TOKEN and pass it in the cURL request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pod &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;productcatalogservice &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;.items..metadata.name&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; istio-proxy &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt; curl  http://frontend:80/ &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt;
200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us remove the token and retry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pod &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;productcatalogservice &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;.items..metadata.name&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; istio-proxy &lt;span class="nt"&gt;--&lt;/span&gt; curl  http://frontend:80/ &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt;
403
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We get an &lt;code&gt;HTTP 403 - Forbidden&lt;/code&gt; response, which validates that our policy is working as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing authorization
&lt;/h3&gt;

&lt;p&gt;Authentication refers to the “who” should be allowed access while Authorization refers to “what” they are allowed to access. For instance, a user request with a valid token can access the frontend service. Let us understand that through a simple example.&lt;/p&gt;

&lt;p&gt;Create a new yaml configuration to enable authorization&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;security.istio.io/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AuthorizationPolicy&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;require-jwt&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;frontend&lt;/span&gt;
  &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ALLOW&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;request.auth.claims[iss]&lt;/span&gt;
      &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admin@infracloud.io"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;request.headers[hello]&lt;/span&gt;
      &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;world"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this AuthorizationPolicy, we validate the issuer of the key for every request. In this case, it’s supposed to be &lt;code&gt;admin@infracloud.io&lt;/code&gt;. If you remember, while creating a JWT token, we provided this as the issuer. We also mention that there has to be a header named &lt;code&gt;hello&lt;/code&gt; and its value must be &lt;code&gt;world&lt;/code&gt; So only those requests which have a token that is issued by &lt;code&gt;admin@infracloud.io&lt;/code&gt; and a valid header will be able to access the frontend service.&lt;/p&gt;

&lt;p&gt;Let us apply this policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; authz.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let us first access the service without a token and a header and see what response we get.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pod &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;productcatalogservice &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;.items..metadata.name&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; istio-proxy &lt;span class="nt"&gt;--&lt;/span&gt; curl  http://frontend:80/ &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt;
403
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is &lt;code&gt;HTTP 403 - Forbidden&lt;/code&gt;, as expected. If we pass a valid token, we get &lt;code&gt;HTTP 200 - Success&lt;/code&gt;. This means the policy is working just fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pod &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;productcatalogservice &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;.items..metadata.name&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; istio-proxy &lt;span class="nt"&gt;--&lt;/span&gt; curl  http://frontend:80/ &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"hello:world"&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt;
200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us also see this using postman. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rRtDsPOH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6z62e8gsy8nbfdmpmnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rRtDsPOH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6z62e8gsy8nbfdmpmnw.png" alt="Postman" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We get &lt;code&gt;RBAC:access denied&lt;/code&gt; error when we pass the header as &lt;code&gt;hello:test&lt;/code&gt; instead of &lt;code&gt;hello:world&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the user tries to access any other service even with a valid token and a header, it will be denied as the authorization policy that we’ve created allows access only to the frontend service and nothing else. &lt;/p&gt;

&lt;p&gt;Hence, using mTLS, JWT Authentication, and Authorization policies, Istio provides finer controls over who accesses your services and what they can do. This fine-grained control is missing in the native options provided in Kubernetes and hence a service mesh like Istio is preferred. You can configure these policies based on your requirements to secure your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Safeguarding the safety and integrity of our applications, authentication, and authorization are of utmost importance. While Kubernetes does offer some solutions out-of-the-box, they fail to provide finer access control options. That’s where service meshes shine and a tool like Istio takes center stage.&lt;/p&gt;

&lt;p&gt;Istio simplifies the implementation of authentication and authorization and provides a seamless solution for controlling access. With Istio, we get fine-grained control over who accesses what which helps us fortify our applications. &lt;/p&gt;

&lt;p&gt;While the blog post showed how easy it is to leverage Istio, in real-world applications, things are much more complicated. There might be hundreds of services, spread across different clusters accessed by thousands of users. &lt;/p&gt;

&lt;p&gt;If you found this blog post helpful, please share it with your peers. If you feel this can be improved, &lt;a href="https://www.linkedin.com/in/atulpriyasharma/"&gt;connect with me on LinkedIn&lt;/a&gt; to take it forward.&lt;/p&gt;

&lt;p&gt;PS: If you're interested to read about my food &amp;amp; travel chronicles, check out my blog on &lt;a href="https://socialmaharaj.com"&gt;socialmaharaj.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>servicemesh</category>
      <category>tutorial</category>
      <category>security</category>
      <category>cloud</category>
    </item>
    <item>
      <title>CNCF Landscape made easy with CNCF Navigator</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Mon, 05 Jun 2023 08:19:28 +0000</pubDate>
      <link>https://dev.to/techmaharaj/cncf-landscape-made-easy-with-cncf-navigator-1kgc</link>
      <guid>https://dev.to/techmaharaj/cncf-landscape-made-easy-with-cncf-navigator-1kgc</guid>
      <description>&lt;p&gt;Today, CNCF is among the fastest-growing open source communities globally, with over 500 members, promoting cloud native tech adoption. It manages popular projects like Kubernetes, Prometheus, and Envoy, which are some of the crucial components for building resilient and scalable cloud native applications.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll talk about the CNCF landscape, its features &amp;amp; challenges, and how a tool like the CNCF Navigator makes it easy to navigate the CNCF landscape.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the CNCF Landscape
&lt;/h2&gt;

&lt;p&gt;If you’ve ever searched for cloud native tools, you would have surely come across the CNCF Landscape. There are so many tools out there that it is overwhelming to understand all of them and choose the right one for your use case.&lt;/p&gt;

&lt;p&gt;The aim of the CNCF landscape navigator is to bring all open source and proprietary cloud native projects under one umbrella to give a comprehensive overview of the system. This makes it a single point of interaction for finding any cloud native tool. It also helps developers/teams find the right tool for their requirements.&lt;/p&gt;

&lt;p&gt;To bring some system to the chaos, the CNCF landscape created 6 broad categories under which projects are listed. These categories are:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Provisioning&lt;/strong&gt;: Tools that are used to create the foundation on which cloud native apps are built.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime&lt;/strong&gt;: Tools that help a container run in a cloud native environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orchestration &amp;amp; Management&lt;/strong&gt;: Tools that help to handle running &amp;amp; connecting to your cloud native applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Definition &amp;amp; Deployment&lt;/strong&gt;: Tools that help developers build cloud native applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability &amp;amp; Analysis&lt;/strong&gt;: Tools in this category observe all the layers through logging, monitoring &amp;amp; tracing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform&lt;/strong&gt;: These offerings bundle tools from all the above categories &amp;amp; provide them as a single offering so that you don’t need to choose a tool from each category.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are further subcategories to each of the categories listed above. Refer to the CNCF landscape Guide to get a detailed overview.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tOstyX54--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://d33wubrfki0l68.cloudfront.net/64d34ef1895347a61db8163ddc021012d42453fe/358a0/assets/img/blog/cncf-landscape-made-easy-with-cncf-navigator/cncf-cloud-native-interactive-landscape.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tOstyX54--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://d33wubrfki0l68.cloudfront.net/64d34ef1895347a61db8163ddc021012d42453fe/358a0/assets/img/blog/cncf-landscape-made-easy-with-cncf-navigator/cncf-cloud-native-interactive-landscape.png" alt="CNCF Landscape" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CNCF Landscape
&lt;/h2&gt;

&lt;p&gt;Above is a screenshot of the CNCF landscape. Projects with a White background are open source projects and the ones with a Grey background are proprietary projects. Further, the ones with a dark blue label are CNCF graduated projects, ones with light blue are incubating projects. Read more about CNCF project maturity levels.&lt;br&gt;
Benefits of CNCF Landscape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Visual Representation&lt;/strong&gt;: CNCF landscape is a pictorial representation of all the CNCF projects. This graphical representation lists projects based on broad categories thus making it easy to visualize and find different projects. The web version of the landscape is interactive and projects are listed as cards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quick &amp;amp; Easy Access to Information&lt;/strong&gt;: Clicking any project card quickly gives you all the relevant information about the project. Details like the website, GitHub repo, commits &amp;amp; contributions, updates &amp;amp; releases are made available. There are filters available that make it easy to find a project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Promotes Standardization&lt;/strong&gt;: All the projects that are listed in the CNCF landscape have the same set of information available. Project details like repo URL, release history, contributions, etc. are common for all the projects. Further to be listed as a CNCF project, certain requirements need to be fulfilled. This helps bring standardization across projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Up-to-date&lt;/strong&gt;: The landscape is updated regularly to reflect the latest changes &amp;amp; developments in the cloud native ecosystem. This ensures that users always have the latest information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community Driven&lt;/strong&gt;: The landscape is developed &amp;amp; maintained by the CNCF community. Anyone can propose to include their cloud native product to be included in this list by raising a PR.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CNCF landscape offers a comprehensive view of various cloud native technologies &amp;amp; makes it easier for users to explore &amp;amp; discover new technologies. However, as the cloud native landscape is rapidly evolving, the CNCF landscape itself comes with its own set of challenges.&lt;br&gt;
Challenges of CNCF Landscape&lt;/p&gt;

&lt;p&gt;The CNCF landscape is constantly evolving. As we write there are 1100+ projects in the landscape collectively having over 3.6Mn GitHub stars with a total funding of close to $6.7Bn. That’s how vast the landscape is and with newer projects added almost every month, it’s only becoming complex. Below are a few challenges that users face while working with the CNCF landscape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Information Overload&lt;/strong&gt;: One of the major challenges with the CNCF landscape is its sheer size. With so many projects already added and newer ones being added continuously, it becomes difficult for the users to find the right information they need. Not only that, it makes it difficult for them to find the right tool for their requirement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complexity&lt;/strong&gt;: The CNCF landscape in its current form is complex and hence overwhelming. With the wide variety of tools present, users may find it difficult to clearly understand the specific use case and benefits of a project. Further, identifying the right project, and implementing and managing it in itself is a complex task.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of Guidance&lt;/strong&gt;: The landscape lists out all the cloud native-related projects. However, it doesn’t provide users with any guidance in terms of which project would be best for their use case, what stack to use, and so on. Without proper guidance, organizations can find it difficult to choose the right project for their need.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From seasoned organizations to newer ones, all of them find it difficult to navigate through the CNCF landscape due to the challenges listed above. The information overload and the sheer complexity along with the lack of guidance make it difficult for organizations to choose the right cloud native tool for their use case.&lt;/p&gt;

&lt;p&gt;Thus arises a need for a tool that can declutter this information, reduce the complexity and provide tailor-made suggestions to choose the best tool to suit your requirements. Comes in the CNCF Navigator, a tool that helps you easily navigate through the CNCF landscape &amp;amp; identify the best one for your requirement.&lt;/p&gt;

&lt;p&gt;Comes in the CNCF Navigator!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pMNNt5t---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://d33wubrfki0l68.cloudfront.net/61ae793e4cfa0696d299f943b9d2348767f2d141/9c6c7/assets/img/blog/cncf-landscape-made-easy-with-cncf-navigator/cncf-landcape-navigator.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pMNNt5t---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://d33wubrfki0l68.cloudfront.net/61ae793e4cfa0696d299f943b9d2348767f2d141/9c6c7/assets/img/blog/cncf-landscape-made-easy-with-cncf-navigator/cncf-landcape-navigator.gif" alt="CNCF Navigator" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CNCF Navigator
&lt;/h2&gt;

&lt;p&gt;As the name suggests, the tools help you find your way through the vast CNCF landscape and find the right tool for your tech stack. The team spent months together brainstorming and understanding the pain areas associated with identifying the right project.&lt;/p&gt;

&lt;p&gt;The CNCF Landscape Navigator provides the following benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduces Complexity&lt;/strong&gt;: Instead of navigating through the vast CNCF landscape, the CNCF Landscape Navigator comes with an interactive Q&amp;amp;A-based smart recommendation engine that helps identify the best CNCF projects that are right for your use case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Accelerate Time-to-Market&lt;/strong&gt;: The tool helps you find the optimal CNCF projects, for your tailored use case. So, your team can focus on building &amp;amp; shipping solutions that your customers care about without worrying about which project to choose.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try out the &lt;a href="https://www.infracloud.io/landscape-navigator/"&gt;CNCF Navigator&lt;/a&gt; Today!&lt;/p&gt;

&lt;p&gt;In its current form, the CNCF Landscape Navigator can suggest tools for &lt;strong&gt;Monitoring &amp;amp; Logging space, Service Mesh, Progressive Delivery, Serverless, Cost Management, and Security&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Using the CNCF Landscape Navigator is easy. Head to the CNCF Landscape Navigator, and choose any one category from Monitoring, Logging, Service Mesh, Progressive Delivery, Serverless, Cost Management, and Security. Answer a few simple questions and let the CNCF Navigator suggest the best tool for you.&lt;/p&gt;

</description>
      <category>cloudnative</category>
      <category>cncf</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Machine Learning 101: Everything You Need to Know About It</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Wed, 05 Apr 2023 08:42:23 +0000</pubDate>
      <link>https://dev.to/techmaharaj/machine-learning-101-everything-you-need-to-know-about-it-24g0</link>
      <guid>https://dev.to/techmaharaj/machine-learning-101-everything-you-need-to-know-about-it-24g0</guid>
      <description>&lt;p&gt;&lt;em&gt;This blog post is adapted from the blog post "&lt;a href="https://www.infracloud.io/blogs/introduction-to-mlops/"&gt;Introduction to MLOps&lt;/a&gt;" on InfraCloud's blog written by me.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As commonly understood, machine learning is a subset of artificial intelligence that enables computers to learn and make predictions without requiring explicit programming.&lt;/p&gt;

&lt;p&gt;Machine learning finds widespread usage across diverse industries. Its applications range from providing personalized movie recommendations such as on YouTube or Netflix to recognizing your voice commands and activating a fan like Alexa. &lt;/p&gt;

&lt;p&gt;Even sectors like banking rely on it to identify instances of credit card fraud and introduce chatbots to enhance customer service speed. These examples are just a few instances of how machine learning is employed in everyday life.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZIEzzA_H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/32ra2cetioroqk3rm3c7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZIEzzA_H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/32ra2cetioroqk3rm3c7.png" alt="Machine Learning 101: Everything You Need to Know About It" width="880" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Machine Learning
&lt;/h3&gt;

&lt;p&gt;Similar to how humans learn in various ways, there exist techniques by which algorithms can also learn. The following are the three primary categories of machine learning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Supervised&lt;/strong&gt;: Supervised learning involves labeled input data, where certain data points are already tagged with the correct answer. For instance, when working with input data comprising images of fruits, each image would be labeled with the corresponding fruit. From this, the model learns and can produce accurate output for new data based on the labeled data. Regression and classification are two types of supervised learning models.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unsupervised&lt;/strong&gt;: Unsupervised learning refers to input data that is neither labeled nor classified. The algorithm must analyze this data without any prior information. The model must group unsorted input based on patterns and similarities. As an example, you could provide input consisting of unlabeled images of fruits that the algorithm has never seen before. The algorithm will categorize the fruits into groups based on the patterns it identifies. Clustering and Association are two types of unsupervised learning models.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reinforcement&lt;/strong&gt;: Reinforcement learning works based on feedback. The algorithm learns to perform actions in an environment and receives feedback based on those actions. It operates using the trial-and-error method, and over time, the model learns to behave in the environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Machine learning models
&lt;/h3&gt;

&lt;p&gt;Machine learning models are at the core of machine learning. These algorithms are trained on datasets and fine-tuned to provide accurate predictions for new data. The outcome of this process is a machine learning model.&lt;/p&gt;

&lt;p&gt;There exist various types of machine learning models based on the approach they use to predict, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regression models:&lt;/strong&gt; Machine learning models that forecast numerical values are designed to identify relationships between dependent and independent variables to make predictions. A regression model is an instance of this type of model. For example, anticipating the stock price using historical data is a regression model. Linear regression stands out as one of the most commonly employed regression models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2MP6Fc8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pimages.toolbox.com/wp-content/uploads/2022/04/07040339/25-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2MP6Fc8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pimages.toolbox.com/wp-content/uploads/2022/04/07040339/25-4.png" alt="Linear Regression. Courtesy: Spiceworks" title="Linear Regression. Courtesy: Spiceworks" width="720" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Classification models:&lt;/strong&gt; Machine learning models that forecast categorical values are designed to recognize patterns in data and classify them into specific categories. A classification model is an instance of this type of model. For example, classifying emails as spam or non-spam is accomplished using a classification model. Decision trees and random forests are two popular types of classification models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pd7-Jp5D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pimages.toolbox.com/wp-content/uploads/2022/09/02134804/Diagram-depicting-SVM-example-with-hyperplane-for-classification-problem.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pd7-Jp5D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pimages.toolbox.com/wp-content/uploads/2022/09/02134804/Diagram-depicting-SVM-example-with-hyperplane-for-classification-problem.jpg" alt="Classification model. Courtesy: Spiceworks" title="Classification model. Courtesy: Spiceworks" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clustering models:&lt;/strong&gt; Clustering models group data points together by identifying patterns and grouping similar data points into clusters. These models function by grouping data points together based on their similarities. K-Means is an example of a well-known clustering model. For instance, clustering models are used to group customers based on their purchase history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--imS_3zir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://data-flair.training/blogs/wp-content/uploads/sites/2/2019/08/clustering-in-machine-learning.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--imS_3zir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://data-flair.training/blogs/wp-content/uploads/sites/2/2019/08/clustering-in-machine-learning.png" alt="Clustering models. Courtesy: DataFlair" title="Clustering models. Courtesy: DataFlair" width="785" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Neural Network Models:&lt;/strong&gt; Neural network models are utilized for intricate tasks, including speech and vision, inspired by the human brain. These models operate by leveraging layers of artificial neurons to detect complex patterns in data. Convolutional Neural Network is one of the most widely employed neural network models and is extensively used for image recognition.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D-6F8Jdg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://otexts.com/fpp2/nnet2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D-6F8Jdg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://otexts.com/fpp2/nnet2.png" alt="Neural network model. Courtesy: Otexts" title="Neural network model. Courtesy: Otexts" width="880" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Machine Learning Development: Existing Challenges
&lt;/h2&gt;

&lt;p&gt;Despite the progress made in the Artificial Intelligence (AI) and machine learning field, the advancement of associated processes has been slow-paced. Many organizations currently utilize machine learning models for various use cases; however, most of these processes are manual and present several challenges.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data quality and management:&lt;/strong&gt; The performance of a machine learning model can be negatively impacted by incomplete or incorrect data. Working manually with various data sources and formats is prone to errors and can impede the process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model complexity:&lt;/strong&gt; Over time, machine learning models can become intricate due to evolving data and environments. The deployment, scaling, and management of complex models can be challenging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reproducibility:&lt;/strong&gt; Recreating machine learning models manually and monitoring changes over time can be challenging due to differences in data, environments, infrastructure, and other factors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deployment Complexity:&lt;/strong&gt; The deployment of machine learning models across diverse environments and systems can be challenging and may necessitate considerable modifications to your infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collaboration:&lt;/strong&gt; When it comes to machine learning development teams, individuals with diverse expertise, such as data scientists, developers, and operations staff, are typically involved. Without a cohesive process in place, these three groups may work independently, leading to communication gaps and misunderstandings.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MLOps was introduced to automate and streamline various processes that hamper the development and deployment of machine learning models. &lt;/p&gt;

&lt;p&gt;By overcoming challenges like incomplete or incorrect data, working with multiple data sources and formats, deploying and scaling complex models, reproducing models in different environments and systems, and siloed teams, MLOps has become a game-changer for the industry. &lt;/p&gt;

&lt;p&gt;You can read the complete blog post on &lt;a href="https://www.infracloud.io/blogs/introduction-to-mlops/"&gt;Introduction to MLOps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Follow me on Twitter &lt;a href="https://twitter.com/thetechmaharaj"&gt;@TheTechmaharaj&lt;/a&gt; for more tech updates. If you're interested to know more about what I do off work, check out my blog &lt;a href="https://socialmaharaj.com"&gt;socialmaharaj.com&lt;/a&gt; :) &lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>beginners</category>
      <category>ai</category>
    </item>
    <item>
      <title>Hyderabad's First AWS Community Day - reCap</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Mon, 20 Mar 2023 07:28:19 +0000</pubDate>
      <link>https://dev.to/techmaharaj/hyderabads-first-aws-community-day-recap-3agn</link>
      <guid>https://dev.to/techmaharaj/hyderabads-first-aws-community-day-recap-3agn</guid>
      <description>&lt;p&gt;Over the last decade, I've been an IT professional on weekdays and a &lt;a href="https://socialmaharaj.com"&gt;Travel &amp;amp; Food Blogger&lt;/a&gt; on weekends. Most of my weekends were spent on roads or restaurants. &lt;/p&gt;

&lt;p&gt;However, the last weekend was different. I attended the &lt;strong&gt;first ever AWS Community Days meetup in Hyderabad, India&lt;/strong&gt;. And this happened just a week after I was inducted into the &lt;strong&gt;AWS Community Builder&lt;/strong&gt; program. &lt;/p&gt;

&lt;p&gt;I thought how would I be able to spend almost 8 hours at a tech meetup, well, didn't realize how time passed. So this post is just a recap of Hyderabad's First AWS Community Day Meetup from my eyes :) &lt;/p&gt;

&lt;p&gt;The event took place at Radisson Blu hotel in Banjara Hills, which is quite a popular hotel in the city. The event from what I know was attended by close to 200 folks. I was there in time, but the registrations were in full swing. I got my badge and swags. Met some familiar faces, some new and also the organizers. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xAhgB9hV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FreRhfyWcAAXjnk%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xAhgB9hV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FreRhfyWcAAXjnk%3Fformat%3Djpg%26name%3D4096x4096" alt="My attendee badge" width="880" height="1564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before starting the proceedings, one good thing that the organizers did was to have all the speakers come on the stage and introduce themselves first. That way all of us knew who's who. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hxMvB_18--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FreaS1lXgAEBng6%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hxMvB_18--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FreaS1lXgAEBng6%3Fformat%3Djpg%26name%3D4096x4096" alt="All the speakers" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Post registrations, we started our day with a keynote by &lt;a href="https://twitter.com/ChandraBalani"&gt;Chandra Balani&lt;/a&gt; who spoke about the changing landscape of technology in India citing the example of UPI. He also spoke about how AWS has expanded over the years and now have Hyderabad a region. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cj_z-OSb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FrebLAJWcAMZm5q%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cj_z-OSb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FrebLAJWcAMZm5q%3Fformat%3Djpg%26name%3D4096x4096" alt="Keynote by Chandra Balani" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/faiz_4k"&gt;Faizal&lt;/a&gt; who is the chapter lead for AWS Hyderabad talked about the growth of the community and how more &lt;em&gt;Hyderabadis&lt;/em&gt; are required to take up the stage. &lt;em&gt;I'm surely looking to contribute to the group!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B0VZtXAH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FretGURX0AAXewj%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B0VZtXAH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FretGURX0AAXewj%3Fformat%3Djpg%26name%3D4096x4096" alt="Faizal talking about AWS Hyderabad Community" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was followed by a Women in Tech panel with &lt;a href="https://twitter.com/RKridhima"&gt;Ridhima Kapoor&lt;/a&gt;, &lt;a href="https://twitter.com/installjournal"&gt;Bhuvaneshwari Subramani&lt;/a&gt; and our very own &lt;a href="https://twitter.com/megha_arora2911"&gt;Megha Arora&lt;/a&gt;. The ladies spoke about how it's important to celebrate small victories and keep learning constantly. The also spoke about their challenges and emphasized on the importance of support groups, quite an insightful talk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hVrchtuM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FreuKTjXwAEfF1n%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hVrchtuM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FreuKTjXwAEfF1n%3Fformat%3Djpg%26name%3D4096x4096" alt="Women in Tech panel" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Post that, there were different tracks that were taking place simultaneously, however I stuck to the talks that I found relevant and interesting.&lt;/p&gt;

&lt;p&gt;The first talk by &lt;a href="https://twitter.com/iamAayushJain"&gt;Ayush Jain&lt;/a&gt; was Highway to code-driven infrastructure where he spoke about &lt;strong&gt;Infrastructure as Code&lt;/strong&gt; and how tools like AWS CloudFormation can help automate infrastructure deployment making it faster and less prone to errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0QkcoyxC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/Fre_OWqWwAAMUKR%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0QkcoyxC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/Fre_OWqWwAAMUKR%3Fformat%3Djpg%26name%3D4096x4096" alt="Ayush Jain" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next talk was by &lt;a href="https://twitter.com/zachjonesnoel"&gt;Jones&lt;/a&gt; who gave us a sneak peek into &lt;strong&gt;Amazon EventBridge&lt;/strong&gt; and how we can integrate it with other SaaS products along with some helpful tips and tricks. &lt;em&gt;He's an AWS Hero in the serverless space and I just joined the AWS Community Builder group in the serverless space.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B2FMzvKR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FrfJ3LNWIAAZ7Lv%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B2FMzvKR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FrfJ3LNWIAAZ7Lv%3Fformat%3Djpg%26name%3D4096x4096" alt="Jones" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Post lunch, we kicked off the proceedings by a talk on &lt;strong&gt;Disaster recovery&lt;/strong&gt; by &lt;a href="https://twitter.com/NeetuMallan"&gt;Neetu Malan&lt;/a&gt; who emphasized on the importance of having DR strategies and discussed important topics like RPO,RTO&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iZbxB1Lu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/Frfe3MIWYAMIVxe%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iZbxB1Lu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/Frfe3MIWYAMIVxe%3Fformat%3Djpg%26name%3D4096x4096" alt="Neetu Malan" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was followed by a session on &lt;strong&gt;Terraform&lt;/strong&gt; and &lt;strong&gt;Jenkins automation&lt;/strong&gt; to streamline AWS cloud resources. An insightful talk by Ashok that had many of us interested.&lt;/p&gt;

&lt;p&gt;The last one for the day was on &lt;strong&gt;GraphQL&lt;/strong&gt; and &lt;strong&gt;AppSync&lt;/strong&gt;. Abhishek and &lt;a href="https://twitter.com/WeShallAWS"&gt;Vishal&lt;/a&gt; help us understand the concepts and gave a deep dive in AppSync and it's features.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7oJSujJz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FrfzcoLXsAcSjJx%3Fformat%3Djpg%26name%3D4096x4096" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7oJSujJz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FrfzcoLXsAcSjJx%3Fformat%3Djpg%26name%3D4096x4096" alt="Vishal and Abhishek" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There were regular breaks for tea, lunches and even networking. While technical glitches happened on-and-off, the organizers ensured that things happened as they were supposed to. There was also a session about AWS certification where they gave us insights into the various tracks and certification levels offered along with the learning paths.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UQYoXG_3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FrgQsxeXgAIF-ql%3Fformat%3Djpg%26name%3Dmedium" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UQYoXG_3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/FrgQsxeXgAIF-ql%3Fformat%3Djpg%26name%3Dmedium" alt="AWS Hyderabad Organizing Committee" width="880" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overall, it was an amazing event full of learning and meeting new and old people. Thanks to all the organizers for a wonderful event, already looking forward to the monthly meetups and the next community day event!&lt;/p&gt;

&lt;p&gt;PS:_ If you're on Twitter, you can also check out &lt;a href="https://twitter.com/TheTechMaharaj/status/1636937064158748674?s=20"&gt;this Twitter thread&lt;/a&gt; for event updates and pictures :)_&lt;/p&gt;

</description>
      <category>aws</category>
      <category>community</category>
      <category>cloud</category>
      <category>news</category>
    </item>
    <item>
      <title>Solving Challenges of Kubernetes YAML Manifest using Monokle</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Tue, 07 Feb 2023 06:08:56 +0000</pubDate>
      <link>https://dev.to/techmaharaj/solving-challenges-of-kubernetes-yaml-manifest-using-monokle-4e1k</link>
      <guid>https://dev.to/techmaharaj/solving-challenges-of-kubernetes-yaml-manifest-using-monokle-4e1k</guid>
      <description>&lt;p&gt;Kubernetes has become a popular platform for deploying and managing applications in the cloud-native environment. While it provides many benefits, it also introduces new challenges for developers, particularly when it comes to validating YAML manifests. &lt;/p&gt;

&lt;p&gt;The manifests are used to define the desired state of the application and its resources, but incorrect manifests can lead to deployment failures or security vulnerabilities.&lt;/p&gt;

&lt;p&gt;In this post, I'll delve into the difficulties of &lt;strong&gt;Kubernetes YAML manifest validation&lt;/strong&gt; and how they can impact the overall deployment process. I'll also give you a quick tour of Monokle and how it can help solve the challenges of Kubernetes YAML manifest validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges with Kubernetes YAML Manifests
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complex and Dynamic Configuration:&lt;/strong&gt; Kubernetes YAML manifests can become complex and difficult to manage as the application and its resources grow. This can lead to difficulties in understanding and validating the configuration, as well as in making changes to it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inconsistent and Ambiguous Syntax:&lt;/strong&gt; Kubernetes YAML manifests use a specific syntax, but there can be inconsistencies and ambiguities in how the syntax is used, leading to difficulties in validation and interpretation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Managing Versioning and Upgrades:&lt;/strong&gt; Kubernetes YAML manifests must be kept up to date with the latest version of Kubernetes and its dependencies. This can be a complex and time-consuming task, and incorrect updates can lead to deployment problems or security vulnerabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Managing dependencies between resources:&lt;/strong&gt; Kubernetes YAML manifests define interdependent resources, making it difficult to ensure that all dependencies are met and that the correct order of operations is followed during deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of Testing and Validation Tools:&lt;/strong&gt; Kubernetes YAML manifests can be challenging to test and validate, especially against live infrastructure. This makes it difficult to ensure that manifests are correct and secure, and can lead to deployment problems.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Any developer working with Kubernetes YAML manifests can surely related to these challenges. &lt;/p&gt;

&lt;h2&gt;
  
  
  How Monokle helps overcome the challenges of Kubernetes YAML manifests
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://monokle.io" rel="noopener noreferrer"&gt;Monokle&lt;/a&gt; is an open-source IDE for Kubernetes. You can import existing infrastructure code or start fresh with your configuration. Monokle comes as a standalone desktop app, CLI as well as a cloud offering.&lt;/p&gt;

&lt;p&gt;I'll talk about one feature of Monokle that helps us solve challenges of Kubernetes YAML Manifests. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource Templates&lt;/strong&gt; in Monokle help ease the creation of resources as well as provide validation against a set of policies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a resource using Monokle Resource Templates
&lt;/h3&gt;

&lt;p&gt;To deploy a simple NGINX application using a &lt;strong&gt;resource template&lt;/strong&gt;, start by launching Monokle and creating a new project. &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%2F7w3elfh0ip059ngfwuuj.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%2F7w3elfh0ip059ngfwuuj.png" alt="Resource Template" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose a basic service deployment template, provide a name and location to save the project, and fill in the deployment settings such as the name of the service, the namespace to deploy to, the image name, the service and target ports, and the service type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validate Resources
&lt;/h3&gt;

&lt;p&gt;In Monokle, once manifests have been loaded, the manifest list is displayed separated by resource type in the Navigator. &lt;/p&gt;

&lt;p&gt;If there are any validation errors, they will be highlighted in the Editor. &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%2Fwyl5jot51auspzk5lpdp.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%2Fwyl5jot51auspzk5lpdp.png" alt="Validation Error" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fix a validation error, such as a policy violation for using the latest image tag, click on "View Images" in the Toolbar, select the image name, choose a specific tag, replace the image tag with a stable version, and check if the error still persists.&lt;/p&gt;

&lt;p&gt;Using the &lt;strong&gt;Open Policy Agent&lt;/strong&gt; feature in Monokle helps ensure best practices and security by identifying and mitigating policy errors before deployment to the cluster. &lt;/p&gt;

&lt;p&gt;Monokle also allows you to deploy application using &lt;strong&gt;Helm&lt;/strong&gt; and &lt;strong&gt;Kustomize&lt;/strong&gt; whilst helping you validate Kubernetes resources.&lt;/p&gt;

&lt;p&gt;Read &lt;a href="https://monokle.io/blog/get-started-validate-kubernetes-resources" rel="noopener noreferrer"&gt;Get Started - Validate Kubernetes Resources&lt;/a&gt; blog post to learn more on how you can use Monokle to solve challenges of Kubernetes YAML Manifest using Monokle&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Setting Up Paralus on DigitalOcean</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Tue, 27 Sep 2022 03:21:53 +0000</pubDate>
      <link>https://dev.to/techmaharaj/setting-up-paralus-on-digitalocean-1hk1</link>
      <guid>https://dev.to/techmaharaj/setting-up-paralus-on-digitalocean-1hk1</guid>
      <description>&lt;p&gt;One of the cloud platforms that I absolutely enjoy working with is &lt;strong&gt;DigitalOcean&lt;/strong&gt; - the sheer ease of use &amp;amp; the helpful #community makes it a preferred choice for me. Along with the various options it gives to developers like to me try things quickly makes it a platform that I'd recommend.&lt;/p&gt;

&lt;p&gt;In this blog post, I'll take you through the steps to setup Paralus on Digital Ocean (DO) using a custom domain and import a local cluster into it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://paralus.io"&gt;Paralus&lt;/a&gt; is a &lt;strong&gt;free, open source tool&lt;/strong&gt; that enables controlled, audited access to Kubernetes infrastructure. It comes with just-in-time service account creation and user-level credential management that integrates with your RBAC and SSO. Ships as a GUI, API, and CLI.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table Of Content:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pre Requisites&lt;/li&gt;
&lt;li&gt;Creating Digital Ocean Cluster&lt;/li&gt;
&lt;li&gt;
Connecting to Digital Ocean Cluster

&lt;ul&gt;
&lt;li&gt;1. Create API Token&lt;/li&gt;
&lt;li&gt;2. Configure doctl&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Installing Paralus&lt;/li&gt;
&lt;li&gt;
Configuring DNS Settings

&lt;ul&gt;
&lt;li&gt;Accessing The Dashboard&lt;/li&gt;
&lt;li&gt;Importing Existing Cluster&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Before you start the installation process, do check out the &lt;a href="https://www.paralus.io/docs/installation#prerequisites"&gt;pre-requisites for installing Paralus&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre Requisites
&lt;/h2&gt;

&lt;p&gt;To setup Paralus on Digital Ocean there are a few things that need to done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Digital Ocean account - &lt;em&gt;you can &lt;a href="https://cloud.digitalocean.com/registrations/new"&gt;register for a Free Digital Ocean account&lt;/a&gt; if you don't have one&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;A Domain Name - &lt;em&gt;with permission to manage DNS settings.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Helm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll start with setting up a cluster on Digital Ocean, followed by deploying Paralus to it using helm charts. Once the installation is done, we'll configure the DNS settings for the domain for Paralus to work. After that we'll login to the Paralus dashboard and import a Kubernetes cluster that is running on a local laptop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Digital Ocean Cluster
&lt;/h2&gt;

&lt;p&gt;Creating a Kubernetes cluster on DO is quite simple. DO offers just one type of Kubernetes cluster and not a variety of offerings like GKE, AWS or AKS. They provide two types of plans when it comes to Nodes - &lt;strong&gt;Basic&lt;/strong&gt; and &lt;strong&gt;Professional&lt;/strong&gt; plans, each of them offering a different configuration.&lt;/p&gt;

&lt;p&gt;You need to choose the professional node plan with &lt;strong&gt;3 nodes&lt;/strong&gt; at the minimum for Paralus to run smoothly.&lt;/p&gt;

&lt;p&gt;Login to your DO account and choose &lt;strong&gt;Kubernetes&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Create Kubernetes Cluster&lt;/strong&gt; and provide details like cluster name, region, Kubernetes version, capacity etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WIRgDidv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/digitalocean-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WIRgDidv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/digitalocean-02.png" alt="Creating Kubernetes cluster on Digital Ocean" width="880" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To know more about how to choose a plan or resize a Kubernetes cluster, check out &lt;a href="https://docs.digitalocean.com/products/kubernetes/concepts/choosing-a-plan/"&gt;this document&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to Digital Ocean Cluster
&lt;/h2&gt;

&lt;p&gt;To connect to your newly created Kubernetes cluster there are two things that you need to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create API Token&lt;/li&gt;
&lt;li&gt;Configure doctl&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Create API Token
&lt;/h3&gt;

&lt;p&gt;You need to generate an API key to be able to access your Kubernetes cluster. You can follow this guide to &lt;a href="https://docs.digitalocean.com/reference/api/create-personal-access-token/"&gt;create a personal access token&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Configure doctl
&lt;/h3&gt;

&lt;p&gt;The next step is to configure &lt;code&gt;doctl&lt;/code&gt; - a CLI tool provided by DO to interact with their API via command line.&lt;/p&gt;

&lt;p&gt;We used a snap package to install the doctl package on our Ubuntu laptop.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Refer to &lt;a href="https://docs.digitalocean.com/reference/doctl/how-to/install/"&gt;doctl installation document&lt;/a&gt; to install it on different environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;sudo snap install doctl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create new context by providing the API token generated in the earlier step and switch to this newly created context&lt;/p&gt;

&lt;p&gt;&lt;code&gt;doctl auth init --context &amp;lt;NAME&amp;gt;&lt;/code&gt; followed by &lt;code&gt;doctl auth switch --context &amp;lt;NAME&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Allow &lt;code&gt;doctl&lt;/code&gt; to access the kube-config that will allow you to communicate with the Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo snap connect doctl:kube-config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The next step is to configure a certificate to your kubectl configuration. You will get this certificate details after your cluster has been provisioned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NLw6e5Dw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/digitalocean-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NLw6e5Dw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/digitalocean-04.png" alt="Adding certificate for doctl" width="880" height="647"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;doctl kubernetes cluster kubeconfig save f4739f01-1433-48e1-b991-742a53769fe7

Notice: Adding cluster credentials to kubeconfig file found &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"/home/atulpriya/.kube/config"&lt;/span&gt;
Notice: Setting current-context to &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="nt"&gt;-ams3-paralus-demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once done, you can validate the connectivity using the following command&lt;br&gt;
&lt;/p&gt;

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

NAME                   STATUS   ROLES    AGE   VERSION
pool-lhosbqych-7fomd   Ready    &amp;lt;none&amp;gt;   16m   v1.23.9
pool-lhosbqych-7fomi   Ready    &amp;lt;none&amp;gt;   16m   v1.23.9
pool-lhosbqych-7fomv   Ready    &amp;lt;none&amp;gt;   16m   v1.23.9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, you have successfully created a Kubernetes cluster &amp;amp; configured access to it using &lt;code&gt;doctl&lt;/code&gt;. The next steps include installing Paralus and importing a local cluster on to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Paralus
&lt;/h2&gt;

&lt;p&gt;In the same terminal, you can follow the below steps to deploy Paralus to your DO cluster.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add helm repo&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;helm repo add paralus https://paralus.github.io/helm-charts&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Paralus
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   helm &lt;span class="nb"&gt;install &lt;/span&gt;myrelease paralus/ztka &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/paralus/helm-charts/main/examples/values.dev-generic.yaml &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--set&lt;/span&gt; fqdn.domain&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"chartexample.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-n&lt;/span&gt; paralus &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--create-namespace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you're installing this in a &lt;strong&gt;production environment&lt;/strong&gt;, please use &lt;a href="https://github.com/paralus/helm-charts/blob/main/charts/ztka/values.yaml"&gt;values.yaml&lt;/a&gt; and configure the values mentioned &lt;a href="https://github.com/paralus/helm-charts/tree/main/charts/ztka#values"&gt;here&lt;/a&gt; as required.&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;  NAME: myrelease
  LAST DEPLOYED: Mon Aug 29 17:29:54 2022
  NAMESPACE: paralus
  STATUS: deployed
  REVISION: 1
  NOTES:
    Access the application URL by running these commands:
    Get the EXTERNAL-IP value using following &lt;span class="nb"&gt;command&lt;/span&gt;:
    kubectl get service myrelease-contour-envoy &lt;span class="nt"&gt;-n&lt;/span&gt; paralus

    Add DNS records of following domains such that it resolves to above address:
    - console.chartexample.com
    - &lt;span class="k"&gt;*&lt;/span&gt;.core-connector.chartexample.com
    - &lt;span class="k"&gt;*&lt;/span&gt;.user.chartexample.com

    Open http://console.chartexample.com &lt;span class="k"&gt;in &lt;/span&gt;browser.

    Note: If you are using a cluster with no load-balancer, &lt;span class="k"&gt;then &lt;/span&gt;the address will be &lt;span class="s2"&gt;"&amp;lt;pending&amp;gt;"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
          If it is Kind or Minikube cluster, check out respective docs to get the external address.

  You can view the recovery &lt;span class="nb"&gt;link &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;admin user by running the following &lt;span class="nb"&gt;command &lt;/span&gt;once all the pods are running:

  kubectl logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--namespace&lt;/span&gt; paralus &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;--namespace&lt;/span&gt; paralus &lt;span class="nt"&gt;-l&lt;/span&gt; app.kubernetes.io/name&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'paralus'&lt;/span&gt; &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="s1"&gt;'{ .items[0].metadata.name }'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; initialize | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'Org Admin signup URL:'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: It can take upto a few minutes before all the pods are running and you can access the dashboard. You can check the status using &lt;code&gt;watch kubectl get pods -n paralus&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Configuring DNS Settings
&lt;/h2&gt;

&lt;p&gt;Once the installation is complete, you need to first get the external IP address provided by the loadbalancer. You can do so by executing the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc myrelease-contour-envoy &lt;span class="nt"&gt;-n&lt;/span&gt; paralus

NAME                      TYPE           CLUSTER-IP     EXTERNAL-IP      PORT&lt;span class="o"&gt;(&lt;/span&gt;S&lt;span class="o"&gt;)&lt;/span&gt;                      AGE
myrelease-contour-envoy   LoadBalancer   10.245.58.69   138.68.122.180   80:32722/TCP,443:32656/TCP   2m32s

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;It may take some time for the loadbalancer to assign the IP address.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note down the &lt;code&gt;EXTERNAL-IP&lt;/code&gt; address for the &lt;code&gt;&amp;lt;releasename&amp;gt;-contour-envoy&lt;/code&gt; service.&lt;/p&gt;

&lt;p&gt;Navigate to your domain's DNS setting page. &lt;em&gt;The steps for changing DNS settings will vary based on your domain name provider.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While you are on your DNS Setting page, for the selected domain name, you need to add three A records. These will be based on the subdomains provided in the notes section post installation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Resolves To&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;console.chartexample.com&lt;/td&gt;
&lt;td&gt;138.68.122.180&lt;/td&gt;
&lt;td&gt;1 Hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;*.core-connector.chartexample.com&lt;/td&gt;
&lt;td&gt;138.68.122.180&lt;/td&gt;
&lt;td&gt;1 Hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;*.user.chartexample.com&lt;/td&gt;
&lt;td&gt;138.68.122.180&lt;/td&gt;
&lt;td&gt;1 Hour&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Accessing The Dashboard
&lt;/h3&gt;

&lt;p&gt;Paralus is installed with a default organization and an admin user. Hence, after installation, you need to set a password for the user. To do so, execute the command that you get after installing Paralus.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--namespace&lt;/span&gt; paralus &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;--namespace&lt;/span&gt; paralus &lt;span class="nt"&gt;-l&lt;/span&gt; app.kubernetes.io/name&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'paralus'&lt;/span&gt; &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="s1"&gt;'{ .items[0].metadata.name }'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; initialize | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'Org Admin signup URL:'&lt;/span&gt;

Org Admin signup URL:  http://console.chartexample.com/self-service/recovery?flow&lt;span class="o"&gt;=&lt;/span&gt;de34efa4-934e-4916-8d3f-a1c6ce65ba39&amp;amp;token&lt;span class="o"&gt;=&lt;/span&gt;IYJFI5vbORhGnz81gCjK7kucDVoiuQ7j

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The password recovery link generated while deploying Paralus is valid only for &lt;code&gt;10 minutes&lt;/code&gt;. For any reason if the link is expired, refer to our &lt;a href="https://www.paralus.io/docs/references/troubleshooting#password-reset-link-expired"&gt;troubleshooting guide&lt;/a&gt; to re-generate the password reset link.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Access the URL in a browser, and provide a new password. In a new browser window/tab navigate to &lt;code&gt;http://console.chartexample.com&lt;/code&gt; and log in with the following credentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;username: &lt;code&gt;admin@paralus.local&lt;/code&gt; - &lt;em&gt;or the one you specified in &lt;code&gt;values.yaml&lt;/code&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;password: &lt;code&gt;&amp;lt;The one you entered above&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll be taken to the projects page where you'll see a default project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GsHsc2In--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GsHsc2In--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-dashboard.png" alt="Paralus default project screen" width="880" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Importing Existing Cluster
&lt;/h3&gt;

&lt;p&gt;Everything in Paralus is grouped into &lt;a href="https://www.paralus.io/docs/usage/projects"&gt;Projects&lt;/a&gt;. Each project will have &lt;a href="https://www.paralus.io/docs/usage/clusters"&gt;clusters&lt;/a&gt;, &lt;a href="https://dev.to/docs/usage/users"&gt;users&lt;/a&gt; and &lt;a href="https://www.paralus.io/docs/usage/groups"&gt;groups&lt;/a&gt; associated with it. Hence the first step it to create a new project.&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;New Project&lt;/strong&gt; to create a new project and then import a cluster in that project. The cluster we are importing is a minikube cluster hosted on my laptop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q9cL7-H9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q9cL7-H9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-1.png" alt="Create New Cluster" width="880" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Continue&lt;/strong&gt; and download the bootstrap yaml file by clicking &lt;strong&gt;Import Bootstrap YAML&lt;/strong&gt;. This will download the YAML file that is required to connect your cluster with Paralus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_2a-PkF8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_2a-PkF8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-2.png" alt="Download Bootstrap YAML file" width="880" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apply the bootstrap configuration yaml file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; mylocalcluster.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for the changes to take place. On the dashboard you will see that the cluster is imported successfully. It usually takes 3-5 minutes for the status to update.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--THudTxST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--THudTxST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-3.png" alt="Import Cluster Success" width="880" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select your newly imported cluster and click on &lt;code&gt;kubectl&lt;/code&gt; to access the prompt and interact with your cluster from the dashboard.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;kubectl&lt;/code&gt; console will open in the bottom half of the screen, enter your kubectl commands to interact with your cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---GBxnOV1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---GBxnOV1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-4.png" alt="Accessing imported cluster via kubectl" width="880" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You've successfully deployed Paralus on Digital Ocean Kubernetes cluster and imported a local cluster.&lt;/p&gt;

&lt;p&gt;If you have any issues with Paralus, feel free to reach out to me :) &lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>cloudnative</category>
      <category>accessmanagement</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Setup Paralus on Kind Cluster</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Fri, 15 Jul 2022 09:28:23 +0000</pubDate>
      <link>https://dev.to/techmaharaj/setup-paralus-on-kind-cluster-5201</link>
      <guid>https://dev.to/techmaharaj/setup-paralus-on-kind-cluster-5201</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/paralus"&gt;Paralus&lt;/a&gt; is the newest Opensource project that helps you with &lt;strong&gt;zero trust&lt;/strong&gt; access management for &lt;strong&gt;Kubernetes&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;It gives you a single dashboard that allows you to manage all your clusters from one portal. In this article, I'll show we can &lt;strong&gt;Install Paralus on a local Kind cluster&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can refer to the &lt;a href="https://paralus.io"&gt;Paralus website&lt;/a&gt; to learn more about Paralus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kind
&lt;/h2&gt;

&lt;p&gt;The following section talks about installing Paralus in a Kind cluster. Kind is a tool used to run local Kubernetes clusters using Docker container nodes. Learn more about &lt;a href="https://kind.sigs.k8s.io/"&gt;Kind&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing and Configuring Kind
&lt;/h3&gt;

&lt;p&gt;If you don't already have Kind installed on your local system, you can do so by following the &lt;a href="https://kind.sigs.k8s.io/docs/user/quick-start/"&gt;Kind Quickstart Documentation&lt;/a&gt;. The default settings are good enough to get you started.&lt;/p&gt;

&lt;p&gt;The next step is to &lt;strong&gt;create a Kind cluster&lt;/strong&gt;. To do that you can create a copy of &lt;a href="https://github.com/paralus/helm-charts/blob/main/docs/kind.config.yaml"&gt;this configuration file&lt;/a&gt; and use that to create a cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kind create cluster &lt;span class="nt"&gt;--config&lt;/span&gt; cluster.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note down the IP address of the control plane by running the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container inspect kind-control-plane &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s1"&gt;'{{ .NetworkSettings.Networks.kind.IPAddress }}'&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;172.20.0.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Installing Paralus
&lt;/h3&gt;

&lt;p&gt;Add the &lt;a href="https://github.com/paralus/helm-charts"&gt;paralus helm repository&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add paralus https://paralus.github.io/helm-charts
helm repo update
&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;   helm &lt;span class="nb"&gt;install &lt;/span&gt;myrelease paralus/ztka &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/paralus/helm-charts/main/examples/values.dev-generic.yaml &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--set&lt;/span&gt; fqdn.domain&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"paralus.local"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-n&lt;/span&gt; paralus &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--create-namespace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: In case you get an error, run &lt;code&gt;helm dependency build&lt;/code&gt; to build the dependencies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You'll see the following output if the installation succeeds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NAME: ztkarelease
LAST DEPLOYED: Wed Jun 15 09:05:49 2022
NAMESPACE: paralus
STATUS: deployed
REVISION: 1
NOTES:
1. Access the application URL by running these commands:
  Open http://console.paralus.local &lt;span class="k"&gt;in &lt;/span&gt;browser.

You can view the recovery &lt;span class="nb"&gt;link &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;admin user by running the following &lt;span class="nb"&gt;command &lt;/span&gt;once all the pods are running:

kubectl logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--namespace&lt;/span&gt; paralus &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;--namespace&lt;/span&gt; paralus &lt;span class="nt"&gt;-l&lt;/span&gt; app.kubernetes.io/name&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'paralus'&lt;/span&gt; &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="s1"&gt;'{ .items[0].metadata.name }'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; initialize | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'Org Admin signup URL:'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: It can take upto a few minutes before all the pods are running and you can access the dashboard. You can check the status using &lt;code&gt;watch kubectl get pods&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Configuring /etc/hosts
&lt;/h3&gt;

&lt;p&gt;Since we are deploying Paralus on local cluster, we need to update the &lt;code&gt;/etc/hosts&lt;/code&gt; file with the IP Address/Ingress Host name to access the dashboard.&lt;br&gt;
In order to do that, edit the &lt;code&gt;/etc/hosts&lt;/code&gt; file using your favourite editor and add the following line at the end of it along with the IP address obtained and save it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;172.20.0.2 console.paralus.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Refer to the value of &lt;code&gt;fqdn.domain&lt;/code&gt; in your &lt;a href="https://github.com/paralus/helm-charts/blob/main/charts/ztka/values.yaml#L145"&gt;values.yaml&lt;/a&gt; file to find the default host.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Open your favorite web browser and navigate to &lt;code&gt;http://console.paralus.local&lt;/code&gt;, you will be see the dashboard with the login screen&lt;/p&gt;

&lt;h3&gt;
  
  
  Resetting Default Password
&lt;/h3&gt;

&lt;p&gt;Paralus comes configured with default credentials that allow you to access the dashboard.&lt;/p&gt;

&lt;p&gt;In order to get the &lt;code&gt;Password Reset URL&lt;/code&gt;, copy the command displayed after helm install and execute it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--namespace&lt;/span&gt; paralus &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;--namespace&lt;/span&gt; paralus &lt;span class="nt"&gt;-l&lt;/span&gt; app.kubernetes.io/name&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'paralus'&lt;/span&gt; &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="s1"&gt;'{ .items[0].metadata.name }'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; initialize | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'Org Admin signup URL:'&lt;/span&gt;

Org Admin signup URL:  http://console.paralus.local/self-service/recovery?flow&lt;span class="o"&gt;=&lt;/span&gt;9ec13c6f-414e-4cb5-bf4c-def35973118f&amp;amp;token&lt;span class="o"&gt;=&lt;/span&gt;ge6bi6zmyzUlQrHlYTOCDeItV82hT08Y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The password recovery link generated while deploying Paralus is valid only for &lt;code&gt;10 minutes&lt;/code&gt;. For any reason if the link is expired, refer to the &lt;a href="https://www.paralus.io/docs/references/troubleshooting"&gt;troubleshooting guide&lt;/a&gt; to re-generate the password reset link.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Access the URL in a browser, and provide a new password.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing Paralus Dashboard
&lt;/h3&gt;

&lt;p&gt;In a new browser window/tab navigate to &lt;code&gt;http://console.paralus.local&lt;/code&gt; and log in with the following credentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;username: &lt;code&gt;admin@paralus.local&lt;/code&gt; - &lt;em&gt;or the one you specified in &lt;code&gt;values.yaml&lt;/code&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;password: &lt;code&gt;&amp;lt;The one you entered in the earlier section&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll be taken to the projects page where you'll see a default project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GsHsc2In--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GsHsc2In--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-dashboard.png" alt="Paralus default project screen" width="880" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Importing Existing Cluster
&lt;/h3&gt;

&lt;p&gt;Everything in Paralus is grouped into Projects. Each project will have clusters, users and groups associated with it. Hence the first step it to create a new project.&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;New Project&lt;/strong&gt; to create a new project and then import a cluster in that project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q9cL7-H9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q9cL7-H9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-1.png" alt="Create New Cluster" width="880" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Continue&lt;/strong&gt; and download the bootstrap yaml file by clicking &lt;strong&gt;Import Bootstrap YAML&lt;/strong&gt;. This will download the YAML file that is required to connect your cluster with Paralus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_2a-PkF8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_2a-PkF8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-2.png" alt="Download Bootstrap YAML file" width="880" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuring Network
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Getting Cluster ID and Hostname
&lt;/h5&gt;

&lt;p&gt;Open the downloaded yaml file in a text editor and look for &lt;code&gt;clusterID&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;clusterID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5dceca49-c6cd-4a2b-b65a-f193c4fa001f&lt;/span&gt;
  &lt;span class="na"&gt;relays&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[{"token":"cakmpdvjd030q1q53p9g","addr":"console.paralus.local:80","endpoint":"*.core-connector.paralus.local:443","name":"paralus-core-relay-agent","templateToken":"cakl93fjd030q1q53p5g"}]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the &lt;code&gt;clusterID&lt;/code&gt; identified, we need to update the hosts file. This becuase we are using hostname to route traffic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;5dceca49-c6cd-4a2b-b65a-f193c4fa001f.user.paralus.local
5dceca49-c6cd-4a2b-b65a-f193c4fa001f.core-connector.paralus.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Updating /etc/hosts
&lt;/h5&gt;

&lt;p&gt;Add two new lines in &lt;code&gt;/etc/hosts&lt;/code&gt; file along with the IP address obtained&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;172.20.0.2 5dceca49-c6cd-4a2b-b65a-f193c4fa001f.user.paralus.local
172.20.0.2 5dceca49-c6cd-4a2b-b65a-f193c4fa001f.core-connector.paralus.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your final &lt;code&gt;/etc/hosts&lt;/code&gt; file should be something like the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;172.20.0.2 console.paralus.local
172.20.0.2 5dceca49-c6cd-4a2b-b65a-f193c4fa001f.user.paralus.local
172.20.0.2 5dceca49-c6cd-4a2b-b65a-f193c4fa001f.core-connector.paralus.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Accessing Existing Cluster
&lt;/h3&gt;

&lt;p&gt;With all the changes in place, it's time to apply the bootstrap yaml file that we download while importing an existing cluster&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; mylocalcluster.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for the changes to take place. On the dashboard you will see that the cluster is imported successfully. It usually takes 3-5 minutes for the status to update.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You can also execute &lt;code&gt;kubectl get pods&lt;/code&gt; to check the status.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--THudTxST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--THudTxST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-3.png" alt="Import Cluster Success" width="880" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select your newly imported cluster and click on &lt;code&gt;kubectl&lt;/code&gt; to access the prompt and interact with your cluster from the dashboard.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;kubectl&lt;/code&gt; console will open in the bottom half of the screen, enter your kubectl commands to interact with your cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---GBxnOV1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---GBxnOV1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.paralus.io/img/docs/paralus-import-cluster-4.png" alt="Accessing imported cluster via kubectl" width="880" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's how you can setup Paralus on a local Kind cluster for trying it out before taking it to production environment.&lt;/p&gt;

&lt;p&gt;Follow me at &lt;a href="https://twitter.com/thetechmaharaj"&gt;@TheTechmaharaj&lt;/a&gt; for more :)&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Guestbook application using Fission &amp; CockroachDB</title>
      <dc:creator>Atulpriya Sharma</dc:creator>
      <pubDate>Fri, 01 Apr 2022 09:07:18 +0000</pubDate>
      <link>https://dev.to/techmaharaj/guestbook-application-using-fission-cockroachdb-8pj</link>
      <guid>https://dev.to/techmaharaj/guestbook-application-using-fission-cockroachdb-8pj</guid>
      <description>&lt;p&gt;Fission provides you with a serverless framework that you can deploy on your Kubernetes clusters.There are various use cases where you can use Fission, and today we'll show you how to develop a guestbook application with Fission in Go using CockroachDB as a database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serverless Guestbook Application
&lt;/h2&gt;

&lt;p&gt;The guestbook is composed with four REST APIs and each API consist of a function and an HTTP trigger. This application allows a user to create, edit and delete a message. You can submit a message, retrieve a list of messages, delete a message all by means of REST APIs.&lt;br&gt;
You can clone &lt;a href="https://github.com/fission/fission-restapi-sample"&gt;Fission REST API Repo&lt;/a&gt; and follow the guide to install/try guestbook sample.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create Fission Objects for REST API
&lt;/h2&gt;

&lt;p&gt;A REST API uses HTTP method to determine what's the action server needs to perform on resource(s) represents in the URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;POST   http://api.example.com/user-management/users/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
PUT    http://api.example.com/user-management/users/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
GET    http://api.example.com/user-management/users/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
DELETE http://api.example.com/user-management/users/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a REST API with fission, we need to create following things to make it work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HTTP Trigger&lt;/code&gt; with specific HTTP method and URL contains the resource type we want to manipulate with. Read more about &lt;a href="//../../docs/reference/crd-reference/#httptrigger"&gt;HTTP Triggers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Function&lt;/code&gt; to handle the HTTP request. Read more about &lt;a href="//../../docs/reference/crd-reference/#function"&gt;Function&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  HTTP Trigger
&lt;/h3&gt;

&lt;p&gt;The first step is to create an HTTP trigger for your function&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="nv"&gt;$ &lt;/span&gt;fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; /guestbook/messages &lt;span class="nt"&gt;--method&lt;/span&gt; POST &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-post &lt;span class="nt"&gt;--name&lt;/span&gt; restpost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are 3 important elements in the command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;method&lt;/code&gt;: &lt;em&gt;The HTTP method of REST API&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;url&lt;/code&gt;: &lt;em&gt;The API URL contains the resource placeholder&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;function&lt;/code&gt;: &lt;em&gt;The function reference to a fission function&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a real world REST API, the URL would be more complex and contains the resource placeholder.&lt;br&gt;
To support such use cases, you can change URL to something like following:&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="nv"&gt;$ &lt;/span&gt;fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/{id:[0-9]+}"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; GET &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-get &lt;span class="nt"&gt;--name&lt;/span&gt; restgetpart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since fission uses &lt;code&gt;gorilla/mux&lt;/code&gt; as underlying URL router, you can write regular expression in URL to filter out illegal API requests.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/fission/fission-restapi-sample/blob/master/specs/route-restGetPart.yaml"&gt;route-restGetPart.yaml&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;&lt;span class="nv"&gt;$ &lt;/span&gt;fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/{id:[0-9]+}"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; GET &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-get &lt;span class="nt"&gt;--name&lt;/span&gt; restgetpart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Function
&lt;/h3&gt;

&lt;p&gt;To handle a REST API request, normally a function need to extract resource from the request URL. In Fission, you can get the resource value from request header directly as we described in Request Payload.&lt;/p&gt;

&lt;p&gt;That means you can get value from header with key &lt;code&gt;X-Fission-Params-Id&lt;/code&gt; if URL is &lt;code&gt;/guestbook/messages/{id}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Go, you can use &lt;code&gt;CanonicalMIMEHeaderKey&lt;/code&gt; to transform letter case.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/fission/fission-restapi-sample/blob/f98a46f4dc3756b42fce7fd292705d74e1fad249/rest-api/api.go#L83-L101"&gt;rest-api/api.go&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"net/textproto"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;URL_PARAMS_PREFIX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"X-Fission-Params"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetPathValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// transform text case&lt;/span&gt;
    &lt;span class="c"&gt;// For example: 'id' -&amp;gt; 'Id', 'fooBAR' -&amp;gt; 'Foobar', 'foo-BAR' -&amp;gt; 'Foo-Bar'.&lt;/span&gt;
    &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;textproto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanonicalMIMEHeaderKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// generate header key for accessing request header value&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s-%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;URL_PARAMS_PREFIX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// get header value&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&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;When Golang server receive HTTP requests, it dispatches &lt;code&gt;entrypoint function&lt;/code&gt; and passes whole &lt;code&gt;response writer&lt;/code&gt; and &lt;code&gt;request&lt;/code&gt; object to the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;MessageGetHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, you can access &lt;code&gt;query string&lt;/code&gt; and &lt;code&gt;message body&lt;/code&gt; as usual.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/fission/fission-restapi-sample/blob/f98a46f4dc3756b42fce7fd292705d74e1fad249/rest-api/api.go#L109-L111"&gt;rest-api/api.go&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetQueryString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/fission/fission-restapi-sample/blob/4398eb195aeb59523101aa68a62782d91f86d85a/rest-api/api.go#L103-L110"&gt;rest-api/api.go&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ioutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error reading request body"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CockroachDB Setup
&lt;/h2&gt;

&lt;p&gt;In guestbook application we need to store messages in a database.&lt;br&gt;
Since fission is build on top of kubernetes, it's very easy to achieve this by creating Kubernetes &lt;code&gt;Service(svc)&lt;/code&gt; and &lt;code&gt;Deployment&lt;/code&gt;.&lt;br&gt;
For this sample application, we are using &lt;a href="https://www.cockroachlabs.com/docs/cockroachcloud/quickstart.html"&gt;CockroachDB&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We also have a post on using &lt;a href="//../how-to-use-postgresql-database-with-fission-functions/"&gt;PostgreSQL with Fission&lt;/a&gt; that you might want to read too.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="/images/how-to-develop-a-serverless-application-with-fission/access-3rd-service.svg" class="article-body-image-wrapper"&gt;&lt;img src="/images/how-to-develop-a-serverless-application-with-fission/access-3rd-service.svg" alt="Access 3rd service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;cockroachdb&lt;/code&gt; helm repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add cockroachdb https://charts.cockroachdb.com/
helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install cockroachdb using helm and provide values from &lt;a href="https://github.com/fission/fission-restapi-sample/blob/master/cockroachdb.yaml"&gt;cockroachdb.yaml&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;my-release &lt;span class="nt"&gt;--values&lt;/span&gt; cockroachdb.yaml cockroachdb/cockroachdb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Guestbook Application Setup
&lt;/h2&gt;

&lt;p&gt;Create the &lt;code&gt;go&lt;/code&gt; environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fission &lt;span class="nb"&gt;env &lt;/span&gt;create &lt;span class="nt"&gt;--name&lt;/span&gt; go &lt;span class="nt"&gt;--image&lt;/span&gt; fission/go-env-1.16 &lt;span class="nt"&gt;--builder&lt;/span&gt; fission/go-builder-1.16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;sourcepackage&lt;/code&gt; from the &lt;code&gt;rest-api&lt;/code&gt; folder.&lt;br&gt;
It is required to create a package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zip &lt;span class="nt"&gt;-j&lt;/span&gt; restapi-go-pkg.zip rest-api/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a package from the source archive&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fission pkg create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--sourcearchive&lt;/span&gt; restapi-go-pkg.zip &lt;span class="nt"&gt;--env&lt;/span&gt; go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create functions for &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fission fn create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-delete &lt;span class="nt"&gt;--executortype&lt;/span&gt; newdeploy &lt;span class="nt"&gt;--maxscale&lt;/span&gt; 3 &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--pkg&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; MessageDeleteHandler
fission fn create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-update &lt;span class="nt"&gt;--executortype&lt;/span&gt; newdeploy &lt;span class="nt"&gt;--maxscale&lt;/span&gt; 3 &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--pkg&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; MessageUpdateHandler
fission fn create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-post &lt;span class="nt"&gt;--executortype&lt;/span&gt; newdeploy &lt;span class="nt"&gt;--maxscale&lt;/span&gt; 3 &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--pkg&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; MessagePostHandler
fission fn create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-get &lt;span class="nt"&gt;--executortype&lt;/span&gt; newdeploy &lt;span class="nt"&gt;--maxscale&lt;/span&gt; 3 &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--pkg&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; MessageGetHandler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;HTTPTriggers&lt;/code&gt; for the endpoints for the above created functions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; /guestbook/messages &lt;span class="nt"&gt;--method&lt;/span&gt; POST &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-post &lt;span class="nt"&gt;--name&lt;/span&gt; restpost
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/{id:[0-9]+}"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; PUT &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-update &lt;span class="nt"&gt;--name&lt;/span&gt; restupdate
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/{id:[0-9]+}"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; GET &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-get &lt;span class="nt"&gt;--name&lt;/span&gt; restgetpart
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/{id:[0-9]+}"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; DELETE &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-delete &lt;span class="nt"&gt;--name&lt;/span&gt; restdelete
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; GET &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-get &lt;span class="nt"&gt;--name&lt;/span&gt; restget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fission Spec
&lt;/h3&gt;

&lt;p&gt;The entire installation can be done using a single block of &lt;code&gt;fission spec&lt;/code&gt; commands as shown below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fission spec init
fission &lt;span class="nb"&gt;env &lt;/span&gt;create &lt;span class="nt"&gt;--name&lt;/span&gt; go &lt;span class="nt"&gt;--image&lt;/span&gt; fission/go-env-1.16 &lt;span class="nt"&gt;--builder&lt;/span&gt; fission/go-builder-1.16 &lt;span class="nt"&gt;--spec&lt;/span&gt;
fission pkg create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--sourcearchive&lt;/span&gt; restapi-go-pkg.zip &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--spec&lt;/span&gt;
fission fn create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-delete &lt;span class="nt"&gt;--executortype&lt;/span&gt; newdeploy &lt;span class="nt"&gt;--maxscale&lt;/span&gt; 3 &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--pkg&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; MessageDeleteHandler &lt;span class="nt"&gt;--spec&lt;/span&gt;
fission fn create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-update &lt;span class="nt"&gt;--executortype&lt;/span&gt; newdeploy &lt;span class="nt"&gt;--maxscale&lt;/span&gt; 3 &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--pkg&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; MessageUpdateHandler &lt;span class="nt"&gt;--spec&lt;/span&gt;
fission fn create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-post &lt;span class="nt"&gt;--executortype&lt;/span&gt; newdeploy &lt;span class="nt"&gt;--maxscale&lt;/span&gt; 3 &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--pkg&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; MessagePostHandler &lt;span class="nt"&gt;--spec&lt;/span&gt;
fission fn create &lt;span class="nt"&gt;--name&lt;/span&gt; restapi-get &lt;span class="nt"&gt;--executortype&lt;/span&gt; newdeploy &lt;span class="nt"&gt;--maxscale&lt;/span&gt; 3 &lt;span class="nt"&gt;--env&lt;/span&gt; go &lt;span class="nt"&gt;--pkg&lt;/span&gt; restapi-go-pkg &lt;span class="nt"&gt;--entrypoint&lt;/span&gt; MessageGetHandler &lt;span class="nt"&gt;--spec&lt;/span&gt;
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; /guestbook/messages &lt;span class="nt"&gt;--method&lt;/span&gt; POST &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-post &lt;span class="nt"&gt;--spec&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; restpost
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/{id:[0-9]+}"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; PUT &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-update &lt;span class="nt"&gt;--spec&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; restupdate
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/{id:[0-9]+}"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; GET &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-get &lt;span class="nt"&gt;--spec&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; restgetpart
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/{id:[0-9]+}"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; DELETE &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-delete &lt;span class="nt"&gt;--spec&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; restdelete
fission httptrigger create &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"/guestbook/messages/"&lt;/span&gt; &lt;span class="nt"&gt;--method&lt;/span&gt; GET &lt;span class="nt"&gt;--function&lt;/span&gt; restapi-get &lt;span class="nt"&gt;--spec&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; restget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will create a &lt;code&gt;specs&lt;/code&gt; folder with all the required yaml files post which you can apply the changes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fission spec apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing The Guestbook Application
&lt;/h2&gt;

&lt;p&gt;Since this guestbook application is created using &lt;code&gt;REST&lt;/code&gt; APIs, we first need to export the &lt;code&gt;$FISSION_ROUTER&lt;/code&gt; along with the port&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;export &lt;/span&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8889
kubectl &lt;span class="nt"&gt;--namespace&lt;/span&gt; fission port-forward &lt;span class="si"&gt;$(&lt;/span&gt;kubectl &lt;span class="nt"&gt;--namespace&lt;/span&gt; fission get pod &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;svc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;router &lt;span class="nt"&gt;-o&lt;/span&gt; name&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$PORT&lt;/span&gt;:8888
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;FISSION_ROUTER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;127.0.0.1:&lt;span class="nv"&gt;$PORT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a post&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
    http://&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FISSION_ROUTER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/guestbook/messages &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "hello world!"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get all posts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FISSION_ROUTER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/guestbook/messages/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will return a list of all the messages&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="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;: 366739357484417025,
        &lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="s2"&gt;"hello world!"&lt;/span&gt;,
        &lt;span class="s2"&gt;"timestamp"&lt;/span&gt;: 1531990369
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;: 366739413774237697,
        &lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="s2"&gt;"hello world!"&lt;/span&gt;,
        &lt;span class="s2"&gt;"timestamp"&lt;/span&gt;: 1531990387
    &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;: 366739416644550657,
        &lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="s2"&gt;"hello world!"&lt;/span&gt;,
        &lt;span class="s2"&gt;"timestamp"&lt;/span&gt;: 1531990399
    &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;You can also get a single post using the id&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FISSION_ROUTER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/guestbook/messages/366456868654284801
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Updating a post&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="se"&gt;\&lt;/span&gt;
    http://&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FISSION_ROUTER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/guestbook/messages/366456868654284801 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "hello world again!"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deleting a post&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; DELETE &lt;span class="se"&gt;\&lt;/span&gt;
    http://&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FISSION_ROUTER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/guestbook/messages/366456868654284801 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Cache-Control: no-cache'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;At this point you know how to create a simple guestbook application using REST APIs and database on Fission.This was a simple application to show you the capabilities of Fission.You can try to create your own application which may be more complex than this one.&lt;/p&gt;

&lt;p&gt;This article was originally posted on &lt;a href="https://fission.io/blog/guestbook-application-with-fission-and-cockroachdb/"&gt;Fission.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>kubernetes</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
