<?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: Tracy Holmes</title>
    <description>The latest articles on DEV Community by Tracy Holmes (@tracypholmes).</description>
    <link>https://dev.to/tracypholmes</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%2F9093%2Fa3a4b0b6-44f0-4bef-99c2-b171f974bbe2.jpeg</url>
      <title>DEV Community: Tracy Holmes</title>
      <link>https://dev.to/tracypholmes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tracypholmes"/>
    <language>en</language>
    <item>
      <title>GitOps Benefits and Considerations</title>
      <dc:creator>Tracy Holmes</dc:creator>
      <pubDate>Wed, 13 Apr 2022 21:41:53 +0000</pubDate>
      <link>https://dev.to/codefreshio/gitops-benefits-and-considerations-3je8</link>
      <guid>https://dev.to/codefreshio/gitops-benefits-and-considerations-3je8</guid>
      <description>&lt;p&gt;&lt;a href="https://codefresh.io/learn/gitops/" rel="noopener noreferrer"&gt;GitOps&lt;/a&gt;. The term appears everywhere, but what are its benefits? And is it as difficult as it sounds? Well, GitOps is a pretty easy paradigm to integrate with your current processes. However, my saying it is “easy” doesn’t help you decide whether you want to adopt it or not. So, let’s talk about it.&lt;/p&gt;

&lt;p&gt;This post will briefly discuss common software delivery challenges, DORA metrics and what they are, how GitOps can help with those metrics, and what to consider if you would like to adopt it.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Software Delivery Challenges&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most existing processes for infrastructure configuration management face challenges like failed deployments, poor infrastructure design, server outages, etc. Some common challenges are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;“Eventual Consistency” or lack of configuration consistency in your environment&lt;/strong&gt;. For example, how do you know if “System A” and “System B” match? The actual configuration and a declared one can alter and change when using manual processes, even when using a centralized configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No idea as to how or where an application is running&lt;/strong&gt;. Implicit infrastructure, its state, and configuration. This sometimes entails a full-scale investigation to determine the “how” and the “where.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failed deployments relying on a &lt;a href="https://containerjournal.com/topics/container-security/backup-and-dr-in-the-age-of-gitops/" rel="noopener noreferrer"&gt;disaster recovery&lt;/a&gt; strategy&lt;/strong&gt;. With manual or semi-manual processes, disaster recovery requires a strict process that teams are disciplined to tackle, which isn’t always reliable—resulting in unplanned downtime that takes away from developers’ skills and productivity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing documentation or unknown development history&lt;/strong&gt;. It can be challenging to figure out how some applications were built initially and who managed them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relying on a system’s previous state for success&lt;/strong&gt;. This can be unpredictable, which affects the stability and success of a project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or, to state these challenges in another way: inconsistent configurations can lead to failed deployments, leading to revenue loss. GitOps can help with all of these challenges. We are going to dive into GitOps more in a bit. But first, let’s talk about DORA metrics and why they matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;DevOps and DORA metrics&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DevOps is a collaboration paradigm, and sometimes it is mistaken for being too abstract or too generic. In an effort to quantify the benefits of adopting DevOps, Dora Research (acquired by Google in 2018) has introduced four key metrics that define specific goals for improving the software lifecycle in companies that are interested in DevOps.&lt;/p&gt;

&lt;p&gt;These four key metrics and their organizational effects have been published as part of the “&lt;a href="https://www.devops-research.com/research.html#reports" rel="noopener noreferrer"&gt;State of DevOps&lt;/a&gt;” reports since 2014. The reports include a survey (with more than 32,000 industry professionals in the last years) that categorize the organizations that responded. These categorizations or performance levels are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Elite performers (companies that have fully adopted DevOps and have exceptional results in the four metrics)&lt;/li&gt;
&lt;li&gt;High performers (companies with excellent results in the four metrics)&lt;/li&gt;
&lt;li&gt;Medium performers (companies with some positive results)&lt;/li&gt;
&lt;li&gt;Low performers (all other companies)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The researchers responsible for the survey apply these different categorizations by examining how teams develop, deliver, and operate software systems, and then segmenting respondents into four performance clusters: elite, high, medium, and low performers.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The 4 Key DevOps Metrics + 1&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The four metrics of software delivery performance are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deployment Frequency (DF) – How frequently a team successfully releases to production, e.g., daily, weekly, monthly, yearly.&lt;/li&gt;
&lt;li&gt;Lead Time for Changes (MLT) – The median amount of time for a commit to be deployed into production.&lt;/li&gt;
&lt;li&gt;Time to Restore Service(s) (MTTR) – How long it takes an organization to recover from a failure in production. For a failure, the median amount of time between the deployment that caused the failure and the remediation. The remediation is measured by closing an associated bug/incident report.&lt;/li&gt;
&lt;li&gt;Change Failure Rate (CR) – The number of failures per the number of deployments. For example, if there are four deployments in a day and one causes a failure, that is a 25% change failure rate.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F04%2F2021-State-of-DevOps-Software-delivery-performance-metric.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F04%2F2021-State-of-DevOps-Software-delivery-performance-metric.png" alt="https://codefresh.io/wp-content/uploads/2022/04/2021-State-of-DevOps-Software-delivery-perform![2021 State of DevOps – Software Delivery Performance Metric](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ugp3xx8kc88dtldhd63.png)&amp;lt;br&amp;gt;
 ance-metric.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2021 State of DevOps – Software Delivery Performance Metric&lt;/p&gt;

&lt;p&gt;Since 2018, a fifth metric around operational performance has also been included: reliability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reliability – the degree to which a team can keep promises and assertions about the software they operate. Reliability was chosen so that availability, latency, performance, and scalability are more broadly represented.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Companies’ DevOps teams ranked as elite or high-performing in these five categories tend to have outstanding performance around market share and profits.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is GitOps?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;What exactly is GitOps? If you are not familiar with GitOps, head over to &lt;a href="https://opengitops.dev/" rel="noopener noreferrer"&gt;https://opengitops.dev&lt;/a&gt;, which is the official page of the GitOps working group. In short, GitOps is a set of standards and best practices that can be applied to application configuration and delivery, all the way to infrastructure management. GitOps is not a tool but works by relying on a single source of truth (typically Git) for declarative applications and infrastructure. The principles of GitOps are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The system is described in a declarative manner.&lt;/li&gt;
&lt;li&gt;The definition of the system is versioned and audited. This tends to be Git though it is not limited to it.&lt;/li&gt;
&lt;li&gt;A software agent automatically pulls the Git state and matches the platform state.&lt;/li&gt;
&lt;li&gt;The state is continuously reconciled. This means that any changes in Git should also be reflected in the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will usually see GitOps paired with Kubernetes, though Kubernetes is not necessarily required. You can use GitOps to build pipelines, provision clusters, manage configurations, and much more.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why GitOps is beneficial for DORA metrics&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DORA metrics are great, especially when demonstrating critical areas for improvement to organizations. However, while organizations know about the metrics, it can be tough to have good performance numbers there. Adopting GitOps principles can help tackle these issues.&lt;/p&gt;

&lt;p&gt;For example, because GitOps adds a structure of repeatability to your organization’s different environments, you can reduce MTTR and the change failure rate. This is because you now have a declarative reference architecture in place of your entire system. You also eliminate delivery as the last step in your Continuous Integration (CI) pipeline because of synchronization. That synchronization also means because you use Git for your systems’ versioning, you can now ensure that your deployments match your desired state. All of this combined means your MTTR is significantly reduced from days or hours to just minutes.&lt;/p&gt;

&lt;p&gt;Also, you now have more frequent releases because you are using continuous deployment, which translates into increased speed and productivity. This increased speed and productivity translate into happier customers because of the potential for new features or functionality due to decreased turnaround time.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Know what is deployed where&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine having a magic wand that handles your deployments. GitOps can do that for you.Some CI tools follow an authoritative or ad-hoc approach and use things like custom kubectl scripts to deploy. The urge to change or edit something manually in environments is significant – it is perceived as quicker or easier. So, for example, you may have “cowboy deployments” or “cowboy engineering” where your DevOps team may be performing manual changes to the cluster. But when this happens, you have no idea what’s going on since those changes aren’t recorded anywhere, and the modifications can be pretty delicate.GitOps gets rid of those manual changes because whatever agent you’re using is in charge of the deployment. The deployment process or synchronization is a consolidation of whatever your current cluster state is to the desired state. The agent is also in charge of monitoring. Because of this, things are alike and in sync.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Faster deployments and rollbacks&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are times when you or a colleague may want to know, “What are the current deployment versions in environments A and B?” or “Is it possible to roll back to version XYZ?” When using a traditional CI/CD solution, these questions may be tough to answer because any number of ad-hoc patches, hotfixes, or other changes may have occurred since the initial deployment.&lt;/p&gt;

&lt;p&gt;However, using GitOps, things are a bit simpler. Your Git repository will be able to tell you what deployments are in the cluster because your commit history can pretty much work as your cluster deployment history. The state of your cluster should look very similar to your latest git commit.&lt;/p&gt;

&lt;p&gt;Rollbacks are also easier with GitOps. Things are more “hands-on” when working with traditional CI/CD. With conventional CI/CD, you have to research your deployment pipeline to find the correct version of what you need and then manually trigger it. With GitOps, this is not the case, as you only need to perform a reset in Git, and once things are synchronized, the cluster will reflect the necessary changes. Or, depending on what agent you are using, you could do something as simple as selecting the appropriate Git release and let the synchronization process handle the rest.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;No configuration drift&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Configuration drift is usually due to manual changes and updates across an organization’s environments. It is a problem that existed even with traditional Virtual Machines and has plagued production deployments long before Kubernetes appeared on the scene. The more environments you have and the longer your configuration drift is present, the more crucial things will become.&lt;/p&gt;

&lt;p&gt;Remember when I mentioned monitoring earlier? Well, even though your agent’s sync process is crucial for performing the initial deployment of your application, one of the true strengths is the continuous monitoring of both states (cluster and Git) after the deployment takes place. The reconciler takes care of eliminating configuration drift by staying true to ONLY to the Git state. This uni-directional reconciliation is vital for solving configuration drift which is a widespread issue in organizations with large numbers of deployment targets.&lt;/p&gt;

&lt;p&gt;If you would like to get an idea of how your team or organization’s software delivery performance compares to the rest of the industry, you can take the DORA “DevOps Quick Check” &lt;a href="https://www.devops-research.com/quickcheck.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Considerations for Adopting GitOps&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There are two things to consider when deciding whether or not to embrace GitOps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You need to have a CI in place already&lt;/li&gt;
&lt;li&gt;You need a GitOps Agent&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first one is simple. If you already have a CI solution in place, keep using what you have. So, let's tackle the second. &lt;/p&gt;

&lt;p&gt;If you need a GitOps agent, &lt;a href="https://codefresh.io/learn/argo-cd/" rel="noopener noreferrer"&gt;Argo CD&lt;/a&gt; is a great choice. Argo CD is a popular deployment solution for Kubernetes. When following a GitOps deployment pattern, Argo CD makes it easy to define a set of applications with their desired state in a repository and where the deployment should happen. After a deployment, Argo CD continuously monitors a Git repository with Kubernetes manifests and listens for commit events.&lt;/p&gt;

&lt;p&gt;When a commit happens (usually one that updates the versions of the image artifacts), Argo CD starts a “synchronization” process responsible for bringing the cluster configuration to the same state as described in Git.&lt;/p&gt;

&lt;p&gt;When the sync process is complete, we know that the application configuration is the same as the Git manifests.&lt;/p&gt;

&lt;p&gt;The Argo CD deployment process is the embodiment of the core ideas behind GitOps that we discussed at the beginning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All application configuration is stored in Git (usually in a separate repository than the source code)&lt;/li&gt;
&lt;li&gt;Deployments are happening in a “pull” manner where the cluster is fetching manifests from Git (instead of traditional solutions where updates are “pushed” to the cluster)&lt;/li&gt;
&lt;li&gt;A deployment is a  uni-directional reconciliation process between the two states (what is described in Git versus what is deployed in the cluster)&lt;/li&gt;
&lt;li&gt;Even though the sync process is vital for performing the initial deployment of the application, one of the true strengths of Argo CD is the continuous monitoring of both states (cluster and Git) after the deployment takes place. This continuous monitoring is essential for solving configuration drift – a common issue in organizations with a considerable number of deployment targets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To clarify: your CI will stay the same. Nothing is changing except GitOps making things simpler. You no longer have to do certain things manually. If you were using Git? Continue to use Git. If you were using Kubernetes? Continue using Kubernetes. GitOps is less painful than you may imagine, and you are not starting over from scratch. Things are now streamlined.&lt;/p&gt;

&lt;p&gt;You can learn how to get started with Argo CD &lt;a href="https://codefresh.io/argo-platform/getting-started-with-gitops-and-argo-cd/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and read about Argo CD best practices &lt;a href="https://codefresh.io/argo-platform/argo-cd-best-practices/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;I mentioned earlier that GitOps was not just for Kubernetes. And that’s true! Kubernetes isn’t a requirement. GitOps can absolutely integrate with other deployment pipelines or infrastructure, including containers and VMs.&lt;/p&gt;

&lt;p&gt;GitOps is also not just for applications. You can also use it with infrastructure toolings such as Terraform or Crossplane. If it is transactional, can be described declaratively, and Infrastructure-as-Code (IaC) tools are available, you can use GitOps in your environment.&lt;/p&gt;

&lt;p&gt;Hopefully, now that you’ve learned more about GitOps you can find ways to introduce this paradigm to your workflow, whether it’s containerizing your application or adding your configuration to your repository. By doing so, you’ll be in good company: CapitalOne, Intuit, Tesla, Red Hat, Google, Codefresh, and many others are using Argo and GitOps to eliminate challenges in their environments. And if you’d like to learn more about how Codefresh has embraced GitOps or get started on your GitOps journey, you can try out the free Community Edition &lt;a href="https://codefresh.io/product/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>gitops</category>
      <category>cicd</category>
      <category>argocd</category>
      <category>devops</category>
    </item>
    <item>
      <title>Terraform Mono Repo vs. Multi Repo: The Great Debate</title>
      <dc:creator>Tracy Holmes</dc:creator>
      <pubDate>Wed, 02 Mar 2022 13:19:00 +0000</pubDate>
      <link>https://dev.to/tracypholmes/terraform-mono-repo-vs-multi-repo-the-great-debate-1dkp</link>
      <guid>https://dev.to/tracypholmes/terraform-mono-repo-vs-multi-repo-the-great-debate-1dkp</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This was originally written 28 Jan 2021. I still experiment with Terraform quite a bit, so thought I would share. --TPH&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;A commonly asked question on HashiCorp forums, posts, blogs, and even at conferences or webinars is: Should my organization use a monolithic source repository (mono repo) or multiple source repositories (multi repo)? The short answer is this: It will depend on your organization and has everything to do with organizational patterns. This post will discuss the nuances of using each approach and when you should eventually break your mono repo into a multi repo.&lt;/p&gt;

&lt;p&gt;For the purposes of this blog post, a mono repo keeps many Terraform configurations as separate directories in a single repository. By comparison, a multi repo approach organizes each Terraform configuration in a separate repository. What happens when you run &lt;code&gt;terraform init&lt;/code&gt;? It uses &lt;a href="https://github.com/hashicorp/go-getter" rel="noopener noreferrer"&gt;go-getter&lt;/a&gt; to download all needed modules and, in essence, behaves like a mono repo. While Terraform supports the local referencing of modules, it handles the sourcing of remote modules, which lends well to a multi repo structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monolithic Source Repositories (Mono Repos)
&lt;/h2&gt;

&lt;p&gt;When we refer to mono repos, do we include application code and its infrastructure? In this blog, we focus on a mono repo for infrastructure components, such as networking, compute, or software as a service (SaaS) resources.&lt;/p&gt;

&lt;p&gt;Mono repos work if you have a personal project or a smaller team, and you need visibility into all of the infrastructure you're creating and uniform access to your configurations. What kind of mono repo structure will help you get the most out of your collaboration efforts and infrastructure as code? In a mono repo, divide your modules into a separate folder with the smallest grouping of resources and their dependencies. For example, you create individual module folders for AWS lambda (&lt;code&gt;function&lt;/code&gt;), queue, and virtual network (&lt;code&gt;vpc&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;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tree my-company-functions
└── modules
    ├── &lt;span class="k"&gt;function&lt;/span&gt;
    │   ├── main.tf      // contains aws_iam_role, aws_lambda_function
    │   ├── outputs.tf
    │   └── variables.tf
    ├── queue
    │   ├── main.tf      // contains aws_sqs_queue
    │   ├── outputs.tf
    │   └── variables.tf
    └── vpc
        ├── main.tf      // contains aws_vpc, aws_subnet
        ├── outputs.tf
        └── variables.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To version modules, you can copy the module folder and append a version number to it. Otherwise, you might need to use some complex repository tagging to achieve versioning.&lt;/p&gt;

&lt;p&gt;Then, separate environment configurations into individual folders per business domain, product, or team. The following example represents two business domains, one related to collecting document metadata and the other translating them, and two environments, production and staging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tree my-company-functions
├── modules
├── production
│   ├── document-metadata
│   │   └── main.tf
│   └── document-translate
│       └── main.tf
└── staging
    ├── document-metadata
    │   └── main.tf
    └── document-translate
        └── main.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configurations for production and staging reference the &lt;code&gt;modules&lt;/code&gt; directory to create the function, queue, and network. This can be per business domain, product, or team. Some examples of dividing by business domain or team could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure team&lt;/li&gt;
&lt;li&gt;Shared services team (CI team)&lt;/li&gt;
&lt;li&gt;Application / product team&lt;/li&gt;
&lt;li&gt;Security team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To apply changes to configuration, you must develop a continuous integration pipeline to reference differences in each subdirectory, change directories, and apply changes in each directory individually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A mono repo becomes a single source of truth to get all infrastructure configuration.&lt;/li&gt;
&lt;li&gt;It consolidates infrastructure configuration for testing and debugging, which can be important for database testing, queues, event streaming, or data pipelines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When you update modules over time, module maintenance overhead increases. Module and provider versioning and dependencies can be fairly confusing to debug in this paradigm. As a best practice, you should &lt;a href="https://www.terraform.io/docs/language/modules/develop/providers.html" rel="noopener noreferrer"&gt;pin provider versions&lt;/a&gt; in each module. However, separating and versioning modules by subdirectory can make it difficult to debug which provider versions are used in each module.&lt;/li&gt;
&lt;li&gt;In addition, your build system cannot scale as you create more subdirectories and environments. When you apply changes through a pipeline, you need to go into every folder and check for changes. Many CI frameworks use changesets to evaluate differences, which can increase your pipeline runtime.&lt;/li&gt;
&lt;li&gt;Access control is applied to the entire mono repo by default. In some circumstances, you might only want a user or group to access specific subdirectories. For example, you may not want all team members to have access to change users and groups. This might be something that has to be approved first by an operations team in a &lt;code&gt;CODEOWNERS&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you find yourself spending more time maintaining your build system logic to accommodate your infrastructure mono repo, you may want to break down your mono repo into multiple repositories.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple Source Repositories (Multi Repos)
&lt;/h2&gt;

&lt;p&gt;A multi repo can better support granular access control and configuration changes. If you have a large team that collaborates on a complex infrastructure system, multiple source repositories allow you to localize changes and lessen the blast radius of failed infrastructure updates across the system. You can scope changes to the teams responsible for the infrastructure.&lt;/p&gt;

&lt;p&gt;There are many approaches to organization your multi repo. For example, you can divide each module into its own repository. In the case of the serverless function, queue, and network, you would create individual repositories for AWS lambda (&lt;code&gt;function&lt;/code&gt;), queue, and virtual network (&lt;code&gt;network&lt;/code&gt;). Individual business units or products would reference these remote modules. Environments would be captured by subdirectories in each product or business repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4x6k2ib6v8fa9s52tij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4x6k2ib6v8fa9s52tij.png" alt="https://www.datocms-assets.com/2885/1611862219-mono-multi-terraform-repo.png?fit=max&amp;amp;fm=png&amp;amp;q=80" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use release tagging to handle the versioning of modules. By separating the modules into their own source repositories, you can test them independently, allow dependent configurations to reference the module version, and update the provider version with the module version.&lt;/p&gt;

&lt;p&gt;You can further structure your multi repo with separate repositories for each business domain, product, or team. Use subdirectories within these repositories to separate environments, which offers visibility into configuration differences between environments. Since you use a repository for each business domain or product, continuous integration pipelines have fewer subdirectories to recursively check for changes. You can optimize your pipelines for each configuration or module.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Multi repos enable teams to self-service and compose based on shared building blocks.&lt;/li&gt;
&lt;li&gt;Independent repositories allow isolated testing for module security &amp;amp; functionality.&lt;/li&gt;
&lt;li&gt;You can apply module versioning using release tagging and existing tag constructs.&lt;/li&gt;
&lt;li&gt;Individual repositories allow for access control of modules and configurations.&lt;/li&gt;
&lt;li&gt;Scoping changes to a specific repository can minimize the blast radius of changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If you have a configuration that references many remote modules, Terraform will take time to download them. Try using git submodules to clone the remote repository and store it locally based on commit.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;There is no right or wrong answer when discussing the use of mono repos and multi repos. By taking a step back and observing different organizational patterns, we can determine which environment structure works best for us.&lt;/p&gt;

&lt;p&gt;For more information on separating configurations for environments, take a look at the &lt;a href="https://www.terraform.io/docs/cloud/guides/recommended-practices/index.html" rel="noopener noreferrer"&gt;Terraform Recommended Practices&lt;/a&gt; documentation. best practices for code for Terraform Cloud workspaces, review our documentation on &lt;a href="https://www.terraform.io/docs/cloud/workspaces/configurations.html#code-organization-and-repository-structure" rel="noopener noreferrer"&gt;code organization and workspace structure&lt;/a&gt;. To restructure your Terraform for production, review our blog on &lt;a href="https://www.hashicorp.com/blog/structuring-hashicorp-terraform-configuration-for-production" rel="noopener noreferrer"&gt;refactoring configuration&lt;/a&gt;. For best practices and pitfalls in a large Terraform mono repo, check out lessons learned from &lt;a href="https://www.hashicorp.com/resources/closing-keynote-terraform-at-google" rel="noopener noreferrer"&gt;Terraform at Google&lt;/a&gt;. To try a hands-on example of breaking up a mono repo into separate dev and prod environments with a module shared between them, follow the Learn tutorial, &lt;a href="https://learn.hashicorp.com/tutorials/terraform/organize-configuration?in=terraform/modules" rel="noopener noreferrer"&gt;Separate Development and Production Environments&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>Getting Started with GitOps and Argo CD</title>
      <dc:creator>Tracy Holmes</dc:creator>
      <pubDate>Thu, 24 Feb 2022 01:15:42 +0000</pubDate>
      <link>https://dev.to/codefreshio/getting-started-with-gitops-and-argo-cd-1j2f</link>
      <guid>https://dev.to/codefreshio/getting-started-with-gitops-and-argo-cd-1j2f</guid>
      <description>&lt;p&gt;Today we are going to explore getting started using Argo CD. This post is going to assume you know a bit about containers, and that you already have an empty cluster in place (or know how to create one). If any of this is unfamiliar, head over to &lt;a href="https://argo-cd.readthedocs.io/en/stable/understand_the_basics/" rel="noopener noreferrer"&gt;Understanding the Basics&lt;/a&gt; to get a bit of practice. Before we get started, let’s talk about GitOps.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is GitOps?
&lt;/h2&gt;

&lt;p&gt;If you are not familiar with GitOps, head over to &lt;a href="https://opengitops.dev/" rel="noopener noreferrer"&gt;https://opengitops.dev&lt;/a&gt; which is the official page of the GitOps working group. In short, GitOps is a paradigm that incorporates best practices applied to the application development workflow all the way to the operating infrastructure of a system. The principles of GitOps are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The system is described in a declarative manner.&lt;/li&gt;
&lt;li&gt;The definition of the system is versioned and audited. This tends to be Git.&lt;/li&gt;
&lt;li&gt;A software agent automatically pulls the Git state and matches the platform state.&lt;/li&gt;
&lt;li&gt;The state is continuously reconciled. This means that any changes happening in Git should also be reflected in the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A GitOps tool that follows this approach of a Git-based workflow is Argo CD. It’s a continuous delivery tool for Kubernetes that is essentially a GitOps controller that does two-way synchronization. Argo continuously monitors running applications, compares the live state against the desired state in Git, and applies it to the cluster. Please note this monitoring is for both directions: Git &amp;gt; cluster AND cluster &amp;gt; Git!&lt;/p&gt;

&lt;p&gt;GitOps relies on Git as the single source of truth for declarative configuration and active reconciliation. What does this mean?&lt;/p&gt;

&lt;p&gt;This means Argo CD implements active reconciliation by automatically monitoring your cluster and detecting any manual changes that are not in the Git state. Adopting the GitOps methodology provides transparency between the application configuration deployed in a cluster and the one residing in Git.&lt;/p&gt;

&lt;p&gt;Additionally, some benefits of GitOps are deploying faster and more often, easier and quicker error handling and recovery, and self-documenting deployments. And most importantly? You also get the complete elimination of configuration drift. These benefits make it easier to handle the applications and allow teams to deliver quality software faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;For this exercise, you can absolutely use a local cluster such as Docker Desktop, minikube, k3s, etc. And if you have access to a cloud cluster? That’s even better.&lt;/p&gt;

&lt;p&gt;However, if you don’t have access to those things, let's make sure we have &lt;a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/" rel="noopener noreferrer"&gt;kubectl&lt;/a&gt; installed. &lt;code&gt;kubectl&lt;/code&gt; is a Kubernetes command-line tool that allows you to run commands against Kubernetes clusters.&lt;/p&gt;

&lt;p&gt;We also need a &lt;code&gt;kubeconfig&lt;/code&gt; file. If you already have an empty cluster, then that part of things has most likely already been done for you! In case you want to check, the default location for the config file is &lt;code&gt;~/.kube/config&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Argo CD
&lt;/h2&gt;

&lt;p&gt;Let’s start off by installing Argo CD. To do this, we’ll first create a new namespace, &lt;code&gt;argocd&lt;/code&gt;, where Argo CD services and application resources will live.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create namespace argocd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s apply our resource configuration file on the &lt;code&gt;argocd&lt;/code&gt; namespace we just created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your installation completes, you can use the watch command to check the status of your Kubernetes pods and make sure they are ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;watch kubectl get pods -n argocd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we are using a stock Argo CD installation, you should see five pods with a &lt;code&gt;Running&lt;/code&gt; status.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                                  READY   STATUS    RESTARTS   AGE
argocd-redis-d486999b7-cd275          1/1     Running   0          8m57s
argocd-dex-server-65bf5f4fc7-p6kv8    1/1     Running   0          8m57s
argocd-repo-server-8465d84869-z4mqb   1/1     Running   0          8m57s
argocd-application-controller-0       1/1     Running   0          8m56s
argocd-server-87b47d787-pbnw8         1/1     Running   0          8m57s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once things are up and running, you can use &lt;code&gt;Ctrl+C&lt;/code&gt; to exit the watch interface. This is only one of the possible ways to install Argo CD! You are also able to use a &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/helm/" rel="noopener noreferrer"&gt;Helm chart&lt;/a&gt; or a smart installer like &lt;a href="https://argocd-autopilot.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Argo Autopilot&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access The Argo CD API Server
&lt;/h2&gt;

&lt;p&gt;By default, the Argo CD API server is not exposed with an external IP. For the purposes of this post, we are going to utilize kubectl port-forwarding to connect to the API server without actually exposing the service. We do that using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl port-forward svc/argocd-server -n argocd 8080:443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make things easier for us as we can now access the API server using &lt;code&gt;localhost:8080&lt;/code&gt;. &lt;strong&gt;Note&lt;/strong&gt;: this method is only for local development or demonstration purposes.&lt;/p&gt;

&lt;p&gt;There are two other techniques you can use to access the API server: Service Type Load Balancer and Ingress. If you’d like to learn more about those methods, definitely check out the &lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/" rel="noopener noreferrer"&gt;Getting Started&lt;/a&gt; guide for more information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download Argo CD CLI
&lt;/h2&gt;

&lt;p&gt;Now that we’ve gotten Argo CD downloaded, installed, and configured for access, it is time to login. There are two ways we can get this done: via the UI (or web interface) and the CLI. The UI and the CLI are mostly similar in capabilities. The CLI is great for changing settings and working with your Argo CD instance. Also, while you can deploy an application using the web interface, it’s typically quicker to deploy via the command line. I tend to use both depending on what I need. We will use both throughout this post.&lt;/p&gt;

&lt;p&gt;I also work across different operating systems, so &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt; is usually my goto installation method as it is available for Linux, Mac, and WSL. To install Argo CD using Homebrew, you will use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install argocd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and check that it has installed correctly using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;argocd version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also download the latest Argo CD version from &lt;a href="https://github.com/argoproj/argo-cd/releases/latest" rel="noopener noreferrer"&gt;https://github.com/argoproj/argo-cd/releases/latest&lt;/a&gt;. If you run into any issues, more detailed installation instructions can be found via the &lt;a href="https://argo-cd.readthedocs.io/en/stable/cli_installation/" rel="noopener noreferrer"&gt;CLI installation documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Login Using The CLI
&lt;/h2&gt;

&lt;p&gt;We are going to login using an admin account. The initial password for this account is auto-generated and stored in your namespace as clear text in the field password and in a secret named &lt;code&gt;argocd-initial-admin-secret&lt;/code&gt;. Let’s retrieve this password using &lt;code&gt;kubectl&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;kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d &amp;amp;&amp;amp; echo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ve added &lt;code&gt;&amp;amp;&amp;amp; echo&lt;/code&gt; to the end of that command to make it easier for us to copy &amp;amp; paste the generated password. Make sure to save it, as we will need it in the next steps.&lt;/p&gt;

&lt;p&gt;Now that we have that password, we can login! So, let’s do that using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;argocd login &amp;lt;ARGOCD_SERVER&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will substitute Argo CD’s IP or hostname where you see &lt;code&gt;&amp;lt;ARGOCD_SERVER&amp;gt;&lt;/code&gt; in that command. Remember when we set up port forwarding for easy access earlier in this post? Now it will come in handy!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;argocd login localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will prompt you for a username and password. The default username is &lt;code&gt;admin&lt;/code&gt;, and the password is the one we exposed up above. You will not see the password while entering it.&lt;/p&gt;

&lt;p&gt;We also want to change the password while we’re here as the generated one was in cleartext, and that’s not safe. The following command will ask you for your current password, the new password you’d like to use, and lastly, to confirm the new password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;argocd account update-password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you do so, make sure to place your new password somewhere safe, as you will need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create An Application From A Git Repository
&lt;/h2&gt;

&lt;p&gt;In order for us to create an application to demonstrate how Argo CD works, we are going to use an example repository containing a guestbook application. If you would like to check it out or follow along, it is available at &lt;a href="https://github.com/argoproj/argocd-example-apps.git" rel="noopener noreferrer"&gt;https://github.com/argoproj/argocd-example-apps.git&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Remember how I said earlier there are two ways we can get things done? You can definitely use one or the other (or both!) according to personal preference. I am a big fan of using the UI when first learning something in order to get a better idea of things I can do. So let’s start there to create our app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating Apps Via UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open a browser to the Argo CD external UI by visiting &lt;code&gt;localhost:8080&lt;/code&gt;, and login using the admin credentials we set up earlier. Your login page should look similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo1.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo1.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After logging in, click the “+ New App” button as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo2.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo2.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give your app the name &lt;code&gt;guestbook&lt;/code&gt;, use the project &lt;code&gt;default&lt;/code&gt;, and leave the sync policy as &lt;code&gt;Manual&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo3.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo3.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect the &lt;a href="https://github.com/argoproj/argocd-example-apps.git" rel="noopener noreferrer"&gt;https://github.com/argoproj/argocd-example-apps.git&lt;/a&gt; repo to Argo CD by setting repository URL to the GitHub repo URL, leave revision as &lt;code&gt;HEAD&lt;/code&gt;, and set the path to &lt;code&gt;guestbook&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo4.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo4.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;Destination&lt;/strong&gt;, set cluster to &lt;code&gt;in-cluster&lt;/code&gt; and namespace to &lt;code&gt;default&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo5.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo5.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We use &lt;code&gt;in-cluster&lt;/code&gt; because when deploying internally (i.e. to the same cluster that Argo CD is running in), the &lt;code&gt;https://kubernetes.default.svc&lt;/code&gt; hostname should be used as the application's Kubernetes API server address.&lt;/p&gt;

&lt;p&gt;After filling out the information above, click &lt;strong&gt;Create&lt;/strong&gt; at the top of the UI to create the guestbook application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo6.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo6.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating Apps Via CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To create that same app using the CLI, you would use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I do use the CLI, I still like to double-check myself using the UI occasionally. Do whichever is comfortable for you!&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Sync (Deploy) The Application
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Syncing via UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the guestbook application is created, you can now view its status:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo7.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo7.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the application status is &lt;code&gt;OutOfSync&lt;/code&gt;! &lt;code&gt;OutOfSync&lt;/code&gt; means the git state is different from the cluster state. You can see this information in multiple ways while in the UI. When the state is not in sync, you can usually tell as it is in a helpful yellow color. You can also filter by status on the left side of the dashboard. I highly recommend poking around the dashboard to see which configuration works for you!&lt;/p&gt;

&lt;p&gt;That said, the application status is initially in &lt;code&gt;OutOfSync&lt;/code&gt; state since the application has yet to be deployed. Also, no Kubernetes resources have been created. To sync (deploy) the application, we’ll use the “Sync” button.&lt;/p&gt;

&lt;p&gt;This will bring up a second set of options. Select “Synchronize”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo8.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo8.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Synchronizing is how we deploy the application. When we “Sync” or “Synchronize”, it means we are updating the cluster state to match the Git state. This is one of the most important tenets of GitOps.&lt;/p&gt;

&lt;p&gt;Once things are complete and you return to the dashboard, you will see the guestbook app is now running. Select the app and see what information you can find!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo9.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo9.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo10.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo10.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click on the application name, you will see a hierarchical view of all the Kubernetes resources that take part in the application. You will also see additional details related to the health and synchronization status.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syncing via CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course, everything we have done via the UI, can be done via CLI. Since we created the guestbook application, you can now check the status of your application using &lt;code&gt;argocd app get&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;argocd app get guestbook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name:               guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://localhost:8080/applications/guestbook
Repo:               https://github.com/howmybrainworks/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        &amp;lt;none&amp;gt;
Sync Status:        OutOfSync from  (13b08f1)
Health Status:      Missing

GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH   HOOK  MESSAGE
       Service     default    guestbook-ui  OutOfSync  Missing
apps   Deployment  default    guestbook-ui  OutOfSync  Missing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you look at the “Sync Status” you will see the application status is initially in &lt;code&gt;OutOfSync&lt;/code&gt; state since the application has yet to be deployed, and no Kubernetes resources have been created. To sync (deploy) the application, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;argocd app sync guestbook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Modifying and redeploying the Application&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here is where I feel Argo CD really shines. Now that we have a healthy system, let's initiate a change. Let’s scale the deployment by modifying the replicas in the &lt;code&gt;deployment.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;deployment.yaml&lt;/code&gt; file, increase the number of replicas from 1 to 2. Since we are following &lt;a href="https://codefresh.io/gitops/" rel="noopener noreferrer"&gt;GitOps&lt;/a&gt;, we want our modification to be declarative. So, we are going to commit and submit this change via Git. This will show things &lt;code&gt;OutOfSync&lt;/code&gt; as well as identify configuration drift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resyncing (redeploying) via UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you go back to the UI, you should now see that we are now once again &lt;code&gt;OutOfSync&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo11.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo11.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I sincerely love this feature, because not only does Argo CD let us know the application is no longer in sync, it also gives you a nice “App Diff” view to give more detail about what was changed! Click on the application name again, and you will see this option at the top of the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo12.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo12.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the default “Diff” view can potentially contain an enormous amount of information, so I like to select the “Compact Diff” option in order to immediately see any changes. As you can see, we increased our replicas from 1 &amp;gt; 2.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo13.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo13.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow the same steps to deploy an application by using the “Sync” button, and we should be back to a healthy app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2022%2F02%2FArgo14.png" alt="https://codefresh.io/wp-content/uploads/2022/02/Argo14.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resyncing (redeploying) via CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's initiate another change. Let’s scale the deployment by modifying the number of replicas using &lt;code&gt;kubectl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;kubectl&lt;/code&gt;, decrease the number of replicas from 2 to 1. You’ll do this using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl scale --current-replicas=2 --replicas=1 deployment/guestbook-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the same steps as above to retrieve our application status using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;argocd app get guestbook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name:               guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://localhost:8080/applications/guestbook
Repo:               https://github.com/howmybrainworks/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        &amp;lt;none&amp;gt;
Sync Status:        OutOfSync from  (13b08f1)
Health Status:      Healthy

GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH   HOOK  MESSAGE
       Service     default    guestbook-ui  Synced     Healthy        service/guestbook-ui created
apps   Deployment  default    guestbook-ui  OutOfSync  Healthy        deployment.apps/guestbook-ui created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you check your output, you will again see we are &lt;code&gt;OutOfSync&lt;/code&gt;. In order to see what’s changed, you’ll  use &lt;code&gt;argocd app diff&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;argocd app diff guestbook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;===== apps/Deployment default/guestbook-ui ======
109c109
&amp;lt;   replicas: 1
--
&amp;gt;   replicas: 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the sync command once again to deploy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;argocd app sync guestbook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything should be back healthy and in order!&lt;/p&gt;

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

&lt;p&gt;As you can see, adopting GitOps is beneficial in many ways! Among other things, you gain faster and more frequent deployments, the ability to avoid configuration drift, and easier error handling. This is shown especially when coupled with Argo CD as it can help leverage your deployment process by performing commits automatically and can also execute rollbacks if there are any issues.&lt;/p&gt;

&lt;p&gt;Argo CD is great by itself, but it is even better when connected to other &lt;a href="https://argoproj.github.io/" rel="noopener noreferrer"&gt;Argo projects&lt;/a&gt; such as Argo Workflows, Rollouts, or Events. Combined with any of these, you can elevate your continuous deployment process.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>devops</category>
      <category>opensource</category>
      <category>gitops</category>
    </item>
  </channel>
</rss>
