<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ayush Sharma</title>
    <description>The latest articles on DEV Community by Ayush Sharma (@ayushsharma).</description>
    <link>https://dev.to/ayushsharma</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F687511%2F8015a192-ac2f-4330-834e-54b6d1aa6429.jpeg</url>
      <title>DEV Community: Ayush Sharma</title>
      <link>https://dev.to/ayushsharma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ayushsharma"/>
    <language>en</language>
    <item>
      <title>Getting started with ArgoCD</title>
      <dc:creator>Ayush Sharma</dc:creator>
      <pubDate>Mon, 16 Aug 2021 14:40:06 +0000</pubDate>
      <link>https://dev.to/ayushsharma/getting-started-with-argocd-d1j</link>
      <guid>https://dev.to/ayushsharma/getting-started-with-argocd-d1j</guid>
      <description>&lt;p&gt;In a typical push-based deployment, tools like Ansible, Jenkins, etc., connect directly to the server or cluster and execute the provisioning commands. This approach works well when the cluster is accessible on the network, and there is direct connectivity between our deployment server and the destination server. For compliance or security reasons, connectivity between the deployment tool and the cluster may not be possible.&lt;/p&gt;

&lt;p&gt;ArgoCD is a pull-based deployment tool. It watches a remote Git repository for new or updated Manifest files and synchronises those changes with the cluster. By managing Manifests in Git and syncing them with the cluster, we get all of the advantages of a Git-based workflow (version control, pull-request reviews, transparency in collaboration, etc.) and a one-to-one mapping between what is in the Git repo and what is deployed in the cluster. This method is called GitOps.&lt;/p&gt;

&lt;p&gt;In this tutorial, I'm going to do the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install ArgoCD on a Minikube installation.&lt;/li&gt;
&lt;li&gt;Create a sample ArgoCD application called &lt;code&gt;ayush-test-application&lt;/code&gt; and &lt;a href="https://gitlab.com/ayush-sharma/example-assets/-/tree/main/argocd/getting-started"&gt;link it with my repo &lt;code&gt;ayush-sharma/example-assets&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Create and &lt;a href="https://gitlab.com/ayush-sharma/example-assets/-/blob/main/argocd/getting-started/nginx-manifest.yml"&gt;Nginx deployment with 3 replicas&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Ensure the new application shows up on the ArgoCD dashboard and verify it using &lt;code&gt;kubectl&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installing ArgoCD
&lt;/h2&gt;

&lt;p&gt;For this tutorial, I'm using Minikube &lt;code&gt;version: v1.21.0&lt;/code&gt;. You can &lt;a href="https://minikube.sigs.k8s.io/docs/start/"&gt;download and install Minikube from here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With Minikube up and running, we're going to install ArgoCD. The ArgoCD documentation contains detailed steps on &lt;a href="https://argoproj.github.io/argo-cd/getting_started/"&gt;how to install and configure it for any cluster&lt;/a&gt;. Once you've executed those steps, make sure to run &lt;code&gt;minikube tunnel&lt;/code&gt; in a separate terminal window to ensure Minikube exposes the ArgoCD Server's load balancer endpoint on your local system. To verify this, run &lt;code&gt;kubectl get po -n argocd&lt;/code&gt; and check if the &lt;code&gt;argo-server&lt;/code&gt; service has an &lt;code&gt;EXTERNAL-IP:&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;user@system ~ kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; argocd
NAME                    TYPE           CLUSTER-IP      EXTERNAL-IP     PORT&lt;span class="o"&gt;(&lt;/span&gt;S&lt;span class="o"&gt;)&lt;/span&gt;                      AGE
argocd-dex-server       ClusterIP      10.110.2.52     &amp;lt;none&amp;gt;          5556/TCP,5557/TCP,5558/TCP   3h32m
argocd-metrics          ClusterIP      10.100.73.57    &amp;lt;none&amp;gt;          8082/TCP                     3h32m
argocd-redis            ClusterIP      10.104.11.24    &amp;lt;none&amp;gt;          6379/TCP                     3h32m
argocd-repo-server      ClusterIP      10.100.132.53   &amp;lt;none&amp;gt;          8081/TCP,8084/TCP            3h32m
argocd-server           LoadBalancer   10.98.182.198   10.98.182.198   80:32746/TCP,443:31353/TCP   3h32m
argocd-server-metrics   ClusterIP      10.105.182.52   &amp;lt;none&amp;gt;          8083/TCP                     3h32m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the installation is complete and the load balanacer is working, the ArgoCD UI will be accessible at the &lt;code&gt;EXTERNAL IP&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the first application
&lt;/h2&gt;

&lt;p&gt;Before we can talk about ArgoCD deployments we need to ensure that a Git repo with a K8s manifest file ready to deploy. I'm using &lt;a href="https://gitlab.com/ayush-sharma/example-assets/-/tree/main/argocd/getting-started"&gt;my public repo &lt;code&gt;example-assets&lt;/code&gt;&lt;/a&gt; with an &lt;a href="https://gitlab.com/ayush-sharma/example-assets/-/blob/main/argocd/getting-started/nginx-manifest.yml"&gt;Nginx deployment manifest file in &lt;code&gt;/argocd/getting-started&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our goal is to get ArgoCD to listen to the K8s manifest file above for changes and then sync them with the cluster it is deployed in, in this case, Minikube. We do this by creating an Application containing information about the Manifest files' source repo, destination cluster details, and synchronisation policies.&lt;/p&gt;

&lt;p&gt;Click &lt;code&gt;New App&lt;/code&gt; on the top left to configure a new Application. Since my destination Kubernetes server is the one ArgoCD is installed on (Minikube), I will leave the server defaults as-is. These are the values I configured:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Application Name: &lt;code&gt;ayush-test-application&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Project: &lt;code&gt;default&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sync Policy: &lt;code&gt;automated&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sync Options: &lt;code&gt;prune: true; selfHeal: true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Source Repository URL:  &lt;code&gt;https://gitlab.com/ayush-sharma/example-assets.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Source Revision: &lt;code&gt;HEAD&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Source Path: &lt;code&gt;argocd/getting-started&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Destination Cluster URL: &lt;code&gt;https://kubernetes.default.svc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Destination Namespace: &lt;code&gt;default&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To make things easier, you can click &lt;code&gt;EDIT AS YAML&lt;/code&gt; on the top-right and paste the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argoproj.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Application&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ayush-test-application&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;default'&lt;/span&gt;
    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
    &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://kubernetes.default.svc'&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argocd/getting-started&lt;/span&gt;
    &lt;span class="na"&gt;repoURL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://gitlab.com/ayush-sharma/example-assets.git'&lt;/span&gt;
    &lt;span class="na"&gt;targetRevision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HEAD&lt;/span&gt;
  &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
  &lt;span class="na"&gt;syncPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;automated&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;prune&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;selfHeal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your configuration should look like this:&lt;/p&gt;

&lt;p&gt;After saving the configuration, your Application should show up as a card on the home page. Since we specified the sync policy as &lt;code&gt;Automated&lt;/code&gt; our new Application will begin syncing with the repo immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Nginx deployment
&lt;/h2&gt;

&lt;p&gt;In this tutorial, my manifest file is a standard Nginx deployment with 3 replicas. Once &lt;code&gt;ayush-test-application&lt;/code&gt; completes syncing, ArgoCD will display a nice graphical view of the deployment.&lt;/p&gt;

&lt;p&gt;Now let me verify the deployment using &lt;code&gt;kubectl get po&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-585449566-584cj   1/1     Running   0          5m
nginx-deployment-585449566-6qn2z   1/1     Running   0          5m
nginx-deployment-585449566-d9fm2   1/1     Running   0          5m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;ArgoCD is a relatively light-weight and more secure approach to K8s deployments. I'm especially fond of the one-to-one relationship between what's in the repo and what's in the cluster making incident management a lot simpler.&lt;/p&gt;

&lt;p&gt;Another big advantage is that since our Git repo contains everything ArgoCD requires, we could delete the entire ArgoCD installation and set things up from scratch. Meaning that bringing up a second identical cluster with all our workload deployed is now more feasible and practical in the event of a catastrophic outage.&lt;/p&gt;

&lt;p&gt;A third big advantage is security: since ArgoCD pulls changes from a remote Git repo, there is no need to define firewall rules and VPC peering connections to get our deployment servers to connect with our cluster, which is one less point of entry. This reduces the attack surface area for our dev/QA/prod servers significantly.&lt;/p&gt;

&lt;p&gt;Since the Git repo and branch name is configurable, you can get creative with deployment models. For example, you could have 2 different ArgoCDs running on 2 different QA and prod clusters listening to the same repo's branch. This guarantees that the same Manifest file is deployed on both clusters, ensuring QA and prod environments contain the same codebase. Also, a single ArgoCD is capable of targeting multiple servers, meaning a hub-and-spoke deployment model is possible, where one Master ArgoCD orchestrates deployments across multiple dev, QA, and prod clusters in different regions/environments.&lt;/p&gt;

&lt;p&gt;I hope this tutorial was informative. Get creative with ArgoCD, and don't forget to share your experiments with others.&lt;/p&gt;

&lt;p&gt;Happy coding :)&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>docker</category>
    </item>
    <item>
      <title>5 key best practices for sane and usable Terraform setups</title>
      <dc:creator>Ayush Sharma</dc:creator>
      <pubDate>Wed, 14 Jul 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/ayushsharma/5-key-best-practices-for-sane-and-usable-terraform-setups-4bgl</link>
      <guid>https://dev.to/ayushsharma/5-key-best-practices-for-sane-and-usable-terraform-setups-4bgl</guid>
      <description>&lt;p&gt;Working with Terraform for over five years has taught me some key lessons. 5 practices have been critical to having a sane and usable Terraform setup regardless of the size of the team or the nature of the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Know your target audience.
&lt;/h2&gt;

&lt;p&gt;This one might seem obvious, but I’ve seen it go wrong several times. When organising Terraform code, either standardising the directory structure or defining naming conventions, it’s vital to consider the intended audience. Will your team be using these Terraform scripts and modules? Are you handing the work over to another team? Will new people be joining your team sooner or later? Are you working on this project solo? Will you be using this setup in 6 months or a year, or will it be assigned to someone else?&lt;/p&gt;

&lt;p&gt;Questions like these will affect several decisions. Ideally, you should have &lt;a href="https://www.terraform.io/docs/language/state/index.html"&gt;Remote State&lt;/a&gt; and &lt;a href="https://www.terraform.io/docs/language/state/locking.html"&gt;State Locking&lt;/a&gt; in place regardless of the team size now or in the future. Remote State will ensure your laptop is not the only place your Terraform works and State Locking will ensure that only one person at a time is changing the infrastructure.&lt;/p&gt;

&lt;p&gt;The naming convention should make sense to the eventual owners of the project, not just the team that is writing the code. If the project is for another team, make sure they have a say in the naming convention. If non-technical stakeholders or internal security/GCR teams review the code, make sure they check the naming convention. In addition to resource names, you should leverage resource tags to highlight any data classification/privacy requirements (high, medium, low) for more careful examination by reviewers.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Reuse. Reuse. Reuse.
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://registry.terraform.io"&gt;Terraform Registry&lt;/a&gt; provides a library of ready-to-use modules for the most common use-cases. I’ve written about the extensive parameterisation available in the &lt;a href="https://dev.to/2020/09/creating-aws-vpcs-in-2-minutes-with-terraform-registry"&gt;VPC module&lt;/a&gt; and &lt;a href="https://dev.to/2020/09/creating-ready-to-use-aws-security-groups-using-terraform-registry-named-groups-and-named-rules"&gt;security groups&lt;/a&gt;. Simply calling modules with different parameters will be enough to handle most, if not all, potential use-cases. Reuse these shared modules as much as possible to avoid useless typing/testing/checking/fixing/refactoring.&lt;/p&gt;

&lt;p&gt;I’ve also found that separating modules and resources based on the frequency of use or change is beneficial. For example, infrastructure scaffolding used only once belongs together, such as setting up the VPC, security groups, routing tables, VPC endpoints, etc. But things like private hosted zone entries, autoscaling groups, target groups, load balancers, etc., might change with every deployment, so separating these from the one-time scaffolding will make code reviews easier and debugging faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Explicit rather than implicit.
&lt;/h2&gt;

&lt;p&gt;Terraform code often contains incorrect assumptions baked into it. Teams assume that the Terraform version used to write the code today will never change, or the external modules won’t change, or the providers they are using won’t change. These lead to invisible issues a few weeks down the road when these external dependencies inevitably get updated.&lt;/p&gt;

&lt;p&gt;Ensure you are explicitly defining versions everywhere possible: in the main Terraform block, in the provider block, in the module block, etc. Defining versions will ensure that your dependent libraries stay frozen so that you can explicitly update dependencies when required after thorough discussions, reviews, and testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Automate everywhere. Your laptop. Your shared VM. Your CI/CD.
&lt;/h2&gt;

&lt;p&gt;Leveraging automation at every stage of the deployment process can avoid future problems before they even arise.&lt;/p&gt;

&lt;p&gt;Use Git pre-commit hooks to run &lt;code&gt;terraform fmt&lt;/code&gt; and &lt;code&gt;terraform validate&lt;/code&gt; before you commit your code. Pre-commit hooks ensure that code is, at a bare minimum, adequately formatted and syntactically correct. Check-in this pre-commit file to the repo, and everyone on your team can benefit from the same automation. This small but vital quality control at the first step of the process can achieve substantial time savings as your project progresses.&lt;/p&gt;

&lt;p&gt;All modern deployment tools have CI processes. You can use these to run SAST and unit testing tools when pushing your code to origin. I’ve written about how &lt;a href="https://dev.to/2021/07/cloud-infrastructure-sast-terraform-checkov"&gt;Checkov can test Terraform code for security and compliance and create custom checks&lt;/a&gt; for organisation-specific conventions. Add these unit testing tools to your CI pipeline to improve code quality and robustness.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Have an awesome README.md!
&lt;/h2&gt;

&lt;p&gt;We all like to think that Terraform code is self-documenting. Sure it is, but only if your future team already knows your company’s naming conventions and guidelines and secret handshakes and inside jokes and whatever else your repo contains besides valid Terraform code. Getting into the habit of having a good &lt;code&gt;README.md&lt;/code&gt; can be a huge time saver, and it will keep your team honest by holding them accountable for everything explicitly committed to in the README.&lt;/p&gt;

&lt;p&gt;At a minimum, your README should contain the steps to initialise the right Terraform environment on your workstations (Mac, Windows, Linux, etc.), including the Terraform version to install. It should specify the required dependencies (Checkov, TerraGrunt, etc.) with versions and any handy Linux aliases your team uses (some people like to define &lt;code&gt;tff&lt;/code&gt; as a short-hand for &lt;code&gt;terraform fmt&lt;/code&gt;). Most importantly, the branching and PR review strategy/process, the naming conventions, and the resource tagging standards should be specified.&lt;/p&gt;

&lt;p&gt;The README should pass a simple test: if a new member joins your team tomorrow, is the README enough to teach them what to do and how to do it correctly? If not, you may find youself hosting never-ending standards and process meetings repeatedly for the next few months.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>cloud</category>
      <category>aws</category>
    </item>
    <item>
      <title>Automating ArgoCD using ArgoCD!</title>
      <dc:creator>Ayush Sharma</dc:creator>
      <pubDate>Wed, 07 Jul 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/ayushsharma/automating-argocd-using-argocd-23l4</link>
      <guid>https://dev.to/ayushsharma/automating-argocd-using-argocd-23l4</guid>
      <description>&lt;p&gt;We have already seen how &lt;a href="https://notes.ayushsharma.in//2021/07/getting-started-with-argocd"&gt;ArgoCD makes pull-based GitOps deployments simple&lt;/a&gt;. In this tutorial, I’ll show you how to automatically create multiple Applications in ArgoCD using ArgoCD!&lt;/p&gt;

&lt;p&gt;Since ArgoCD’s job is to listen to a repo and apply the Manifest files it finds to the cluster, we can use this approach to configure ArgoCD internals as well. In our last example, we used the GUI to create a sample Nginx application with three replicas. We will use the same approach as before. But this time, we will create an Application from the GUI, which will deploy three separate applications - &lt;code&gt;app-1&lt;/code&gt;, &lt;code&gt;app-2&lt;/code&gt;, and &lt;code&gt;app-3&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring our child applications
&lt;/h2&gt;

&lt;p&gt;Let’s start by creating the Manifest files for our three applications. In my &lt;a href="https://gitlab.com/ayush-sharma/example-assets"&gt;&lt;code&gt;example-assets&lt;/code&gt; repository&lt;/a&gt;, I have &lt;a href="https://gitlab.com/ayush-sharma/example-assets/-/tree/main/argocd/my-apps"&gt;created three applications under &lt;code&gt;argocd/my-apps&lt;/code&gt;&lt;/a&gt;. All three applications are Nginx with three replicas. Remember to create each application in its own folder.&lt;/p&gt;

&lt;p&gt;This is &lt;code&gt;my-apps/app-1/app.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app-1
  labels:
    app: nginx-app-1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-app-1
  template:
    metadata:
      labels:
        app: nginx-app-1
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

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

&lt;/div&gt;



&lt;p&gt;This is &lt;code&gt;my-apps/app-2/app.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app-2
  labels:
    app: nginx-app-2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-app-2
  template:
    metadata:
      labels:
        app: nginx-app-2
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

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

&lt;/div&gt;



&lt;p&gt;And this is &lt;code&gt;my-apps/app-3/app.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app-3
  labels:
    app: nginx-app-3
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-app-3
  template:
    metadata:
      labels:
        app: nginx-app-3
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

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

&lt;/div&gt;



&lt;p&gt;Now that our Manifest files are ready, we need to create ArgoCD Applications to point to those Manifests.&lt;/p&gt;

&lt;p&gt;ArgoCD can be configured in three different ways: using the GUI, using the CLI, or using Kubernetes Manifest files. We will use the third method.&lt;/p&gt;

&lt;p&gt;Create the following Manifest files in a new folder &lt;code&gt;argocd/argo-apps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is &lt;code&gt;argocd-apps/app-1.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-1
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  project: default
  source:
    path: argocd/my-apps/app-1
    repoURL: https://gitlab.com/ayush-sharma/example-assets.git
    targetRevision: HEAD

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

&lt;/div&gt;



&lt;p&gt;This is &lt;code&gt;argocd-apps/app-2.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-2
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  project: default
  source:
    path: argocd/my-apps/app-2
    repoURL: https://gitlab.com/ayush-sharma/example-assets.git
    targetRevision: HEAD

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

&lt;/div&gt;



&lt;p&gt;And this is &lt;code&gt;argocd-apps/app-3.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-3
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  project: default
  source:
    path: argocd/my-apps/app-3
    repoURL: https://gitlab.com/ayush-sharma/example-assets.git
    targetRevision: HEAD

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

&lt;/div&gt;



&lt;p&gt;As you can see, we are creating a Kubernetes object called &lt;code&gt;Application&lt;/code&gt; in the &lt;code&gt;argocd&lt;/code&gt; namespace. This object contains the source Git repository and destination server details. Our Applications are pointing to the Nginx manifest files we created earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring our main application
&lt;/h2&gt;

&lt;p&gt;Now we need some way to tell ArgoCD how to find our three Nginx applications. We do this by creating yet another Application! This pattern is called the &lt;code&gt;App of Apps&lt;/code&gt; pattern, where one Application contains the instructions to deploy multiple child Applications.&lt;/p&gt;

&lt;p&gt;Create a new Application from the GUI called &lt;code&gt;my-apps&lt;/code&gt; with the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-apps
spec:
  destination:
    namespace: default
    server: 'https://kubernetes.default.svc'
  source:
    path: argocd/argocd-apps
    repoURL: 'https://gitlab.com/ayush-sharma/example-assets.git'
    targetRevision: HEAD
  project: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

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

&lt;/div&gt;



&lt;p&gt;After creation, &lt;code&gt;my-apps&lt;/code&gt; will begin syncing on the GUI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SxIs_-VS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.ayushsharma.in/static/images/automating-argocd-with-argocd-main-app.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SxIs_-VS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.ayushsharma.in/static/images/automating-argocd-with-argocd-main-app.png" alt="Automating ArgoCD with ArgoCD! - Main app."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the sync is complete, our three Nginx applications will appear on the GUI as well:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2PEaFWCz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.ayushsharma.in/static/images/automating-argocd-with-argocd-dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2PEaFWCz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.ayushsharma.in/static/images/automating-argocd-with-argocd-dashboard.png" alt="Automating ArgoCD with ArgoCD! - Dashboard."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we did not enable &lt;code&gt;AutoSync&lt;/code&gt;, manually sync &lt;code&gt;app-1&lt;/code&gt;, &lt;code&gt;app-2&lt;/code&gt;, and &lt;code&gt;app-3&lt;/code&gt;. Once synced, our Nginx replicas will be deployed for all three apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zWuzhPOG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.ayushsharma.in/static/images/automating-argocd-with-argocd-deployment.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zWuzhPOG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://notes.ayushsharma.in/static/images/automating-argocd-with-argocd-deployment.png" alt="Automating ArgoCD with ArgoCD! - Deployment."&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Mastering the &lt;code&gt;App of Apps&lt;/code&gt; pattern is critical to leveraging the full power of ArgoCD. This method allows us to manage groups of applications cleanly. For example, deploying Prometheus, Grafana, Loki, etc., could be managed by a DevOps Application, whereas deploying frontend code could be managed by a Frontend Application. Configuring different sync options and repo locations for each allows more granular control over different application groups.&lt;/p&gt;

&lt;p&gt;Happy coding :)&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
