<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Onkar Naik on Medium]]></title>
        <description><![CDATA[Stories by Onkar Naik on Medium]]></description>
        <link>https://medium.com/@onkar17?source=rss-99099847e264------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*ab2dFMKEb1A6gh599aEX_w.png</url>
            <title>Stories by Onkar Naik on Medium</title>
            <link>https://medium.com/@onkar17?source=rss-99099847e264------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 28 May 2026 17:57:56 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@onkar17/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Streamlining Domain Redirects: Unlocking Efficiency with Istio]]></title>
            <link>https://medium.com/google-cloud/streamlining-domain-redirects-unlocking-efficiency-with-istio-41728ecf7fbb?source=rss-99099847e264------2</link>
            <guid isPermaLink="false">https://medium.com/p/41728ecf7fbb</guid>
            <category><![CDATA[istio-service-mesh]]></category>
            <category><![CDATA[dns]]></category>
            <category><![CDATA[network]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Onkar Naik]]></dc:creator>
            <pubDate>Tue, 24 Jun 2025 05:18:04 GMT</pubDate>
            <atom:updated>2025-06-25T06:55:42.721Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*p6czQnbHNwF9rXgENL5-Jg.png" /><figcaption>Source: Google</figcaption></figure><h4>What is Domain Redirection?</h4><p>A domain redirect is a technique for automatically redirecting users from one web address to another. It is also known as URL redirection, which forwards one domain or URL to another. When users attempt to access a specific domain, the server redirects them to a different domain.</p><h4>Types of Redirections</h4><ul><li><strong>301 Redirect:</strong> This is a permanent redirection, indicating that the original URL has permanently moved to a new location. Search engines recognize this redirection type and transfer the page rank to the new URL.</li><li><strong>302 Redirect:</strong> This is a temporary redirection. It indicates that the move is temporary, and search engines typically don’t transfer page rank to the new URL.</li><li><strong>Meta Refresh:</strong> This method of redirection is executed at the HTML level. It involves placing a meta tag in the HTML header of a web page, which automatically redirects the browser to a different URL after a specified amount of time.</li><li><strong>JavaScript Redirect:</strong> Similar to Meta Refresh, JavaScript can redirect users to a different URL after a certain amount of time or immediately.</li></ul><h4>Use Cases</h4><ol><li><strong>Changing Domain Names:</strong> If you’ve changed your website’s domain name, you can redirect the old domain to the new one so that visitors who use the old URL are automatically directed to the new one.</li><li><strong>Consolidating Multiple Domains:</strong> If you have multiple domains that you want to point to a single website, you can set up redirection to all lead to the same destination.</li><li><strong>Correcting Misspellings:</strong> If users frequently misspell your domain name, you can redirect the misspelled versions to the correct ones to ensure they still reach your site.</li><li><strong>Managing Traffic:</strong> Redirection can also be used to manage traffic flow. For example, during high-traffic periods, you might redirect visitors to a different server or a cached version of your site to improve performance.</li></ol><h4>Problem Statement</h4><p>An organization deployed its product application on the Google Kubernetes Engine, enabled with <strong>ASM (Anthos Service Mesh)</strong>, and recently renewed its brand name. To continue serving older customers using the initial domain name, they have set <strong>Nginx Redirection.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I8ZH8oyPXeMEwoIkB29Osg.png" /><figcaption>Redirection Setup Using Nginx</figcaption></figure><p>The challenge here is to set up the Redirection using <strong>Native</strong> <strong>Istio Service Mesh</strong> instead of Nginx, which adds another layer of Nginx management overhead.</p><h4>Solution</h4><p>Istio supports various kinds of domain redirections and URL rewrites. We can use it to handle domain redirection using the Istio native approach instead of adding additional redirection services or Ingress.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3YvES3ZY0nYMyrBmGCC3dQ.png" /><figcaption>Istio Native Domain Redirection</figcaption></figure><h4>Prerequisites</h4><ol><li>Google Cloud Platform Account</li><li>Google Kubernetes Engine (GKE) Cluster with ASM or Istio</li></ol><p>We have already set up a Google Kubernetes Engine cluster with Anthos Service Mesh (ASM), which was installed as part of the prerequisites.</p><p><strong>Anthos Service Mesh</strong> is a managed service mesh, based on Istio, that provides a security-enhanced, observable, and standardized communication layer for applications.</p><ul><li><a href="https://cloud.google.com/service-mesh/docs/overview">About Anthos Service Mesh | Google Cloud</a></li><li><a href="https://cloud.google.com/service-mesh/docs/unified-install/anthos-service-mesh-prerequisites">Anthos Service Mesh prerequisites | Google Cloud</a></li></ul><p>Let’s deploy one sample microservice application as part of our use case. We use the <strong>Bank of Anthos Application</strong> provided by GCP for demo purposes.</p><p>Create a separate namespace to deploy all the Bank of Anthos Application microservices.</p><pre>kubectl create ns anthos-app</pre><p>You can refer to the deployment Quickstart below provided by GCP for the BOA application deployment.</p><p><a href="https://github.com/GoogleCloudPlatform/bank-of-anthos">GitHub - GoogleCloudPlatform/bank-of-anthos: Retail banking sample application showcasing Kubernetes and Google Cloud</a></p><h4>ASM Ingress Gateway Deployment</h4><p>An ingress Gateway describes a load balancer operating at the edge of the mesh that receives incoming HTTP/TCP connections. Unlike <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/">Kubernetes Ingress Resources</a>, it does not include any traffic routing configuration.</p><pre>kubectl apply -f asm-ingressgateway-deployment.yaml</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d02c98794d8c3cb8eee9cb44d5339ecf/href">https://medium.com/media/d02c98794d8c3cb8eee9cb44d5339ecf/href</a></iframe><p>After the Ingress Gateway deployment, we need to create the ASM Ingress Gateway deployment service to integrate it with GKE Ingress and expose the BOA application to external traffic.</p><p><strong>Note: </strong>The difference between the routing of a regular GKE Ingress and an ASM Ingress is that the routing decisions are performed inside the cluster (e.g., inside namespace/asm-ingress/deployment/asm-ingressgateway).</p><pre>kubectl apply -f ingressgateway-service.yaml</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b2c8ed1d7c3ec22ad67f54739416d060/href">https://medium.com/media/b2c8ed1d7c3ec22ad67f54739416d060/href</a></iframe><p><strong>GKE Ingress Deployment</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b2435dbf7aa3df7fd9ca61974607c381/href">https://medium.com/media/b2435dbf7aa3df7fd9ca61974607c381/href</a></iframe><p><strong>Frontend Istio VirtualService Configuration</strong></p><p>A VirtualService is a high-level configuration resource that controls how requests are routed to services in your cluster.</p><p>Below is the frontend virtual service configuration for routing traffic to the BOA frontend application.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c25ed30914e89ac3d006ec2532897ef5/href">https://medium.com/media/c25ed30914e89ac3d006ec2532897ef5/href</a></iframe><h4><strong>Domain Redirection Istio VirtualService Configuration</strong></h4><p>The provided manifest is an <strong>Istio </strong><strong>VirtualService</strong> configuration used to <strong>redirect HTTP traffic</strong> from one domain to another domain.</p><ul><li><strong>Host</strong>: Matches incoming requests to demo.example.com.</li><li><strong>Gateway</strong>: Uses the Istio Gateway example-ingressgateway under the asm-ingress namespace.</li><li><strong>Redirect</strong>:<br>When a request comes to demo.example.comIstio will <strong>redirect the authority (host)</strong> to app.demo.example.com.<br>This typically results in an <strong>HTTP 301/302 redirect.</strong></li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/13ac536acd942ffef69d051f0cb4fb3c/href">https://medium.com/media/13ac536acd942ffef69d051f0cb4fb3c/href</a></iframe><p><strong>Note:</strong> If you also want to redirect the <strong>path or scheme (e.g., HTTP to HTTPS)</strong>, you can extend the rule like this:</p><pre>http:<br>  — match:<br>      — uri:<br>          prefix: /<br>    redirect:<br>      authority: app.demo.example.com<br>      scheme: https</pre><h4><strong>Testing the domain redirection</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*BYE7jfUWnwe2SUbv.jpg" /><figcaption>Source: Google</figcaption></figure><ol><li>If we curl to the old domain URL as shown below, Istio redirects it to the new domain as configured in the Istio Virtual Service.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BmT3tTHBHL4uP2kl_UCaHg.png" /></figure><p>2. If we curl to the old domain URL with any prefix with it as shown below, Istio redirects it to the new domain as configured in the Istio Virtual Service.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hfdsmqfQUma9S26PJ-3b7Q.png" /></figure><p>3. Upon hitting the Old domain URL from the browser, you can see it redirecting to the new domain URL successfully.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OvgpYxYo1ykLdhGf7Vh9lw.png" /><figcaption>Redirected BOA application UI Page</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x-U69Z9Q49SBjuG9uJQKug.png" /><figcaption>Redirected BOA application UI Page</figcaption></figure><h4>Conclusion</h4><p>Istio’s powerful traffic management capabilities allow you to implement clean and efficient HTTP redirection policies through its <strong>VirtualService</strong> configuration. By simply leveraging the <strong>redirect</strong> block, you can seamlessly route users to a new domain, subdomain, or even enforce HTTPS—all <strong>without changing your application code.</strong></p><p>This is especially useful during domain migrations, enforcing canonical URLs, or setting up SEO-friendly redirects. Combined with Istio Gateways, you gain fine-grained control over ingress behavior in a secure and declarative way.</p><p>Whether you’re managing a microservices architecture or just introducing smart routing at the edge, Istio makes redirection easy, scalable, and cloud-native.</p><h4>🔗 References:</h4><ol><li>Sample BOA application source code: <a href="https://github.com/GoogleCloudPlatform/bank-of-anthos">https://github.com/GoogleCloudPlatform/bank-of-anthos</a></li><li>Istio Service Mesh Documentation: <a href="https://istio.io/latest/docs/">https://istio.io/latest/docs/</a></li></ol><h4>🤔 Questions?</h4><p>If you have any questions, I’ll be happy to read them in the comments. Follow me on <a href="https://medium.com/@onkar17">Medium</a> or <a href="https://www.linkedin.com/in/onkar17/">LinkedIn</a> for more interesting content.</p><p>😃 Try out the Istio Native Redirection &amp; let me know your experience or use cases in the comments.</p><p>🚀 Let’s connect and embark on a transformative cloud journey together!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*AKBWNZ-L8CQUBXdQ.png" /><figcaption>Source: Google</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=41728ecf7fbb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/google-cloud/streamlining-domain-redirects-unlocking-efficiency-with-istio-41728ecf7fbb">Streamlining Domain Redirects: Unlocking Efficiency with Istio</a> was originally published in <a href="https://medium.com/google-cloud">Google Cloud - Community</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Terraform As A Service: Google Infrastructure Manager]]></title>
            <link>https://medium.com/google-cloud/terraform-as-a-service-google-infrastructure-manager-409c2c9e71d5?source=rss-99099847e264------2</link>
            <guid isPermaLink="false">https://medium.com/p/409c2c9e71d5</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Onkar Naik]]></dc:creator>
            <pubDate>Wed, 01 Nov 2023 14:08:05 GMT</pubDate>
            <atom:updated>2023-11-04T14:34:24.766Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-M8UF1is-XV_jH8sAvuzYQ.png" /><figcaption>Credits: Onkar Naik</figcaption></figure><h4>What is Google Infrastructure Manager?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zMPFIZmmMXeLv_MkmKY_Ew.jpeg" /><figcaption>Source: Google</figcaption></figure><p>Infrastructure Manager is a GCP-managed service that automates the deployment and management of Google Cloud infrastructure resources.</p><p>Infrastructure is defined using Terraform and deployed onto Google Cloud by Infra Manager, enabling you to manage GCP resources using <strong>Terraform as a service.</strong></p><h4>Infra Manager for IAC Lifecycle Management</h4><ol><li>You can keep the Terraform code or configuration, either in a public Git repository, in a Cloud Storage bucket, or in a local machine.</li><li>Infra Manager keeps the versioning of every terraform deployment by creating revisions of the deployments.</li><li>For every revision, Infra Manager stores the Logs, terraform source code, Artifacts, and state files in a cloud storage bucket.</li></ol><h4>Infra Manager Workflow</h4><ol><li>Creating Infra Manager deployment using gcloud CLI to deploy resources from terraform code.</li><li>Infra Manager takes the request and creates a cloud build trigger to perform terraform init | validate | plan and apply stages.</li></ol><h4>Infra Manager Terraform Constraints</h4><ol><li>Templating or generation of Terraform is not supported.</li><li>The configuration should be using Terraform version 1.2.3.</li><li>Backend blocks shouldn’t be defined.</li><li>Provisioners are not supported.</li></ol><h4>Infra Manager Pricing</h4><p>Infrastructure Manager charges for Cloud Build execution and Cloud Storage of source code + logs blueprints.</p><h3>Infra Manager In Action</h3><p>In this article, we will be deploying sample GCS buckets using Google Infra Manager.</p><h4>Prerequisite</h4><ol><li>Google Cloud Project</li></ol><p>As a part of the prerequisite, we already have an active GCP Project where we can use the GCP Infra manager to provision the GCP resources.</p><h4>Enabling Infra Manager Service API</h4><p>Before getting started with GCP Infra Manager we need to enable the Infra Manager service API for the GCP Project.</p><pre>gcloud services enable config.googleapis.com</pre><h4>Authentication for Infra Manager Deployments</h4><p>In order to create Infra Manager deployment the service account used for deploying the resources defined in the terraform code needs to have a config agent role.</p><ol><li>Create the service account (If you do not have one already)</li></ol><pre>gcloud iam service-accounts create SERVICE_ACCOUNT_NAME</pre><p>2. Grant the roles/config.agent IAM role to the service account:</p><pre>gcloud projects add-iam-policy-binding PROJECT_ID --member=&quot;serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com&quot; --role=roles/config.agent</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GDyf34DEBtm2hneMXHLTcA.png" /><figcaption>IAM bindings for Terraform/Infra Manager service account</figcaption></figure><p>3. Grant the additional required permissions for deploying the resources described in the terraform code.</p><pre>gcloud projects add-iam-policy-binding PROJECT_ID \<br>    --member=serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \<br>    --role=storage.Admin // for creating GCS buckets</pre><h4>Creating Infra Manager Deployment</h4><p>Below are the respective commands for creating Infra Manager deployments based on source code location.</p><ol><li><strong>Deploy a Terraform configuration stored in a Cloud Storage bucket</strong></li></ol><pre>gcloud alpha infra-manager deployments apply projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID \<br>    --service-account projects/SERVICE_ACCOUNT_PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT \<br>    --gcs-source gs://BUCKET_NAME/OBJECT_NAME \<br>    --input-values=INPUT_1_NAME=VALUE,INPUT_2_NAME=VALUE</pre><p><strong>2. Deploy a Terraform configuration stored in a public Git repository</strong></p><pre>gcloud alpha infra-manager deployments apply projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID \<br>    --service-account projects/SERVICE_ACCOUNT_PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT \<br>    --git-source-repo=&quot;GIT_REPO&quot; \<br>    --git-source-directory=&quot;DIRECTORY&quot; \<br>    --git-source-ref=&quot;REF&quot; \<br>    --input-values=INPUT_1_NAME=VALUE,INPUT_2_NAME=VALUE</pre><p><strong>3. Deploy a Terraform configuration stored on your local machine</strong></p><pre>gcloud alpha infra-manager deployments apply projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID \<br>    --service-account projects/SERVICE_ACCOUNT_PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT \<br>    --local-source=&quot;LOCAL_DIRECTORY&quot; \<br>    --input-values=INPUT_1_NAME=VALUE,INPUT_2_NAME=VALUE</pre><p>In our case, we have the terraform source code (root+calling modules) stored in a public git repository.</p><p><strong>Note: Currently Infra Manager only supports public git repositories.</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8cc33844ac046170a8aa89768e1923e7/href">https://medium.com/media/8cc33844ac046170a8aa89768e1923e7/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yvCi9FZT021Grmsa71_LLg.png" /><figcaption>Infra Manager Deployment for GCS bucket creation</figcaption></figure><p>We can also see the cloud build trigger created by Infra Manager at the backend for deploying the terraform code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*p9QzKgBhd7FbVAB4k9clQg.png" /><figcaption>Infra Manager Cloud Build trigger output</figcaption></figure><p>After Infra Manager terraform deployment we can see that the sample GCS bucket has been provisioned successfully.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mupIzvZsaxGYW3VMyuEIow.png" /><figcaption>GCS Bucket provisioned by Infra Manager deployment</figcaption></figure><p>Infra Manager creates a storage bucket in the project and location where Infra Manager is run. Currently, the <strong>supported locations</strong> include <strong>asia-east1, europe-west1, and us-central1.</strong></p><p>After the deployment is created, the Infrastructure Manager artifacts are in this storage bucket which has the name in the format: gs://PROJECT_ID-LOCATION-blueprint-config.</p><p>The artifacts in the blueprint storage bucket include:</p><ul><li>Cloud Build logs.</li><li>Terraform logs.</li><li>A copy of the Terraform configuration.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*alcWxyn8C1m0gXSb_L7U1w.png" /><figcaption>Infra Manager Blueprint Storage Bucket</figcaption></figure><h4>Infra Manager Deployment Revisions</h4><p>For every terraform run Infra Manager deployment creates revisions to keep versioning.</p><p>When you initially create a deployment, this deployment is also a revision and has the revision ID r-0.</p><p>If you <strong>update the deployment(Terraform code modification)</strong>, then Infrastructure Manager creates a new revision with an identifier(revision ID)r-1. For every new revision, the identifier increases by one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KqEf5vCc6PvyMLxlSOv_Eg.png" /><figcaption>Infra Manager Deployment Revisions</figcaption></figure><p>Now, Let&#39;s create a new GCS bucket named gcp-infra-manager-bucket-2 using Infra Manager deployment. This will create a new revision of Infra manager deployment named gcs-deployment.</p><pre>gcloud alpha infra-manager deployments apply projects/onkar-17-cloud/locations/us-central1/deployments/gcs-deployment\<br>   --service-account projects/onkar-17-cloud/serviceAccounts/infra-manager-gcp@onkar-17-cloud.iam.gserviceaccount.com\<br>    --git-source-repo=https://github.com/Onkar179/google-infra-manager-repo \<br>    --git-source-directory=gcs-buckets \<br>    --git-source-ref=main \<br>    --input-values=name=gcp-infra-manager-bucket-2</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gLTrcqC7-ZeSo7-bXWA-1Q.png" /></figure><p>You can also check &amp; view the deployments, revisions &amp; state of the resources that have been deployed by the Infra Manager.</p><h4><strong>Listing Infra Manager deployment</strong></h4><pre>gcloud alpha infra-manager deployments list --project PROJECT_ID --location &quot;LOCATION&quot;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9DV3D8jkuFwyfGV4LDTptg.png" /><figcaption>Infra Manager deployment list</figcaption></figure><h4><strong>Checking Infra Manager deployment state</strong></h4><p>The Infra Manager deployments have several states from which the status of deployment can be checked.</p><p><a href="https://cloud.google.com/infrastructure-manager/docs/reference/rest/v1/projects.locations.deployments#state">REST Resource: projects.locations.deployments | Infrastructure Manager | Google Cloud</a></p><pre>gcloud alpha infra-manager deployments describe projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*S5JXE_6qMZXbYZudam2FQA.png" /><figcaption>Infra Manager deployment state</figcaption></figure><h4>Listing revisions in a deployment</h4><pre>gcloud alpha infra-manager revisions list --deployment=projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XaIOC0EuYc4FpKMO91_i1Q.png" /><figcaption>Infra Manager deployment revisions</figcaption></figure><h4>Checking the State of a revision in a deployment</h4><pre>gcloud alpha infra-manager revisions describe projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID/revisions/REVISION_ID</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VeaT4f3y4oz_5B-HzQYkQA.png" /><figcaption>Infra Manager deployment revision state</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aslErDFKETNQDHvyj3CZOg.png" /><figcaption>Infra Manager deployment revision state</figcaption></figure><h4>Listing the resources provisioned by deployment under a particular revision</h4><p>Similar to deployments each revision has several states given below from which the status of resource provisioning can be checked.</p><p>STATE_UNSPECIFIED, PLANNED, IN_PROGRESS, RECONCILED, FAILED</p><pre>gcloud alpha infra-manager resources list --revision=projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID/revisions/REVISION_ID</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*r0g0SVO-N3v2BvmBddQPOw.png" /><figcaption>Infra Manager deployment revisions resources</figcaption></figure><h4>Checking details of deployed resources</h4><p>The below command requires Resource ID which you can get from the above command while listing out the resources.</p><pre>gcloud alpha infra-manager resources describe projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID/revisions/REVISION_ID/resources/RESOURCE_ID</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uqR6qWNHBE9ZnbtwPZZ0uQ.png" /><figcaption>Infra Manager deployment resources state</figcaption></figure><h3>Managing Terraform states with Infra Manager</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/834/1*YDIPWS-iJ_qqYBoJPjSBgw.png" /><figcaption>Source: <a href="https://spacelift.io/">spacelift.io/</a></figcaption></figure><p>Google Infra Manager does support terraform state modification &amp; inspection for each deployment &amp; revision by which we can do <strong>state mutation or import the states of manually created resources for managing those resources using Google Infra Manager.</strong></p><p>For <strong>importing the terraform state</strong> of any manually created resource into the Infra Manager managed terraform state, first we need to <strong>lock the Infra Manager deployment and</strong> <strong>download the state file locally.</strong></p><ol><li><strong>Lock the deployment</strong></li></ol><p>Lock the deployment to prevent any changes to the deployment while you mutate the state file. The deployment must be locked to be able to download the state file.</p><pre>gcloud alpha infra-manager deployments lock DEPLOYMENT_ID --project PROJECT_ID --location LOCATION</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Xr4oJ4_w14ds9gpcTsLWzg.png" /><figcaption>locked Infra Manager deployment</figcaption></figure><p>2. <strong>Download the state file</strong></p><p>Downloading state files requires a blueprint cloud storage bucket signed URL.</p><pre>SIGNED_STATE_DOWNLOAD_URL=$(gcloud alpha infra-manager deployments export-statefile DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --format=&quot;get(signedUri)&quot;)</pre><pre>curl -s -X GET --output terraform.tfstate ${SIGNED_STATE_DOWNLOAD_URL}</pre><p>Once the state file is downloaded you can place it under local terraform code workspace and perform state import.</p><p>Here we have one bucket named onkar-datathat is manually created in our GCP project. Going forward, In order to manage it using Infra Manager we need to import the state of that bucket in the Infra Manager deployment state that we downloaded above.</p><h4><strong>Importing the terraform state</strong></h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e0844c953c845b1ddd7e5a283c6762d6/href">https://medium.com/media/e0844c953c845b1ddd7e5a283c6762d6/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3OAtqaQV1LTVgROMjJknCg.png" /><figcaption>terraform plan</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/908/1*xncz6_Zt98PpWE7o2No5PA.png" /><figcaption>terraform plan</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9eNK8aHpV7rB9u89p2VZ3A.png" /><figcaption>terraform apply</figcaption></figure><p>After the successful state import, if you have made changes to terraform code files locally then have to upload the modified terraform code to the storage bucket, or public git repository that you are using as the source to deploy the configuration.</p><p>In our case, it is a public git repository so have to push the updated terraform code for onkar-data GCS bucket, so that Infra Manager will sync the updated source code with the updated state in order to manage new resources.</p><p><strong>Upload back the terraform state file to the Infra Manager storage bucket</strong></p><ol><li>Getting the lock ID of Infra Manager deployment to unlock</li></ol><pre>LOCK_ID=$(gcloud alpha infra-manager deployments export-lock DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --format=&quot;get(lockId)&quot;</pre><p>2. Uploading the modified/imported state file</p><pre>SIGNED_STATE_UPLOAD_URL=$(gcloud alpha infra-manager deployments import-statefile DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --lock-id ${LOCK_ID} --format=&quot;get(signedUri)&quot;)<br><br>curl -s -X PUT --upload-file terraform.tfstate $SIGNED_STATE_UPLOAD_URL</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Sb1zfbutIgeJWHHHhOpVhg.png" /><figcaption>terraform state bucket signed URL</figcaption></figure><p>3. Unlock the Infra Manager deployment</p><pre>LOCK_ID=$(gcloud alpha infra-manager deployments export-lock DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --format=&quot;get(lockId)&quot;)<br><br>gcloud alpha infra-manager deployments unlock DEPLOYMENT_ID --project PROJECT_ID --location LOCATION --lock-id ${LOCK_ID}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ggWM9EZ7aGh2Wz0TsgmXUA.png" /><figcaption>Unlocked Infra Manager deployment</figcaption></figure><p>Once the deployment is unlocked &amp; after successful terraform state import, the Infra Manager also manages the manually created bucket onkar-data along with gcp-infra-manager-bucket-2 .</p><h4>Deleting the Infra Manager Deployment</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OU0oqAxrYbC-lIcACl2toA.gif" /><figcaption>Source: Google</figcaption></figure><ol><li><strong>Delete the deployment and provisioned resources</strong></li></ol><pre>gcloud alpha infra-manager deployments delete projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID</pre><p>2.<strong> Delete the deployment by keeping resources undeleted</strong></p><p>Google Infra Manager also supports deletion of deployment by keeping the provisioned resources undeleted.</p><p>This can be useful in scenarios where you want to <strong>manage the resources manually not using IAC</strong> for which you can only delete the deployment.</p><pre>gcloud infra-manager deployments delete projects/PROJECT_ID/locations/LOCATION/deployments/DEPLOYMENT_ID \<br>    --delete-policy=abandon</pre><h4>Why Google Infra Manager? Why not just run Terraform directly?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/626/1*B5wb-aKosta6O5mEbrzl1Q.png" /><figcaption>Source: Google</figcaption></figure><h4>Google Infrastructure Manager Vs Terraform</h4><p>Google Infra Manager provides the below features in addition to using Terraform locally, which makes it more useable as <strong>Terraform as a service</strong>.</p><ol><li>Provides history or traceability of all deployments</li><li>Role-based access control for each deployment &amp; revisions</li><li>Governance and auditing controls</li><li>Secured storage of terraform state files (SIGNED URLs)</li><li>UI and Observability</li></ol><h3>Conclusion</h3><p>With Infrastructure Manager, users can create templates, version their infrastructure configurations, and deploy resources consistently, promoting scalability, agility, and resource optimization.</p><p>This tool streamlines infrastructure management and enhances the overall efficiency and reliability of operations on Google Cloud.</p><h3>🔗 References</h3><ol><li><strong>Demo Source Code:</strong> <a href="https://github.com/Onkar179/google-infra-manager-repo.git">https://github.com/Onkar179/google-infra-manager-repo.git</a></li><li><strong>Infra Manager Documentation:</strong> <a href="https://cloud.google.com/infrastructure-manager/docs/">https://cloud.google.com/infrastructure-manager/docs/</a></li></ol><h3>🤔 Questions?</h3><p>If you have any questions, I’ll be happy to read them in the comments. Follow me on <a href="https://medium.com/@onkar17">Medium</a> or <a href="https://www.linkedin.com/in/onkar17/">LinkedIn</a> for more interesting content.</p><p>😃 Try out the Infra Manager deployments &amp; let me know your experience or use cases in the comments.</p><p>🚀 Let’s connect and embark on a transformative cloud journey together!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WrArzFmAGDql1-emrQpe1Q.png" /><figcaption>Source: Google</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=409c2c9e71d5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/google-cloud/terraform-as-a-service-google-infrastructure-manager-409c2c9e71d5">Terraform As A Service: Google Infrastructure Manager</a> was originally published in <a href="https://medium.com/google-cloud">Google Cloud - Community</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Microservices Authentication Using Ambassador API Gateway on GKE]]></title>
            <link>https://blog.searce.com/microservices-authentication-using-ambassador-api-gateway-on-gke-76437fcbd2c2?source=rss-99099847e264------2</link>
            <guid isPermaLink="false">https://medium.com/p/76437fcbd2c2</guid>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[api]]></category>
            <dc:creator><![CDATA[Onkar Naik]]></dc:creator>
            <pubDate>Mon, 10 Oct 2022 06:10:04 GMT</pubDate>
            <atom:updated>2023-11-01T06:32:10.001Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cAyf5yvJlF4PFaWCiK0AUQ.png" /></figure><p>This Article is based on <strong>how to secure Microservices on GKE using Ambassador Edge Stack API Gateway Authentication.</strong></p><h4>Problem Statement</h4><p>Multiple microservices are deployed on the GKE Cluster and exposed to the public world using GKE Ingress. The challenge here is setting up authentication for users accessing various application microservices via GKE Ingress.</p><h4>Use Case</h4><p>Let&#39;s assume a scenario where we have applications microservices deployed on the GKE cluster and expose them using GKE Ingress to the public users. All incoming user requests to GKE Ingress must be authenticated before routing them to the actual application or backend microservices.</p><h4>Solution</h4><p>The solutions to the use case are either having the authentication preconfigured within the application code itself or else having a separate application for authentication only. The requirement here is to have a particular application that does the authentication which can be achieved by using the Ambassador Edge Stack API Gateway solution which handles all the routing and authentication parts more efficiently in microservices.</p><h4>Prerequisites</h4><ol><li>Google Cloud Platform Account</li><li>Google Kubernetes Engine (GKE) Cluster</li></ol><h4>What is Ambassador Edge Stack?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*E-hWHadLP8WblwBixmwq5w.jpeg" /></figure><p>Ambassador Edge Stack is a Kubernetes-native API Gateway that delivers scalability, security, and simplicity for Kubernetes microservices.</p><p>The Ambassador Edge Stack makes securing microservices easy with comprehensive security functionality, including automatic TLS, authentication, rate limiting, WAF integration, and fine-grained access control.</p><p>As part of the prerequisites, we have already set up a zonal Google Kubernetes Engine cluster for deploying the Ambassador Edge Stack and sample quote microservice application.</p><p><a href="https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-zonal-cluster">Creating a zonal cluster | Google Kubernetes Engine (GKE) | Google Cloud</a></p><h4>Ambassador Edge Stack Installation on GKE Cluster</h4><p><a href="https://www.getambassador.io/docs/edge-stack/latest/topics/install/#installing-ambassador-edge-stack">Installing Edge Stack | Edge Stack</a></p><p>You can install Ambassador Edge Stack using various options like Helm charts, Kubernetes YAML, or Docker Image.</p><p>We are using the Kubernetes YAML Installation method for Edge Stack.</p><ol><li><strong>Creating Namespace for Ambassador Edge Stack</strong></li></ol><pre>kubectl create namespace ambassador</pre><p>2. <strong>Installing Ambassador Edge Stack</strong></p><p>For installing the Ambassador Edge Stack first we need to install the Ambassador Edge Stack-related CRDs in order to deploy various edge stack-specific resources on GKE.</p><pre>kubectl apply -f <a href="https://app.getambassador.io/yaml/edge-stack/3.1.0/aes-crds.yaml">https://app.getambassador.io/yaml/edge-stack/3.1.0/aes-crds.yaml</a> &amp;&amp; \</pre><pre>kubectl wait --timeout=90s --for=condition=available deployment emissary-apiext -n emissary-system &amp;&amp; \</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6SHnbgSx-Q3nyn8VxkG_AA.png" /></figure><p>After installing the Edge Stack Kubernetes CRDs we can begin the installation of the Ambassador Edge Stack on GKE.</p><p><strong>Note:</strong> By default, the service type for edge-stack service is Node Port. As GKE Ingress only supports ClusterIP services as the backend, you need to change this service type for edge-stack service to Cluster IP before installing the ambassador edge stack on GKE.</p><pre>kubectl apply -f <a href="https://app.getambassador.io/yaml/edge-stack/3.1.0/aes.yaml">https://app.getambassador.io/yaml/edge-stack/3.1.0/aes.yaml</a> &amp;&amp; \</pre><pre>kubectl -n ambassador wait --for condition=available --timeout=90s deploy -lproduct=aes</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QUHiimOgRyWwPNeA6EUy4Q.png" /></figure><pre>kubectl get pods -n ambassador</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QWqIHJhDwyrRZeR5B5YonA.png" /></figure><pre>kubectl get service -n ambassador</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AL9Am14IY72OA9D-OxyfLg.png" /></figure><pre>kubectl get all -n emissary-system</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1UOoe5U2rDimPjko12p-Vw.png" /></figure><p><strong>We have successfully installed Ambassador Edge Stack on the GKE Cluster.</strong></p><p>As part of our use case, let&#39;s deploy one sample microservice application. For demo purposes, we use a sample quote application provided by Ambassador.</p><p><a href="https://github.com/datawire/quote">GitHub - datawire/quote: The Quote of the Moment Service... now with 100% more Go.</a></p><ol><li><strong>Sample Quote Application Deployment</strong></li></ol><p>This basic configuration creates the quote deployment and service to expose that deployment on port 80.</p><pre>kubectl apply -f quote.yaml</pre><p>quote.yaml :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/72fdf288a340f1327c686e24598897c9/href">https://medium.com/media/72fdf288a340f1327c686e24598897c9/href</a></iframe><p>2. <strong>Routing traffic to Quote Application from Ambassador Edge Stack</strong></p><p>In order to route traffic from the Ambassador Edge Stack service (gateway) to the Quote application, we need to attach the quote application as the backend to the Ambassador Edge Stack service.</p><p>Ambassador Edge Stack mainly provides <strong>two CRDs (Listener and Mapping)</strong> for routing traffic to specific applications from the edge stack.</p><p><strong>Listener</strong> CRD tells Ambassador Edge Stack what port to listen on, and the <strong>Mapping</strong> CRD tells Ambassador Edge Stack how to route incoming requests by host and URL path from the edge of your cluster to Kubernetes services.</p><p><strong>Listener for HTTP on port 8080 &amp; HTTPS on port 8443 :</strong></p><p>listener.yaml :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a0190f48b89a4cd1368a23f4676141ce/href">https://medium.com/media/a0190f48b89a4cd1368a23f4676141ce/href</a></iframe><pre>kubectl get listener -n ambassador</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MWFpjHqBoN-dhfLkG-9EYg.png" /></figure><p><strong>Mapping for Quote Application service :</strong></p><pre>kubectl apply -f quote-mapping.yaml</pre><p>quote-mapping.yaml :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7c82110cf89574382bfce6173fe2838f/href">https://medium.com/media/7c82110cf89574382bfce6173fe2838f/href</a></iframe><pre>kubectl get mappings -n ambassador</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bioWqOvQ77DgVoa5UaT9tQ.png" /></figure><p><strong>Note:</strong> If you are using Ambassador Edge Stack in the Private GKE Cluster you might get the below error while creating the mapping for backend services.</p><p>The error while creating the mapping for the quote application :</p><pre>Error from server: error when creating &quot;quote-mapping.yaml&quot;: conversion webhook for getambassador.io/v3alpha1, Kind=Mapping failed: Post &quot;https://emissary-apiext.emissary-system.svc:443/webhooks/crd-convert?timeout=30s&quot;: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)</pre><p>The issue is that the control plane (API Server) is trying to call emissary-apiext.emissary-system.svc:443 but the pods behind it are listening on port 8443.</p><p>To solve this issue you need to edit the preconfigured GKE Control Plane firewall rule <strong>gke-&lt;cluster_name&gt;-xxxxx-master </strong>and<strong> </strong>add the 8443 TCP port.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EYSVhd7D-VZ0GY_BaGLFzw.png" /></figure><p>We have successfully deployed the <strong>sample quote microservice application</strong> in the ambassador namespace.</p><p>Now let&#39;s create <strong>GKE Ingress for the Quote Application </strong>for L7 application layer load balancing features and expose it to the public users.</p><p><a href="https://cloud.google.com/kubernetes-engine/docs/concepts/ingress">GKE Ingress for HTTP(S) Load Balancing | Google Kubernetes Engine (GKE) | Google Cloud</a></p><p><strong>Optional:</strong> Here we are configuring SSL termination on GKE Ingress using Google Managed Certificates.</p><p><a href="https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs">Using Google-managed SSL certificates | Google Kubernetes Engine (GKE) | Google Cloud</a></p><pre>kubectl apply -f managed-cert.yaml</pre><p>managed-cert.yaml :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d4a98c2953d7c9d1c9f7425293cc61a3/href">https://medium.com/media/d4a98c2953d7c9d1c9f7425293cc61a3/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sAwFhmmA22yqRzzqTwivQg.png" /></figure><p>Before creating the Ingress we need to configure <strong>health checks (backend config) </strong>for the edge-stack service so that GKE Ingress will mark the backend as healthy without failure.</p><pre>kubectl apply -f backendconfig.yaml</pre><p>backendconfig.yaml :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eb8ced6214bed6263579e73221ca372c/href">https://medium.com/media/eb8ced6214bed6263579e73221ca372c/href</a></iframe><pre>kubectl annote service edge-stack -n ambassador<br>cloud.google.com/backend-config: &#39;{&quot;default&quot;: &quot;ambassador-hc-config&quot;}&#39;</pre><p><strong>Creating GKE Ingress for quote microservice application service :</strong></p><p>Here we are placing the ambassador edge stack service as a backend to the GKE Ingress. Ambassador Edge Stack service routes the traffic coming from GKE Ingress to its mapped backends i.e quote application microservice.</p><pre>kubetl apply -f ingress.yaml</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ec9e7d5725e9bf87d1d107cf7b7d9f54/href">https://medium.com/media/ec9e7d5725e9bf87d1d107cf7b7d9f54/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-hgDc4DSHB46yWE4x8gkZA.png" /></figure><p>After creating GKE Ingress successfully let&#39;s access the <strong>quote microservice application mapped as the backend to edge-stack service</strong> by sending curl requests to the configured domain for GKE Ingress and the path on which the quote application running.</p><pre>curl &lt;GKE_INGRESS_DOMAIN&gt;/backend/</pre><p><strong>GKE Ingress → edge-stack service → quote application service</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lufyau6F2TEGVPH4hWro8Q.png" /></figure><p>You can see that now all public users can able to access the quote application without any kind of authentication.</p><p>The requirement is to have authentication in place for authenticating all user&#39;s requests before routing them to the main application.</p><p>Here you can use the <strong>ambassador edge stack authentication feature</strong> which gives you options to <strong>configure and Integrate the authentication with various third-party authentication providers.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JJp8wku8aSzlBXQ37BD3gA.png" /></figure><p>Ambassador Edge Stack can authenticate incoming requests before routing them to a backing service.</p><p><strong>As per our use case, we are configuring Ambassador Edge Stack to use an external third-party authentication service. </strong>Here we are using a sample authentication service application for <strong>implementing the authentication on the GKE Ingress level using Ambassador Edge Stack for the quote application we deployed earlier.</strong></p><h4>Deploying the Authentication Service Application</h4><p><a href="https://github.com/datawire/ambassador-auth-service">GitHub - datawire/ambassador-auth-service: Example auth service for Ambassador</a></p><p>Ambassador Edge Stack delegates the actual authentication logic to a third-party authentication service which :</p><ul><li>listens for requests on port 3000</li><li>expects all URLs to begin with /extauth/</li><li><strong>performs HTTP Basic Auth only for the URLs starting with </strong><strong>/backend/get-quote/ (other URLs are always permitted without authentication)</strong></li><li>accepts only user username, password password</li><li>makes sure that the x-qotm-session the header is present, generating a new one if needed</li></ul><p>Ambassador Edge Stack routes all requests through the authentication service. It relies on the auth service to distinguish between requests that need authentication and those that do not.</p><p>This <strong>sample authentication service</strong> takes all requests from the ambassador edge stack service but <strong>only performs or asks for authentication on </strong><strong>/backend/get-quote/ path requests.</strong> Rest all requests on other paths will be permitted by auth service without authentication.</p><p>If the request gets unauthenticated due to an incorrect username or password then it will return a 404 User Unauthorised message.</p><p>If Ambassador Edge Stack cannot contact the auth service, it will return a 503 for the request.</p><p><strong>It is important to have the auth service running before configuring Ambassador Edge Stack to use it.</strong></p><pre>kubectl apply -f auth-service.yaml</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eb4df0311ff6782b2b31f177c312e01c/href">https://medium.com/media/eb4df0311ff6782b2b31f177c312e01c/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8h9DSAtKFG3J_xL_CHigeQ.png" /></figure><h4>Configure Ambassador Edge Stack authentication</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*NUreBjRJ6QpoyDSatWUl5A.jpeg" /></figure><p>Once the auth service is running, we need to tell Ambassador Edge Stack about it.</p><p>The easiest way to tell Ambassador Edge Stack to use the authentication service that we deployed is using ambassador CRD called <strong>Filters and Filter Policy.</strong></p><p><a href="https://www.getambassador.io/docs/edge-stack/latest/topics/using/filters/#filters-and-authentication">Filters and authentication | Edge Stack</a></p><p><strong>Filters</strong></p><p>Filters are used to extend the Ambassador Edge Stack to modify or intercept a request before sending it to your backend service. The most common use case for Filters is authentication, and Edge Stack includes a number of built-in filters for this purpose. Edge Stack also supports developing custom filters.</p><p>There are various types of Filters, as per our solution we are using <strong>External Filter.</strong></p><p>The External Filter calls out to an external service speaking the ext_authZ protocol, providing a highly flexible interface to plug in your own authentication, authorization, and filtering logic.</p><pre>kubectl apply -f filter.yaml</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/217fd060eb1456776f65730a08b2312c/href">https://medium.com/media/217fd060eb1456776f65730a08b2312c/href</a></iframe><p>This configuration tells Ambassador Edge Stack about the Filter which has the type External which includes <strong>auth_service</strong> reference to the authentication service running on port 3000.</p><p><strong>Filter Policy</strong></p><p>Filters are managed using a FilterPolicy resource. The FilterPolicy resource specifies a particular host or URL to match, along with a set of filters to run when a request matches the host/URL.</p><p>The following filter policy would enable you to Filter requests to all hosts and paths.</p><p>The authentication service that we are using is only configured to perform authentication on requests to /backend/get-quote/ .</p><pre>kubectl apply -f filter-policy.yaml</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a0fb6df1b77e9af3cf67bcd5fbe542c4/href">https://medium.com/media/a0fb6df1b77e9af3cf67bcd5fbe542c4/href</a></iframe><pre>kubectl get filter &amp;&amp; kubectl get filterpolicy</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XdNZPdOpJvMccrtGaLFhXw.png" /></figure><h4>Test authentication</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QNBNuCgkUImdV7mBs37JFQ.png" /><figcaption>Ambassador API Gateway Authentication on GKE</figcaption></figure><ol><li>If we curl to a protected URL (/backend/get-quote/). We get a <strong>401</strong> since we haven’t authenticated by username and password.</li><li>Similarly for authenticating by the wrong username or password we get 401 unauthorized responses.</li></ol><pre>curl &lt;GKE_INGRESS_DOMAIN&gt;/backend/get-quote/  <br>                             //without passing username or password</pre><pre>curl -Lv -u username:password123 &lt;GKE_INGRESS_DOMAIN&gt;/backend/get-quote    <br>                              //passing wrong username or password</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qq1Dz_adWahLldPQdyqalg.png" /></figure><p>You can also test the API Authentication using Postman Tool.</p><p><strong>Using Postman API Console :</strong></p><p><a href="https://www.postman.com/">Postman: The World&#39;s Leading API Platform | Sign Up for Free</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mAtCORVbVoqcqmlYKeHf7A.png" /><figcaption>401 Unauthorized — without authentication</figcaption></figure><p>3. If you authenticate to the protected URL (/backend/get-quote/) with the correct username and password, you will able to access the quote application microservice.</p><p><strong>Note: </strong>The only valid credentials for the sample authentication service (example-auth:3000) we deployed are username:password.</p><p><a href="https://github.com/datawire/ambassador-auth-service/blob/master/server.js">ambassador-auth-service/server.js at master · datawire/ambassador-auth-service</a></p><pre>curl -Lv -u <strong>username:password</strong> &lt;GKE_INGRESS_DOMAIN&gt;/backend/get-quote/ </pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aB295KLWe0riBWBvSHJlfw.png" /><figcaption>quote application microservice output</figcaption></figure><p><strong>Using Postman API Console :</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Yz-dblbJaZufCABqlG8vFg.png" /><figcaption>quote application microservice output</figcaption></figure><p><strong>Accessing the quote application from the browser with a protected URL :</strong></p><pre>&lt;GKE_INGRESS_DOMAIN&gt;/backend/get-quote/</pre><p>As the user hit the protected URL for accessing the quote application behind the scene ambassador first intelligently routes this request to the authentication service (example-auth:3000) and it will prompt the user for authentication.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nde-sDbhjc2A7girOyG6pw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_nXg2CWdqau316h3nANCLg.png" /></figure><p>After entering the correct username and password, the authentication service (example-auth) validates it with the username &amp; password configured in its database and routes the request to quote application microservice after completion of end-user authentication.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cV_jn5ArUx8jLkH4jX5Gkg.png" /></figure><p>But if any requests come on a path <strong>other than</strong> <strong>/backend/get-quote/ </strong>the requests are <strong>permitted without authentication</strong> to quote application as the authentication service which we deployed as example-auth only performs authentication on <strong>/backend/get-quote/ </strong>path.</p><pre>curl &lt;GKE_INGRESS_DOMAIN&gt;/backend/</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lufyau6F2TEGVPH4hWro8Q.png" /></figure><h4>Conclusion</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*U1ekxHWVu8cZTlLQN5dF-w.jpeg" /></figure><p>In the world of DevOps automation, many organizations moving their applications to microservice architecture. Managing the security for these applications includes multiple factors in DevOps such as Authentication or Authorization etc.</p><p>Using Ambassador API Gateway — Edge Stack solution we can set up Authentication on Kubernetes microservices APIs for end users by Integrating it with various kinds of third-party authentication providers such as SSO with Google, Keycloak, OIDC, Azure AD, and many more.</p><p>Ambassador API Gateway authentication makes applications or microservices unaware of the authentication part so that developers don&#39;t need to include authentication logic into the application itself as it&#39;s handled by a separate application or third-party authentication providers Integrated with edge stack API Gateway.</p><p>For AWS cloud-based deployments, AWS Provides the feature called API Gateway Lambda authorizers under AWS Lambda which can be extended according to the use case for authentication and authorization for microservices.</p><p><a href="https://aws.amazon.com/blogs/security/use-aws-lambda-authorizers-with-a-third-party-identity-provider-to-secure-amazon-api-gateway-rest-apis/">Use AWS Lambda authorizers with a third-party identity provider to secure Amazon API Gateway REST APIs | Amazon Web Services</a></p><h3>Questions?</h3><p>If you have any questions, I’ll be happy to read them in the comments.</p><p>For more Interesting <strong>Cloud &amp; DevOps content</strong> follow me on <a href="https://medium.com/@onkar17">Medium</a> or <a href="https://www.linkedin.com/in/onkar17/">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=76437fcbd2c2" width="1" height="1" alt=""><hr><p><a href="https://blog.searce.com/microservices-authentication-using-ambassador-api-gateway-on-gke-76437fcbd2c2">Microservices Authentication Using Ambassador API Gateway on GKE</a> was originally published in <a href="https://blog.searce.com">Searce</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gremlin Chaos Engineering On Google Cloud]]></title>
            <link>https://medium.com/google-cloud/gremlin-chaos-engineering-on-google-cloud-2568f9fc70c9?source=rss-99099847e264------2</link>
            <guid isPermaLink="false">https://medium.com/p/2568f9fc70c9</guid>
            <category><![CDATA[sre]]></category>
            <category><![CDATA[chaos-engineering]]></category>
            <category><![CDATA[gcp-security-operations]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Onkar Naik]]></dc:creator>
            <pubDate>Mon, 08 Aug 2022 15:49:47 GMT</pubDate>
            <atom:updated>2022-08-09T11:55:55.378Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*0USL-EsvwXU9detj7JmvnA.jpeg" /></figure><p>This Article is based on how to implement <strong>Chaos Engineering Experiments Using Gremlin on Google Cloud.</strong></p><h4>Prerequisites</h4><ol><li>Google Cloud Platform Account</li><li>Gremlin Application Account</li><li>GKE Cluster</li></ol><h4>What Is Chaos Engineering?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EmEinzq_SYrW_H1R5Ck-qQ.png" /></figure><p><strong>Chaos engineering</strong> is a method of testing distributed software that deliberately introduces failure and faulty scenarios to verify its resilience in the face of random disruptions.</p><blockquote><strong>Chaos Engineering lets you compare what you think will happen to what actually happens in your systems. You literally “break things on purpose” to learn how to build more resilient systems.</strong></blockquote><h4>What Is Gremlin?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*4jws-rnkWWZkpAZe4_eZnQ.png" /></figure><p><strong>Gremlin</strong> is a simple, safe, and secure way to improve the resilience of your systems by using Chaos Engineering to identify and fix failure modes.</p><p><strong>Gremlin</strong> is a cloud-native platform that runs in any environment. Gremlin supports all public cloud environments — AWS, Azure, and GCP — and runs on Linux, Windows, and containerized environments like Kubernetes, and bare metal.</p><p>In 2010,<strong> Netflix</strong> introduced a technology to switch production software instances off randomly — like setting a monkey loose in a server room — to test how the cloud handled its services. Thus, the tool <a href="https://netflixtechblog.com/5-lessons-weve-learned-using-aws-1f2a28588e4c">Chaos Monkey</a> was born.</p><p><strong>Chaos engineering matured at organizations such as Netflix, and gave rise to technologies such as </strong><a href="https://www.gremlin.com/community/tutorials/chaos-engineering-the-history-principles-and-practice/"><strong>Gremlin (2016)</strong></a><strong>,</strong> becoming more targeted and knowledge-based.</p><p>Now let&#39;s start <strong><em>Gremlin Chaos Engineering Experiments on Google Cloud</em></strong> as follows :</p><ol><li><strong>Gremlin Shutdown Attack on GKE Pods to validate the High Availability of the application</strong></li><li><strong>Gremlin CPU Attack on GKE Pods to validate GKE Horizontal Pod Autoscaling</strong></li><li><strong>Gremlin Blackhole Attack on GKE Load Balancer to validate High Availability of web application on GKE</strong></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KDg5BOSYfCtr8VBXTKHtZQ.png" /></figure><p>As the part of prerequisites, we already signed up for the Gremlin Web App account.</p><p>To signup for a Gremlin Web App account → <a href="https://app.gremlin.com/signup">https://app.gremlin.com/signup</a></p><p>In order to perform various chaos experiments on GKE, we need to install the Gremlin Kubernetes Client in GKE so that we can create various attacks on GKE from the Gremlin web application.</p><h4>Installing the Gremlin Client Agent on GKE Cluster</h4><p>To install the Gremlin Kubernetes client, you will need your <strong>Gremlin Team ID and Secret Key</strong>. If you don’t know what your Team ID and Secret Key are, you can get them from the Gremlin web app.</p><p>Visit the <a href="https://app.gremlin.com/settings/teams">Teams page</a> in Gremlin, and then click on your team’s name in the list.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jfwoAtY2bjNxN9Gr1n9UgQ.png" /></figure><p>On the Teams screen click on Configuration.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TqoA90U0OBMzAwYuq2imYQ.png" /></figure><p>If you don’t know your Secret Key, you will need to reset it. Click the Reset button. You’ll get a popup reminding you that any running clients using the current Secret Key will need to be configured with the new key. Hit Continue.</p><p>Next, you’ll see a popup screen that will show you the new Secret Key. Make a note of it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*ElQWfCbDGN-Eb093WOlYng.png" /></figure><h4>Install the Gremlin Client with Helm</h4><p><a href="https://www.gremlin.com/docs/getting-started/install-kubernetes-helm/">Getting Started &gt; Installing Gremlin on Kubernetes with Helm | Gremlin Docs</a></p><p>Add the Gremlin Helm chart:</p><pre>helm repo add gremlin <a href="https://helm.gremlin.com">https://helm.gremlin.com</a></pre><p>Create a namespace for the Gremlin Kubernetes client:</p><pre>kubectl create namespace gremlin</pre><p>Next, you will run the helm command to install the Gremlin client. In this command, there are three placeholder variables that you will need to replace with real data. Replace $GREMLIN_TEAM_ID with your Team ID, and replace $GREMLIN_TEAM_SECRET with your Secret Key. Replace $GREMLIN_CLUSTER_ID with the name of GKE Cluster.</p><pre>helm install gremlin gremlin/gremlin <br>--namespace gremlin \<br>--set gremlin.hostPID=true \<br>--set gremlin.secret.managed=true \<br>--set gremlin.container.driver=docker-runc \<br>--set gremlin.secret.type=secret \<br>--set gremlin.secret.teamID=$GREMLIN_TEAM_ID \ <br>--set gremlin.secret.clusterID=$GREMLIN_CLUSTER_ID \<br>--set gremlin.secret.teamSecret=$GREMLIN_TEAM_SECRET</pre><p><strong>Note: </strong>Here in the above helm installation gremlin. container. driver value may vary as per your cluster node container runtime. In my case, I have used GKE Nodes with the Ubuntu-docker image type.</p><p>To verify that the installation was successful, run this command:</p><pre>kubectl get pods -n gremlin</pre><p>The output should show one chao pod and one gremlin pod for each node in your cluster. These should all be in the Running state:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Cfll2uBDG4YaBaWl0wok0g.png" /></figure><p>You can also check the status of the client from Gremlin Web Application</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G0AWy2lITrENB9kfBIdeug.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TJb7lEH5LYr0RArWgGxBiA.png" /></figure><h4>Setting Up Slack Integration with Gremlin Web App</h4><p>We can also Integrate our Slack app with Gremlin for getting Attack reports and Notifications on the slack channel.</p><p>For setting up Slack Integration with Gremlin we have to add the slack channel In Gremlin Integration we created for getting Gremlin attacks notifications.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3xXjJvmpH_hhPTrczjj7FA.jpeg" /></figure><p>Now just select your slack channel where you want to receive Gremlin Notifications and Click Allow.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/839/1*g5yp6jhzOJzZMhlknuO5-w.jpeg" /></figure><p>That’s all your <strong>Slack Integration with Gremlin Is now Ready.</strong>🎉🎉</p><p>Now we have the Gremlin Agent Installed on the GKE cluster with slack app notifications enabled.</p><p>Let us deploy one sample Nginx web application on the GKE cluster.</p><h4>Deploying Nginx Application on GKE Cluster with HPA</h4><ol><li>Create a separate namespace for Nginx deployment.</li></ol><pre>kubectl create ns app</pre><p>2. Deploying Nginx deployment in app namespace.</p><pre>kubectl apply -f nginx.yaml</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fae9b98c1b391b573d0ac775cf65d5ba/href">https://medium.com/media/fae9b98c1b391b573d0ac775cf65d5ba/href</a></iframe><p>3. Exposing Nginx Deployment with GKE Load Balancer.</p><pre>kubectl expose deployment myapp --type=LoadBalancer --port=80</pre><p>4. Deploying Horizontal Pod Autoscalar for Nginx Deployment.</p><pre>kubectl apply -f hpa.yaml</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f36d5abb9c369d2902b10db3c87f8d88/href">https://medium.com/media/f36d5abb9c369d2902b10db3c87f8d88/href</a></iframe><p>5. Check all resources deployed correctly or not using the below command.</p><pre>kubectl get all -n app</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fRqkKPiQ052qPbu7k37Qqw.png" /></figure><p>We can now start performing various chaos experiments or attacks on Nginx sample deployment to validate various things like monitoring, alerting, scaling and availability, etc working or not.</p><h4>Gremlin Attacks</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/499/1*Su9N0ao2leRgaDmlgP5Glw.gif" /></figure><p><strong>An attack is a method of injecting failure into a system in a simple, safe, and secure way.</strong> Gremlin provides a range of attacks that you can run against your infrastructure. This includes impacting system resources, delaying or dropping network traffic, shutting down hosts, and more. In addition to running one-time attacks, you can also schedule regular or recurring attacks, create attack templates, and view attack reports.</p><p>Gremlin provides three categories of attacks:</p><ul><li><strong>Resource attacks:</strong> test against sudden changes in consumption of computing resources</li><li><strong>Network attacks:</strong> test against unreliable network conditions</li><li><strong>State attacks:</strong> test against unexpected changes in your environment such as power outages, node failures, clock drift, or application crashes</li></ul><p>We are going to perform one attack from each of these types of attacks on the Nginx Deployment to validate various aspects of our system.</p><h4>Validating High Availability with Gremlin Shutdown Attack</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5slTujrcQT92X6Hrsj04-g.png" /></figure><p><strong>Shutdown attacks</strong> let teams build resilience to host failures by testing how their applications and systems behave when an instance is no longer running.</p><h4>Configuring Gremlin Attacks for Nginx Deployment</h4><p>Go to Attacks Menu in Gremlin Web App Console → Select Kubernetes → Choose a Cluster and Namespace ( where the target app is present )</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZSpv4MfBAsXkrSpsvX-hug.png" /></figure><p>Select the target Deployment on which Gremlin performs the attack and define the blast radius for the attack.</p><p><strong>Blast Radius: Number of hosts included or amount of target part in the attack</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N1VVL1OlYNyiH4TIAZhs5A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rVlDIAapJe2Wfiq1AHjxMA.png" /></figure><p>For Shutdown, Attacks choose the type of attack as Shutdown attack from State Attacks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*98-l0UDXPhgsnHCIjowgvg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qN49mH-U_VO6Vi3vSi4hHg.png" /></figure><p>Click on unleash Gremlin to Run the particular Attack.</p><p><strong>Running Gremlin Shutdown Attack</strong></p><p>Click on attack details to see the attack details and output of the attack which Gremlin is running on Nginx Deployment Pods.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dc5ifwqB6n_0uawXz3tcQg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-5a1wjuX134ZN9qYHzX16Q.png" /></figure><p>We can see that the Nginx Deployment is highly available even while running the shutdown attack due to more replicas.</p><pre>kubectl get pods -n app -w</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LvgiHSH3xRcHtXDfEW7Qhg.png" /></figure><p><strong>A shutdown Attack can answers questions such as:</strong></p><ul><li>How long does it take for an instance to restart? Does my application successfully restart when the instance comes back online?</li><li>Does my load balancer automatically reroute requests away from the failed instance? Do I have other instances available to handle these requests?</li><li>If a user has an active session on an instance that fails, does the session gracefully continue on a different instance?</li><li>Is there any data loss? Are ongoing processing jobs restarted?</li></ul><h4>Validating GKE Horizontal Pod Autoscaling with Gremlin</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*44KKIV70KOhw4FgtL6nC0w.png" /></figure><p>CPU attacks help you ensure that your application behaves as expected even when CPU capacity is limited or exhausted. CPU attacks can also help test and validate automatic remediation processes, such as auto-scaling and load balancing.</p><p>For CPU Attack choose the type of attack as the CPU attack from Resource Attacks and configure more details for the attack like attack duration time, target CPU capacity going to be impacted, etc.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*98-l0UDXPhgsnHCIjowgvg.png" /></figure><p><strong>Running Gremlin CPU Attack</strong></p><p>Click on attack details to see the attack details and output of the attack which Gremlin is running on Nginx Deployment Pods.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6uL2aPbYSc1T-kZNKWaloA.png" /></figure><p>we can validate whether the Horizontal Pod Autoscaling defined for CPU Utilization by Nginx Pods working or not during the attack.</p><pre>kubectl get pods -n app -w</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XbfS9U_D6Qlklmy775814Q.png" /></figure><p>We can see that GKE HPA scaling up the Nginx Pods to count 4 as Max Count we defined is 4.</p><pre>kubectl get hpa</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9pBtvgU-IBTlqfwwH2a0bg.png" /></figure><p>In this way, by running CPU or Memory attacks we can validate the HPA defined for the application.</p><p><strong>CPU attacks can answer questions such as:</strong></p><ul><li>How is the user experience impacted when CPU resources are exhausted?</li><li>Do I have monitoring and alerting in place to detect CPU spikes?</li><li>Do I have quotas configured to limit CPU by application or process or container?</li><li>Do I have cleanup scripts to get rid of corrupted threads?</li></ul><h4>Validating Nginx Web App High Availability with Gremlin Blackhole Attack on GKE Load Balancer</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*off-U26FDMd6wuiRk3LERg.png" /></figure><p>Blackhole attacks let you simulate these outages by dropping network traffic between services. This lets you uncover hard dependencies, test fallback, and failover mechanisms, and prepare your applications for unreliable networks.</p><p>For Blackhole Attack choose the type of attack as the Blackhole attack from Network Attacks and configure more details for the attack like Port details etc.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*do5rnVBMY5Q_5sU4AW15gQ.png" /></figure><p>In our case, we have Nginx Deployment running on port 80.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ErLNIBQS-ZhusC8fvIWb-g.png" /></figure><p><strong>Running Gremlin Blackhole Attack</strong></p><p>Click on attack details to see the attack details and output of the attack which Gremlin is running on Nginx Deployment Pods.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TLgIE1g1lf4AJ9VwLk09ZQ.png" /></figure><p>We can check the Nginx web page status from the GCP Load Balancer External IP. There is no latency or blockage in terms of web experience due to high availability and GCP Load Balancing between multiple backend pods.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ENJXjV6OZ5_AHk1K1VuI6Q.png" /></figure><p><strong>Blackhole attacks can answer questions such as:</strong></p><ul><li>Where do dependencies exist within our system?</li><li>Do we have monitoring in place to alert on the unavailability of each service?</li><li>Does our application gracefully degrade if a dependency is unavailable?</li><li>Is the user experience negatively affected when a downstream dependency is unavailable?</li><li>Do we have dependencies that we think are non-critical, but can actually bring down our entire application?</li></ul><p>For the <strong>notification</strong> part, we have configured <strong>the slack Integration with the Gremlin web app</strong>, by which we get all the notifications in the slack channel regarding the status of each Gremlin attack we perform on GKE.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rk3CskzQgu7vapR79geb8A.png" /></figure><h4>Conclusion</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*NNUp98Dtq5TyzXEbqWruyw.gif" /></figure><p>The overarching goal of Chaos Engineering is to improve the reliability of our applications and systems by testing how they handle failure. To do this, we need to take a structured and well-organized approach with clearly defined objectives and key performance indicators (KPIs).</p><p>Running random experiments without any direction or oversight won’t yield actionable results and will put our systems at unnecessary risk.</p><p>To meet the high-level goal of improved reliability, we need to guide our Chaos Engineering adoption process using more granular objectives.</p><h3>Questions?</h3><p>If you have any questions, I’ll be happy to read them in the comments. Follow me on <a href="https://medium.com/@onkar17">medium</a> or <a href="https://www.linkedin.com/in/onkar17/">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2568f9fc70c9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/google-cloud/gremlin-chaos-engineering-on-google-cloud-2568f9fc70c9">Gremlin Chaos Engineering On Google Cloud</a> was originally published in <a href="https://medium.com/google-cloud">Google Cloud - Community</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Jenkins Distributed Cluster Using Dynamic Build Agents On GKE]]></title>
            <link>https://blog.searce.com/jenkins-distributed-cluster-using-dynamic-build-agents-on-gke-e2262a59dcb3?source=rss-99099847e264------2</link>
            <guid isPermaLink="false">https://medium.com/p/e2262a59dcb3</guid>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[jenkins]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[devops]]></category>
            <dc:creator><![CDATA[Onkar Naik]]></dc:creator>
            <pubDate>Fri, 01 Jul 2022 07:28:45 GMT</pubDate>
            <atom:updated>2022-07-01T07:28:45.687Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZebbU1FjXrLINjZ9m0-GbA.png" /></figure><p>This Article is based on how to set up <strong>Jenkins Distributed Cluster in GKE with Dynamic Build Agents on Kubernetes Pods</strong>.</p><h3>Problem Statement</h3><p>We have our Jenkins Master setup built on a GKE Cluster environment from where the CICD Pipeline Jobs build and deploy the applications on another GKE Application cluster. The challenge over here is how we set up the CI environment for Jenkins to run its Jobs more efficiently.</p><h3>Use Case</h3><p>Let’s assume a scenario where we have the Jenkins Master deployed on GKE Cluster and applications are being deployed on another GKE Cluster which served as Application Cluster. By default, the Jenkins runs all its pipeline Jobs on the Master Node which results in more compute power consumption and less isolation between multiple Jobs as they running on the same environment.</p><h3>Solution</h3><p>The solution to the use case is building a Distributed Jenkins Cluster using Dynamic Agents. The use of Jenkins agents provides clustering functionality to Jenkins so that Jenkins can distribute its jobs to various slave nodes or agents on a need basis.</p><h3>Prerequisites</h3><ol><li>Google Cloud Platform Account</li><li>Google Kubernetes Engine Clusters</li></ol><h3>What Is Distributed Jenkins Cluster?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/945/1*3YLyuCy8FHcgGqz_MYDA8A.jpeg" /></figure><p>Jenkins is one of the most important tools in DevOps. Jenkins is used in both <strong>Continuous Integration and Continous Deployment or Delivery </strong>stage of DevOps.</p><p>In many cases, you require testing your build jobs in different environments, which is not possible to handle with a single Jenkins server. The creation of a heavy project also requires more than a single server, because a single server can’t handle its load.</p><p><strong><em>Jenkins Distributed Cluster </em></strong>allows you to add multiple Jenkins slaves under a central (main) Jenkins server. This Jenkins server is also known as Jenkins Master. These Jenkins slaves perform different tasks according to the instructions given by the Jenkins server. <strong>It also allows you to run your build jobs on a different operating system like Windows, macOS, Ubuntu, etc.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8DYEAWjjnlmIFkX45cn1RQ.jpeg" /></figure><p>There are mainly two parts we need to configure according to our use case for setting up the Distributed Jenkins Cluster.</p><ol><li>Configure Nodes → slave node configurations like windows, Linux, mac machine, etc.</li><li>Configure Clouds → dynamic agents configurations like Docker, Kubernetes, etc.</li></ol><p>As the part of prerequisite, we have already set up <strong>two zonal Google Kubernetes Engine clusters </strong>for Jenkins and applications respectively as <strong>management and application clusters</strong> on GCP.</p><p><a href="https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-zonal-cluster">Creating a zonal cluster | Google Kubernetes Engine (GKE) | Google Cloud</a></p><p><strong>1. Jenkins Management Cluster </strong>→ For Jenkins Cluster Deployment</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vWu3tHtUzfeNKsiRc3J9PA.png" /></figure><p><strong>2. Application Cluster </strong>→ For Application Deployments</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jB2-I4HKl5EcPBTu75qc4A.png" /></figure><h4>Jenkins Server Deployment On Management GKE Cluster</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*qFLdcKgx9yDY10hpPwhokQ.png" /></figure><p>There are typically two scenarios for Jenkins server deployment as follows :</p><ol><li><strong>Jenkins master and slave running inside the same Kubernetes cluster.</strong></li><li><strong>Jenkins master and slave running in separate Kubernetes cluster.</strong></li></ol><p>In our use case, we have both Jenkins Master and Slave or Agents running in the same GKE Cluster.</p><p>Let us start the setting up the Jenkins Server on the GKE management cluster as follows :</p><ol><li>Create a namespace called jenkins .</li><li>Manifest stack for Jenkins Server Deployment :</li></ol><p>Jenkins Deployment Manifest :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/09eee63b7aad493ea9625e97ce692a32/href">https://medium.com/media/09eee63b7aad493ea9625e97ce692a32/href</a></iframe><p>Jenkins Service Manifest :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1c7811c67844a25113dbce474b71a856/href">https://medium.com/media/1c7811c67844a25113dbce474b71a856/href</a></iframe><p>Jenkins Ingress Manifest :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dea379ccd7e7bf2f3a23254b22ff88ec/href">https://medium.com/media/dea379ccd7e7bf2f3a23254b22ff88ec/href</a></iframe><p><strong>Note:</strong> Ensure that your Kubernetes cluster setup supports persistent volumes. <strong>If you deploy Jenkins without a persistent volume, you will lose the Jenkins data on every restart or pod deletion.</strong></p><p>Jenkins Storage Class Manifest :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6db1a438b2a6bf1853c2b9c5a0a7837c/href">https://medium.com/media/6db1a438b2a6bf1853c2b9c5a0a7837c/href</a></iframe><p>Jenkins PVC Manifest :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a5afd2e2201ca757c85d89953caee316/href">https://medium.com/media/a5afd2e2201ca757c85d89953caee316/href</a></iframe><p>3. Apply all the above manifests in order to get the Jenkins Master running.</p><pre>kubectl apply -f storage-class.yaml<br>kubectl apply -f pvc.yaml<br>kubectl apply -f deployment.yaml<br>kubectl apply -f service.yaml<br>kubectl apply -f ingress.yaml</pre><p>You can also use the <strong>Jenkins helm chart</strong> to deploy the Jenkins using the helm stack on Kubernetes.</p><p><a href="https://artifacthub.io/packages/helm/jenkinsci/jenkins">jenkins 4.1.8 · jenkins/jenkinsci</a></p><p>Now let&#39;s check to access the Jenkins Master or Server using Jenkins UI by the IP Address of Jenkins Ingress.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_5yxapCuRiIGYgRTRuL1SA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/985/1*FjZ9VhNvQdPZrSruqeLNQQ.png" /></figure><p>The Initial Admin password for Jenkins can be found in the Jenkins pods logs. To check the same run the below command :</p><pre>kubectl logs &lt;jenkins_pod_name&gt; -n jenkins</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D1FaWmqGG_cQsqolCU__mg.png" /></figure><p>Copy and paste the Initial Admin password from the above logs. Then Jenkins will prompt for new user creation and suggested plugin installation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wHuYLvpT7xIscoNXMIoDsQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zVlfWTyttouupjQNc8KSCw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LLDjFHfBWG9MfP0tT_kFeQ.png" /></figure><p>The Jenkins UI configuration part is now done and we are now good to use Jenkins CICD Tool.</p><p>Before moving to the configuration of Distributed Jenkins Cluster or Dynamic Agents on Kubernetes Pods let&#39;s understand how the workflow works.</p><h4>Jenkins Dynamic Kubernetes Agents Workflow</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aukSHPUQPrQxEvfUWbvKHw.png" /></figure><ol><li>Whenever the Jenkins job is triggered, the <strong>Jenkins Kubernetes plugin</strong> will make an API call to Kubernetes API Server to create a Kubernetes agent pod.</li><li>Then, the Jenkins agent pod gets deployed in the Kubernetes for running the Jenkins Job. As soon as the job has completed the agent pod got terminated automatically.</li><li>When the agent pod comes up, it uses the details in its environment variables and talks back to Jenkins using the <strong>JNLP method</strong>.</li><li>Using <strong>JNLP Protocol</strong> the slave gets connected to the Jenkins Master Node and the resultant architecture serves as <strong>Distributed Jenkins Cluster.</strong></li></ol><p>Now let us start the Jenkins Dynamic Agents or Slaves configuration for Kubernetes.</p><h4>Jenkins Dynamic Kubernetes Pods Build Agents Configuration</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/793/1*EsR_Y5685ce_NeN0wMqCNQ.png" /></figure><p><strong>Step 1: Install Jenkins Plugin for Kubernetes</strong></p><p><a href="https://plugins.jenkins.io/kubernetes/">Kubernetes</a></p><p>Go to Manage Jenkins –&gt; Manage Plugins, search for Kubernetes Plugin in the available tab and install it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5nEzvya9lWfoP4qDeGP4Mw.png" /></figure><p>After installing the plugin you need to restart the Jenkins server in order to enable the plugin.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xe6lJ3XwW5UwUVc62eJQZA.png" /></figure><p><strong>Step 2: Kubernetes Cloud Configuration</strong></p><p>Go to <strong>Manage Jenkins → Manage Nodes and Cloud → Configure Clouds →</strong> <strong>Add a new cloud</strong> then select <strong>Kubernetes</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kA6PH7VKsz56HmfbD2zOOA.png" /></figure><p>Select Kubernetes Cloud Details.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uhYBJvmHUM6-mkxJSv85Uw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_UwuEy1MTK41V715xHLQ2w.png" /></figure><p>Here we have two scenarios of configurations:</p><ol><li><strong>Jenkins master and slave running inside the same Kubernetes cluster.</strong></li><li><strong>Jenkins master and slave running in separate Kubernetes cluster.</strong></li></ol><p>Since we have <strong>Jenkins Master inside the same Kubernetes cluster</strong> with a default service account since <strong>no need to specify Kubernetes URL or Kubernetes Server Certificate Key.</strong></p><p>If you have <strong>Jenkins Master outside the Kubernetes cluster, you have to specify Kubernetes URL or Kubernetes Server Certificate Key and add the respective service account token secret in the credentials section.</strong></p><p><strong>Note:</strong> Here we are using the default service account for Jenkins Master Pod. For Jenkins to communicate with the Kubernetes cluster, we need a service account token with permissions to deploy dynamic build agent pods in the Jenkins namespace.</p><p>If your service account doesn&#39;t have appropriate permissions you will get the below error for Jenkins master connection to the Jenkins namespace.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5yWhdoPoRPprpkcxeR8UtA.png" /></figure><p>In order to resolve the above error, we need to create cluster-role-binding for the default service account attached to the Jenkins Master pod by granting a cluster-admin role. So that now Jenkins can able to launch Dynamic Agent pods in the Jenkins Namespace.</p><pre>kubectl create clusterrolebinding jenkins — clusterrole cluster-admin — serviceaccount=jenkins:default</pre><p>To validate the connection using the service account, use the Test connection button as shown below. It should show a connected message if the Jenkins pod can connect to the Kubernetes master API.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iWY58-A1XUAdCA75I0IGcw.png" /></figure><p><strong>Step 3: Configure the Jenkins URL Details</strong></p><p>For Jenkins master running inside the cluster, you can use the Service endpoint of the Kubernetes cluster as the Jenkins URL because agents pods can connect to the cluster via internal service DNS.</p><p><strong>Note:</strong> If the Jenkins master runs outside the Kubernetes cluster, you can use the <strong>Jenkins IP or DNS </strong>in the Jenkins URL configuration.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lwI33O1EsbwDCLugepGa7A.png" /></figure><p><strong>Step 5: Create POD and Container Template</strong></p><p>For the POD and container templates, you need to provide basic details for the Jenkins worker or slave build agent pods which will be dynamically launched by Jenkins Master in order to run the pipeline jobs.</p><p>The label <strong>slave</strong> will be used in the job as an <strong>identifier to pick this pod as the build agent.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VynW-CGUCXnY8ytSV7LCTw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jiys1qPK0MRKZ1_PMjY89A.png" /></figure><p>Next, we need to add a container template for Dynamic Jenkins agent pods. Here specify the container name as JNLP only and the docker image URL for the agent image on which the Jenkins runs its jobs.</p><p><strong>Note: </strong>If you don’t add a container template, the Jenkins Kubernetes plugin will use the default JNLP image from the Docker hub to spin up the agents. ie, <a href="https://hub.docker.com/r/jenkins/inbound-agent/">Jenkins/inbound-agent</a></p><p>You can also define POD and Container Template in Jenkinsfile also as shown below as an example :</p><pre>agent {<br>        kubernetes {<br>            yaml &#39;&#39;&#39;<br>apiVersion: v1<br>kind: Pod<br>spec:<br>  containers:<br>  - name: shell<br>    image: ${image_name}<br>    command: [&quot;sleep&quot;, &quot;infinity&quot;]<br>    env:<br>    - name: JAVA_HOME<br>      value: /root/.sdkman/candidates/java/current<br>    volumeMounts: <br>    - name: &quot;workspace-volume&quot;<br>      mountPath: /<br>    - name: &quot;volume-0&quot;<br>      mountPath: /var/run/docker.sock<br>      readOnly: false<br>    securityContext:<br>      privileged: true<br>      runAsGroup: 0<br>      runAsUser: 0<br>  serviceAccountName: &quot;jenkins-sa&quot;<br>  volumes:<br>  - hostPath:<br>      path: &quot;/var/run/docker.sock&quot;<br>    name: &quot;volume-0&quot;<br>    <br>&#39;&#39;&#39;<br>            defaultContainer &#39;shell&#39;<br>        }<br>    }</pre><p>For our use case, we are going to execute a complete CICD Pipeline for the sample application from the build stage to deploy it to the application cluster. Since we need to build a custom docker image for Jenkins Build Agent which has preinstalled stack for all the dependencies of the CICD Pipeline</p><p><strong>Dockerfile for Jenkins Dynamic Build Agent Pod :</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b037c644db1b324a2079b51875364e4e/href">https://medium.com/media/b037c644db1b324a2079b51875364e4e/href</a></iframe><p><strong>Building the custom docker image for Jenkins Dynamic Build Agents :</strong></p><pre>docker build . -t asia-south-1-  docker.pkg.dev/PROJECT_ID/jenkins/jenkins-slave:v1</pre><p><strong>Pushing the custom docker image for Jenkins Dynamic Build Agents to Google Artifact Registry :</strong></p><p><a href="https://cloud.google.com/artifact-registry/docs/docker/pushing-and-pulling">Push and pull images | Artifact Registry documentation | Google Cloud</a></p><pre>gcloud auth configure-docker asia-south1-docker.pkg.dev</pre><pre>docker push docker.pkg.dev/PROJECT_ID/jenkins/jenkins-slave:v1</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*08pCmCAYk9XUZv37IaS4fA.png" /></figure><p>We can also add multiple container templates to the POD template and use them in the pipeline.</p><p>After the container template, we need to <strong>add volume details</strong> for the docker container of Jenkins dynamic agent pod as it requires <strong>docker inside docker because our pipeline has build and push application image stages.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*RnaO5JH7lV1f_Ide0fZdnA.png" /></figure><p>Click Add Volume → Select Host Path Volume</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VGvweadXJfHo10KFPs97Vg.png" /></figure><p>For running<strong> docker inside docker</strong> we need to <strong>mount base Kubernetes node docker daemon socket on the Jenkins agent pod</strong> so that the agents can able to run docker-related jobs like building/pushing and creating containers etc.</p><p>For both Host and Mount Path provide the value as <strong>/var/run/docker.sock.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qi3DNCPloTdZuHsBBK4kOw.png" /></figure><p>After the volume details, we need to provide service account details for Jenkins dynamic agent pods by which it can able to communicate with external services like Google Artifact Registry for pushing the images or GKE for deploying the applications, etc.</p><p>As part of Google&#39;s best practices instead of creating the service account keys and adding in Jenkins Credentials to attach and use it for agent pods, we can make use of <strong>workload identity.</strong></p><p><strong>Configuring service account for dynamic agent pods using Workload Identity :</strong></p><p><a href="https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity">Authenticate to Google Cloud APIs from GKE workloads | Google Kubernetes Engine (GKE)</a></p><p>1. Create a Kubernetes service account for the agent pods.</p><pre>kubectl create serviceaccount jenkins-sa --namespace jenkins</pre><p>2. Create an IAM service account for your agent pods or use an existing IAM service account instead.</p><pre>gcloud iam service-accounts create jenkins-sa --project=PROJECT_ID</pre><p>3. Ensure that your IAM service account has the roles you need. You can grant additional roles using the following command.</p><p><strong>Note:</strong> In our use case we need two roles as for pushing the application images to Google Artifact Registry and deploying it to GKE Cluster.</p><pre>gcloud projects add-iam-policy-binding PROJECT_ID --member &quot;serviceAccount:jenkins-sa@PROJECT_ID.iam.gserviceaccount.com&quot; --role &quot;ROLE_NAME&quot;</pre><p>4. Allow the Kubernetes service account to impersonate the IAM service account by adding an IAM policy binding between the two service accounts. This binding allows the Kubernetes service account to act as the IAM service account.</p><pre>gcloud iam service-accounts add-iam-policy-binding jenkins-<br>sa@PROJECT_ID.iam.gserviceaccount.com --role roles/iam.workloadIdentityUser --member<br>&quot;serviceAccount:PROJECT_ID.svc.id.goog[jenkins/jenkins-sa]&quot;</pre><p>5. Annotate the Kubernetes service account with the email address of the IAM service account.</p><pre>kubectl annotate serviceaccount jenkins-sa --namespace jenkins<br>iam.gke.io/gcp-service-account=jenkins-sa@PROJECT_ID-<br>v1.iam.gserviceaccount.com</pre><p>After the creation of the service account put the service account name and <strong>User ID as 0</strong> in order to run Jenkins dynamic agent pod container as the root user to avoid any permission issues for running docker inside docker.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0La-bqxBqNwH8BWfYvQLpg.png" /></figure><p>At last, click apply and save the POD and Container Template configuration. This is the basic cloud configuration required in order to work with Jenkins dynamic agent pods on Kubernetes.</p><h4>Jenkins CICD Pipeline with Jenkins Distributed Cluster using Dynamic Build Agents</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/666/1*dLNK-1UGmh-bMJWMZ8BinQ.png" /></figure><p>The proposed Jenkins CICD Pipeline is consist of multiple stages as follows:</p><ol><li>Git Checkout → Application Code</li><li>Build and Tag Application Docker Image</li><li>Push the Application Docker Image to Google Artifact Registry</li><li>Updating the Deployment Manifest with New Application Image Tags</li><li>Deploy the Application to Application GKE Cluster</li></ol><p>The <strong>groovy script</strong> for the <strong>Pipeline As A Code</strong> is as follows:</p><p>You can refer to the syntax of Jenkinsfile from the official documentation provided by the Jenkins community.</p><p><a href="https://www.jenkins.io/doc/book/pipeline/syntax/">Pipeline Syntax</a></p><p>In the pipeline code first, we need to define the agent on which Jenkins master can run its jobs.</p><p>If you don&#39;t have an agent or you are running the Jobs on the Jenkins master itself then you can define as an <strong>agent none.</strong></p><p>In our use case, we are going to use Kubernetes dynamic build agent pods to run the pipeline jobs. In order to define the same use Kubernetes as the agent and provide the label of the agent pod that we have set in the POD template as a slave.</p><p>For the rest of the pipeline code, we have defined the stages for various jobs.</p><p><strong>Jenkinsfile</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7a80973cd072840bc93129a9d3b2e952/href">https://medium.com/media/7a80973cd072840bc93129a9d3b2e952/href</a></iframe><p><strong>Application Code Stack</strong></p><p>The sample application code being deployed on app GKE Cluster by Jenkins CICD is as follows:</p><p><strong>main. go</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9791a908e79b6e1b635099230b24fa02/href">https://medium.com/media/9791a908e79b6e1b635099230b24fa02/href</a></iframe><p><strong>Application Dockerfile</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/93663eed95e4edd6113871edd2bad7af/href">https://medium.com/media/93663eed95e4edd6113871edd2bad7af/href</a></iframe><p><strong>Application Deployment Manifests:</strong></p><p><strong>deployment.yaml</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/aedc9b5d003f5f8f74d90bb394b27622/href">https://medium.com/media/aedc9b5d003f5f8f74d90bb394b27622/href</a></iframe><p><strong>service.yaml</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cdd0502539ed72dc7d3878aff7bfa8b2/href">https://medium.com/media/cdd0502539ed72dc7d3878aff7bfa8b2/href</a></iframe><p>Let&#39;s start configuring Jenkins CICD Pipeline Job for the sample application deployment.</p><ol><li>Click on Create a job</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8idChZdn3rCbMF9uBKisUA.png" /></figure><p>2. Select <strong>Type of Project as Pipeline</strong> and Enter the Project Name.</p><p><strong>Note:</strong> If you don&#39;t have a pipeline in place and want to configure the Job using UI options you can choose <strong>Freestyle Project.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1rnx9SCznXyf235rxd879g.png" /></figure><p>3. For the SCM Tool configuration of the Pipeline we need to connect Jenkins to the location where the application code is present eg Github so that Jenkins can able to clone or check out the code from the location.</p><p>In order to do so, we need to configure credentials for the application Github Repo by using which Jenkins can able to clone or check out the application code into agent pods.</p><p>Click Manage Jenkins → Manage Credentials → Add Credentials</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W28BiAA3Bd9bWm6o70vROQ.png" /></figure><p>Choose the Kind of credential as Username and Password. Before this, you need to <strong>create an access token for your Github</strong> which becomes your password for the application repo.</p><p><strong>Note:</strong> If you have SSH Keys configured for Github then you can choose a kind of secret file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vK_jg4T7Z7P5NKowS7zWMQ.png" /></figure><p>For the username and password enter your Github username and access token as passwords respectively.</p><p>Set ID of the credentials by your preferred naming. In the pipeline, we call the credentials using its ID.</p><p>Click Save.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Mr06-0BK32DCsccSPGFpoQ.png" /></figure><p>3. <strong>click on Configure </strong>to configure the pipeline.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*os2vfykbvCX8dxf5h9wQ3A.png" /></figure><p>In the last script section, we can pass the Jenkins Pipeline Code from the Jenkinsfile.</p><p>Here, if you have the Jenkinsfile already on your application git repo, you just need to give the path to Jenkinsfile.</p><p>We are going to add the Jenkinsfile Pipeline code in the script section itself as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k32tX9ISXeG0tzjWbBEhkw.png" /></figure><p>4. After configuring the Jenkins Job we can now run it. For running the Job <strong>Click on Build Now.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*os2vfykbvCX8dxf5h9wQ3A.png" /></figure><p>As soon as the Job starts building or running we can see the same in build history.</p><p>As you can see below our Job started building first time as build number 1.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*g0ZQgSMHplNmbA4jsX26BA.png" /></figure><p>5. Let&#39;s check the output of the Job by clicking on Job Build #1 and console output.</p><p>We can see that Jenkins has launched one build agent or slave Kubernetes pod dynamically using the Kubernetes plugin to run the pipeline.</p><p>In the output, we can see Jenkins showing the manifest that is used for the build agent pod from the POD template we configured earlier. It populates all the details we configured in the POD template in the build agent pods like environmental variables etc.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fPxssHclwyJr1_HeAgjHTg.png" /></figure><p>6. Meanwhile the Job started running we can quickly check the dynamic agent pod launched by Jenkins on the management GKE cluster in the Jenkins namespace.</p><p>Below you can see Jenkins has successfully launched the dynamic build agent Jenkins-slave for running the pipeline code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XtKakkVboJsbgFuMbJeafg.png" /></figure><p>As soon as the pipeline is executed completely, Jenkins will terminate the agent pod.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FWT391d9eN_wBGsRcfn5Qg.png" /></figure><p>7. We can check the status of the pipeline briefly using the <strong>stage view</strong> option in Jenkins UI.</p><p>As you can see the Jenkins pipeline has been successfully executed using the power of dynamic build agent pods with all the defined stages.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WDNQY45K7l4FEWDx6wJVMw.png" /></figure><p>8. Let&#39;s check the output of the defined pipeline stages.</p><ol><li>Pushing Application Docker Image to Google Artifact Registry</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FJHGIMaQ26qFLZ1d6QeCcw.png" /></figure><p>2. Deploying the Application stack on application GKE Cluster ( in platform namespace )</p><pre>kubectl get all -n platform</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*olnpEKGf6y-4c58ziwGciA.png" /></figure><p>Let&#39;s check whether the application is working or not by accessing through LoadBalancer IP from the service that we have deployed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9n3DCFuFVtqfrAyuYROWvQ.png" /></figure><p>The application got successfully deployed on the app cluster by Jenkins Dynamic Build Agent pods.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/698/1*ndXDsCbC4BC5b70tgZ5pkw.png" /></figure><h4>Conclusion</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/866/1*VYOdRBak6QMPJKvTmzS7qg.png" /></figure><p>If you are using Jenkins &amp; Kubernetes, you should definitely use the approach of dynamic build agent pods.</p><p>Running Jenkins agents on the Kubernetes pods will give you good build isolation for different application versions.</p><p>Also, an ephemeral Kubernetes pod-based Jenkins agent is a great way of reducing the cost of the CI environment as Jenkins agents get spun up only if there is a build request.</p><p>Scaling the Jenkins build agents with the Kubernetes cluster gives you much more flexibility in reducing the overhead of running out of resources for the Jenkins as this gives us distributed Jenkins cluster.</p><p>You can also use a static build VM as the Jenkins slave there also you can get options for dynamic builds but it&#39;s much slower than the dynamic build agents like containers.</p><h3>Questions?</h3><p>If you have any questions, I’ll be happy to read them in the comments. Follow me on <a href="https://medium.com/@onkar17">medium</a> or <a href="https://www.linkedin.com/in/onkar17/">LinkedIn</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*yR6h1bZ5w-SoRw2QYKPznw.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e2262a59dcb3" width="1" height="1" alt=""><hr><p><a href="https://blog.searce.com/jenkins-distributed-cluster-using-dynamic-build-agents-on-gke-e2262a59dcb3">Jenkins Distributed Cluster Using Dynamic Build Agents On GKE</a> was originally published in <a href="https://blog.searce.com">Searce</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Multi-Cloud Private DNS Forwarding PART II]]></title>
            <link>https://blog.searce.com/multi-cloud-private-dns-forwarding-part-ii-54bb0ec5fbea?source=rss-99099847e264------2</link>
            <guid isPermaLink="false">https://medium.com/p/54bb0ec5fbea</guid>
            <category><![CDATA[aws-route53]]></category>
            <category><![CDATA[dns]]></category>
            <category><![CDATA[cloud-networking]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Onkar Naik]]></dc:creator>
            <pubDate>Fri, 25 Mar 2022 10:59:50 GMT</pubDate>
            <atom:updated>2022-03-25T11:18:17.081Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8A2p2Kr9e74bTepzamt_vA.png" /><figcaption>credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><h3>Problem Statement</h3><p>We have our Infrastructure setup built on a multi-cloud or hybrid cloud environment where we need to establish a networking stack that includes private endpoints connections from one cloud or on-premises server to another cloud server. The challenge over here is how to achieve this private DNS endpoint resolution from another network.</p><h3>Use Case</h3><p>Let’s assume a scenario where we have the Infrastructure setup built on AWS and GCP Cloud. There are some private GCP Endpoints managed in GCP Cloud DNS Private Zone and the applications deployed in AWS Cloud need access to this endpoint. By default, the AWS Route53 is not able to resolve GCP Cloud DNS Private endpoints.</p><h3>Solution</h3><p>The solution to such use cases is the approach of setting up DNS Query forwarders so that the DNS Servers of another cloud can able to resolve the private endpoints residing in different clouds. To solve the above scenario we can use AWS Outbound Endpoint service by AWS Route53.</p><h3>Prerequisites</h3><ol><li>Amazon Web Services (AWS) Account</li><li>Google Cloud Platform (GCP) Account</li><li>High Availability Virtual Private Network (VPN) between GCP VPC and AWS VPC</li></ol><p>As the part of prerequisite we have already set up <strong>High Availability VPN Setup with BGP Sessions configured between AWS Cloud and GCP Cloud</strong> as follow :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*eWYDvHCwhDPQdW1O.png" /><figcaption>Architecture Diagram for HA VPN between AWS and GCP Cloud</figcaption></figure><p><a href="https://cloud.google.com/network-connectivity/docs/vpn/how-to/creating-ha-vpn">Create an HA VPN gateway to a peer VPN gateway | Google Cloud</a></p><p>Now let us create the private DNS zone in GCP for managing private endpoint DNS records.</p><h4>What Is Google Cloud DNS?</h4><p>Google Cloud DNS offers both public zones and privately managed DNS zones. A public zone is visible to the public internet, while a private zone is visible only from one or more Virtual Private Cloud (VPC) networks that you specify.</p><p><a href="https://cloud.google.com/dns/docs/overview/">Cloud DNS overview | Google Cloud</a></p><h4>Creating A Managed Google Cloud DNS Private Zone</h4><ol><li>In the Cloud Console, go to the <strong>Create a DNS zone</strong> page.</li><li>Go to Create a DNS zone.</li><li>For the <strong>Zone type</strong>, select <strong>Private type</strong>.</li><li>Enter a <strong>Zone name</strong> as per your choice.</li><li>Enter a <strong>DNS name</strong> suffix for the DNS private zone.</li><li>Optional: Add a description.</li><li>Under <strong>Options</strong>, select the <strong>Default (private) option</strong>.</li><li>Select the Virtual Private Cloud (VPC) networks to which the private zone must be visible. Only the VPC networks that you select are authorized to query records in the zone.</li><li>Finally Click <strong>Create.</strong></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u5YCskLEzmfTIJ14Sx_lIQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*T3mgyekw9LEXwnIp291QnQ.png" /></figure><h4>To create a recordset, follow these steps:</h4><ol><li>In the Google Cloud Console, go to the <strong>Cloud DNS zones</strong> page.</li><li>Click the name of the GCP DNS managed zone that you want to add the record to.</li><li>On the <strong>Zone details</strong> page, click <strong>Add recordset option</strong>.</li><li>On the <strong>Create recordset</strong> page, in the <strong>DNS name</strong> field, enter the subdomain of the DNS zone. The trailing dot is automatically added at the end.</li><li>Select the <strong>Resource record type</strong> — for example, A.</li><li>In the <strong>TTL</strong> field, enter a numeric value for the resource record’s time to live, which is the amount of time that it can be cached. This value must be a positive integer.</li><li>From the <strong>TTL unit</strong> menu, select the unit of time.</li><li>Depending on the resource record type that you have selected, populate the remaining fields.</li><li>To enter additional information, click <strong>Add item</strong>.</li><li>Finally Click <strong>Create</strong>.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2eaYs4gUslh7gRKvJ4hAZg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RC00diJPI1znk0lwXQX2mA.png" /></figure><p>Now let us check if the AWS Route53 is able to resolve the Google Cloud DNS endpoints or not. For this, we have created one EC2 Instance In AWS VPC for testing this DNS connectivity working or not.</p><pre>nslookup &lt;domain_name&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jdAd_JqnE79YiOq2zH2Y-w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/498/0*OHqQtGk2QaZWiFBd.gif" /><figcaption>credits:<a href="http://tenor.com/">tenor.com</a></figcaption></figure><p>As expected you can see that AWS Route53 DNS is unable to resolve the Google Cloud DNS endpoints as they are managed via a private zone.</p><p>Since for AWS Side, Route 53 Resolver automatically uses a Resolver on the VPC to answer DNS queries for local Amazon VPC domain names for EC2 instances and records in private hosted zones. For all other domain names, Resolver performs recursive lookups against public name servers.</p><p>To solve this problem and to make AWS Route53 able to resolve private endpoints from Google Cloud DNS we can use the <strong>AWS Route53 Resolver Outbound Endpoint Service</strong>.</p><h4>What Is Amazon Route53 Resolver Endpoint?</h4><p>Amazon Route53 Resolver helps to resolve AWS Private DNS endpoints or DNS records residing in the private hosted zone from the on-premise network or another cloud network using the feature of Route53 Resolver Endpoints.</p><p><a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver.html#resolver-overview-forward-network-to-vpc">Resolving DNS queries between VPCs and your network</a></p><p>There are two types of Route53 Resolver Endpoints:</p><h4>1. Inbound Endpoint :</h4><p>DNS resolvers on your network can forward DNS queries to Route 53 Resolver via this endpoint</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/928/0*lFD9VqGbdYnI6yck.png" /><figcaption>AWS Route53 Resolver Inbound Endpoint</figcaption></figure><p>This allows your DNS resolvers to easily resolve domain names for AWS resources such as EC2 instances or records in a Route 53 private hosted zone.</p><h4>2. Outbound Endpoint:</h4><p>Resolver conditionally forwards queries to resolvers on your network via this endpoint</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/946/0*BZ-1EkYsmRIZ-IXr.png" /><figcaption>AWS Route53 Resolver Outbound Endpoint</figcaption></figure><p>This would enable your AWS resources to resolve the domain names of your on-prem network resources using resolver rules, which would forward selected queries to the on-prem DNS resolvers.</p><p>Before you start to forward queries, you need to create Resolver inbound and/or outbound endpoints in the connected VPC. These endpoints provide a path for inbound or outbound queries.</p><p>For our use case, we have to resolve Google Cloud DNS Private endpoints from AWS Route53. In order to resolve this, we can make use of <strong>Amazon Route53 Outbound Endpoint to start forwarding our Cloud DNS queries to Google Cloud DNS</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VY957gtdl3fiOrT7Iz6Dsw.gif" /><figcaption>credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>Before configuring the AWS Route53 Outbound Endpoint we have to <strong>configure the Inbound Server Policy for Google Cloud DNS to accept the queries from AWS Network.</strong></p><h4>What Is Google Cloud DNS Server Policy?</h4><p>You can configure one DNS server policy for each Virtual Private Cloud (VPC) network. The policy can specify inbound DNS forwarding, outbound DNS forwarding, or both. <strong><em>Inbound server policy</em></strong> refers to a policy that permits inbound DNS forwarding. <strong><em>Outbound server policy</em></strong> refers to one possible method for implementing outbound DNS forwarding.</p><p><a href="https://cloud.google.com/dns/docs/server-policies-overview">DNS server policies | Google Cloud</a></p><h4>Google Cloud DNS Inbound server policy</h4><p>By default, a VPC network’s name resolution services — through its name resolution order — are only available to that VPC network itself. We can create <strong><em>an inbound server policy in your VPC network to make these name resolution services available to an on-premises network that is connected using Cloud VPN or Cloud Interconnect.</em></strong></p><p><strong>When we create an inbound server policy, Cloud DNS takes an internal IP address from the primary IP address range of each subnet that your VPC network uses.</strong></p><h4>Creating Google Cloud DNS Inbound Server Policy</h4><ol><li>In the Google Cloud Console, go to the <strong>Cloud DNS zones</strong> page.</li><li>Switch to the <strong>DNS Server Policies section</strong> and <strong>click Create Policy</strong>.</li><li>Enter DNS Policy Name.</li><li>Optional: Add a description.</li><li>For the Logs select on or off as per your use case.</li><li>Set Inbound query forwarding <strong>on.</strong></li><li>Optional: Add the alternate DNS Servers.</li><li>Add the <strong>VPC Network for which the DNS Server policy is to be configured.</strong></li><li>Click <strong>Create</strong>.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XfQg-0O1REdxSxDJ4f9eWA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1i-EYEJFHHVyZRt6rTeEWw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xV2D0qRtknsZqgOqzo-q5g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YAFEZ33yhb36SHS_zru5jg.png" /></figure><h4>Inbound Query Forwarding IP</h4><p><a href="https://cloud.google.com/dns/docs/policies">Apply Cloud DNS server policies | Google Cloud</a></p><p>The Inbound Query Forwarding IP is nothing but the <strong>Entrypoint for the remote networks to resolve the Google Cloud DNS private endpoints.</strong></p><p><strong>When an inbound server policy applies to a VPC network, Cloud DNS creates a set of regional internal IP addresses that serve as destinations to which your on-premises systems or name resolvers can send DNS requests.</strong></p><h4>Configuring AWS Route53 Resolver Outbound Endpoint</h4><p><a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-forwarding-outbound-queries.html">Forwarding outbound DNS queries to your network</a></p><ol><li>Open the Route 53 console.</li><li>In the navigation pane, choose Outbound endpoints.</li><li>On the navigation bar, choose the Region for the VPC where you want to create the outbound endpoint.</li><li>Choose to Create an outbound endpoint.</li><li>On the Create outbound endpoint page, complete the General settings for the outbound endpoint section. <strong>Choose a Security group that allows outbound TCP and UDP connectivity to the IP addresses and the ports that the resolvers use for DNS queries on your remote network.</strong></li><li>Complete the IP addresses section. You can let the Resolver choose IP addresses for you from the available IP addresses in the subnet, or specify IP addresses yourself.</li></ol><ul><li>Route tables that include routes to the IP addresses of the DNS resolvers on your remote network using AWS Direct Connect, a VPN connection, or a network address translation (NAT) gateway.</li><li>Network access control lists (ACLs) that allow both UDP and TCP traffic to the IP addresses and the ports that the resolvers use for DNS queries on your remote network and from resolvers on destination port range 1024–65535.</li></ul><p>7. (Optional) Complete the Tags section.</p><p>8. Finally, Choose Submit.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f-e1IB9FQjAj3p4sMCML2A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Hhn3kdqff-EX6nGYASe7lw.png" /></figure><p><strong>Now to tell the Route53 Resolver Outbound Endpoint their Destination/Target DNS Server ( In our case it is Google Cloud DNS ) to resolve the private endpoints or records in Google Cloud we need to configure the Resolver Rule for the same.</strong></p><p><a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-rules-managing.html">Managing forwarding rules</a></p><h4>Configure a Resolver Rule</h4><ol><li>Open the Route 53 console.</li><li>Choose Rules from the Route 53 navigation pane.</li><li>On the navigation bar, choose the Region where the newly created outbound endpoint exists.</li><li>Choose Create rule.</li><li>On the Create rule page, complete the Rule for outbound traffic sections. For Rule Type, configure a Forward rule and associate it to the VPC where you’ll forward DNS queries to your remote network from. For the Outbound endpoint, choose the outbound endpoint that you just created.<br><strong>Note: The VPC that you associate this rule to doesn’t need to be the same VPC where you created the outbound endpoint.</strong></li><li>Complete the IP addresses section. For IP addresses, specify the IP addresses of the DNS resolvers on your remote network. For Port, specify the ports that these resolvers use for DNS queries.<br><strong>Note: Resolver forwards any DNS query that matches this rule and originates from a VPC associated with this rule to the referenced outbound endpoint. As a result, these queries are forwarded to the target IP addresses you specify here.</strong></li><li>Finally, Choose Submit.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-MVRmARXe0qfFPsdTC2QcA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5q-n3ZpcjlpnJ_69bNoXhQ.png" /></figure><p>In our case, the <strong>Target IP Address is Google Cloud Inbound Query Forwarding IP</strong> as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YAFEZ33yhb36SHS_zru5jg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uwaF_3TRwPK1zNOT3hb6qw.png" /></figure><p>Now we have our complete DNS Query Forwarding Setup ready. Let us check now if Amazon Route53 is able to resolve the Google Cloud Private Endpoints or records In Google Cloud private hosted zone.</p><pre>nslookup &lt;domain_name&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jo-3dOdnBVsLrZKMv8O4TA.png" /></figure><p><strong>Amazon Route53 is now able to resolve Google Cloud DNS Private Records or Endpoints by forwarding these DNS queries to Google Cloud DNS Using AWS Route53 Resolver Outbound Endpoint.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OyPGGwCFTf04ZeGdqRl0ZA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vRYKYmWIYlRVFT5w0RWJtw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/0*PkMMjoKlOLea-Dv_.gif" /><figcaption>credits:<a href="http://tenor.com/">tenor.com</a></figcaption></figure><p><strong><em>Creating an outbound endpoint doesn’t change the behavior of Resolver, it just provides a path to a location outside the AWS network to Resolver.</em></strong></p><p>If you have a use case of building the <strong><em>Hybrid Networking between Google Cloud and AWS as part of DNS Forwarding from Google Cloud to AWS Cloud</em></strong> then you can go through<strong> PART-I of the Multi-Cloud Private DNS Forwarding Series </strong>as follow.</p><p><a href="https://blog.searce.com/multi-cloud-private-dns-forwarding-a77718e2a3f9">Multi Cloud Private DNS Forwarding</a></p><h3>Conclusion</h3><p>You can set up a Hybrid kind of Private DNS forwarding for the multi-cloud infrastructure or hybrid cloud environment where multiple applications or services need to connect private endpoints from different networks.</p><h3>Questions?</h3><p>If you have any questions, I’ll be happy to read them in the comments. Follow me on <a href="https://medium.com/@onkar17">medium</a> or <a href="https://www.linkedin.com/in/onkar17/">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=54bb0ec5fbea" width="1" height="1" alt=""><hr><p><a href="https://blog.searce.com/multi-cloud-private-dns-forwarding-part-ii-54bb0ec5fbea">Multi-Cloud Private DNS Forwarding PART II</a> was originally published in <a href="https://blog.searce.com">Searce</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Multi Cloud Private DNS Forwarding]]></title>
            <link>https://blog.searce.com/multi-cloud-private-dns-forwarding-a77718e2a3f9?source=rss-99099847e264------2</link>
            <guid isPermaLink="false">https://medium.com/p/a77718e2a3f9</guid>
            <category><![CDATA[amazon-web-services]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[dns]]></category>
            <category><![CDATA[dns-forwarding]]></category>
            <category><![CDATA[route-53]]></category>
            <dc:creator><![CDATA[Onkar Naik]]></dc:creator>
            <pubDate>Mon, 24 Jan 2022 07:25:44 GMT</pubDate>
            <atom:updated>2022-03-15T12:56:50.649Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dIvX-EFRUnbXqsMGRrOECg.png" /><figcaption>credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>This Article is based on how to setup <strong>Multi Cloud</strong> <strong>Private DNS Forwarding between Google Cloud and AWS Cloud.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*349p-VhGQsrIw2H5WbIPSQ.png" /><figcaption>credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><h4>Problem Statement</h4><p>We have our Infrastructure setup built on a multi-cloud or hybrid cloud environment where we need to establish a networking stack that includes private endpoints connections from one cloud or on-premises server to another cloud server. The challenge over here is how to achieve this private DNS endpoint resolution from another network.</p><h4>Use Case</h4><p>Let&#39;s assume a scenario where we have the Infrastructure setup built on AWS and GCP Cloud. There are some private AWS Endpoints managed in AWS Route 53 private hosted zone and the applications deployed in GCP Cloud need access to this endpoint. By default, the GCP Cloud DNS is not able to resolve AWS Route53 Private endpoints.</p><h4>Solution</h4><p>The solution to such use cases is the approach of setting up DNS Query forwarders so that the DNS Servers of another cloud can able to resolve the private endpoints residing in different clouds. To solve the above scenario we can use AWS Inbound endpoint service by AWS Route53.</p><h4>Prerequisites</h4><ol><li>Amazon Web Services Account</li><li>Google Cloud Platform Account</li><li>High Availability Virtual Private Network (VPN) between GCP VPC and AWS VPC</li></ol><h4>What Is DNS Query Forwarding?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xrZo4L7xaHyx5LQyTnwoCw.png" /></figure><p>DNS forwarding is the process by which particular sets of DNS queries are forwarded to a designated server for resolution according to the DNS domain name in the query rather than being handled by the initial server that was contacted by the client. This process improves the network’s performance and resilience. It provides a way to resolve name queries both inside and outside of the network by passing on namespaces or resource records that aren’t contained in the zone of a local DNS server to a remote DNS server for resolution.</p><p><strong>When a DNS server is configured to use a forwarder, if it can’t resolve a name query by using its local primary zone, secondary zone, or cache, it forwards the request to the designated forwarder</strong> instead of attempting to resolve it by using root hints.</p><p>As the part of prerequisite we have already set up <strong>High Availability VPN Setup with BGP Sessions configured between AWS Cloud and GCP Cloud</strong> as follow :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q-ChD86PVqlLVgsM5VDwGQ.png" /><figcaption>Architecture Diagram for HA VPN between AWS and GCP Cloud</figcaption></figure><p><a href="https://cloud.google.com/network-connectivity/docs/vpn/how-to/creating-ha-vpn">Create an HA VPN gateway to a peer VPN gateway | Google Cloud</a></p><p><strong>1. AWS Cloud VPC</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qg_-YjwrzqOz9rNv" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/1*ZZ18DpS9QTMcqepq9lAiBA.png" /></figure><p><strong>2. AWS Virtual Private Gateway</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*25OBhONcLO1yBDS-" /></figure><p><strong>3. AWS Customer Gateway</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*QqkWwpCpkRsAQW9f" /></figure><p><strong>4. AWS Site to Site VPN Connection</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*So6i0BeQZ2CrubXA" /></figure><p><strong>5. GCP Cloud VPC</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*k4y5hScnOC1QTn20" /></figure><p><strong>6. GCP Cloud HA VPN Gateway with VPN Tunnels</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Wr0qz-pFnKJl4mxC" /></figure><p><strong>7. GCP Peer VPN Gateway</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*OsabQSrHhCZKvZcm" /></figure><p><strong>8. GCP Cloud Router with BGP Sessions Configuration</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DWX0MO63Jhcz_fz4" /></figure><p>Now let us create the private hosted zone in AWS Route53 for managing private endpoint DNS records.</p><h4>What is Amazon Route53?</h4><p>Amazon Route 53 is a highly available and scalable Domain Name System (DNS) web service. You can use Route 53 to perform three main functions in any combination: domain registration, DNS routing, and health checking.</p><p><a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html">What is Amazon Route 53?</a></p><h4>What is a Private hosted zone in AWS Route 53?</h4><p>A private hosted zone is a container that holds information about how you want Amazon Route 53 to respond to DNS queries for a domain and its subdomains within one or more VPCs that you create with the Amazon VPC service.</p><p><a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html">Working with private hosted zones</a></p><h4>Creating Private Hosted Zone In Amazon Route53</h4><p><a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zone-private-creating.html">Creating a private hosted zone</a></p><ol><li>Sign in to the AWS Management Console.</li><li>If you’re new to Route 53, choose the <strong>Get started </strong>option</li><li>If you’re already using Route 53, choose <strong>Hosted zones</strong> in the navigation pane.</li><li>Click <strong>Create hosted zone</strong>.</li><li>In the <strong>Create private hosted zone</strong> pane, enter a domain name and, optionally, a comment.</li><li>In the Type list, choose the Private hosted zone.</li><li>In the <strong>VPC ID</strong> list, choose the VPC that you want to associate with the hosted zone.</li><li>Choose to <strong>Create hosted zone</strong>.</li></ol><p>So we have created the Private Hosted Zone and attached it to our AWS VPC as follow :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hAls93plA5C-4wBe" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/953/0*ExFAAnlJREjd5K2i" /></figure><h4>Creating DNS Records In Amazon Route53 Private hosted zone</h4><p>You can follow the below-given link which explains the procedure to create records using Amazon Route53 Console:</p><p><a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html">Creating records by using the Amazon Route 53 console</a></p><p>Let&#39;s create a DNS record (aws.onkar.dns) of type A mapped to AWS EC2 Instance Private IP that resides in AWS VPC as follow:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*3b5KICyM5A3rZVEL" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*j_4F0LMpgLuZhaE0" /></figure><p>Now let us check if the GCP Cloud DNS is able to resolve the AWS Route53 DNS endpoints or not. For this, we have created one GCP Compute VM in GCP VPC for testing this DNS connectivity working or not.</p><pre>nslookup &lt;domain_name&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/836/0*HkbNaKuXfVvNhPuS" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/498/1*eJ5k-6KtGqy2dJMKAqT7XQ.gif" /><figcaption>credits:<a href="http://tenor.com">tenor.com</a></figcaption></figure><p>As expected you can see that GCP Cloud DNS is unable to resolve the AWS Route53 endpoints as they are managed via a private hosted zone.</p><p>Since for AWS Side, Route 53 Resolver automatically uses a Resolver on the VPC to answer DNS queries for local Amazon VPC domain names for EC2 instances and records in private hosted zones. For all other domain names, Resolver performs recursive lookups against public name servers.</p><p>To solve this problem and to make GCP Cloud DNS able to resolve private endpoints from Amazon Route53 we can use the <strong>approach of DNS Query Forwarding</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fVuamYMrn_YdiJ_VaGGotg.gif" /><figcaption>credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>In order to implement DNS Query forwarding, we need to set up <strong>DNS Forwarders</strong> so that our DNS queries are forwarded to an intended destination DNS server which results in private DNS endpoints resolution.</p><p><strong>To set up the DNS Forwarders AWS Route53 has the feature of Resolver Endpoints.</strong></p><h4>What Is Amazon Route53 Resolver Endpoint?</h4><p>Amazon Route53 Resolver helps to resolve AWS Private DNS endpoints or DNS records residing in the private hosted zone from the on-premise network or another cloud network using the feature of <strong>Route53 Resolver Endpoints</strong>.</p><p><a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver.html#resolver-overview-forward-network-to-vpc">Resolving DNS queries between VPCs and your network</a></p><p>There are two types of Route53 Resolver Endpoints:</p><h4><strong>1. Inbound Endpoint :</strong></h4><p><strong>DNS resolvers on your network can forward DNS queries to Route 53 Resolver via this endpoint</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/928/1*E7js4UbhYuZKXyFQHFjHOA.png" /><figcaption>AWS Route53 Resolver Inbound Endpoint</figcaption></figure><p>This allows your DNS resolvers to easily resolve domain names for AWS resources such as EC2 instances or records in a Route 53 private hosted zone.</p><h4><strong>2. Outbound Endpoint:</strong></h4><p><strong>Resolver conditionally forwards queries to resolvers on your network via this endpoint</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/946/1*UAxcYnCP9cj5CJ8GXAZijg.png" /><figcaption>AWS Route53 Resolver Outbound Endpoint</figcaption></figure><p>This would enable your AWS resources to resolve the domain names of your on-prem network resources using resolver rules, which would forward selected queries to the on-prem DNS resolvers.</p><p><strong>Before you start to forward queries, you need to create Resolver inbound and/or outbound endpoints in the connected VPC. These endpoints provide a path for inbound or outbound queries.</strong></p><p>For our use case, we have to resolve AWS Route53 Private endpoints from Google Cloud DNS. <strong>In order to resolve this, we can make use of Amazon Route53 Inbound Endpoint to start forwarding our Cloud DNS queries to Amazon Route53.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DmqgTfdMln-dVHhSL9sQkg.gif" /><figcaption>credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p><strong>Before we create Amazon Route53 Inbound Endpoints, make sure you have the following prerequisites in place:</strong></p><ul><li>Ensure that there’s network connectivity between your on-prem network and AWS via a VPN connection or Direct Connect.</li><li>Enable DNS hostnames and resolutions in the DNS support attributes in the VPC in which you would create the endpoint.</li><li>There’s at least a private hosted zone with the records you would like to resolve created there and attached to the VPCs with the resources that the records point to.</li><li>For the inbound endpoint, you would need a<strong> security group with inbound rules that allow incoming traffic from the Google Cloud DNS IP addresses via the following port:</strong></li><li><strong>TCP/UDP 53</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NFblvaPpI6mQnMPqlsGN_g.png" /></figure><h4>Creating Amazon Route53 Resolver Inbound Endpoint</h4><ol><li>Go to the Route 53 console and click <strong>Inbound endpoints.</strong></li><li>Click <strong>Create inbound endpoint.</strong></li><li>Then enter a name for the endpoint and select a VPC through which all the inbound DNS queries will flow on the way to the Resolver. Then set the security group, which is mentioned in the prerequisites.</li></ol><p><strong>Note: The VPC in which you would create the endpoint should be attached to the private hosted zone.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*p4peU0-6qdgAWggA" /></figure><p>4. Afterward, specify the IP addresses of the endpoint. <strong>To improve reliability, Resolver requires that you specify two IP addresses for DNS queries.</strong> It is recommended to span them across different availability zones.</p><p><strong>Note: You can add more than two IPs if you wish.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*uAsCL-R6ZbSzj9-6" /></figure><p>5. We also need to keep in mind <strong>while choosing the subnet that has route tables that include routes to the IP addresses of the DNS resolvers on the GCP network in the VPN connection</strong> (Since <strong>we have the BGP session it is automatically done</strong> but if not we will need to modify the routes).</p><p>The Google Cloud DNS has an IP Range of <strong>35.199.192.0/19 .</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*R-UVJ8eqPTyjwQqu" /></figure><h4>What Is Google Cloud DNS?</h4><p>Google Cloud DNS offers both public zones and private managed DNS zones. A public zone is visible to the public internet, while a private zone is visible only from one or more Virtual Private Cloud (VPC) networks that you specify.</p><p><a href="https://cloud.google.com/dns/docs/overview/">Cloud DNS overview | Google Cloud</a></p><h4>Creating A Managed Google Cloud DNS Private Forwarding Zone</h4><ol><li>In the Cloud Console, go to the <strong>Create a DNS zone</strong> page.</li><li>Go to Create a DNS zone option.</li><li>For the <strong>Zone type</strong>, select <strong>Private </strong>type.</li><li>Enter a <strong>Zone name</strong> as per your choice.</li><li>Enter a <strong>DNS name</strong> suffix for the private zone. <strong>Note: The DNS name must be the same as the privately hosted zone name in AWS’s Route 53 (onkar.dns)</strong></li><li>Under <strong>Options</strong>, select <strong>Forward queries to another server</strong>.</li><li>Select the networks to which the private zone must be visible.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*dlDO268iDaJGhYlg" /></figure><p>8. To add the IPv4 addresses of a forwarding target, click <strong>Add item</strong>. <strong>Here we have to add the IP address that we got from Amazon Route53 Resolver Inbound Endpoint as the Destination DNS Server for Google Cloud DNS.</strong></p><p>9. <strong>To force private routing to the forwarding target</strong>, under <strong>Private forwarding</strong>, select the <strong>Enable</strong> checkbox.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*wIe1EiVNSqu5Kipm" /></figure><p>10. Finally click create and the <strong>Google Cloud DNS is now configured to forward the queries to Amazon Route53 Resolver Inbound Endpoint which results in AWS Private Endpoints resolution by Google Cloud DNS</strong>.</p><p>After creating Google Cloud DNS Private Forwarding Zone we have to <strong>modify Cloud router Routes as by default they have default advertisement mode of IP Ranges which includes IP Ranges of GCP VPC Network and subnet.</strong></p><p><strong>By changing the IP Ranges advertisement mode of Cloud Router that we have configured with BGP Sessions dynamically propagates the Google Cloud DNS IP Range Route in AWS VPC Route Tables</strong>.</p><h4>Advertising Google Cloud DNS IP Range In Cloud Router</h4><p><a href="https://cloud.google.com/network-connectivity/docs/router/how-to/advertising-custom-ip">Advertising custom IP ranges | Cloud Router | Google Cloud</a></p><ol><li>In the Google Cloud Console, go to the <strong>Cloud Routers</strong> page.</li><li>Go to Cloud Routers</li><li>Select the Cloud Router that contains the BGP session to update.</li><li>On the <strong>Router details</strong> page, select the BGP session to update.</li><li>On the <strong>BGP session details</strong> page, click edit.</li><li>For <strong>Routes</strong>, select <strong>Create custom routes</strong>.</li><li>Select the <strong>Advertise all subnets visible to the Cloud Router.</strong></li><li>Select <strong>Add custom route</strong> to add an advertised route.</li><li>Configure the route advertisement:</li></ol><ul><li><strong>Source</strong>: Select <strong>Custom IP range</strong>.</li><li><strong>IP address range</strong>: <strong>Google Cloud DNS IP Range</strong> (<strong>35.199.</strong> <strong>192.0/19)</strong></li><li><strong>Description</strong>: Add a description for the custom route purpose, and then click <strong>Done</strong>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*cKJYFX5_W3yGB2Tu" /></figure><p>10. After you finish adding custom routes, click <strong>Save</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*UiTEAFYareDfZ4WG" /></figure><p>In AWS Cloud under VPC Section we can see that the <strong>custom route that we have configured above in Google Cloud Router BGP Sessions dynamically propogated in AWS VPC Route table as follow:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*doMWn79D-6KFhAq8" /></figure><p>Now we have our complete DNS Query Forwarding Setup ready. Let us check now if the Google Cloud DNS is able to resolve the AWS Private Endpoints or records In Route53 private hosted zone.</p><pre>nslookup  &lt;domain_name&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/793/0*d74GUtKKdCu8clgu" /></figure><p>Google Cloud DNS is now able to resolve AWS Route53 Private Records or Endpoints by forwarding these DNS queries to Amazon Route53 Resolver Inbound Endpoint.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/766/0*u9mJT2uctTczhe_p" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/744/0*RdynL036eXnlj1O8" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*avjWpq3K6ljG_jAOv0f6BA.gif" /><figcaption>credits:<a href="http://tenor.com">tenor.com</a></figcaption></figure><h4>How AWS Route53 Resolver resolves DNS queries that originate from Google Cloud Network?</h4><ol><li>A web browser or another application on the Google Cloud network submits a DNS query for a domain name that you forwarded to Resolver.</li><li>Google Cloud DNS forwards the query to the IP addresses in your inbound endpoint.</li><li>The inbound endpoint forwards the query to AWS Route53 Resolver.</li><li>Resolver gets the applicable value for the domain name in the DNS query, either internally or by performing a recursive lookup against public name servers.</li><li>The resolver returns the value (typically an IPv4 IP address) to the inbound endpoint.</li><li>The inbound endpoint returns the value to the Google Cloud DNS.</li><li>The Google Cloud DNS Resolver returns the value to the application running on the Google Cloud Platform.</li></ol><p><strong><em>Creating an inbound endpoint doesn’t change the behavior of Resolver, it just provides a path from a location outside the AWS network to Resolver.</em></strong></p><h3>Conclusion</h3><p>You can set up a Hybrid kind of Private DNS forwarding for the multi-cloud infrastructure or hybrid cloud environment where multiple applications or services need to connect private endpoints from different networks.</p><h3>Questions?</h3><p>If you have any questions, I’ll be happy to read them in the comments. Follow me on <a href="https://medium.com/@onkar17">medium</a> or <a href="https://www.linkedin.com/in/onkar17/">LinkedIn</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KwpzT6Wt2oA8yPqLIDWBOg.gif" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a77718e2a3f9" width="1" height="1" alt=""><hr><p><a href="https://blog.searce.com/multi-cloud-private-dns-forwarding-a77718e2a3f9">Multi Cloud Private DNS Forwarding</a> was originally published in <a href="https://blog.searce.com">Searce</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Automated Logging Solution Using EFK Stack on GCP]]></title>
            <link>https://blog.searce.com/automated-logging-solution-using-efk-stack-on-gcp-e64125690439?source=rss-99099847e264------2</link>
            <guid isPermaLink="false">https://medium.com/p/e64125690439</guid>
            <category><![CDATA[elasticsearch]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[elastic-stack]]></category>
            <dc:creator><![CDATA[Onkar Naik]]></dc:creator>
            <pubDate>Thu, 21 Oct 2021 13:40:43 GMT</pubDate>
            <atom:updated>2021-10-21T13:54:50.438Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nBeLLG84fBRIY3wYxZPQ2g.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>🔷 This Article is based on <strong>Terraform Automation for Google Kubernetes Engine Cluster Monitoring using Elastic Cloud Deployment for Elastic Search &amp; Kibana 🔷</strong></p><h4>Prerequisites</h4><ol><li>An Elastic Cloud Account</li><li>Google Cloud Platform Account</li></ol><h4>What Is Elastic Cloud?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*4nXd7ScR7I7Kf6M9hLq6mA.gif" /><figcaption>Credits:<a href="https://www.elastic.co/">https://www.elastic.co/</a></figcaption></figure><p><strong>Elastic Cloud</strong> is a family of Elasticsearch SaaS offerings — including hosted Elasticsearch, hosted app search, and hosted site search. Elastic Cloud offers multiple managed services including Elastic Stack which includes Hosted Elasticsearch Cluster &amp; Kibana as a Deployment on various public clouds like AWS | GCP, and Azure.</p><p>As Elastic Cloud provides managed Elasticsearch + Kibana Stack since we don’t require to deploy and Manage our own Elastic Stack. We just have to set up the Data shipping agents that ship the target system logs or metrics to the Elasticserach Cluster hosted on Elastic Cloud.</p><p>You can open your Elastic Cloud account free tier account which comes with 14 days free trial.</p><p><a href="https://www.elastic.co/">Elastic - The Search AI Company</a></p><h4>What is Elastic Search?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tU4oycCzKpoy6hvb4h4q-w.png" /><figcaption>Credits:<a href="https://www.elastic.co/">https://www.elastic.co/</a></figcaption></figure><p><strong>Elasticsearch is a distributed, free and open search and analytics engine for all types of data, including textual, numerical, geospatial, structured, and unstructured.</strong> Elasticsearch is the central component of the Elastic Stack, a set of free and open tools for data ingestion, enrichment, storage, analysis, and visualization. Commonly referred to as the ELK Stack (after <strong><em>Elasticsearch, Logstash, and Kibana</em></strong>), the Elastic Stack now includes a rich collection of lightweight shipping agents known as <strong><em>Beats</em></strong> for sending data to Elasticsearch.</p><p><a href="https://www.elastic.co/elasticsearch/">Elasticsearch: The Official Distributed Search &amp; Analytics Engine | Elastic</a></p><h4>What Is Kibana?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/866/1*YEtuSeawBmkoc5nOnuQcmA.jpeg" /><figcaption>Credits:<a href="https://www.elastic.co/">https://www.elastic.co/</a></figcaption></figure><p><strong>Kibana is a free and open frontend application that provides search and data visualization capabilities for data indexed in Elasticsearch.</strong> It is commonly included in Elastic Stack which is normally called<strong> ELK Stack</strong> which includes <strong>Elasticsearch, Logstash, and Kibana</strong>.<strong><em> Kibana also acts as the user interface for monitoring, managing, and securing an Elastic Stack cluster — as well as the centralized hub for built-in solutions developed on the Elastic Stack.</em></strong></p><p><a href="https://www.elastic.co/kibana/">Kibana: Explore, Visualize, Discover Data | Elastic</a></p><h4>What Is Beat or Data Shipping Agent?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/820/1*qsSgXeO6_Uo5QjyoBvJx7Q.png" /><figcaption>Credits:<a href="https://www.elastic.co/">https://www.elastic.co/</a></figcaption></figure><p><strong>Beats</strong> are open source data shippers that you install as agents on your servers to send operational data to Elasticsearch. Elastic provides Beats for capturing:</p><ol><li><strong>Auditbeat for Audit Data</strong></li><li><strong>Filebeat for log files</strong></li><li><strong>Metricbeat for metrics</strong></li></ol><p>Beats can send data directly to Elasticsearch or via Logstash, where you can further process and enhance the data, before visualizing it in Kibana.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/927/1*Y9s1FiDY6OEuOE_apLBnng.png" /><figcaption>Credits:<a href="https://www.elastic.co/">https://www.elastic.co/</a></figcaption></figure><p>Here I have used <strong>Filebeat </strong>as a Data Shipping Agent which collects the GKE cluster logs from the log files of respective resources and sends them to Elasticsearch deployed on Elastic Cloud and Visualized using Kibana. This is termed as<strong> EFK Stack ( Elasticsearch + Filebeat + Kibana ).</strong></p><h4>⚡ Logs → Filebeat → Elasticsearch → Kibana ⚡</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/860/1*iGcyg1yYuUuVYZm8u8YMAg.png" /><figcaption>Credits:<a href="https://www.elastic.co/">https://www.elastic.co/</a></figcaption></figure><p>You can also use <strong>Logstash | Fluented</strong> etc as a Data Shipping Agent Instead of Filebeat. Using these Lightweight Data shippers we can collect and send logs or metrics of various systems to Elastic Cloud.</p><p>Now after creating the account on Elastic Cloud we have to create Deployment which includes ( Elastic Search + Kibana ) Services which are deployed on Compute Virtual Machines of the chosen public cloud provider. We can configure the deployment according to our requirements we can set resources for Elastic Cloud Deployment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mlvh3_Z0K7rzTk0ItGfZDA.png" /><figcaption>Credits:<a href="https://cloud.elastic.co/deployments">https://cloud.elastic.co/deployments</a></figcaption></figure><p>Here I am using Terraform for Provisioning Elastic Cloud Deployment on Elastic Cloud.</p><p>As Elastic Cloud user has its own credentials for the elastic cloud deployment which are required for login and provisioning the deployment. Since I have used <strong>GCP Secret Manager</strong> to store the credentials of elastic cloud securely.</p><p>You can also use different secret managers like <strong>Hashicorp Vault.</strong></p><p><a href="https://cloud.google.com/secret-manager/docs">Secret Manager documentation | Google Cloud</a></p><p>There is a total of 3 secrets being created for storing <strong><em>Elastic Cloud API key | Elastic Cloud Deployment Password &amp; Elastic Cloud ID.</em></strong></p><p><strong>Terraform Code for creating the secrets | setting up accessors for the secret and storing the credentials of Elastic Cloud by creating secret versions →</strong></p><h4>providers.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a47905262e071aca9fba9e8f62b82676/href">https://medium.com/media/a47905262e071aca9fba9e8f62b82676/href</a></iframe><h4>backend.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c58cf23615f8881de4f65485e50b8e43/href">https://medium.com/media/c58cf23615f8881de4f65485e50b8e43/href</a></iframe><h4>main.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5c548fc78a9587bb55c15e187d1cf391/href">https://medium.com/media/5c548fc78a9587bb55c15e187d1cf391/href</a></iframe><h4>variables.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/83b369ff4017474205027f899888210f/href">https://medium.com/media/83b369ff4017474205027f899888210f/href</a></iframe><p>Now run the Terraform code by basic steps of executing Terraform Code</p><h4>terraform init</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/899/1*CIAQ79uaBES6nt7bgVRNJA.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><h4>terraform plan</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MpRSOVOoqIYaP7V3Zk5bwg.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/989/1*DDRLY5wD5wHuTnYOUIWK_g.jpeg" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/996/1*jk3OZwQ33LxFkwfieiwhOw.jpeg" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><h4>terraform apply</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J0xRr8j9zDuEKUeTOjWy3Q.jpeg" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>We can see that secrets created successfully by Terraform.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bV6ajVxzPi8Yw0ikm0VYFw.png" /><figcaption>Credits:<a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a></figcaption></figure><p><strong>Terraform Code for provisioning Elastic Cloud Deployment</strong> →</p><h4>providers.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/80c1aa4466cf746d099bde1b79207928/href">https://medium.com/media/80c1aa4466cf746d099bde1b79207928/href</a></iframe><h4>backend.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b50e795e01a6f2c05eb1f0a4376e7df9/href">https://medium.com/media/b50e795e01a6f2c05eb1f0a4376e7df9/href</a></iframe><h4>main.tf</h4><p>Here we are accessing the API key required for Elastic Cloud Login from the GCP Secret we created using Terraform Data resource.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1158eb68beab16bdae99a97fe5726f91/href">https://medium.com/media/1158eb68beab16bdae99a97fe5726f91/href</a></iframe><h4>variables.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/83f5c901a487a9ef9f9d45d01256d6b1/href">https://medium.com/media/83f5c901a487a9ef9f9d45d01256d6b1/href</a></iframe><p>Now run the Terraform code by basic steps of executing Terraform Code</p><h4>terraform init</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/899/1*CIAQ79uaBES6nt7bgVRNJA.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><h4>terraform plan</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PKk2lq-2srPUrfULVmrn0A.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RJUY8OzS_0T-4ZkQxTntwQ.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/872/1*D9FAsJSgUWh4r1mn7TTAKQ.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><h4>terraform apply</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/901/1*4KI8y8ZPYFjPNmUj4FSIig.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>The Elastic Cloud Deployment successfully created by Terraform. We can check through Elastic Cloud Console.</p><p><strong>Elastic Cloud Deployment</strong></p><p>Elastic Cloud Deployment comes with various services managed by Elastic Cloud which includes Elasticsearch Cluster | Kibana &amp; Enterprise Search with lots of various features.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DPTh2iJ7obAZ_-gntxiG0Q.png" /><figcaption>Credits:<a href="https://cloud.elastic.co/home">https://cloud.elastic.co/home</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JdShh88Roti6QKiiBr_Auw.png" /><figcaption>Credits:<a href="https://cloud.elastic.co/home">https://cloud.elastic.co/home</a></figcaption></figure><p><strong>Kibana Dashboard</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*87YXN0cNP3TjgruyjBubyA.png" /><figcaption>Credits:Kibana Console</figcaption></figure><p><strong>Elasticsearch Cluster</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3o87sBFXfezbzKSQ_KRC2g.png" /><figcaption>Credits:<a href="https://cloud.elastic.co/home">https://cloud.elastic.co/home</a></figcaption></figure><p><strong>Elasticsearch API Console</strong></p><p>Elasticsearch Database records can be accessed using API but Elasticcloud provides Elasticsearch Cluster with an API console through which we can easily use API queries for Elasticsearch.</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html">REST APIs | Elasticsearch Guide [8.11] | Elastic</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kvJnh8qu5VKvg_81iGzSCw.png" /><figcaption>Credits:<a href="https://cloud.elastic.co/home">https://cloud.elastic.co/home</a></figcaption></figure><p>When you create the Deployment manually in Elastic Cloud you get a username (elastic) and password for Elasticsearch which you can download. Now we have created the Deployment using Terraform so you need to reset the Elasticsearch password through the console and store that password in the GCP secret we created using Terraform.</p><p><a href="https://www.elastic.co/guide/en/cloud/current/ec-password-reset.html">Reset the elastic user password | Elasticsearch Service Documentation | Elastic</a></p><h3>Google Kubernetes Engine</h3><p><a href="https://cloud.google.com/kubernetes-engine#section-5">Kubernetes - Google Kubernetes Engine (GKE) | Google Cloud</a></p><p>For connecting Google Kubernetes Engine GKE Cluster with Elastic Cloud we need to Deploy any of the <strong>Data Shipping Agent</strong> which can <strong>send the GKE cluster logs to Elasticsearch on Elastic Cloud.</strong></p><p>Here I have used <strong>Filebeat as Data Shipping Agent</strong> which can collect the containers logs ( Kubernetes Resources ) from the Log File and send them to Elasticsearch on Elastic Cloud.</p><p><a href="https://www.elastic.co/guide/en/beats/filebeat/current/index.html">Filebeat Reference</a></p><p>For Monitoring GKE Cluster we have to Deploy <strong>Filebeat as a Daemon set</strong> that collects logs from each GKE Nodes and sends them to Elasticsearch.</p><p><strong>Filebeat Manifest →</strong></p><h4>Filebeat Daemon set</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9c6f74754392294149449ad3ddeea044/href">https://medium.com/media/9c6f74754392294149449ad3ddeea044/href</a></iframe><h4>Filebeat ConfigMap</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ac3f0290e12232e89f166f0bac553851/href">https://medium.com/media/ac3f0290e12232e89f166f0bac553851/href</a></iframe><h4>Filebeat Service Account</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5ab9c05121bf7e0d1a75d9ce2d9d6472/href">https://medium.com/media/5ab9c05121bf7e0d1a75d9ce2d9d6472/href</a></iframe><h4>Filebeat Role</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/154cd46ea89b34a48fbfab94d80ff591/href">https://medium.com/media/154cd46ea89b34a48fbfab94d80ff591/href</a></iframe><h4>Filebeat Role Binding</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d541680474337ba731563a2ace3dbef4/href">https://medium.com/media/d541680474337ba731563a2ace3dbef4/href</a></iframe><p><strong>Terraform Code for Provisioning GKE Cluster &amp; Deploying Filebeat as a Daemon set for Monitoring GKE Using Elastic Cloud</strong></p><h4>providers.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a47905262e071aca9fba9e8f62b82676/href">https://medium.com/media/a47905262e071aca9fba9e8f62b82676/href</a></iframe><h4>backend.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a9d90d5f1ced01600b4dac8c695b2f25/href">https://medium.com/media/a9d90d5f1ced01600b4dac8c695b2f25/href</a></iframe><h4>main.tf</h4><p>Using Data Resource provided by Terraform we can access the secret value i.e Elastic Cloud ID &amp; Password and that passed using sed command to filebeat manifests which updates the Elasticsearch cluster details to Filebeat deployment.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0a66e7bc43ce15368080f18acd0d5086/href">https://medium.com/media/0a66e7bc43ce15368080f18acd0d5086/href</a></iframe><h4>variables.tf</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8e6141b9b336ca7059d1d55f2b38cc66/href">https://medium.com/media/8e6141b9b336ca7059d1d55f2b38cc66/href</a></iframe><p>Now run the Terraform code by basic steps of executing Terraform Code</p><h4>terraform init</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/899/1*CIAQ79uaBES6nt7bgVRNJA.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><h4>terraform plan</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WzzsBUh2QKS7hjxSGvTXeg.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*YdNHlRu6l5WNxKRhFicCHg.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Fdziq6SmtLdNRxhdJ_-uHg.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/795/1*LZ_RdQbwKvoI9FHZJcN6og.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><h4>terraform apply</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YqM1Xjd64Y29nIY2Kn-2HQ.jpeg" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>Here we can see that terraform updating the kubeconfig file in the local system by GKE Cluster credentials to connect through local system &amp; Deploying Filebeat Daemon Set on GKE Cluster.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AQxEXZcbduRVLCUOAHlQ7A.jpeg" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/914/1*y3rMQaYUKZMLl4A9McVpKQ.jpeg" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p><strong>GCP Infrastructure Provisioned by Terraform →</strong></p><h4>GCP VPC</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7dnxCPI0HejvsrqmtSjkxA.png" /><figcaption>Credits:<a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a></figcaption></figure><h4>GCP Subnet</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*K3ve9P_xkUoSry4-hf89XQ.png" /><figcaption>Credits:<a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a></figcaption></figure><h4>GCP IAP Firewall</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1022/1*IpbTzJR4msRSH9Mrkh7RQA.png" /><figcaption>Credits:<a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a></figcaption></figure><h4>Google Kubernetes Engine GKE Cluster</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ma6HWhX62Mbvez7Vdnoxzg.png" /><figcaption>Credits:<a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a></figcaption></figure><h4>GKE Node Pool</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BPfLstYSRSC12wdeevYv4Q.png" /><figcaption>Credits:<a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a></figcaption></figure><h4>Filebeat Daemon Set on GKE Cluster</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vp9mu0LjoINbUaVE2Hy_FA.png" /><figcaption>Credits:<a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a></figcaption></figure><h4>Connecting to GKE Cluster from Local system using Updated kubeconfig by Terraform</h4><p>Here I am using <strong>kubectx </strong>command to switch the kubeconfig context between multiple clusters. Using <strong>kubectx</strong> we can switch to multiple clusters by updating the context of kubeconfig done by <strong>kubectx</strong>.</p><p><a href="https://github.com/ahmetb/kubectx">GitHub - ahmetb/kubectx: Faster way to switch between clusters and namespaces in kubectl</a></p><h4>kubectx</h4><p>You can see that kubectx showing the <strong>kubeconfig active cluster as ‘my-test-k8s’ cluster provisioned using Terraform</strong> which clear that Terraform successfully updated the kubeconfig file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/536/1*B2K5V0PoDJR16XN5uttfdQ.jpeg" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><pre>$ kubectl get nodes</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1015/1*ijxVtwIok7Fu58-ysLR-2g.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><pre>$ kubectl get ds -n kube-system</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-zBQc29gEI8I1jltGbv3Eg.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GVwaqm_dLj_ZW-QL7bjvLA.png" /><figcaption>Credits:<a href="https://console.cloud.google.com/">https://console.cloud.google.com/</a></figcaption></figure><pre>$ kubectl describe ds filebeat -n kube-system</pre><p>Terraform has successfully updated the Login Details taken from GCP Secret Manager i.e Password &amp; Cloud ID of Elasticsearch in Filebeat configmap.</p><p><strong>$ELASTICSERACH_PASSWORD</strong> &amp; $<strong>ELASTIC_CLOUD_ID </strong>values updated as shown below in Filebeat Daemonset Description</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1j8Ugk_EZxAUdItxJ3_Fww.jpeg" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/885/1*1hlpKEtoYDbUZgFr1jN8IQ.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>As shown above, the Filebeat configmap is mounted on<strong> </strong>the<strong> /var/log directory</strong> of GKE Nodes such that Filebeat is now configured for <strong>Log file as an Input from GKE Cluster</strong>.</p><pre>filebeat.inputs:   <br>- type: container     <br>  paths:        <br>    - /var/log/containers/*.log      <br>  processors:        <br>    - add_kubernetes_metadata:          <br>        host: ${NODE_NAME}          <br>        matchers:          <br>          - logs_path:              <br>               logs_path: &quot;/var/log/containers/&quot;</pre><p>We can also check that Filebeat taking Input from the<strong>/var/log/containers </strong>directory from GKE Nodes. For that, I have set up<strong> IAP Firewall Rule</strong> so that we can<strong> SSH into GKE Nodes </strong>and can see the Filebeat Input.</p><p>After going inside GKE Node we can see the <strong>Filebeat Input as .log files</strong> listed inside <strong>/var/log/containers.</strong></p><p><strong>Filebeat takes all these log files as Input and sends them to Elasticsearch hosted on Elastic Cloud.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mzHIfN8pbQU6ib_pmkvtHA.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><pre>$ kubectl get pods -n kube-system</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2ZFfgGwTmHNoLPzyuj5nIQ.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><pre>$ kubectl logs &lt;filebeat-pod-name&gt; -n kube-system</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jAU-8WWid04V-tf54wihvA.png" /><figcaption>Credits:<a href="https://www.linkedin.com/in/onkar17/">https://www.linkedin.com/in/onkar17/</a></figcaption></figure><p>Filebeat logs showing that the Data Pipeline has started and filebeat successfully connected to Elasticsearch on Elastic Cloud and started collecting and sending logs to Elasticsearch.</p><p>As filebeat now started sending GKE Cluster Logs to Elastic Cloud. To visualize GKE Cluster Logs Using Kibana first we need to<strong> create Elasticsearch Index Pattern by going on Elastic Cloud Console.</strong></p><p><a href="https://www.elastic.co/guide/en/kibana/current/index-patterns.html">Create an index pattern | Kibana Guide [7.14] | Elastic</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ljSxMokwliXQPkzEFJiDFg.png" /></figure><p>Provide Index pattern name as <strong>filebeat-*</strong> which <strong>matches the index sources already created in Elasticsearch which includes GKE logs sent by Filebeat.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_aJi-TyZ03RBKgbc6Bci0w.png" /></figure><p>Now filebeat Index Pattern created for Kibana by which<strong> Kibana can access</strong> the <strong>GKE Logs from Elasticsearch and visualize it.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QLGlAP3Px3-02XfcT7z8gw.png" /></figure><p>We can also verify that there is Index created for Filebeat in Elasticsearch Database. Using API Console we can query and check the Filebeat Index.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4oIpCyyDCIv1hiNplzdXSA.png" /></figure><p><strong>GKE Cluster Logs Visualization Using Kibana →</strong></p><p>In the Kibana Console go inside the Observability section then select filebeat index pattern there, you can see that Live data <strong>Kibana fetching live data from Elasticsearch.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ey__uQ8uKcX3SQq_vQ4Wqw.jpeg" /></figure><h4>GKE Cluster Logs →</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VID-vwew53xyhPcGZcaTuw.png" /></figure><p>You can also use different queries to access data from Elasticsearch in Kibana using <strong>Kibana Query Language KQL.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ky85hmlXwAKJQTU_F2iJ4A.png" /></figure><p>Using <strong>Visualize Library</strong> provided by Kibana we can visualize GKE Cluster logs in detail.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3N3gr6V-HJQHa9Uf4K7JxQ.png" /></figure><p>Now for testing the Monitoring of the GKE Cluster by Elastic Cloud <strong>I have launched one Nginx pod In GKE Cluster and check whether the logs of the Nginx Pod coming to Elastic Cloud or Not.</strong></p><pre>$ kubectl run myapp --image=nginx</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/508/1*iyV2PxvYV0lvhCSPiscJpA.png" /></figure><p>Filebeat has successfully collected and sent<strong> ‘myapp’ </strong>pod logs to Elastic Cloud as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TA8J7yAccj73tbKnj_YVcQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*P0ee3a8GbjoCbDuZxyjziw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2xRKQ_7eAglOUFFSe0QG9w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*saWqX_A_clNUqGRbBV_Mew.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*26BimWTgtfLFR-6TXk0Yzw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bfjfGU0GQYk88wYsoragdQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3OXiCInvCSOMGWZmHji54A.png" /></figure><h4>GKE Nodes as a Hosts In Kibana →</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QHEfYeFD-b0dSbHF06CFfw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KMuJ6SURaO2GcHEjPpYATQ.png" /></figure><p><strong><em>In this way, all K8S resources that launched inside GKE Cluster are monitored by Elastic Cloud which is Integrated with GKE Cluster Using Terraform Automation.</em></strong></p><p>This complete <strong>Integrated Infrastructure of GKE Cluster and Elastic Cloud</strong> is termed as ⚡ <strong>EFK Stack</strong> ( <strong>Elasticsearch + Filebeat + Kibana ) ⚡</strong></p><h3>✨ GKE Cluster → Filebeat → Elastic Cloud → Elasticsearch + Kibana ✨</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/614/1*ZMz7wLqqF_qN-RIH2c-7ZA.jpeg" /><figcaption>Credits:<a href="https://www.elastic.co/">https://www.elastic.co/</a></figcaption></figure><h3>Conclusion</h3><p>You can also <strong>Integrate Elastic Cloud with any platform by using Elastic Cloud Agents provided by Elastic Cloud.</strong> Elastic Cloud also gives you the facility of <strong>Uploading your Data directly to Elasticsearch Cluster which can be further be visualized Using Kibana.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rwODkCqrDTsQxxu2ExU30Q.png" /></figure><h3>Reference Links</h3><p><strong>Elastic Cloud:</strong> <a href="https://www.elastic.co/guide/index.html">https://www.elastic.co/guide/index.html</a></p><p><strong>Elasticsearch:</strong> <a href="https://www.elastic.co/elasticsearch/service">https://www.elastic.co/elasticsearch/service</a></p><p><strong>Filebeat: </strong><a href="https://www.elastic.co/guide/en/beats/filebeat/current/index.html">https://www.elastic.co/guide/en/beats/filebeat/current/index.html</a></p><p><strong>Kibana:</strong> <a href="https://www.elastic.co/guide/en/kibana/current/get-started.html">https://www.elastic.co/guide/en/kibana/current/get-started.html</a></p><p><strong>Terraform:</strong> <a href="https://registry.terraform.io/providers/elastic/ec/latest/docs">https://registry.terraform.io/providers/elastic/ec/latest/docs</a></p><p><strong>GCP Docs:</strong> <a href="https://cloud.google.com/docs">https://cloud.google.com/docs</a></p><h4>🔷 Terraform Code for the Complete Infrastructure from GKE Cluster to Elastic Cloud Integration Using Filebeat Deployment →</h4><p><a href="https://github.com/Onkar179/EFK-Stack-with-Elastic-Cloud-and-Integrating-with-GKE-Using-Terraform.git">GitHub - Onkar179/EFK-Stack-with-Elastic-Cloud-and-Integrating-with-GKE-Using-Terraform</a></p><h3>Questions?</h3><p>If you have any questions, I’ll be happy to read them in the comments. Follow me on <a href="https://medium.com/@onkar17">medium</a> or <a href="https://www.linkedin.com/in/onkar17/">LinkedIn</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e64125690439" width="1" height="1" alt=""><hr><p><a href="https://blog.searce.com/automated-logging-solution-using-efk-stack-on-gcp-e64125690439">Automated Logging Solution Using EFK Stack on GCP</a> was originally published in <a href="https://blog.searce.com">Searce</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>