<?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 AmrAlaaYassen on Medium]]></title>
        <description><![CDATA[Stories by AmrAlaaYassen on Medium]]></description>
        <link>https://medium.com/@amralaayassen?source=rss-636d55c8d20------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*lbQB28idvO49X_l6jzYhoQ.jpeg</url>
            <title>Stories by AmrAlaaYassen on Medium</title>
            <link>https://medium.com/@amralaayassen?source=rss-636d55c8d20------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 21:30:47 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@amralaayassen/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[Ephemeral Kubernetes Environments: A Cost-Effective Solution for Streamlining Minor Environments…]]></title>
            <link>https://amralaayassen.medium.com/ephemeral-kubernetes-environments-a-cost-effective-solution-for-streamlining-minor-environments-d23a00c9f66f?source=rss-636d55c8d20------2</link>
            <guid isPermaLink="false">https://medium.com/p/d23a00c9f66f</guid>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[ephemeral-environment]]></category>
            <category><![CDATA[capsule]]></category>
            <category><![CDATA[vcluster]]></category>
            <category><![CDATA[multitenancy]]></category>
            <dc:creator><![CDATA[AmrAlaaYassen]]></dc:creator>
            <pubDate>Tue, 02 May 2023 09:11:39 GMT</pubDate>
            <atom:updated>2023-05-02T09:11:39.177Z</atom:updated>
            <content:encoded><![CDATA[<h3>Ephemeral Kubernetes Environments: A Cost-Effective Solution for Streamlining Minor Environments and Multi-Tenancy</h3><h3>Introduction</h3><p>In today’s fast-paced software development world, minor environments such as feature, development, and testing environments play a crucial role in ensuring that software is developed, tested, and released quickly and efficiently. However, managing these environments can be a challenge, especially when it comes to scaling, security, and isolation. Kubernetes ephemeral environments offer a solution to these challenges by allowing developers and testers to create and destroy environments on-demand, with minimal overhead and maximum flexibility. In this article, we’ll explore how Kubernetes ephemeral environments can revolutionize minor environments and improve the efficiency of software development and testing. and will provide a demo on how to automate the creation of our minor environment using GitHub actions.</p><h3>Table Of Content</h3><p>· <a href="#d5db">Why Using Ephemeral Kubernetes Clusters for Minor Environments?</a><br>· <a href="#d9d1">How to create Ephemeral Kubernetes Environment?</a><br>· <a href="#35ac">Working with Development Environments</a><br>· <a href="#049e">Pull Request Flow with Ephemeral Environments</a><br>· <a href="#0b12">Demo</a><br>· <a href="#6e5f">Summary</a></p><h3>Why Use Ephemeral Kubernetes Clusters for Minor Environments?</h3><p>It is a common strategy to have permanent Kubernetes clusters for minor environments such as PreProd, feature, and development environments. However, this approach has some drawbacks:</p><ol><li>Each environment has its own dedicated infrastructure and Kubernetes cluster, which can be time-consuming and costly to set up.</li><li>If we are not using managed cloud services like EKS and building and provisioning our own Kubernetes clusters in our data centre, we have additional operational work to manage minor environments, which can be resource-intensive and challenging to maintain.</li></ol><p>There are different types of minor environments:</p><blockquote><strong>PreProd Environments</strong></blockquote><p>PreProd environments are typically used to perform integration tests before going into production. They should have production-like databases to test data integrity. However, PreProd environments are not always in use, and running them all the time can be costly. There are only specific use cases where they need to be running all the time:</p><ul><li>To maintain the state of the deployed version on the production environment and test the migration to the new version. This is mainly because not all workloads are stateless.</li><li>When third parties integrate with our APIs and need to test the newer versions before going into production. These parties require the environment to be up and running all the time.</li></ul><p>We should be able to create the PreProd environment only when needed before production releases and on-demand, and with the use of Infrastructure as Code (IaC) and manifest files, we can have the ability to automate this process.</p><blockquote><strong>Feature Environments</strong></blockquote><p>Feature environments are used to test a specific new feature before it takes its way for production release, these kinds of environments shouldn’t be running all the time because:</p><ol><li>If we do not have multiple feature Kubernetes environments, then we will most likely face the issue of dependencies. Most features require another feature to be deployed, and there is a third feature that needs both features to be deployed, or we have a large team of developers that overwrite each other’s work to test their features.</li><li>On the other hand, if we have many permanent feature Kubernetes environments, these environments can be expensive and contribute to the issue of <a href="https://d2iq.com/blog/kubernetes-cluster-sprawl"><strong>cluster sprawl.</strong></a></li></ol><p>one of the best ways to handle feature environments is to have ephemeral Kubernetes clusters on demand. For example, we can create an ephemeral Kubernetes cluster when a developer creates a pull request. After the developer finishes testing the new feature and closes the pull request, we will destroy the Kubernetes cluster. This way, we create a fully isolated environment that solves the issue of dependencies and prevents developers from overwriting each other’s deployments, which increases developers’ productivity. This approach also saves us money because these environments should be up for only a few hours, maybe days, <strong>but not weeks.</strong></p><blockquote><strong>Development Environments</strong></blockquote><p>Dev environments are mainly used to test ongoing tasks or features developers working on.</p><p>If we have a single Kubernetes cluster for our development environment, our development team will likely experience productivity issues due to dependencies and conflicts. Moreover, a single developer might be working on different features on two different components, and it can be challenging for that developer to work on both features in parallel in the same Kubernetes environment.</p><p>Once again, the solution to such a problem is to create ephemeral Kubernetes clusters for dev environments on demand. A developer should be able to create an ephemeral environment for a branch, and that environment should be destroyed after finishing the development work. These environments should be up and running only for a few minutes or hours.</p><h3>How to create Ephemeral Kubernetes Environment?</h3><p>so we have come to the idea that we can use Ephemeral Kubernetes clusters for all minor environments, now we are going to discuss how we can create those Ephemeral Environments, we have 4 different ways to do that:</p><ol><li>Kubernetes cluster per environment.</li><li>Namespace per environment.</li><li>Capsule Tenant per environment.</li><li>Virtual Cluster per environment.</li></ol><blockquote><strong>Kubernetes cluster per environment</strong></blockquote><p>we can create a whole Kubernetes cluster for each environment as we will avoid having a cluster sprawl because we know that in the end those clusters will be created and destroyed in an automated way, while this way provides full isolation for all environments but it has some drawback though, to create a Kubernetes environment we have two options.</p><ol><li>Creating clusters in our data centres will lead to keeping our virtual machines busy most of the time, also it will add some operational work and it will take some time for those clusters to be up and ready to host temporary workloads.</li><li>Creating clusters using managed services on the cloud (EKS) takes around 15 to 25 minutes and that’s not the best option, especially for ephemeral environments and we are paying for the cluster nodes.</li></ol><blockquote><strong>Kubernetes namespace per environment</strong></blockquote><p>We can create a single permanent Kubernetes cluster for minor environments and isolate different ephemeral environments using Kubernetes namespaces for logical isolation, this will provide us with some isolation though it is not the best way because it has some drawbacks at well using this kind of isolation for ephemeral environments doesn’t allow us to implement advanced multi-tenancy. It’s easy for that way to become complicated easily</p><blockquote><strong>Capsule Tenant per environment</strong></blockquote><p>As per the K8S documentation, there’s no single definition for a tenant because it will vary depending on the use case, and in our use case, we need a tenant that provides us with full isolation and admission control that will help us set some resources limit and give us the ability to easily remove the tenant with all its resources with few commands or even a single one and the most important thing is those tenants are sharing the same Kubernetes cluster.</p><p>One of the well-known Kubernetes projects is <a href="https://capsule.clastix.io/"><strong>Capsule</strong></a><strong>,</strong> Capsule takes a different approach than the native Kubernetes namespaces, it provides a Capsule policy engine that keeps the different tenants isolated from each other, it gives the user the ability to operate their environment in autonomy in a much better way than Kubernetes namespaces but with some permission limits.</p><p>The only issue with that approach is that Capsule doesn’t support cluster-level isolation, for example, if we have some CRDs which are needed as part of our deployment or any cluster-level resources Capsule is not the best tool for that.</p><blockquote><strong>Virtual Cluster per Environment</strong></blockquote><p>As mentioned before the best scenario is to have a full dedicated Kubernetes cluster for each developer or each pull request but it’s hard to manage, has lots of operations work, and is very expensive, but what if we have the ability to create multiple Kubernetes clusters on the same Kubernetes cluster and that cluster could be created easily on demand and also could be destroyed easily after finishing our testing activities on them.</p><p>And Here comes the advantage of Kubernetes Virtual Clusters, a virtual cluster is a Kubernetes cluster that’s created on top of the actual Kubernetes cluster, and it’s built on K3S which is a lightweight (compared to the actual one) distribution designed for production workloads.</p><p>This makes it easy to manage a single (relatively big) Kubernetes cluster and partition it into smaller Kubernetes clusters with low costs and low operation headaches.</p><p><a href="https://www.vcluster.com/">Virtual clusters</a> provide the ability to deploy and use cluster-wide resources or Kubernetes CRDs, and it gives the developer (tenant owner) the luxury of owning a real cluster without restrictions on the permissions level.</p><h3>Working with Development Environments</h3><p>Let’s take an example of a developer who’s developing a new feature on a microservice and for simplicity let’s assume that this microservice depends on two other microservices, it needs a database for storage and a queuing service to push or consume some messages, now the developer after finishing some coding and writing or fixing some function needs to test this feature locally and to be able to do that the developer needs to have those dependencies up and running locally but as we see here those are huge workloads to run locally on the developer machine. and if we have an environment where the developer could deploy those workloads this will be much better.</p><p>but for the developer to be able to deploy his new feature on some remote Kubernetes cluster, first he needs to create an Image and after that deploy his workloads, but here comes the question what if the developer did some changes after that? the traditional answer to such a question is the developer needs to push the new changes and create a new image and redeploy with a newer version that has those changes or fixes, but as this solution has some productivity drawbacks we need another solution.</p><p>A solution that will give us the ability to update our local changes to remote workloads.</p><p>We need something that gives us the ability to synchronize our local changes to remote Kubernetes pods, and for that, we can use tools like DevSpace, DevSpace is an open source command line tool that lets us develop and deploy cloud native software, that gives us the ability to develop with hot reloading and updating our running containers without a rebuild or even a restart, it communicates with Kubernetes using the local Kubernetes context we provide.<br>Now with the combination of creating Ephemeral Kubernetes environments and tools like <a href="https://www.devspace.sh/">DevSpace</a> we increase developer productivity and improve the developer experience.</p><h3>Pull Request Flow with Ephemeral Environments</h3><p>Now that we are done with our development process, we have created a feature and pushed the changes to git and we have created a Pull request for that feature, now we need to test those changes before going to production or PreProd Environment, there are different ways to do that testing we may deploy this new feature on a staging environment this is fine but if we are working with a team of other developers another pull request may overwrite our deployment, it will be better if we have a full isolated ephemeral environment for only testing this new feature, and after finishing testing we can destroy the whole environment when the Pull request is merged using git hooks for that.</p><p>So it seems to be clear that we will use the CICD pipeline to create this testing or preview environment, in combination with V-Cluster or Capsule to create a Kubernetes isolated environment that’s easy to destroy when there’s a pull request that’s merged the diagram below clarify that in more details.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/821/1*5F1t5Ce56ZL9Eo_xPiOubw.png" /></figure><h3>Demo</h3><p>you can find the Github Repository for that demo here</p><p><a href="https://github.com/AmrAlaaYassen/ephemeral-kubernetes-environments">GitHub - AmrAlaaYassen/ephemeral-kubernetes-environments: A Demo for Kubernetes Ephemeral Environments and Multi-tenancy</a></p><p>in this demo we will have a system that consists of 2 microservices and a single Mongo database for storage, we will open a Pull request on one of the microservices and by opening this PR a new Environment should be created on Kubernetes We will use vcluster for creating and destroying the ephemeral environment and after finishing our testing we should easier close or merge the pull request which will trigger another pipeline to destroy the ephemeral environment.</p><p>I have deployed those workloads locally on a Kubernetes cluster, the pipelines are created using GitHub actions workflows, and kustomize to easily deploy the whole system.</p><p>I’m going to make use of the below GitHub repository as it provides a sample microservices system to do the demo</p><p><a href="https://github.com/ashleydavis/nodejs-microservices-example">GitHub - ashleydavis/nodejs-microservices-example: Example of a monorepo with multiple Node.js microservices (using Docker, Docker-Compose and Kubernetes) that have separate CI/CD pipelines.</a></p><p>For development environments We need to create pipelines to automate the creation of the ephemeral environment for each microservice, our pipeline should have the following steps:</p><ol><li>checkout the code</li><li>build docker image</li><li>push the new docker image</li><li>update our Kubernetes manifests</li><li>deploy a new ephemeral environment</li><li>deploy the whole system on this environment</li><li>provide access to this environment</li></ol><p>this is not the ultimate pipeline for your development workflow but those steps are just for demonstration.</p><p>we will use <a href="https://www.vcluster.com/"><strong>vcluster</strong></a> to create fully isolated Kubernetes environments, check GitHub action workflow file below:</p><pre>name: Development Environment gateway<br>on:<br>  workflow_dispatch:<br>    <br>jobs:<br>  dev-deploy:<br>    runs-on: self-hosted<br>    timeout-minutes: 10<br><br>    env:<br>      VERSION: ${GITHUB_REF##*/}<br>      CONTAINER_REGISTRY: ${{ secrets.CONTAINER_REGISTRY }}<br>      REGISTRY_UN: ${{ secrets.DOCKER_USERNAME }}<br>      REGISTRY_PW: ${{ secrets.DOCKER_PASSWORD  }}<br>    steps:<br>      - uses: actions/checkout@v2<br>        name: checkout<br>        with:<br>          persist-credentials: false<br><br>      - name: Login to Docker Hub<br>        uses: docker/login-action@v2<br>        with:<br>          username: ${{ secrets.DOCKER_USERNAME }}<br>          password: ${{ secrets.DOCKER_PASSWORD }}<br><br>      - name: Build<br>        run: ./scripts/build-image.sh gateway ${{github.sha}}<br><br>      - name: Publish<br>        run: ./scripts/push-image.sh gateway ${{github.sha}}<br><br>    <br>      - name: install kubectl<br>        run: |<br>          sudo curl -LO &quot;https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl&quot;;<br>          sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl<br>          sudo rm -rf kubectl<br>          kubectl get pods<br>      - name: install vcluster<br>        run: |<br>          curl -L -o vcluster &quot;https://github.com/loft-sh/vcluster/releases/latest/download/vcluster-linux-amd64&quot; &amp;&amp; sudo install -c -m 0755 vcluster /usr/local/bin &amp;&amp; sudo rm -f vcluster<br>      - name: create vcluster for preview env<br>        run: |<br>          vcluster create gateway-dev-${{ github.sha }} --namespace preview-${{github.sha}} &amp;<br>          sleep 20<br>          vcluster connect gateway-dev-${{ github.sha }} --namespace preview-${{github.sha}} &amp;<br><br>          sleep 20<br>          kubectl create ns gateway-dev-${{ github.actor_id }};<br><br>      - name: install YQ<br>        run: sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq &amp;&amp; sudo chmod +x /usr/bin/yq<br><br>      - name: update image<br>        run: |<br>          yq -e -i &#39;.spec.template.spec.containers[0].image=&quot;${{ secrets.CONTAINER_REGISTRY }}/ephemeral-envs-gateway:${{ github.sha }}&quot;&#39; ./scripts/kubernetes/gateway.yaml<br>          yq -e -i &#39;.spec.template.spec.containers[0].env[1].value=&quot;mongodb://db:27017&quot;&#39; ./scripts/kubernetes/worker.yaml<br><br>      - name: Update changes<br>        run: |<br>          git config --global user.email ${{secrets.ORG}}<br>          git config --global user.name ${{secrets.USERNAME}}<br>          git add .<br>          git commit -m &quot;push image changes for ${{github.sha}}&quot;<br>      - name: Push to Git<br>        uses: ad-m/github-push-action@master<br>        with:<br>          github_token: ${{ secrets.TOKEN }}<br>          repository: ${{ secrets.USERNAME }}/ephemeral-kubernetes-environments<br><br>      - name: Deploy<br>        run: |<br>          sudo curl -s &quot;https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh&quot;  | sudo bash &amp;&amp; \<br>          ./kustomize build ./scripts/kubernetes | kubectl apply -f - -n gateway-dev-${{ github.actor_id }}<br><br>      - name: Artifacting KUBECONFIG Fille<br>        uses: actions/upload-artifact@v3<br>        with:<br>          name: &#39;dev-${{github.actor}}&#39;<br>          path: ~/.kube/config</pre><p>the steps on this pipeline will create an image and push it to our docker registry and update Github with a new tag, after that will deploy a virtual cluster and provide access to it using through normal KUBECONFIG file.</p><p>you can handle access to the cluster in a different way depending on your way of authorizing your users</p><p>now by running vcluster list command, we will be able to see the newly create ephemeral cluster, the cluster name depends on the GitHub commit SHA and the user id on GitHub to avoid creating clusters with the same name.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/943/1*kyT7dk4QDtuOrKUw7KDrpQ.png" /><figcaption>the newly created cluster</figcaption></figure><p>now let’s check the deployed workloads</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/583/1*kbVZubw5Ixsv_0mfNVKcvA.png" /><figcaption>deployed workloads</figcaption></figure><p>it’s clear that we have the full workloads deployed to the new environment and only for that environment.</p><p>as development environments are created on demand whenever the developer needs it, it will be better to have an automated job that destroys those development environments every few hours to avoid keeping our main cluster resources busy all the time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*AEBu0ABQWhK0q5mAM8J1lA.gif" /><figcaption>time for PR</figcaption></figure><p>Now that we have finished our development and we are ready to open a pull request to merge the new changes to the main branch, on PR creation a new environment will be created only to test the new changes, this environment should be used by the QA and testing teams to accept the new changes/features.</p><p>PR GitHub workflow will be almost the same as the development environment but we won’t push the new image tag on GitHub we will deploy it directly on the newly created ephemeral environment.</p><pre>name: gateway PR<br>on:<br>  pull_request:<br>    # Sequence of patterns matched against refs/heads<br>    branches:<br>      - main<br>    paths:<br>      - &#39;gateway/**&#39;<br>jobs:<br>  pr-deploy:<br>    runs-on: self-hosted<br>    timeout-minutes: 10<br><br>    env:<br>      VERSION: ${GITHUB_REF##*/}<br>      CONTAINER_REGISTRY: ${{ secrets.CONTAINER_REGISTRY }}<br>      REGISTRY_UN: ${{ secrets.DOCKER_USERNAME }}<br>      REGISTRY_PW: ${{ secrets.DOCKER_PASSWORD  }}<br>    steps:<br>      - uses: actions/checkout@v2<br>        name: checkout<br>        with:<br>          persist-credentials: false<br><br>      - name: Login to Docker Hub<br>        uses: docker/login-action@v2<br>        with:<br>          username: ${{ secrets.DOCKER_USERNAME }}<br>          password: ${{ secrets.DOCKER_PASSWORD }}<br><br>      - name: Build<br>        run: ./scripts/build-image.sh gateway pr-${{ github.event.pull_request.number }}<br><br>      - name: Publish<br>        run: ./scripts/push-image.sh gateway pr-${{ github.event.pull_request.number }}<br><br><br>      - name: install kubectl<br>        run: |<br>          sudo curl -LO &quot;https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl&quot;;<br>          sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl<br>          sudo rm -rf kubectl<br>          kubectl get pods<br>      - name: install vcluster<br>        run: |<br>          curl -L -o vcluster &quot;https://github.com/loft-sh/vcluster/releases/latest/download/vcluster-linux-amd64&quot; &amp;&amp; sudo install -c -m 0755 vcluster /usr/local/bin &amp;&amp; sudo rm -f vcluster<br>      - name: create vcluster for PR env<br>        run: |<br>          vcluster create gateway-pr-${{ github.event.pull_request.number }} --namespace pr-${{ github.event.pull_request.number }} &amp;<br>          sleep 20<br>          vcluster connect gateway-pr-${{ github.event.pull_request.number }} --namespace pr-${{ github.event.pull_request.number }} &amp;<br><br>          sleep 20<br>          kubectl create ns gateway-pr-${{ github.actor_id }};<br><br>      - name: install YQ<br>        run: sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq &amp;&amp; sudo chmod +x /usr/bin/yq<br><br>      - name: update image<br>        run: |<br>          yq -e -i &#39;.spec.template.spec.containers[0].image=&quot;${{ secrets.CONTAINER_REGISTRY }}/ephemeral-envs-gateway:pr-${{ github.event.pull_request.number }}&quot;&#39; ./scripts/kubernetes/gateway.yaml<br>          yq -e -i &#39;.spec.template.spec.containers[0].env[1].value=&quot;mongodb://db:27017&quot;&#39; ./scripts/kubernetes/worker.yaml<br><br><br>      - name: Deploy<br>        run: |<br>          sudo curl -s &quot;https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh&quot;  | sudo bash &amp;&amp; \<br>          ./kustomize build ./scripts/kubernetes | kubectl apply -f - -n gateway-pr-${{ github.actor_id }}<br><br>      - name: Artifacting KUBECONFIG Fille<br>        uses: actions/upload-artifact@v3<br>        with:<br>          name: &#39;pr-${{github.actor}}&#39;<br>          path: ~/.kube/config</pre><p>we need to create a flow that will destroy the created environment when we merge or close the pull request.</p><pre>name: pr-destroy-gateway<br>on:<br>  pull_request:<br>    types: [closed]<br>    paths:<br>      - &#39;gateway/**&#39;<br>jobs:<br>  pr-destroy:<br>    runs-on: self-hosted<br>    timeout-minutes: 8<br>   <br>    steps:<br>      - uses: actions/checkout@v2<br>        name: checkout<br>        with:<br>          persist-credentials: false<br><br>      - name: install kubectl<br>        run: |<br>          sudo curl -LO &quot;https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl&quot;;<br>          sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl<br>          sudo rm -rf kubectl<br>          kubectl get pods<br>    <br>      - name: install vcluster<br>        run: |<br>          curl -L -o vcluster &quot;https://github.com/loft-sh/vcluster/releases/latest/download/vcluster-linux-amd64&quot; &amp;&amp; sudo install -c -m 0755 vcluster /usr/local/bin &amp;&amp; sudo rm -f vcluster<br>      - name: delete vcluster for PR env<br>        run: |<br>          vcluster delete gateway-pr-${{ github.event.pull_request.number }} &amp;<br>          sleep 20</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1015/1*UQMj7X-GuGZ0BAivaG5DZA.png" /><figcaption>PR for a new feature</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/794/1*DOddgPrhzHJpowchA9meOA.png" /><figcaption>newly created ephemeral environment</figcaption></figure><p>now let’s merge this PR to see the destroy workflow running</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*siiMjx3LYV5KISu9bwaeMA.png" /><figcaption>destroying the environment on PR close/merge</figcaption></figure><h3><em>Summary</em></h3><p>In conclusion, ephemeral environments are good if you have a large team or multiple teams working in the same environment and it will avoid high costs for creating different clusters and boost your team&#39;s productivity.</p><p>A side note on data management, you need to maintain your data to be production-like data and provide it for the PreProd environment to have data integrity, and for that, you need a way to automate the creation of the needed data.</p><p>Ephemeral Environments may not suit you if you have a tiny team of developers that work on independent features</p><p>Overall, ephemeral Kubernetes clusters offer a flexible and powerful tool for achieving more efficient and effective testing and development processes. By adopting this approach, organizations can ensure their minor environments are fully optimized, enabling faster and more agile development cycles.</p><h4>References</h4><ul><li><a href="https://www.vcluster.com/">https://www.vcluster.com/</a></li><li><a href="https://capsule.clastix.io/">https://capsule.clastix.io/</a></li><li><a href="https://www.devspace.sh/">https://www.devspace.sh/</a></li><li><a href="https://d2iq.com/blog/kubernetes-cluster-sprawl">https://d2iq.com/blog/kubernetes-cluster-sprawl</a></li><li><a href="https://www.youtube.com/watch?v=nQly_CEjJc4&amp;t=404s">https://www.youtube.com/watch?v=nQly_CEjJc4&amp;t=404s</a></li><li><a href="https://www.youtube.com/watch?v=JqBjpvp268Y">https://www.youtube.com/watch?v=JqBjpvp268Y</a></li><li><a href="https://www.youtube.com/watch?v=H8bzEJN7fj8">https://www.youtube.com/watch?v=H8bzEJN7fj8</a></li></ul><h4>Contact</h4><p><a href="https://www.linkedin.com/in/amr-alaa-yassen-609785108/">https://www.linkedin.com/in/amr-alaa-yassen-609785108/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d23a00c9f66f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to create ArgoCD Applications Automatically using ApplicationSet? “Automation of the Gitops”]]></title>
            <link>https://amralaayassen.medium.com/how-to-create-argocd-applications-automatically-using-applicationset-automation-of-the-gitops-59455eaf4f72?source=rss-636d55c8d20------2</link>
            <guid isPermaLink="false">https://medium.com/p/59455eaf4f72</guid>
            <category><![CDATA[devops-practice]]></category>
            <category><![CDATA[gitops]]></category>
            <category><![CDATA[argo]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[devops]]></category>
            <dc:creator><![CDATA[AmrAlaaYassen]]></dc:creator>
            <pubDate>Sun, 20 Feb 2022 17:04:58 GMT</pubDate>
            <atom:updated>2022-02-20T21:08:46.458Z</atom:updated>
            <content:encoded><![CDATA[<h3>How to create ArgoCD Applications Automatically using ApplicationSet? “Automation of GitOps”</h3><h3>What will we discuss today?</h3><p>In this article we will discuss ArgoCD ApplicationSet and how to use ApplicationSet generators to automatically create ArgoCD Applications templates using the flexibility of the ApplicationSet controller to our own benefit, we will give examples for some of ApplicationSet generators and at the end of the article, we will implement a very specific use case and give final opinions and conclusions.</p><h3>Table of content</h3><ol><li><a href="#c628">Introduction</a></li><li><a href="#1305">The problem that ApplicationSet tries to solve.</a></li><li><a href="#7a86">What is the ArgoCD ApplicationSet?</a></li><li><a href="#681b">How ApplicationSet controller solves the problem?</a></li><li><a href="#ccbb">ApplicationSet generators and use cases for every generator</a></li><li><a href="#1e08">Generators Examples</a></li><li><a href="#5702">Demo</a></li><li><a href="#bf6b">Conclusions and Opinions</a></li></ol><h3>Introduction</h3><p>One of the very popular tools in the Kubernetes ecosystem is ArgoCD, so let’s briefly explain what ArgoCD has been built for, it applies the theoretical parts of the GitOps approach and brings it to the practical world through a tool built with a wonderful UI which makes everyone’s life easier, the tool simply watches over a GitHub Repository which defines the desired state to be deployed to our Kubernetes cluster and continuously compare this desired state with the actual state deployed on the cluster if there’s a difference between the stats, the tool has a set of well-defined actions to take (we define those actions) to handle those differences, as a result, we will have a defined state on GitHub Repository applied to our Kubernetes cluster, to know more about ArgoCD I highly recommend to take a look over the <a href="https://argo-cd.readthedocs.io/en/stable/">documentation</a>.</p><h3>The problem that ApplicationSet tries to solve.</h3><p>ArgoCD will give you the opportunity to version control your cluster deployments, configurations and Kubernetes objects by monitoring a GitHub repository (the source of truth) and applying it to the cluster.</p><p>you can do this by defining an ArgoCD application manifest like the one below</p><p>Simple ArgoCD Application</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcarbon.now.sh%2Fembed%3Fbg%3Drgba%2528171%252C%2B184%252C%2B195%252C%2B1%2529%26t%3Dseti%26wt%3Dnone%26l%3Dyaml%26width%3D680%26ds%3Dfalse%26dsyoff%3D86px%26dsblur%3D66px%26wc%3Dfalse%26wa%3Dtrue%26pv%3D0px%26ph%3D0px%26ln%3Dtrue%26fl%3D1%26fm%3DCascadia%2BCode%26fs%3D14px%26lh%3D133%2525%26si%3Dfalse%26es%3D2x%26wm%3Dfalse%26code%3DapiVersion%25253A%252520argoproj.io%25252Fv1alpha1%25250Akind%25253A%252520Application%25250Ametadata%25253A%25250A%252520%252520name%25253A%252520guest-book%25250A%252520%252520namespace%25253A%252520argocd%25250Aspec%25253A%25250A%252520%252520destination%25253A%25250A%252520%252520%252520%252520namespace%25253A%252520default%25250A%252520%252520%252520%252520server%25253A%252520https%25253A%25252F%25252Fkubernetes.default.svc%25250A%252520%252520project%25253A%252520default%25250A%252520%252520source%25253A%25250A%252520%252520%252520%252520path%25253A%252520kustomize-guestbook%25250A%252520%252520%252520%252520repoURL%25253A%252520https%25253A%25252F%25252Fgithub.com%25252Fargoproj%25252Fargocd-example-apps.git%25250A%252520%252520%252520%252520targetRevision%25253A%252520HEAD&amp;display_name=Carbon&amp;url=https%3A%2F%2Fcarbon.now.sh%2F%3Fbg%3Drgba%252528171%25252C%2B184%25252C%2B195%25252C%2B1%252529%26t%3Dseti%26wt%3Dnone%26l%3Dyaml%26width%3D680%26ds%3Dfalse%26dsyoff%3D86px%26dsblur%3D66px%26wc%3Dfalse%26wa%3Dtrue%26pv%3D0px%26ph%3D0px%26ln%3Dtrue%26fl%3D1%26fm%3DCascadia%2BCode%26fs%3D14px%26lh%3D133%252525%26si%3Dfalse%26es%3D2x%26wm%3Dfalse%26code%3DapiVersion%2525253A%25252520argoproj.io%2525252Fv1alpha1%2525250Akind%2525253A%25252520Application%2525250Ametadata%2525253A%2525250A%25252520%25252520name%2525253A%25252520guest-book%2525250A%25252520%25252520namespace%2525253A%25252520argocd%2525250Aspec%2525253A%2525250A%25252520%25252520destination%2525253A%2525250A%25252520%25252520%25252520%25252520namespace%2525253A%25252520default%2525250A%25252520%25252520%25252520%25252520server%2525253A%25252520https%2525253A%2525252F%2525252Fkubernetes.default.svc%2525250A%25252520%25252520project%2525253A%25252520default%2525250A%25252520%25252520source%2525253A%2525250A%25252520%25252520%25252520%25252520path%2525253A%25252520kustomize-guestbook%2525250A%25252520%25252520%25252520%25252520repoURL%2525253A%25252520https%2525253A%2525252F%2525252Fgithub.com%2525252Fargoproj%2525252Fargocd-example-apps.git%2525250A%25252520%25252520%25252520%25252520targetRevision%2525253A%25252520HEAD&amp;image=https%3A%2F%2Fcarbon.now.sh%2Fstatic%2Fbrand%2Fbanner.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;scroll=auto&amp;schema=carbon" width="1024" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/d52441de123a485caec54b679d987e02/href">https://medium.com/media/d52441de123a485caec54b679d987e02/href</a></iframe><p>This should create an ArgoCD Application like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NfG8eu17ybGbbLSq8vOQPg.png" /><figcaption>ArgoCD Application UI</figcaption></figure><p>This is for a single application, let’s assume you are working in a microservice architecture, then you will have to create a new ArgoCD application for every microservice, even if you are using tools like kustomize or Helm for sure you will have different values for every deployment which will lead you to create a separate application for each, and as the applications number grows it becomes very hard and doesn’t make any sense to handle that very large number of ArgoCD Applications manifests.</p><p><strong>Here comes ApplicationSet in place, it makes it very easy to automatically create Application manifests using its generators.</strong></p><h3>What is ArgoCD ApplicationSet?</h3><p>ApplicationSet is a Kubernetes CRD (Custom Resource Definition) that helps us to automatically create ArgoCD Applications and adds more flexibility to manage those applications and provide a single place to make changes to all of your applications, whether you have different destinations for those applications or different configuration values it will automatically handle setting those values for your Applications.</p><p>Alongside ApplicationSet CRD, comes the ApplicationSet controller that adds support to ApplicationSet CRD, the controller works side by side with an existing ArgoCD installation, you can consider ApplicationSet as a plugin or extension that makes handling Applications easier.</p><h3>How ApplicationSet controller solves the problem.</h3><p>While an ArgoCD application holds a Git repository for the desired manifests and a Kubernetes cluster destination, An ApplicationSet definition holds the generators that will automatically create ArgoCD applications with different values for different sources and destinations, ApplicationSet creates an application using an application template defined in a YAML format and fills that template with the outputted values from the generators.</p><p>so it’s best to use ApplicationSet when you have too many applications to handle using ArgoCD and those applications are similar in a way to be able to use the generators in your favor.</p><p>The image below show a usecase where you have Kubernetes tools that you want to be deployed in all Kubernetes clusters that you work on, for example, a Prometheus operator that you want it to be deployed on all clusters, in a normal scenario you will have to create 7 different Application Manifests pointing to the same Git repository as the source and different clusters as the destination, but that could be handled using a Single ApplicationSet Manifests</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/835/1*xt98FAJrqxu5dQ3yhZ2ZRg.png" /><figcaption>Single app — multiple clusters</figcaption></figure><h3>ApplicationSet generators and use cases for every generator.</h3><p>There are lots of ApplicationSet generators we will mention the most important ones and usecases for each but I advice to take a look at <a href="https://argocd-applicationset.readthedocs.io/en/stable/Generators/">the generators documentation</a></p><ul><li><strong>List Generator</strong></li></ul><p>The list generator simply creates ArgoCD application templates given a list of elements that we define the values for, so let’s take an example that we have an application that we need to deploy to a list of namespaces (e.g dev, test, uat), the ApplicationSet manifest will be like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xcdCLa2MTPwi5Fi9CHjYVQ.png" /><figcaption>ApplicationSet List Generator</figcaption></figure><p>The above ArgoCD ApplicationSet manifest deploys 3 different ArgoCD apps dev-color-app,test-color-app, and uat-color-app to 3 different namespaces dev, test, and uat on ArgoCD UI you will see three applications created for you on the fly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hAzUpJlDmrYA7WP6gOEx3A.png" /><figcaption>Applications Created by ApplicationSet</figcaption></figure><p>here comes the magic of the ApplicationSet generators it has created all needed applications using a very simple ApplicationSet manifest file.</p><ul><li><strong>Git Generators</strong></li></ul><p>The git generator has two types under the git generator tree:</p><ol><li><strong>Git Directory Generator.</strong></li></ol><p>It creates variables based on the directory structure in a specific Git repository and then uses different paths/subPaths as variables to use them in the ArgoCD Application template, this generator will help you to automatically create applications if you have a structure where you put every application manifests in a single directory in the same Git repository, or you have a common helm chart repository for all your applications or environments.</p><p>2. <strong>Git File Generator.</strong></p><p>It creates variables using the contents of a file (JSON or YAML format) from a defined Git repository, the contents of the file may include different destinations or clusters to deploy the application to.</p><p>In the example below we will use the Git-Dir generator to create deployments for some Argo projects like Argo workflows, Argo rollouts, and Argo image updater and we want each of these applications to be deployed on a different namespace on our cluster that has been created to manage only Argo projects on it, ApplicationSet definition will be something like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*w3rKX9kTC_tK1HqP2d88Tw.png" /><figcaption>ApplicationSet Git-Dir Generator</figcaption></figure><p>this ApplicationSet manifest will create 3 ArgoCD Applications using directories names and paths as variables to be used in the Application template in the ApplicationSet manifest.</p><p>in the generator section above we point to a Git repository to get the directories from and specify the path that includes those directories <a href="https://github.com/AmrAlaaYassen/ArgoCD-ApplicationSet-Demo/tree/main/git-dir-generator-example/argo-projects">the path</a> specified above includes 3 sub-directories</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FGCvrMmYNBfAdgJG4W9sWA.png" /><figcaption>Directory structure</figcaption></figure><p>this will create 3 variables for us to be used in the template section above and those 3 variables are git-dir-generator-example/argo-projects/argo-image-updater, git-dir-generator-example/argo-projects/argo-rollouts, and git-dir-generator-example/argo-projects/argo-workflows each one of these variables has a child value which we refer to as path.basename that has the value of basename of the path (the right-most pathname) in our case will be argo-image-updater or argo-rollouts or argo-workflows.</p><p>we will use names of directories to specify different destinations (different namespaces in our case) to deploy our applications, as a result, we will have 3 ArgoCD applications like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sSCPZ1obdiFF4r5QVLm0Lw.png" /><figcaption>Git-Dir Applications</figcaption></figure><p><strong>Note different namespaces are specified.</strong></p><h3>Demo</h3><p>In this demo we have advanced usage of the git-dir generator</p><p><strong>usecase:</strong> let’s assume that we have a Git repository that contains our deployments using a common helm chart like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_avHbXGL6npVncacV0eKlw.png" /><figcaption>Directory Structure (2)</figcaption></figure><p>as you see here we have a common helm chart that will be used to deploy all of our applications and for each application we have different environments directories that include different <strong>values.yaml</strong> file that specifies the needed values for each environment (prod, qa, stating), we want to name our application in the following naming convention appname-environmentand we want to select different values files for each application based on the environment that we will make deployment for, in a normal case scenario using the above structure you will have to create 9 different ArgoCD Application manifests to specify different values files for helm to use and for each application and the application different environment, but using ApplicationSet Generator you will only create a single manifest file as below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*g-H010vGGOxPb6BBRQLIiw.png" /><figcaption>Demo ApplicationSet</figcaption></figure><p>This ApplicationSet manifest will create the 9 applications manifests we mentioned above automatically using the git-dir generator with paths and sub-paths pattern</p><p>demo/configs/*/* here we use the directories under the configs folder and the subdirectories of the directories under the config folder so we will have 9 different values generated form the above generator</p><p>demo/config/app-hulk/prod demo/config/app-hulk/qa demo/config/app-hulk/staging and the same for app-iron and app-spider this will help us to specify different values files for those different apps, the diagram below explains more</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SQmLFFqXMUx-xw1HiG-01w.png" /><figcaption>Demo Example Illustration</figcaption></figure><p>as a result, you will see in Argo UI the below</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NR_PlZllZEZNoZ-_ZZgaJw.png" /><figcaption>ArgoCD Demo Example UI</figcaption></figure><p>This demo introduces a concept called “mono-repository” where you manage all of your ArgoCD Applications from a single Git Repository you can find more about that concept <a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/#monorepo-scaling-considerations">here</a>, if you face issues using this approach and want some way to work it around comment below in the comments this may be our next blog.</p><p><strong>Repository includes the examples and demos we discussed in this blog</strong></p><p><a href="https://github.com/AmrAlaaYassen/ArgoCD-ApplicationSet-Demo">GitHub - AmrAlaaYassen/ArgoCD-ApplicationSet-Demo</a></p><h3>Conclusions and Opinions</h3><p>ArgoCD ApplicationSet has other amazing generators like Matrix Generator a matrix generator combines the variables generated from 2 different ApplicationSet generators, it generates different ArgoCD Applications for every combination of the generated values, this generator gives us the flexibility to use different generators features and use the values generated from each generator.</p><p>ArgoCD is already a very powerful tool that makes it really easy to manage your deployments using the GitOps approach however it lacks some kind of automation here’s where ArgoCD ApplicationSet comes in place and introduces its way around creating ArgoCD Applications Manifest automatically if you are using ArgoCD ApplicationSet I’d like to hear more about your use case and what is the challenge that you have faced and how it’s been solved.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=59455eaf4f72" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>