<?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>Forem: Hannah</title>
    <description>The latest articles on Forem by Hannah (@hseligson).</description>
    <link>https://forem.com/hseligson</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%2F653868%2F74c2d244-5332-450e-bb4a-cc1f20bd6ad9.png</url>
      <title>Forem: Hannah</title>
      <link>https://forem.com/hseligson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hseligson"/>
    <language>en</language>
    <item>
      <title>Deploying Microservices with GitOps</title>
      <dc:creator>Hannah</dc:creator>
      <pubDate>Thu, 28 Apr 2022 20:50:52 +0000</pubDate>
      <link>https://forem.com/codefreshio/deploying-microservices-with-gitops-3ln8</link>
      <guid>https://forem.com/codefreshio/deploying-microservices-with-gitops-3ln8</guid>
      <description>&lt;p&gt;&lt;a id="post-22229-_fklv3mbvlb17"&gt;&lt;/a&gt; Learn how to adopt GitOps for your microservices deployments.&lt;/p&gt;

&lt;p&gt;This blog post will explain the highlights listed below and how it's possible to adopt GitOps and the benefits of deploying with Argo for your microservices.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;What are microservices?&lt;/li&gt;
    &lt;li&gt;What are some of the challenges with microservices?&lt;/li&gt;
    &lt;li&gt;What is GitOps?&lt;/li&gt;
    &lt;li&gt;What is Argo CD?&lt;/li&gt;
    &lt;li&gt;How can GitOps and Argo CD help your deployments for your microservices?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
&lt;a id="post-22229-_j6miu69v4mbk"&gt;&lt;/a&gt;Microservices&lt;/h3&gt;

&lt;p&gt;Microservices are a software architecture pattern for building scalable distributed applications. It's essentially a framework that helps break down monolithic architectures into small independent services that can communicate over common patterns like APIs, event-driven, or even messages. An organization might do this because monolithic architectures are tightly coupled and run as a single service. So, if a particular process of your application with a monolithic architecture experiences a spike in demand, this affects your entire architecture and must be scaled.&lt;/p&gt;

&lt;p&gt;It's also important to note that any features or experiments made to this type of application become more complex and therefore can experience more issues and failures.&lt;/p&gt;

&lt;p&gt;Breaking down a monolithic application with API services allows you to build and version each function of an application independently. Because of this, microservices enable an organization to run, modify, deploy and scale each service for an application much more quickly.&lt;/p&gt;

&lt;p&gt;(include visual of monolithic architecture vs. microservice)&lt;/p&gt;

&lt;h3&gt;
&lt;a id="post-22229-_jcj0n5hgdsz2"&gt;&lt;/a&gt;Challenges of Microservices&lt;/h3&gt;

&lt;p&gt;Microservices provide several benefits for organizations by enabling autonomy amongst development teams, allowing applications to scale, deploying those applications efficiently, and increasing flexibility and resilience for those applications. However, microservices include challenges that we will dive into and explain.&lt;/p&gt;

&lt;p&gt;Those challenges are:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;The exploding number of pipelines.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As the number of applications increases, the management of such pipelines becomes more complex. Often this can result in messy scripts and needing to leverage configuration management tools. With all of that comes maintenance, and operators spend a lot of time fixing pipelines. We have a &lt;a href="https://codefresh.io/continuous-deployment/ci-cd-pipelines-microservices/"&gt;blog post&lt;/a&gt; that dives deeper into this issue if you'd like to learn more.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Difficulty managing deployments (all at once, in sequence, and with dependencies).&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While deploying a single microservice is more manageable than deploying a monolithic legacy application, there are still challenges. Suddenly, only a few pipelines for a monolithic application have turned into 20 or more pipelines with multiple microservices. These numbers will vary based on your organization, but it's no doubt that now managing multiple microservice repositories and pipelines is more complicated as more and more are created.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Difficult to monitor.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that there are multiple pipelines and multiple applications with an increase in deployments, those deployments and pipelines need to be monitored for any issues. Previously when using a monolithic architecture, these things could be monitored manually. However, the increased complexity of a distributed system can lead to chances of failure.&lt;/p&gt;

&lt;p&gt;This is why it’s so important to ensure you’re monitoring for total failures, network failures, cascading failures caused by remote procedure calls between your microservices, and even ensuring that you’re honoring your SLAs (service level agreements). With a microservice architecture, we need to keep in mind that services can even be temporarily unavailable due to broken releases, configurations, and any changes due to human error. Clients of services should be architected in a resilient way so they do not suffer catastrophic failure when a service is down.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Difficult to debug (when things go wrong).&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This topic itself could be a blog post. However, some of the critical challenges when debugging a microservice is fragmentation and ensuring that you create the same environment where the bug was identified. This means you need to ensure an identical setup to production, this may include specific cluster versions, serverless functions, the correct environment where the bug was reported, etc. In addition to the asynchronous call complications, the technicalities of running the microservice locally, and the cost it can take to execute all of these things in what you hope is a timely execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2022/04/word-image-1.png" rel="noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QUCdUqRX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/04/word-image-1-1024x891.png" alt="Monolithic vs Microservices" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even with the above example of the complexity that microservices can create when transitioning from a monolithic architecture to a microservice architecture, the benefits of moving to microservices can’t be understated. To gain the full benefits of microservices in scaling, reliability, and security we need to address these challenges head-on&lt;/p&gt;

&lt;p&gt;So, what could help you with some of the challenges organizations face when managing, monitoring, deploying, and maintaining their microservices? Let me introduce you to GitOps, how you can apply it to your microservices, and how it might help!&lt;/p&gt;

&lt;h3&gt;
&lt;a id="post-22229-_y4bb54vbtqko"&gt;&lt;/a&gt;GitOps&lt;/h3&gt;

&lt;p&gt;Before we dive into microservices and explain what they are and what sort of challenges they create for us. First, let's dive into what &lt;a href="https://codefresh.io/learn/gitops/" rel="noopener"&gt;GitOps&lt;/a&gt; is so you can begin to percolate your thoughts as to WHY this might be helpful for your microservices as we explain them.&lt;/p&gt;

&lt;p&gt;Perhaps you're familiar with Git and use it already for your source control and recognize how it enables a source of truth for your source code, but what if we expanded on that idea and applied it to our entire system? This is where GitOps comes into play.&lt;/p&gt;

&lt;p&gt;GitOps is a paradigm that leverages a Git repository as the source of truth to manage continuous deployments and infrastructure management as code. This allows you to drive automation, bring repeatability, reduce downtime and eliminate human interventions in constant release cycles.&lt;/p&gt;

&lt;p&gt;Now that we better understand GitOps let's explore a potential solution for deploying your microservices with GitOps that can be enabled by using Argo CD.&lt;/p&gt;

&lt;h3&gt;
&lt;a id="post-22229-_6yto5ouqmeap"&gt;&lt;/a&gt;Argo CD&lt;/h3&gt;

&lt;p&gt;When determining the best deployment process and tools for GitOps, &lt;a href="https://codefresh.io/learn/argo-cd/" rel="noopener"&gt;Argo CD&lt;/a&gt; is a great solution. Argo CD is a declarative CD (Continuous Delivery) tool that automatically synchronizes and deploys your applications whenever a change is made to your Git repository. This is why it’s one of the leading GitOps solutions.&lt;/p&gt;

&lt;p&gt;It allows you to manage the lifecycle of your application and deployments while also providing version control, configuration management, and application definitions with a Kubernetes manifest. This allows you to organize your environments and complex infrastructure data with more ease.&lt;/p&gt;

&lt;p&gt;Within this post, we will highlight ways that you can use Argo CD to deploy your microservices while applying GitOps to your workflow.&lt;/p&gt;

&lt;h3&gt;
&lt;a id="post-22229-_nhe8sc9avj9"&gt;&lt;/a&gt;How GitOps and Argo can help&lt;/h3&gt;

&lt;p&gt;When trying to determine the best strategy to manage your Kubernetes applications, an increasingly popular approach is GitOps. Argo CD makes GitOps practical for you to use because Argo CD is a Kubernetes-native declarative continuous delivery tool that follows GitOps principles. Argo CD also enables you to accelerate the frequency of your application deployments and lifecycle management by maintaining your configurations and ensuring they’re in sync, applying your desired state directly from Git.&lt;/p&gt;

&lt;p&gt;Essentially, Argo CD helps support your deployments while effectively providing several other benefits for your microservices which we’ll explain more below!&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;No more deployment pipelines -&amp;gt; Argo CD deploys them from Git&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Previously we mentioned the explosion of pipelines when converting from a monolithic architecture to a microservice architecture. However, by leveraging Argo CD it can reduce the number of pipelines by simply eliminating them. This is because you can use Argo to deploy your microservice you rely on your Git repository instead of using a pipeline. When you add an Argo CD &lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#applications" rel="noopener"&gt;Application&lt;/a&gt; and an &lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#projects" rel="noopener"&gt;AppProject&lt;/a&gt;, your app's configuration settings can be defined using the Application Custom Resource (CRD) that your Kubernetes resource object represents.&lt;/p&gt;

&lt;p&gt;Argo CD fully automates the deployment of an application by recognizing your configuration details from your manifest files and synchronizes any changes made to your system within your targeted namespace. Argo CD allows you to eliminate the use of a deployment pipeline.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Reduce files -&amp;gt; use an ApplicationSet&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While microservices do make it easier to deploy more frequently, there’s also the increase in files for your configurations. Even when a service is deployed and managed using GitOps, this doesn’t reduce the number of files, such as your Kubernetes manifests, your services, secrets, and configmaps, all stored within your Git repository.&lt;/p&gt;

&lt;p&gt;Luckily, Argo CD offers a controller known as an &lt;a href="https://argocd-applicationset.readthedocs.io/en/stable/" rel="noopener"&gt;ApplicationSet&lt;/a&gt; to help us manage our deployments and files easier. The ApplicationSet allows you to create multiple Argo CD Applications and organize your microservices per Application. The controller also allows you to use a single manifest to target numerous clusters and a single manifest to deploy multiple applications, not just from one repository but multiple!&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Always know their health -&amp;gt; Argo CD health&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whenever you make any change to your microservices or your system there’s a risk of a potential failure. For example, if you make a change and apply it to your manifest YAML file, Kubernetes does not wait until the resource reports back its status, nor do your automation tools typically report back, either. Instead, Kubernetes will apply the manifest and move on to the following manifest without waiting to know if the first one succeeded and was created or not. Something that can help alert you and provide observability for the state of your service is the Argo CD &lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/health/#resource-health" rel="noopener"&gt;health status&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Argo CD offers a built-in health assessment that provides an overall Application health status for you. Argo CD checks the health for the following resources: services, ingress, deployment, replicaset, statefulset, daemonset, and a persistentvolumeclaim. You can also add custom health checks for custom resources or any persistent known issues affecting your Ingress or StatefulState. These custom health checks can be done two ways: within a ConfigMap or with a script and implemented with a YAML file. If you cannot find a health check for your resource, you can create one yourself for whatever use case you need it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2022/04/word-image-2.png" rel="noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ETQTfXRA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/04/word-image-2.png" alt="" width="206" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Above is an example of the Argo CD Application health status within the Argo CD Web UI. Since Git is our source of truth, this sort of observability and information about your service provides that source of truth for the actual state of your running system.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Deployment cadence -&amp;gt; Argo CD sync phases/waves&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Typically when managing several microservices and making frequent deployments, it can be a challenge when needing to deploy a specific service in a particular order or, let's say, you want to deploy a service with a database, apart from deployment files. It would help if you had some solution for this. Whatever your use case may be, Argo CD provides a solution for this!&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/sync-waves/#how-do-i-configure-waves" rel="noopener"&gt;Syncwave&lt;/a&gt; allows you to order how Argo CD applies the manifest files stored in your Git repository. By default, all manifests have a wave of zero, but you can set these by using an argocd.argoproj.io/sync-wave annotation.&lt;/p&gt;

&lt;p&gt;For example, if you wanted to specify a wave, it would look something like this:&lt;/p&gt;

&lt;pre&gt;metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "5"&lt;/pre&gt;

&lt;p&gt;When Argo CD starts a sync action, the manifest gets placed in the following order of their Phase.&lt;/p&gt;

&lt;p&gt;When you apply the manifest in a &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/sync-waves/#how-do-i-configure-phases" rel="noopener"&gt;Phase&lt;/a&gt;, you're using a resource hook to control the sync operation. Those operations are defined by the three primary phases known as the pre-sync, sync, and post-sync phases. To enable a sync, annotate the specific object manifest with argocd.argoproj.io/hook with the type of sync you want to use for that resource.&lt;/p&gt;

&lt;p&gt;For example, if you wanted to use the PostSync hook, it would look something like this:&lt;/p&gt;

&lt;pre&gt;metadata:
  annotations:
    argocd.argoproj.io/hook: PostSync&lt;/pre&gt;

&lt;p&gt;Whenever Argo CD starts a sync, it orders the resources in the following precedence: the phase, the wave they are in, by kind (e.g., namespaces first and then other Kubernetes resources, followed by custom resources), and by name.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Dependencies -&amp;gt; See the graphical view of Argo CD&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you have containerized your microservices and wrapped your brain around the Kubernetes ecosystem. Suddenly an extra layer of complexity is added when trying to deploy all of those microservices and reference the never-ending Kubernetes documentation. This is where having some visualization for your deployments is helpful! Enabling some sort of topology for your application and infrastructure would allow you to better understand, monitor, and control your containerized microservice.&lt;/p&gt;

&lt;p&gt;Argo CD does just that. The web UI provides a real-time view of application activity and dependencies and continuously monitors running applications when using Argo CD. Monitoring all deployed applications allows you to compare the current, live state against the desired target state (as specified within your Git repository). Any deployed application whose live state deviates from the target state is reported and allows you to view the differences while also providing facilities to automatically or manually sync the live state back to the desired target state of your system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2022/04/word-image-3.png" rel="noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZYE_9pCC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/04/word-image-3.png" alt="" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/argoproj/argo-cd/blob/master/docs/assets/argocd-ui.gif" rel="noopener"&gt;Image from Argo CD&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above exemplifies an Argo CD Application with a topology view that shows all of the dependencies of that application.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Fast rollbacks/progressive delivery -&amp;gt; Argo Rollouts&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When beginning to plan your deployment process for your new microservices, it's essential to determine which deployment strategy is best for you and your organization.&lt;/p&gt;

&lt;p&gt;Potential strategies could include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rolling&lt;/strong&gt;: Services that don't need to be available 24/7 can utilize a pattern of swapping in the new for old and essentially hitting the restart button. This allows minimal disruption should there be a service outage. The simplicity aspect is compelling, and the disruptions to end users are less so.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Progressive delivery&lt;/strong&gt; (this includes blue-green deployments and canary): A blue-green deployment is simple, has excellent rollback, and has minimal downtime in best-case scenarios. Canary deployments tie together the best of all worlds for minimizing downtime, fast rollback, and minimal disruptions in the case of failed deployments.&lt;/p&gt;

&lt;p&gt;However, while progressive delivery improves the reliability and stability of deployments, applying it within your complex microservice environments doesn't come easy. Kubernetes was built as a container orchestrator, not a deployment system, requiring manual work to execute progressive delivery. Kubernetes also has a default rolling update strategy that is simple to deploy yet provides little control over user traffic and rollback compared to the more advanced deployment methods like blue-green and canary.&lt;/p&gt;

&lt;p&gt;This is where &lt;a href="https://codefresh.io/learn/argo-rollouts/" rel="noopener"&gt;Argo Rollouts&lt;/a&gt; walks down the red carpet as an open source Kubernetes controller with a GitOps-based progressive delivery strategy.&lt;/p&gt;

&lt;p&gt;Argo Rollouts introduces a new Kubernetes CRD for a rollout entity. It has the same functionality as a Kubernetes Deployment entity, but the Argo Rollouts will monitor for changes and can control the rollout. Users can define a specific rollout strategy configured with a manifest file. Argo Rollouts helps you simplify your release processes and provide full support of progressive delivery with automated deployment rollout and management in one!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2022/04/word-image-4.png" rel="noopener"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WohRCjln--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/04/word-image-4.png" alt="" width="800" height="593"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://argoproj.github.io/argo-rollouts/dashboard/#individual-rollout-view" rel="noopener"&gt;Argo Rollout Image of UI Dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This image above exemplifies a visualization of an individual Rollout using a Canary deployment strategy.&lt;/p&gt;

&lt;h3&gt;
&lt;a id="post-22229-_wpmw7qt4ftus"&gt;&lt;/a&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;As you transition from a monolithic architecture to microservices, this process shares a common goal with GitOps: making it easier to deploy more frequently.&lt;/p&gt;

&lt;p&gt;We have shared the benefits and possibilities of adopting GitOps with Argo for your microservices deployments within this blog post. To help you leverage these benefits and get started with your GitOps journey, make sure you understand what GitOps is and the fundamentals of this paradigm. To get started, you can check out our &lt;a href="https://codefresh.learnworlds.com/" rel="noopener"&gt;GitOps Fundamentals&lt;/a&gt; course for free, which allows you to learn about GitOps and get started with the basics of Argo, in tandem with receiving a certificate of completion to share with your employer and others!&lt;/p&gt;

&lt;p&gt;Once you’ve completed this course, you should put your knowledge to the test and try Codefresh GitOps CD to help manage your Argo CD instances. This will provide you with a visualization of your services and any possible failures tied to a commit, a test, pipeline, etc. You can quickly pinpoint issues with access to a release timeline and functionality to execute rollbacks when needed.&lt;/p&gt;

&lt;p&gt;Learn more about Codefresh GitOps CD and sign up &lt;a href="https://codefresh.io/codefresh-signup/" rel="noopener"&gt;here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>gitop</category>
      <category>microservices</category>
      <category>cd</category>
      <category>argo</category>
    </item>
    <item>
      <title>Best Practices for Argo CD</title>
      <dc:creator>Hannah</dc:creator>
      <pubDate>Mon, 04 Apr 2022 15:20:18 +0000</pubDate>
      <link>https://forem.com/codefreshio/best-practices-for-argo-cd-4h38</link>
      <guid>https://forem.com/codefreshio/best-practices-for-argo-cd-4h38</guid>
      <description>&lt;h4&gt;What are some best practices when using Argo CD?&lt;/h4&gt;

&lt;p&gt;Within this blog post, we’ll be highlighting some best practices tied to &lt;a href="https://argo-cd.readthedocs.io/en/stable/#what-is-argo-cd"&gt;Argo CD&lt;/a&gt;, that allow you to leverage GitOps easily within your deployment workflow.&lt;br&gt;
Below we will explain the following:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;What is Argo CD&lt;/li&gt;
    &lt;li&gt;What are some best practices with Argo CD?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;What is Argo CD&lt;/h3&gt;

&lt;p&gt;Argo CD is the most popular and fastest-growing &lt;a href="https://codefresh.io/gitops/" rel="noopener"&gt;GitOps&lt;/a&gt; tool 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 they should be deployed. After a deployment, Argo CD constantly monitors the state and can even catch configuration drift.&lt;/p&gt;

&lt;p&gt;Argo CD's core component is the &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/auto_sync/" rel="noopener"&gt;Applications Controller&lt;/a&gt; that executes continuous monitoring of applications and then compares them to the live application state against your target state defined within your Git repository.&lt;/p&gt;

&lt;p&gt;The Application controller retrieves the desired resource manifest from the Git repository and compares it to the live resource from your Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;This approach enables GitOps for your deployment workflow by leveraging Git as your source of truth. Now, let's further explore how we can leverage Argo CD best for our deployments!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PfQvSxVZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/app-status-in-sync.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PfQvSxVZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/app-status-in-sync.png" alt="App Status - In Sync" width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows the primary Argo CD dashboard with a single Argo application successfully deployed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lh3.googleusercontent.com/AQ28k1lG1SA_xvJjki5PQJD3Cy4RrxL7BlNca30kW3L_scMn6b9LHPfQkLHrj2dyuetUMQQvQyO2loFmQ0l8V742f3V29ow1ztan82FLuJoXhJCy7AoFERrpT34uRBR-pmTqWaS9"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--di-Zya5w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/hierarchical-view-of-all-kubernetes-resources.png" alt="Hierarchical view of all Kubernetes resources" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The dashboard above provides a detailed view of the same Argo application deployed in the image above. However, it also provides an understanding of the status of the Kubernetes resources.&lt;/p&gt;

&lt;p&gt;Now, let's explore how we can apply best practices to our Argo CD deployments!&lt;/p&gt;

&lt;h3&gt;
&lt;a id="post-21871-_m13x9eymh82e"&gt;&lt;/a&gt;&lt;strong&gt;Argo CD Best Practices&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Argo CD has several best practices; however, we will review some of the most important ones we've gathered from the Argo community and prioritized below.&lt;/p&gt;

&lt;ol&gt;
&lt;h4&gt;1. &lt;strong&gt;Separate your Git repositories&lt;/strong&gt;
&lt;/h4&gt;
&lt;/ol&gt;

&lt;p&gt;It's super important to separate your configurations and source code into different Git repositories. Separating your configs in their repository limits commit access to avoid something being pushed to production environments. For example, if you accidentally push manifest changes to the config repo, it can trigger an infinite loop of build jobs and Git commit triggers. Using an automated CI pipeline, you can also prevent pushing manifest changes to the same repo.&lt;/p&gt;

&lt;p&gt;Separating your repositories is also more secure and restricts commit access, so someone does not accidentally misconfigure an application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jC7TEfcV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/word-image-20220330-174003.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jC7TEfcV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/word-image-20220330-174003.png" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Argo CD does not connect to your source code repository. However, if you make a change to your code and you want to deploy the change to a specific environment, you can do the following:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Build a new application code version and then merge a pull request (PR) in the configuration repo to use the new application version you created.&lt;/li&gt;
    &lt;li&gt;Utilize automation for the update you made to your source code by using a pipeline in the source code repository.&lt;/li&gt;
    &lt;li&gt;Argo CD Image Updater allows you to update your container images of the Kubernetes workload managed by Argo CD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These approaches allow you to maintain logs for any auditing process. You can quickly identify development activity and reference your Git history for easy traceability.&lt;/p&gt;

&lt;ol&gt;
&lt;h4&gt;2. &lt;strong&gt;Create a directory structure to enable a multi-application system for your Argo CD deployments&lt;/strong&gt;
&lt;/h4&gt;
&lt;/ol&gt;

&lt;p&gt;Once you've separated your source code and configs into separate repositories, it's essential to set up a directory structure that applies GitOps for Argo CD deployments. You can leverage several approaches for your Git repository structure that best serves your organization's needs.&lt;/p&gt;

&lt;p&gt;However, we'll highlight some tips to best structure your directory when using Argo CD.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Do: We suggest modeling your environments or clusters using different folders instead of branches in your configuration repository (e.g., prod, staging, testing, etc.).&lt;/li&gt;
    &lt;li&gt;Do: Make sure your cluster and environment configurations repositories are separated (i.e., separate your prod configuration in a different repository from staging).&lt;/li&gt;
    &lt;li&gt;Do: Utilize some sort of manifest management, such as a raw Kubernetes YAML file, Kustomize, or Helm for your environment definitions for your apps.&lt;/li&gt;
    &lt;li&gt;Do: Create an 'argocd' folder in your configuration repository for each cluster and create an Argo CD Application manifest for each app in the cluster's repository.
&lt;ul&gt;
    &lt;li&gt;By creating the separate 'argocd' folder, you can also implement role-based access control for different clusters if you wish with Git repository permissions.&lt;/li&gt;
&lt;/ul&gt;




&lt;/li&gt;

    &lt;li&gt;Do: Leverage a multi-folder or a multi-repo structure instead of a multi-branch approach. You should NOT have permanent branches for your clusters or environments.&lt;/li&gt;

    &lt;li&gt;Don't: Never put any independent applications or applications managed by different teams in the same repository.&lt;/li&gt;

&lt;/ul&gt;
&lt;br&gt;&lt;br&gt;
Implementing these strategies above for your directory structure provides several advantages. Those advantages include improved security, easy rollbacks, audit log, easier testing, and automating your manifest updates. It also allows you to create and delete applications dynamically. If you'd like to see some examples of these directory structures, look &lt;a href="https://github.com/argoproj/argocd-example-apps" rel="noopener"&gt;here&lt;/a&gt;.

&lt;ol&gt;
&lt;h4&gt;3. &lt;strong&gt;Determine a promotion strategy&lt;/strong&gt;
&lt;/h4&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you've established a directory structure, you may face a challenge regarding the best promotion practice between clusters. When deploying multiple applications with Argo CD, it's best to pick one promotion strategy that suits your directory structure and stick with it. Below we'll highlight how you can do this based on your own needs.&lt;/p&gt;

&lt;h5&gt;
&lt;a id="post-21871-_9m9qm130wnjz"&gt;&lt;/a&gt;Group your applications&lt;/h5&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://argocd-applicationset.readthedocs.io/en/stable/" rel="noopener"&gt;ApplicationSets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First and foremost, once you've established a way to manage your applications and deployments, and there are too many apps to keep track of - the ApplicationSet is your best solution. We should also note that the ApplicationSet was previously an external controller that you had to install on your own, and now it's integrated and makes things much easier! However, you need some extra support when using the ApplicationSet instead of the App of Apps pattern that is easy enough to use right away without any additional help or a learning curve.&lt;/p&gt;

&lt;p&gt;Yet, when deploying to production, an ApplicationSet is the best choice. This is because an ApplicationSet is a Kubernetes controller/custom resource definition (CRD) that enables automation and allows flexibility when managing multiple applications across several clusters.&lt;/p&gt;

&lt;p&gt;The ApplicationSet consists of two main components:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://argocd-applicationset.readthedocs.io/en/stable/Generators/" rel="noopener"&gt;Generators&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://argocd-applicationset.readthedocs.io/en/stable/Template/#templates" rel="noopener"&gt;Application template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are essentially allowing the ApplicationSet to act as a templating agent.&lt;/p&gt;

&lt;p&gt;The generators used with the ApplicationSet are responsible for generating params, utilizing the template to consume the variables, and then applying them to the cluster as Argo CD applications. So, any changes made to an ApplicationSet template and its fields will automatically be applied to each application created.&lt;/p&gt;

&lt;p&gt;This way, you can simultaneously deploy your Argo apps to multiple Kubernetes clusters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4U0R2Dwc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/word-image-20220330-174007.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4U0R2Dwc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/word-image-20220330-174007.png" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://argoproj.github.io/argo-cd/operator-manual/cluster-bootstrapping/#app-of-apps-pattern" rel="noopener"&gt;App of Apps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When managing ten or fewer applications, it's best to use the App of Apps pattern.&lt;/p&gt;

&lt;p&gt;App of Apps was the pioneer before ApplicationSets that allowed us to deploy multiple applications at once with ease.&lt;/p&gt;

&lt;p&gt;You are leveraging the actual app itself, aka a "Root App," to contain the other applications instead of individual Kubernetes objects. This, in turn, allows you to manage a group of applications that you can deploy declaratively. Essentially this pattern supports the declaration of children apps in a recursive way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wrz38Uea--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/word-image-20220330-174013.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wrz38Uea--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2022/03/word-image-20220330-174013.png" width="678" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/cluster-bootstrapping/"&gt;Image from the Argo CD documentation&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Another possible approach to promoting changes is the &lt;a href="https://argocd-image-updater.readthedocs.io/en/stable/#argo-cd-image-updater" rel="noopener"&gt;Argo CD Image Updater&lt;/a&gt;. It's still a relatively new project, but it provides a manual way to update your manifest versions.&lt;/p&gt;

&lt;p&gt;However, we should note that this approach is not GitOps friendly. Meaning it goes against the declarative nature of GitOps, but perhaps its functionality is what you and your team needs.&lt;/p&gt;

&lt;h5&gt;
&lt;a id="post-21871-_ojk5dlxw0p0e"&gt;&lt;/a&gt;Which to choose?&lt;/h5&gt;

&lt;p&gt;One does not "need" a promotion strategy when beginning to deploy with Argo CD. The strategies listed above are needed when trying to solve "too many apps." This problem dramatically depends on the number of Argo CD applications you are managing and whether or not you already have a deployment process in place or not.&lt;/p&gt;

&lt;p&gt;The Argo community has developed the strategies listed above to help you manage all your Argo CD application deployments, depending on your scale, directory structure, and manifest types, amongst other factors.&lt;/p&gt;

&lt;p&gt;However, it's ultimately up to you and your workload, which is best for you and your team.&lt;/p&gt;

&lt;ol&gt;
&lt;h4&gt;4. &lt;strong&gt;Manage your secrets securely&lt;/strong&gt;
&lt;/h4&gt;
&lt;/ol&gt;

&lt;p&gt;No one solution for &lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/secret-management/" rel="noopener"&gt;secret management&lt;/a&gt; will work for all organizations. However, some common approaches for how to best handle your secrets with Argo CD can help based on these two significant factors:&lt;/p&gt;

&lt;h5&gt;
&lt;a id="post-21871-_w2ry0j4kjmyh"&gt;&lt;/a&gt;Encrypt your secrets directly in your Git repository:&lt;/h5&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://engineering.bitnami.com/" rel="noopener"&gt;Bitnami Sealed Secrets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sealed secrets are one way to encrypt secrets created by anyone but can only be decrypted by the controller running within the target cluster.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://github.com/mozilla/sops" rel="noopener"&gt;SOPS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SOPS (Secret OperationS) is an open source solution that allows you to encrypt and decrypt an entire file or field for your Kubernetes secrets. This approach will enable you to store your secrets, and other Kubernetes manifests directly in your Git repository.&lt;/p&gt;

&lt;h5&gt;
&lt;a id="post-21871-_22nwzap9k2bt"&gt;&lt;/a&gt;Externalizing your secrets from your Git repository:&lt;/h5&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://github.com/argoproj-labs/argocd-vault-plugin" rel="noopener"&gt;Argo CD Vault plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This solution creates debate about whether it's GitOps or not. Nonetheless, it's a solution using Kubernetes auth in Vault. The Argo CD repo server authorizes Vault to use the service account token in the secret manifest, substituting the required value and creating a secret for you.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Cloud Provider Secrets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cloud provider secrets are created by your cloud service providers (CSP) depending on the cloud service. It depends on what your CSP offers and if their secret management solution meets your needs. Ensure you evaluate which strategy secures your data best.&lt;/p&gt;

&lt;p&gt;Firstly, storing your secrets in a Git repository isn't easy! Perhaps your organization has a different policy for secrets, or you already have a system in place, so in this case, you may want to externalize your secrets.&lt;/p&gt;

&lt;p&gt;However, if you want to store your secrets in your Git repository, plaintext secrets cannot be stored in your repo, and you never want to risk storing sensitive data and exposing it!&lt;/p&gt;

&lt;p&gt;But, Git can truly be the source of truth, including your secrets, and you won't have to risk getting fired when they are encrypted asymmetrically. You can use Argo CD to manage your deployment state from Git into your cluster, including your secrets, by ensuring processes are put in place, and the tools above are used safely.&lt;/p&gt;

&lt;ol&gt;
&lt;h4&gt;5. &lt;a id="post-21871-_igoj40bhubr"&gt;&lt;/a&gt;&lt;strong&gt;Confirm how your team accesses Argo CD &lt;/strong&gt;
&lt;/h4&gt;
&lt;/ol&gt;

&lt;p&gt;Essentially, we cannot say what the best practice for you and your team is to access Argo CD. However, we can advise you and your team to choose which approach works best for your organization and set a standard for your team.&lt;/p&gt;

&lt;h5&gt;
&lt;a id="post-21871-_u8z9ow43nf9v"&gt;&lt;/a&gt;Developers require access to Argo CD, so you need to set security measures and role-based access control (RBAC).&lt;/h5&gt;

&lt;p&gt;This approach allows your developers to access the Argo CD UI and ensure that each team has the appropriate access to their applications and their applications only.&lt;/p&gt;

&lt;p&gt;Argo CD provides an &lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/#rbac-configuration" rel="noopener"&gt;RBAC configuration&lt;/a&gt; that includes two pre-defined roles:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Read-only&lt;/li&gt;
    &lt;li&gt;Admin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also implement a permissions definition for your applications and other resource types with Argo CD. You can then sync these roles and permissions together to create a policy to define access to your system.&lt;/p&gt;

&lt;h5&gt;
&lt;a id="post-21871-_vmpdf9n1pfnd"&gt;&lt;/a&gt;No one within your organization requires access to Argo CD.&lt;/h5&gt;

&lt;p&gt;Some organizations do not want anyone to access the Argo CD UI or the API server. Perhaps the organization would like to use the automation but does not want to leverage the UI component. In this case, you can use a variant of Argo CD, also known as &lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/installation/#core" rel="noopener"&gt;Argo CD Core&lt;/a&gt;. This allows developers to make a commit and ignore the UI aspects and reduce complexity. However, we should note that you lose multi-tenancy benefits by installing Argo CD Core.&lt;/p&gt;

&lt;p&gt;So, whichever approach you choose above - as long as it benefits you and your team, you're making the right choice.&lt;/p&gt;

&lt;ol&gt;
&lt;h4&gt;6. &lt;a id="post-21871-_twnsu4heyo9s"&gt;&lt;/a&gt;&lt;strong&gt;Increase automation for your system with the other Argo projects&lt;/strong&gt;
&lt;/h4&gt;
&lt;/ol&gt;

&lt;p&gt;If you're using &lt;a href="https://codefresh.io/learn/argo-cd/" rel="noopener"&gt;Argo CD for Continuous Delivery (CD)&lt;/a&gt;, you want to elevate the rest of your workflow to automate everything in Kubernetes to reduce downtime. Then, you should check out the other &lt;a href="https://github.com/argoproj" rel="noopener"&gt;Argo projects&lt;/a&gt; and learn more about how they can help.&lt;/p&gt;

&lt;p&gt;We don't encourage you to use any specific projects to leverage best practices, but instead, we encourage you to use those that will help you and your system best.&lt;/p&gt;

&lt;p&gt;In the meantime, we can explore how we could use Argo Events, Workflows, and Rollouts to enhance your system if you choose to.&lt;/p&gt;

&lt;h5&gt;
&lt;a id="post-21871-_xfyh0qwuofic"&gt;&lt;/a&gt;Progressive Delivery&lt;/h5&gt;

&lt;p&gt;Progressive delivery is a set of practices that roll out new features gradually instead of all at once.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://github.com/argoproj/argo-rollouts" rel="noopener"&gt;Argo Rollouts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rollouts provide advanced deployment capabilities and rolling updates for progressive delivery approaches you might already know, such as blue-green, canary, etc.&lt;/p&gt;

&lt;h5&gt;
&lt;a id="post-21871-_cr8bufalkf5s"&gt;&lt;/a&gt; Advanced Deployment with CI&lt;/h5&gt;

&lt;p&gt;Argo Workflows and Events require you to have an existing Continuous Integration (CI) process to leverage these projects.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://github.com/argoproj/argo-workflows" rel="noopener"&gt;Argo Workflows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Workflows allow you to build and orchestrate parallel jobs and utilize a pipeline on Kubernetes.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://github.com/argoproj/argo-events" rel="noopener"&gt;Argo Events&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Events is an event-driven workflow automation framework that is used with Kubernetes.&lt;/p&gt;

&lt;p&gt;By utilizing these other Argo projects, you can easily manage your clusters, run workflows, and implement GitOps for your Kubernetes system! However, not all organizations are ready to implement automation for everything in Kubernetes. Combining all these tools requires time and understanding of how your system works before identifying which tool will best help your team's process.&lt;/p&gt;

&lt;h4&gt;
&lt;a id="post-21871-_sbcsl1bw8rj8"&gt;&lt;/a&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Argo CD and the other Argo projects certainly make life easier by allowing you to automate each step for a production release, migration, and the operation workflows for your system!&lt;/p&gt;

&lt;p&gt;By leveraging these best practices above, you're on the right track to empower your teams and apply GitOps for your infrastructure so you can deploy to prod more frequently.&lt;/p&gt;

&lt;p&gt;I'd like to thank those who are part of the Argo community who participated and provided feedback for this blog. If you have any questions or think there are better ways to work with Argo CD, please reach out and let me know!&lt;/p&gt;

</description>
      <category>argocd</category>
      <category>gitops</category>
      <category>bestpractices</category>
      <category>cd</category>
    </item>
    <item>
      <title>Using Codefresh with GKE Autopilot for native Kubernetes pipelines and GitOps deployment</title>
      <dc:creator>Hannah</dc:creator>
      <pubDate>Mon, 06 Dec 2021 18:16:39 +0000</pubDate>
      <link>https://forem.com/codefreshio/using-codefresh-with-gke-autopilot-for-native-kubernetes-pipelines-and-gitops-deployment-4ned</link>
      <guid>https://forem.com/codefreshio/using-codefresh-with-gke-autopilot-for-native-kubernetes-pipelines-and-gitops-deployment-4ned</guid>
      <description>&lt;p&gt;Several companies nowadays offer a cloud-native solution that manages Kubernetes applications and services. While these solutions seem easy at first glance, in reality, they still require manual maintenance.&lt;/p&gt;

&lt;p&gt;As an example, an important decision for any Kubernetes cluster is the number of nodes and the autoscaling rules you define. You want to ensure that the size is just right and matches your workload, otherwise, this could become costly, unstable, and decrease the availability of your workload when you need it most!&lt;/p&gt;

&lt;h4&gt;GKE Autopilot Cluster&lt;/h4&gt;

&lt;p&gt;A solution to these problems is &lt;a href="https://cloud.google.com/blog/products/containers-kubernetes/introducing-gke-autopilot"&gt;Google Kubernetes Engine (GKE) Autopilot&lt;/a&gt; from Google Cloud. GKE's cluster autoscaler adjusts the node pools based on whatever the demand is for your workload. For example, if the workload is high or low GKE Autopilot will scale depending on which and provide control on costs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-11-16-at-3.30.21-PM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cppYg4uD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-11-16-at-3.30.21-PM.png" alt="" width="728" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This allows you and your teams to no longer worry about maintaining your node pools or provisioning them - with Autopilot clusters these jobs are automatically done. This streamlined approach follows best practices for a cluster and workload setup, in addition to other best practices about security and observability. Allowing you to specify configurations needed for deployment to production and simplifying operations needed to manage an application’s infrastructure, nodes, and the control plane. &lt;/p&gt;

&lt;p&gt;The Codefresh platform fully supports GKE Autopilot. By combining the two platforms you can easily:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run CI/CD pipelines on your cluster to compile source code, run unit tests, perform security checks, etc.&lt;/li&gt;
&lt;li&gt;Deploy your containers to your cluster by following the &lt;a href="https://codefresh.io/gitops/"&gt;GitOps principles&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Deploying applications to your GKE Autopilot cluster following the GitOps principles&lt;/h2&gt;

&lt;h4&gt;Codefresh GitOps Controller&lt;/h4&gt;

&lt;p&gt;Like any Kubernetes cluster integrations or the GKE Standard cluster, the GKE Autopilot Cluster integrates the same way with the Codefresh GitOps dashboard. The GitOps dashboard allows you to look at all your deployments in greater detail and instantly know the critical information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Git commit was deployed&lt;/li&gt;
&lt;li&gt;Which cluster was affected&lt;/li&gt;
&lt;li&gt;Who initiated the change&lt;/li&gt;
&lt;li&gt;What features were shipped&lt;/li&gt;
&lt;li&gt;Which pipelines took part in the deployment&lt;/li&gt;
&lt;li&gt;What Kubernetes services were affected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;To achieve this level of GitOps visibility, a GKE autopilot cluster can be the target of the &lt;a href="https://codefresh.io/docs/docs/integrations/argo-cd/"&gt;Codefresh GitOps Controller&lt;/a&gt;, which is an agent installed in the cluster that monitors both the cluster and any defined Git repositories for changes. It installs an ArgoCD instance within the cluster and the associated GitOps Controller. This is done through the Codefresh CLI and can be authenticated with a Codefresh account, simply by creating an API token. This agent can also manage the runtime environment for a pipeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-11-17-at-7.01.44-PM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qvnVHfEB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-11-17-at-7.01.44-PM.png" alt="" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the GitOps controllers are installed, you can easily deploy any kind of application to your GKE Autopilot cluster using GitOps. This means that you can combine all the benefits of GitOps such as audibility, visibility, reduced downtime with the easy management of the GKE Autopilot capabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/GitOpsDashboard.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rw8BGfMC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/GitOpsDashboard.png" alt="" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;GKE Autopilot cluster allows you to pursue a production-ready and scalable workflow for both your application and infrastructure systems. Its ability to configure cluster autoscaling and node auto-provisioning can improve resource utilization and reduce day-to-day challenges for organizations. These features reduce the operational cost of managing clusters and optimize them for production.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;Google Cloud also provides a user-friendly experience, creating, configuring, and operating a Kubernetes cluster that you can integrate with the &lt;a href="https://codefresh.io/codefresh-argo-platform/"&gt;Codefresh DevOps Platform&lt;/a&gt; with a GitOps Controller, powered by &lt;a href="https://codefresh.io/argo-codefresh/"&gt;ArgoCD&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>gke</category>
      <category>gitops</category>
      <category>argo</category>
    </item>
    <item>
      <title>Applied GitOps with Kustomize</title>
      <dc:creator>Hannah</dc:creator>
      <pubDate>Wed, 01 Dec 2021 18:07:50 +0000</pubDate>
      <link>https://forem.com/codefreshio/applied-gitops-with-kustomize-3d7</link>
      <guid>https://forem.com/codefreshio/applied-gitops-with-kustomize-3d7</guid>
      <description>&lt;h3&gt;
  
  
  What is Kustomize?
&lt;/h3&gt;

&lt;p&gt;Have you always wanted to have different settings between production and staging but never knew how? You can do this with Kustomize!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kustomize.io/"&gt;Kustomize&lt;/a&gt; is a CLI configuration manager for Kubernetes objects that leverage layering to preserve the base settings of the application. This is done by overlaying the declarative YAML artifacts to override default settings without actually making any changes to the original manifest.&lt;/p&gt;

&lt;p&gt;Kustomize settings are defined in a kustomization.yaml file. Kustomize is also integrated with kubectl. With Kustomize, you can configure raw, template-free YAML files, which allows you to modify settings between deployment and production easily. This enables troubleshooting misconfigurations and keeps use-case-specific customization overrides intact.&lt;/p&gt;

&lt;p&gt;Kustomize also allows you to scale easily by reusing a base file across all your environments (development, production, staging, etc.) and then overlay specifications for each.&lt;/p&gt;


&lt;li&gt;
&lt;strong&gt;Base Layer&lt;/strong&gt;: This layer specifies the most common resources and original configuration.&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;
&lt;strong&gt;Overlays Layer&lt;/strong&gt;: This layer specifies use-case-specific resources by utilizing patches to override other kustomization files and Kubernetes manifests.&lt;/li&gt;
&lt;br&gt;
Overlays are what help us accomplish our goal by producing variants without templating.
&lt;h3&gt;
  
  
  Benefits of Kustomize
&lt;/h3&gt;

&lt;p&gt;Kustomize offers some of the following benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reusability&lt;/strong&gt;&lt;br&gt;
With Kustomize you can reuse one of the base files across all environments (development, staging, production, etc.) and overlay specifications for each of those environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quick Generation&lt;/strong&gt;&lt;br&gt;
Since Kustomize doesn't utilize templates, a standard YAML file can be used to declare configurations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Debug Easily&lt;/strong&gt;&lt;br&gt;
Using a YAML file allows easy debugging, along with patches that isolate configurations, allowing you to pinpoint the root cause of performance issues quickly. You can also compare performance to the base configuration and other variations that are running.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kubernetes Native Configuration&lt;/strong&gt;&lt;br&gt;
Kustomize understands Kubernetes resources and their fields and is not just a simple text templating solution like other tools.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See below an example of a Kustomize file structure including the base and overlays within an application. You can also reference a code-based demo project on &lt;a href="https://github.com/hseligson1/kustomize-gitops-example"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-12-01-at-10.32.44-AM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6kwgmVOU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-12-01-at-10.32.44-AM-300x175.png" alt="" width="300" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tree structure above is a simple example of how you can deploy a single application to 2 different environments (staging and production). Let's dig deeper into each directory and create an overlay.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;base folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#base"&gt;base&lt;/a&gt; folder holds common resources, such as the deployment.yaml, service.yaml, and configuration files. It contains the initial manifest and includes a namespace and label for the resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;overlays folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#overlay"&gt;overlays&lt;/a&gt; folder houses environment-specific overlays, which use patches to allow YAML files to be defined and overlaid on top of the base for any changes. Let's take a look at a couple of the environments within the overlays folder below that also includes the kustomization.yaml.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kustomization.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each directory contains &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#kustomization-root"&gt;a kustomization file&lt;/a&gt;, which is essentially a list of resources or manifests that describes how to generate or transform Kubernetes objects. There are &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/"&gt;multiple fields&lt;/a&gt; that can be added, and when this list is injected, the kustomization action can be referenced as an overlay that refers to the base.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Overlays
&lt;/h3&gt;

&lt;p&gt;Let's explore a simple example of how overlays work.&lt;br&gt;
We'll make the following changes within our production and staging directories:&lt;br&gt;
&lt;/p&gt;
&lt;li&gt;Within the staging overlay, we will enable a risky feature that is NOT enabled in production.&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;Within the production overlay, we'll assign a higher replica count.&lt;/li&gt;

&lt;p&gt;We'll also ensure the web server from the cluster variants is different from one another.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;overlays/staging/kustomization.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the staging directory, let's make a kustomization defining a new name prefix and different labels.&lt;/p&gt;

&lt;pre&gt;namePrefix: staging-
commonLabels:
 variant: staging
commonAnnotations:
  note: “Welcome to staging!”
bases:
- ../../base
patchesStrategicMerge:
- config-map.yaml
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Staging patch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a configMap kustomization to change the server greeting from "Hello!" to "Kustomize rules!" We'll also enable the risky flag.&lt;/p&gt;

&lt;pre&gt;apiVersion: v1
kind: ConfigMap
metadata:
 name: the-map
data:
 altGreeting: “Kustomize rules!”
 enableRisky: “true”
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;overlays/production/kustomization.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Within the production directory, we will make a kustomization with a different name prefix and label.&lt;/p&gt;

&lt;pre&gt;namePrefix: production-
commonLabels:
 variant: production
commonAnnotations:
  note: “Welcome to production!”
bases:
- ../../base
patchesStrategicMerge:
- deployment.yaml
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Production patch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We'll make a production patch that will increase the replica count.&lt;/p&gt;

&lt;pre&gt;apiVersion: apps/v1
kind: Deployment
metadata:
 name: the-deployment
spec:
 replicas: 10
&lt;/pre&gt;

&lt;p&gt;Now, we can compare these overlays - the kustomizations and patches are required to create noticeable differences between staging and production variants within the Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;Based on the changes above, the output would look something like this:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;   altGreeting: Kustomize rules!
&amp;lt;   enableRisky: "true"
---
&amp;gt;   altGreeting: Hello!
&amp;gt;   enableRisky: "false"

&amp;lt;     note: Welcome, I am staging!
---
&amp;gt;     note: Welcome, I am production!

&amp;lt;     variant: staging
---
&amp;gt;     variant: production
&lt;/pre&gt;

&lt;p&gt;You can now see the difference between the staging and production overlays.&lt;br&gt;
Overlays contain a kustomization.yaml, and can also include manifests as new or additional resources, or to patch resources. The kustomization file is what defines how the overlays should be applied to the base and this is what we refer to as a &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#variant"&gt;variant&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each time a change is made to an application, like the example above - it is the overlays that are doing the heavy lifting.&lt;/p&gt;

&lt;p&gt;So, now that you have learned a bit about Kustomize, you might be wondering how you can apply the GitOps workflow to it. Below we'll explain more about GitOps and how you can apply it to your Kustomize project and deploy it.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitOps works with all your existing tools
&lt;/h3&gt;

&lt;p&gt;Now, let's learn more about how to apply GitOps to your Kustomize application deployment!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/gitops/"&gt;GitOps&lt;/a&gt; is a paradigm that incorporates best practices applied to both an application development workflow and the infrastructure of a system. This is done to empower organizations and developers to operate their systems from a single source of truth enabled by Git.&lt;br&gt;
A couple of key aspects of GitOps that most aren't as familiar with and are crucial are the:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;GitOps controller&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The controller reads the declarative configuration and uses the reconciliation loops to converge the desired end state. This controller detects the differences between states and makes the necessary changes to maintain the desired state.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Automation reconciliation loop&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The concept of the reconciliation loop is used to keep the state as defined within a manifest. This is such an important principle for the GitOps paradigm because these loops are what drive the entire cluster to the desired state in Git.&lt;/p&gt;

&lt;p&gt;Now that you have a basic understanding of what both Kustomize and &lt;a href="https://opengitops.dev/"&gt;GitOps&lt;/a&gt; are and what some of their capabilities are, perhaps you've considered applying GitOps to your existing or future application and infrastructure workflow.&lt;/p&gt;

&lt;p&gt;We'll explore 2 approaches on how to use Kustomize with or without GitOps:&lt;br&gt;
&lt;/p&gt;
&lt;li&gt;Using only Kustomize&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;Using Kustomize with ArgoCD&lt;/li&gt;
&lt;h3&gt;
  
  
  What is ArgoCD?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/argoproj/argo-cd"&gt;ArgoCD&lt;/a&gt; is a GitOps controller specifically created for Kubernetes deployments. It supports a variety of configuration management tools like Helm (take a look at &lt;a href="https://codefresh.io/helm-tutorial/using-helm-with-gitops/"&gt;our documentation&lt;/a&gt; for more information), Ksonnet, Kustomize, &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/application_sources/"&gt;etc&lt;/a&gt;. The core component is the Application Controller, which continuously monitors any running applications and compares the live state against the desired state defined in a Git repository.&lt;/p&gt;

&lt;p&gt;If a deployed application whose live state drifts from the target state, ArgoCD is then considered OutOfSync. It then provides reports and visualizations to identify these changes and can provide automation when any modifications are made so that the target environments reflect the desired state of a system in Git.&lt;/p&gt;

&lt;p&gt;If you'd like to explore these different deployment approaches with Kustomize from a code-based perspective, here is an &lt;a href="https://github.com/hseligson1/kustomize-gitops-example"&gt;example project&lt;/a&gt; that you can follow along with on GitHub. However, we will explore both of these approaches below with some more details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach #1: Deploying only with Kustomize
&lt;/h2&gt;

&lt;p&gt;If you want to use Kustomize, but your organization isn't ready to implement GitOps with your workflow, you can still use Kustomize on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Kustomize&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, install Kustomize and this can be done either by utilizing kubectl version 1.14 or later, otherwise you can install based on your operating system and reference the &lt;a href="https://kubectl.docs.kubernetes.io/installation/kustomize/"&gt;Kustomize documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a base directory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, in order to deploy an application with Kustomize, you need a kustomization.yaml file, and this is added to the base directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-12-01-at-11.17.06-AM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3cOH-EyI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-12-01-at-11.17.06-AM-300x213.png" alt="" width="300" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The kustomization.yaml file specifies what resources to manage due to the complexity of multiple resource types and different environments when handling configuration files for Kubernetes.&lt;/p&gt;

&lt;p&gt;Within the base directory, there is also a service and deployment resource.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create an Overlays directory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, you'll want to create an overlays directory, and this directory is what allows you to kustomize the base and apply any changes with a &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/"&gt;patch&lt;/a&gt; to modify a resource.&lt;/p&gt;

&lt;p&gt;The overlays still use the same resources as the base but may vary in the number of replicas in a deployment, the CPU for a specific pod, or the data source used in the ConfigMap, etc.&lt;/p&gt;

&lt;p&gt;Within our example, we have a staging and production overlay. These overlay directories contain the kustomizations and patches previously mentioned that are required to create distinct staging and production &lt;a href="https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#variant"&gt;variants&lt;/a&gt; in a cluster. However, with Kustomize you can use the overlays for anything needed to organize environments, whether it's based on location: USA, Asia, Europe or internal/external, team A/team B, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-12-01-at-11.18.43-AM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AE79yh-P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-12-01-at-11.18.43-AM-293x300.png" alt="" width="293" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kustomize is essentially an overlay-based engine that functions by finding and replacing specific sections in the manifest and replacing it with required fields and values. These values are then merged and deployed!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a namespace for specific environments&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;kubectl create ns staging
&lt;/pre&gt; 

&lt;p&gt;or &lt;/p&gt;

&lt;pre&gt;kubectl create ns production
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Build and Deploy to environments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can then apply the overlays to your cluster and deploy with the command:&lt;/p&gt;

&lt;pre&gt;kubectl apply -k overlays/staging
&lt;/pre&gt; 

&lt;p&gt;or &lt;/p&gt;

&lt;pre&gt;kubectl apply -k overlays/production
&lt;/pre&gt;

&lt;p&gt;You are now successfully using Kustomize to manage your Kubernetes configurations and deploy your application to production and staging environments!&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach #2: Deploying using Kustomize with GitOps
&lt;/h2&gt;

&lt;p&gt;In the previous approach, you learned how to deploy an application using only Kustomize, so let's see how it fits into ArgoCD and how it can be used in a GitOps workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/kustomize/"&gt;ArgoCD supports Kustomize&lt;/a&gt; and has the ability to read a kustomization.yaml file to enable deployment with Kustomize and allow ArgoCD to manage the state of the YAML files.&lt;/p&gt;

&lt;p&gt;ArgoCD monitors the resources within the git repository for any changes, ensuring that the live state of your system matches the desired state. Each time customization is made, ArgoCD detects those modifications and updates the deployment.&lt;/p&gt;

&lt;p&gt;So, let's begin walking through the process to deploy a Kustomize project using ArgoCD!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install ArgoCD and access a Kubernetes Cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, we need to ensure the Kubernetes cluster is set up and you are logged into ArgoCD so that these resources are provided and can be deployed. You can use any Kubernetes cluster and &lt;a href="https://github.com/argoproj/argo-cd/blob/master/docs/cli_installation.md"&gt;install&lt;/a&gt; the argocd CLI.&lt;/p&gt;

&lt;p&gt;Once you've accessed the argocd CLI you can &lt;a href="https://argo-cd.readthedocs.io/en/stable/getting_started/#4-login-using-the-cli"&gt;access the ArgoCD server and log in&lt;/a&gt; to the ArgoCD UI. However, if you're more of a terminal fan, you can also deploy the application through the argocd CLI. Feel free to reference the &lt;a href="https://github.com/hseligson1/kustomize-gitops-example"&gt;demo application&lt;/a&gt; that will walk you through the deployment process through your terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create an ArgoCD application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, we can set up the Kustomize Project. Similar to &lt;a href="https://codefresh.io/helm-tutorial/using-helm-with-gitops/"&gt;using Helm with GitOps&lt;/a&gt;, we will approach this deployment the same way within the UI by creating an ArgoCD application.&lt;/p&gt;

&lt;p&gt;Let's begin! First, click on the +NEW APP and include the name of the ArgoCD application, select the default project, and enable the Automatic SYNC POLICY.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-11-22-at-11.55.41-AM.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YuJsPfsm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/Screen-Shot-2021-11-22-at-11.55.41-AM.png" alt="" width="800" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, when adding your Kustomize project it helps to include a specific Path to segregate the application manifests inside the Git repository. We can then ask ArgoCD to only read the specific directories in the repository and read manifests within that path. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/argocd-source-ui-staging.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NpI4zfzG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/argocd-source-ui-staging.png" alt="" width="800" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, within the Destination section, you need to provide the destination of the Kubernetes cluster details. Also, make sure to click on the checkbox for auto-create namespace when adding the input field value, or you can add a custom namespace you've created prior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/argocd-ns-ui.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lCGlih8i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/argocd-ns-ui.png" alt="" width="800" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ArgoCD will read the kustomization.yaml file in the path you provided and prompt you to allow override with different values.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/12/argocd-kustomize-ui-staging.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--smT0_G9y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://codefresh.io/wp-content/uploads/2021/12/argocd-kustomize-ui-staging.png" alt="" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synchronize Application and Deploy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Assuming you enabled auto-synchronization when creating your ArgoCD application, it will read the parameters and the Kubernetes manifests. Then, once the manifests are applied, you can review the application health and resources you deployed.&lt;/p&gt;

&lt;p&gt;If your application has an error when trying to synchronize, you can execute the argocd history command, allowing you to view the application deployment history to identify a possible error:&lt;/p&gt;

&lt;pre&gt;
argocd app history argocd_app_name
&lt;/pre&gt;

&lt;p&gt;If you need to rollback you can do so by executing this command:&lt;/p&gt;

&lt;pre&gt;
argocd app rollback argocd_app_name history_id
&lt;/pre&gt;

&lt;p&gt;These commands leverage a faster and more secure deployment by enabling the tracking from the Git repository. This allows you to track the active Kubernetes resources and events. These actions can also be done within the UI.&lt;/p&gt;

&lt;p&gt;Once the application is healthy and synchronized, each time you create a new kustomization.yaml file and the file changes, ArgoCD will be able to detect those changes and make updates to your deployment. You can even mention specific &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/kustomize/"&gt;Kustomize tags&lt;/a&gt; and set up custom build options for your Kustomize build.&lt;/p&gt;

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

&lt;p&gt;Kustomize allows you to use different configurations of a base Kubernetes manifest. Within this post, we've covered the Kustomize basics and how to deploy using just Kustomize and deploying with GitOps. This allows you to leverage the power of Kustomize to define the Kubernetes files without using a templating system.&lt;/p&gt;

&lt;p&gt;To start deploying your Kustomize application, sign up for a &lt;a href="https://codefresh.io/codefresh-signup/"&gt;Codefresh&lt;/a&gt; account today to apply &lt;a href="https://codefresh.io/gitops/"&gt;GitOps&lt;/a&gt; to your deployment process!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>kustomize</category>
      <category>gitops</category>
      <category>continuousdeployment</category>
    </item>
    <item>
      <title>Using Helm with GitOps</title>
      <dc:creator>Hannah</dc:creator>
      <pubDate>Thu, 30 Sep 2021 15:15:45 +0000</pubDate>
      <link>https://forem.com/codefreshio/using-helm-with-gitops-2had</link>
      <guid>https://forem.com/codefreshio/using-helm-with-gitops-2had</guid>
      <description>&lt;p&gt;&lt;span&gt;This is the first of many posts highlighting GitOps topics that we’ll be exploring. Within this post, we will explore Helm, a tool used for Kubernetes package management, that also provides templating. Helm provides utilities that assist Kubernetes application deployment.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;In order to better understand how Helm charts are mapped to Kubernetes manifests, we’ll explain more details below and how to use Helm with and without GitOps.&lt;/span&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;&lt;span&gt;Kubernetes&lt;/span&gt;&lt;/a&gt;&lt;span&gt; is an orchestrator for containers that allows you to automate scheduling, deployments, networking, scaling, and health monitoring for the containers.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Kubernetes was needed because we increased the usage of the following:&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;span&gt;Microservices&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Containers&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span&gt;This was difficult to manage with scripts and self-made tools and caused the need for orchestration technology like Kubernetes. It provides features like scalability, disaster recovery, and less downtime.&lt;/span&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://helm.sh/" rel="noopener noreferrer"&gt;&lt;span&gt;Helm&lt;/span&gt;&lt;/a&gt;&lt;span&gt; is a package manager for Kubernetes. It’s a convenient way for packaging collections of YAML files with a Helm chart for the Kubernetes application and allowing distribution with a Helm repository. &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Maintaining Kubernetes manifests is time-consuming and tedious and this is why Helm is helpful!&lt;/span&gt;&lt;/p&gt;

&lt;h4&gt;Helm Charts&lt;/h4&gt;

&lt;p&gt;&lt;span&gt;Helm Charts are deployable units for Kubernetes applications. These charts are a collection of files inside a directory. This directory is the name of the Helm chart and consists of a self-descriptor file, YAML file, and one or more Kubernetes manifests. Helm charts are typically written in the &lt;/span&gt;&lt;a href="https://pkg.go.dev/text/template" rel="noopener noreferrer"&gt;&lt;span&gt;Go template language&lt;/span&gt;&lt;/a&gt;&lt;span&gt;. Charts are created as such files, describing a related set of Kubernetes resources. Here’s an example of a Helm chart directory and it’s layout:&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/09/helm-chart-example.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2021%2F09%2Fhelm-chart-example.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;This particular directory contains a &lt;/span&gt;&lt;span&gt;Chart.yaml&lt;/span&gt;&lt;span&gt; file and this is where the global variables, versions, and descriptions are stored. Then, the templates directory is what contains the YAML files for Kubernetes, otherwise known as the Kubernetes manifests.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Files such as the &lt;/span&gt;&lt;span&gt;deployment&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;service&lt;/span&gt;&lt;span&gt;, and &lt;/span&gt;&lt;span&gt;ingress&lt;/span&gt;&lt;span&gt; files contain variables from the &lt;/span&gt;&lt;span&gt;values.yaml&lt;/span&gt;&lt;span&gt; file when the chart is deployed. The &lt;/span&gt;&lt;span&gt;_helpers.tpl&lt;/span&gt;&lt;span&gt; incorporates helpful functions for variable calculations.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;You can then share the Helm chart to increase easy reusability for others to use. Sharing is done by storing the chart to a Helm repository. This repository can then be shared with others to deploy the application with the chart.&lt;/span&gt;&lt;/p&gt;

&lt;h4&gt;Helm Repositories&lt;/h4&gt;

&lt;p&gt;&lt;span&gt;Helm supports a chart repository service that can be used to store the Helm charts. You can use any web server host or source code host for the Helm repository.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;The repository has an &lt;/span&gt;&lt;span&gt;index.yaml&lt;/span&gt;&lt;span&gt; file that contains metadata about the package, including the &lt;/span&gt;&lt;span&gt;Chart.yaml&lt;/span&gt;&lt;span&gt; file. The index will contain information about each Helm chart in the chart repository. Then the server can serve your index and charts or the packages can be stored in the repository for shareable access.&lt;/span&gt;&lt;/p&gt;

&lt;h4&gt;Helm Release&lt;/h4&gt;

&lt;p&gt;&lt;span&gt;Each install or upgrade will create a Helm release. A Helm release is a running instance of your Helm chart running within a Kubernetes cluster or a namespace. It’s essentially an instance of a versioned, templated chart. &lt;/span&gt;&lt;span&gt;It’s also possible to have multiple releases of the same chart in a single cluster or namespace since the chart is self-contained. You can also roll back a Helm release to a previous version in case there are any failures.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/09/Helm-WF.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2021%2F09%2FHelm-WF-1024x632.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Assuming you’re a developer with an existing cluster, perhaps you’d like to share your Helm application with an external vendor. Let's recap the Helm workflow and release process:&lt;/span&gt;&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;
&lt;span&gt;To share an application with others, you need to create a Helm chart. The chart is a package that contains templates for a set of resources necessary for the application. The template uses variables applied to the &lt;/span&gt;&lt;span&gt;Values.yaml&lt;/span&gt;&lt;span&gt; file when the manifest is created and describes how to configure the resources.&lt;/span&gt;
&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;The Helm charts are then hosted within a repository that can then be downloaded or accessed from a server. This chart will contain all the necessary resource definitions needed for the developer to run an application.&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Now that you have access to the cluster, you can add new features or bug fixes to the application and update the Helm chart. Helm offers useful tools to manage your releases. You can upgrade the chart and create a new deployment. In Helm a deployed instance of your application is referred to as the release. &lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;You can now deploy your packaged application to the cluster.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;span&gt;Within this workflow we identified how Helm packages files and deploys them to a cluster. So, how do you apply GitOps to the workflow above? Let’s explore this below...&lt;/span&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://codefresh.io/gitops/" rel="noopener noreferrer"&gt;&lt;span&gt;GitOps&lt;/span&gt;&lt;/a&gt;&lt;span&gt; is a paradigm that incorporates best practices applied to the application development workflow all the way to the operating infrastructure of a system.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Some benefits of GitOps are:&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;span&gt;Deploying faster and more often&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Easier and quicker error handling and recovery&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Self documenting deployments&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Increased developer productivity and an enhanced experience for teams&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Greater visibility on the lifecycle of developed features&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span&gt;These benefits make it easier to handle the applications and allow teams to deliver quality software faster.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;GitOps relies on Git as the single source of truth for declarative configuration and active reconciliation. By adopting the GitOps methodology it provides transparency between the application configuration deployed in a cluster and the one residing in Git. &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&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 and compares the live state against the desired state in Git and applies it to the cluster. In addition, it also monitors the container registry for new images and updates the workload definitions based on the deployment policies.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;We will mention Argo CD again in this post and can assume that it’s already been installed and implemented within our workflow!&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;GitOps works with all of your existing tools&lt;/h2&gt;

&lt;p&gt;&lt;span&gt;Now that you have a good understanding of what Helm is and it’s capabilities, perhaps you’ve considered applying GitOps to your existing or future applications.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Let’s explore the various approaches of how to use GitOps with or without Helm:&lt;/span&gt;&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;&lt;span&gt;Using only Helm (without GitOps)&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Using GitOps (without Helm)&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Using Helm with GitOps&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;span&gt;If you’d like to explore these different approaches from a code-base perspective, here is an &lt;/span&gt;&lt;a href="https://github.com/codefresh-contrib/helm-gitops-example/blob/main/README.md" rel="noopener noreferrer"&gt;&lt;span&gt;example project&lt;/span&gt;&lt;/a&gt;&lt;span&gt; that you should check out on GitHub that digs deeper into how you can:&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;span&gt;Install an application with Helm and deploy locally&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;Install an application with Argo CD and deploy locally both within the UI and command line&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span&gt;If not, then we’ll be sure to highlight these approaches below!&lt;/span&gt;&lt;/p&gt;

&lt;h4&gt;Approach #1: Using only Helm without GitOps&lt;/h4&gt;

&lt;p&gt;&lt;span&gt;If you want to use Helm but your organization isn’t quite ready to implement the GitOps workflow, that’s perfectly fine. Helm was created before the GitOps methodology came to fruition, but can still work with GitOps (as we will see in the latter point).&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;The workflow allows you to search through Helm repositories for charts and install them to clusters, creating releases. This process enables execution of application deployments on a cluster. The maintenance of YAML manifests for Kubernetes objects is still the same as before. Helm releases are what keeps track of the version history of each chart installation and change and still allows rolling back to the previous cluster version. When installing a chart it creates a release of the new package and it’s the Helm release that deploys the Helm application.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;When using Helm there are some powerful commands you will find useful, please see below.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;To install a new package:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;helm install &amp;lt;release_name&amp;gt; &amp;lt;name_of_chart_you_want_to_install&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;To view currently deployed releases:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;helm list&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;helm ls&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;To view revision numbers for a particular release:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;helm history &amp;lt;release_name&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;span&gt;To learn more details about these commands and how to use them, reference the &lt;/span&gt;&lt;a href="https://github.com/codefresh-contrib/helm-gitops-example/blob/main/README.md" rel="noopener noreferrer"&gt;&lt;span&gt;example project&lt;/span&gt;&lt;/a&gt;&lt;span&gt; in GitHub.&lt;/span&gt;&lt;/p&gt;

&lt;h4&gt;Approach #2: Using GitOps without Helm&lt;/h4&gt;

&lt;p&gt;&lt;span&gt;If you’re sold on the idea of GitOps, there are alternative tools that can be used if you’re unable to use Helm or choose not to. &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;You can use ArgoCD on its own. It is pretty flexible and can work with other templating solutions or even plain manifests. &lt;/span&gt;&lt;span&gt;Another templating tool that can be used instead of Helm is &lt;/span&gt;&lt;a href="https://kustomize.io/" rel="noopener noreferrer"&gt;&lt;span&gt;Kustomize&lt;/span&gt;&lt;/a&gt;&lt;span&gt;. This tool is built into &lt;/span&gt;&lt;span&gt;&lt;code&gt;kubectl&lt;/code&gt;&lt;/span&gt;&lt;span&gt; and is native to Kubernetes. It allows you to customize Kubernetes configurations using only the Kubernetes API resource files.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Now, let’s explore our third approach about how to implement GitOps using Helm and Argo CD...&lt;/span&gt;&lt;/p&gt;

&lt;h4&gt;Approach #3: Using Helm with GitOps&lt;/h4&gt;

&lt;p&gt;&lt;span&gt;Now that you’ve seen how GitOps can be applied without Helm, let’s explore how you can use it with Helm. &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;First, the Helm chart and any application changes must be committed in Git prior to being applied to the cluster. Meaning all of your workload definitions in a YAML format, the Helm charts, and any other Kubernetes custom resources that define the cluster’s desired state must be committed to the repo. This way rollbacks and logs are accessible and the state of production can be restored easily.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Within Argo CD you can connect the Git repository using HTTPS and add the URL directly. This then allows you to enable auto-synchronization to automatically synchronize the cluster to the desired state in the Git repository. Once synced successfully, the application status is recognized as Healthy. Otherwise, if the application is OutOfSync, you can rollback or view the release history to resolve the issue.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Here’s an example of a Healthy application in the Argo CD UI.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/09/HelmGitOpsArgoUI.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2021%2F09%2FHelmGitOpsArgoUI-1024x455.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;When the application is running you can view its resource components, logs, events, and the health status.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;For good measure, here’s a visual of the Argo CD UI exemplifying an OutOfSync application when the live state deviates from the target state.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/09/OutOfSyncArgoUI.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2021%2F09%2FOutOfSyncArgoUI.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;If your application had an error or was OutOfSync like the example above, you could execute the argo history command that allows you to view the application deployment history:&lt;/span&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;argocd app history &amp;lt;argocd_app_name&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Then, if you need to rollback the deployment you can do so by executing this command:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;argocd app rollback &amp;lt;argocd_app_name&amp;gt; &amp;lt;history_id&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Essentially, these commands leverage a faster and more secure deployment, by enabling the tracking from the Git repository. It also allows you to track the active Kubernetes resources and events.&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Therefore, using source control like this is what classifies this application deployment as GitOps!&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Something important to note is that Argo CD provides native support for Helm, meaning you can directly connect a packaged Helm chart and Argo CD will monitor it for new versions. When this takes place the Helm chart will no longer function as a Helm chart and instead, is rendered with the Helm template when Argo is installed, using the Argo CD application manifest.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Argo CD then deploys and monitors the application components until both states are identical. The application is no longer a Helm application and is now recognized as an Argo app and can only operate by Argo CD. Hence if you execute the &lt;/span&gt;&lt;span&gt;helm list&lt;/span&gt;&lt;span&gt; command, you should no longer be able to view your &lt;/span&gt;&lt;span&gt;helm release&lt;/span&gt;&lt;span&gt; because the Helm metadata no longer exists.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Here’s an example of the command output. As you can see, the Argo CD application is NOT detected as a Helm application.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codefresh.io/wp-content/uploads/2021/09/Empty-Helm-List.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodefresh.io%2Fwp-content%2Fuploads%2F2021%2F09%2FEmpty-Helm-List.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;span&gt;Helm is a powerful tool that is used often with Kubernetes deployments and provides tracking for each release. This helps ensure reliable and quick deployments for development teams. &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;So, if you’re completely new to Helm, I suggest referring to our documentation to learn more about it, here: &lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://codefresh.io/helm-tutorial/helm-deployment-environments/" rel="noopener noreferrer"&gt;&lt;span&gt;Helm Deployment Environments&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://codefresh.io/docs/docs/new-helm/helm-best-practices/" rel="noopener noreferrer"&gt;&lt;span&gt;Helm Best Practices&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://codefresh.io/helm-tutorial/simplify-kubernetes-helm-deployments/" rel="noopener noreferrer"&gt;&lt;span&gt;How to Simplify your Kubernetes Helm Deployments&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span&gt;We'll discuss additional tools in our next post that can help you and your team continue implementing a GitOps process to your development and infrastructure systems.&lt;/span&gt;&lt;/p&gt;

</description>
      <category>gitops</category>
      <category>helm</category>
      <category>argocd</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>How to Create Docker Images for ASP.NET Core</title>
      <dc:creator>Hannah</dc:creator>
      <pubDate>Fri, 16 Jul 2021 19:25:33 +0000</pubDate>
      <link>https://forem.com/codefreshio/how-to-create-docker-images-for-asp-net-core-1bi2</link>
      <guid>https://forem.com/codefreshio/how-to-create-docker-images-for-asp-net-core-1bi2</guid>
      <description>&lt;p&gt;Microsoft has begun working with the Docker team and community so Docker can be used for the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Build&lt;/li&gt;
&lt;li&gt;  Host&lt;/li&gt;
&lt;li&gt;  Scale .NET applications with ease&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What will you learn in this tutorial?
&lt;/h3&gt;

&lt;p&gt;If you would like to run an ASP.NET Core web app in a Docker container and learn how to create images, we will explain all the steps on how to do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Build a custom image with Dockerfile&lt;/li&gt;
&lt;li&gt;  Use a prebuilt image hosted by Microsoft&lt;/li&gt;
&lt;li&gt;  Use a prebuilt image with HTTPS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A Docker container image is a standalone, lightweight package that can be executed and contains all the requirements you need to run an application, such as: code, runtime, libraries, and settings. The image can then be pushed to a container registry and pulled to your server to run as a container.&lt;/p&gt;

&lt;p&gt;For this demo you can clone or download the ASP.NET Core sample app and run it in Docker containers. The sample app builds in a &lt;a href="https://hub.docker.com/_/microsoft-dotnet-sdk/"&gt;.NET SDK&lt;/a&gt; container that copies the result of the build into a new image based on the &lt;a href="https://hub.docker.com/_/microsoft-dotnet-runtime/"&gt;.NET Docker Runtime&lt;/a&gt; image. This demo also works with both Linux and Windows containers too!&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://dotnet.microsoft.com/download"&gt;Latest version of ASP.Net Core&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup Docker:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.docker.com/docker-for-windows/install/"&gt;Windows&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.docker.com/docker-for-mac/install/"&gt;macOS&lt;/a&gt;&lt;br&gt;
Linux distributions:*   &lt;a href="https://docs.docker.com/install/linux/docker-ce/centos/"&gt;CentOS&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.docker.com/install/linux/docker-ce/debian/"&gt;Debian&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.docker.com/install/linux/docker-ce/fedora/"&gt;Fedora&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://desktop.github.com/"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Build a custom Docker image with Dockerfile
&lt;/h2&gt;

&lt;p&gt;Let’s start this tutorial by creating a Docker image from scratch using a Dockerfile for your app. Later on in this tutorial, we’ll explain how to use prebuilt Docker images with your ASP.NET Core web app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ASP.NET Core web app:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/visualstudio/ide/quickstart-aspnet-core?view=vs-2019"&gt;Create your own app&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/hseligson1/DockerDemo"&gt;DockerDemo app with Dockerfile&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note: The Dockerfile within the demo app uses a Docker &lt;a href="https://docs.docker.com/develop/develop-images/multistage-build/"&gt;multi-stage build feature&lt;/a&gt; that can be used to build and run in different containers. We’ll share more about this in a future blog post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create a Dockerfile in your project folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The  &lt;a href="https://docs.docker.com/samples/dotnetcore/"&gt;Dockerfile&lt;/a&gt; is essentially a recipe for creating your Docker image and is added to the project’s root. It includes the necessary commands for a user to build an image when executing &lt;code&gt;docker build&lt;/code&gt;. For additional details to better understand the commands within the file, please refer to the &lt;a href="https://docs.docker.com/engine/reference/builder/"&gt;Dockerfile reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 80&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mcr.microsoft.com/dotnet/core/sdk:3.1-buster&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; \["DockerDemo.csproj", ""\]&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet restore &lt;span class="s2"&gt;"./DockerDemo.csproj"&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; "/src/."&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet build &lt;span class="s2"&gt;"DockerDemo.csproj"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;-o&lt;/span&gt; /app/build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;publish&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet publish &lt;span class="s2"&gt;"DockerDemo.csproj"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;-o&lt;/span&gt; /app/publish

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;final&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=publish /app/publish .&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; \["dotnet", "DockerDemo.dll"\] &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create a .dockerignore file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Similar to a .gitignore file a &lt;a href="https://docs.docker.com/engine/reference/builder/#dockerignore-file"&gt;.dockerignore&lt;/a&gt; file allows you to mention a list of files or directories that you want to ignore while building the Docker image. This is essential because it helps reduce the size of an image and speeds up the docker building process.&lt;/p&gt;

&lt;p&gt;Note: We also have an excellent article reviewing the &lt;a href="https://codefresh.io/docker-tutorial/not-ignore-dockerignore-2/"&gt;.dockerignore&lt;/a&gt; file that you might enjoy&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.dockerignore&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;\*\*/.classpath
\*\*/.dockerignore
\*\*/.env
\*\*/.git
\*\*/.gitignore
\*\*/.project
\*\*/.settings
\*\*/.toolstarget
\*\*/.vs
\*\*/.vscode
\*\*/\*.\*proj.user
\*\*/\*.dbmdl
\*\*/\*.jfm
\*\*/azds.yaml
\*\*/bin
\*\*/charts
\*\*/docker-compose\*
\*\*/Dockerfile\*
\*\*/node\_modules
\*\*/npm-debug.log
\*\*/obj
\*\*/secrets.dev.yaml
\*\*/values.dev.yaml
LICENSE
README.md     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build Docker image and start container&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.docker.com/engine/reference/commandline/build/"&gt;docker build&lt;/a&gt; builds a Docker image from the Dockerfile and a &lt;a href="https://docs.docker.com/engine/reference/commandline/build/#examples"&gt;“context”&lt;/a&gt;. The context is a set of files located in a specified PATH or URL.&lt;/p&gt;

&lt;p&gt;Open the terminal or command prompt and navigate to your project folder. Use the following command to build your Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; dockerdemo &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;This returns the status of your build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create and run container&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.docker.com/engine/reference/commandline/run/"&gt;docker run&lt;/a&gt;command creates a new container and runs the Docker image.&lt;/p&gt;

&lt;p&gt;Open the terminal or command prompt and use the following command to run your Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 &lt;span class="nt"&gt;--name&lt;/span&gt; myapp dockerdemo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D5J6W67p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/78148nehxd94jo0pbisb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D5J6W67p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/78148nehxd94jo0pbisb.png" alt="Alt Text" width="512" height="41"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check that the container was created and is running with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Lastly, go to &lt;a href="http://localhost:8080/"&gt;http://localhost:8080/&lt;/a&gt; to access your app in a web browser.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Note:
&lt;/h3&gt;

&lt;p&gt;The Dockerfile and the .dockerignore files are generated for an ASP.NET Core Web app in Visual Studio 2019 when you select Create a new project and Docker is enabled. For more information, you can reference the &lt;a href="https://docs.microsoft.com/en-us/visualstudio/containers/container-tools?view=vs-2019"&gt;Quickstart guide for Docker in Visual Studio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also generate a Dockerfile and .dockerignore file in Visual Studio Code by opening the Command Palette and utilizing the &lt;strong&gt;Docker:Add Docker Files to Workspace&lt;/strong&gt; command. For more information you can reference the &lt;a href="https://code.visualstudio.com/docs/containers/overview"&gt;Working with containers guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetch, Build, and Run a prebuilt Docker image
&lt;/h2&gt;

&lt;p&gt;Now that you’re familiar with how to create a Docker image with a Dockerfile, let’s dive into using a prebuilt image for your ASP.NET Core app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Download/Clone sample app &lt;a href="https://github.com/dotnet/dotnet-docker"&gt;https://github.com/dotnet/dotnet-docker&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assuming all your prerequisites are complete, you can now access existing prebuilt Docker images. You can reference existing Docker images at the public register, &lt;a href="https://hub.docker.com/_/microsoft-dotnet-core"&gt;Docker Hub&lt;/a&gt;. Search for .NET Core and you will find several repos hosted by Microsoft.&lt;/p&gt;

&lt;p&gt;Run the sample app and execute the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:80 &lt;span class="nt"&gt;--name&lt;/span&gt; my&lt;span class="se"&gt;\_&lt;/span&gt;sample mcr.microsoft.com/dotnet/core/samples:aspnetapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command is fetching and running your container which is stored within:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mcr.microsoft.com/dotnet/core/samples
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you receive an error, it’s likely a port conflict, and you’ll need to select a port you’re not using.&lt;/p&gt;

&lt;p&gt;However, your output should look like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5oqFgsHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nv04g93eimxmfzcvj1hd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5oqFgsHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nv04g93eimxmfzcvj1hd.png" alt="Alt Text" width="512" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;View all the images that you are currently running by simply running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;This returns a lot of helpful information, including your container ID, the registry location, and even the command used to run it.&lt;/p&gt;

&lt;p&gt;Launch your browser and navigate to:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:8000"&gt;http://localhost:8000&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Note:
&lt;/h3&gt;

&lt;p&gt;If you've changed your port, make sure you also change this url.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Oo_HcBcH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/91mrnfwvntnu9c6w6dqv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Oo_HcBcH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/91mrnfwvntnu9c6w6dqv.png" alt="Alt Text" width="512" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wasn’t that easy? This demonstrates the simplicity and value of containerization and not having to worry about infrastructure complexities.&lt;/p&gt;

&lt;p&gt;Next, run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker image list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9Xp5LI8n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyiif3d2kud29d57q1co.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9Xp5LI8n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyiif3d2kud29d57q1co.png" alt="Alt Text" width="512" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The screenshot above is a list of all the installed images, with the latest at the top.&lt;/p&gt;

&lt;p&gt;This demonstrates how to serve an image over HTTP locally; however, with containerization you should run your containers over HTTPS. HTTPS provides a secure channel within an insecure network by relying on &lt;a href="https://en.wikipedia.org/wiki/Public_key_certificate"&gt;certificates&lt;/a&gt; and encryption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build prebuilt Docker images with HTTPS
&lt;/h2&gt;

&lt;p&gt;You’re on a roll! Let's review how to build prebuilt container images with HTTPS. ASP.NET Core uses &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-5.0&amp;amp;tabs=visual-studio"&gt;HTTPS by default&lt;/a&gt; for security purposes because it encrypts the traffic between the client and server, so others can't see and prevents any modifications from malicious attackers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;p&gt;.NET Core 3.1 or .NET 5&lt;/p&gt;

&lt;h3&gt;
  
  
  Certificates
&lt;/h3&gt;

&lt;p&gt;For both Windows and macOS or Linux operating systems you will need a &lt;a href="https://en.wikipedia.org/wiki/Self-signed_certificate"&gt;self-signed development certificate&lt;/a&gt; to host the image locally for non-production purposes. Using this certificate helps enable HTTPS on the server and protect your data using a &lt;a href="https://www.ssl.com/faqs/faq-what-is-ssl/"&gt;Secure Socket Layer&lt;/a&gt; (SSL). This can be done multiple ways, and some of those ways are by utilizing &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/additional-tools/self-signed-certificates-guide#with-dotnet-dev-certs"&gt;dotnet dev-certs&lt;/a&gt;, &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/additional-tools/self-signed-certificates-guide#with-powershell"&gt;Powershell&lt;/a&gt;, and &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/additional-tools/self-signed-certificates-guide#with-openssl"&gt;OpenSSL&lt;/a&gt;. This way you can access your application from either port for demo purposes. There’s no right or wrong way to go about this. However, these instructions are similar to using a production certificate you can request within your team.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="http://localhost:8000"&gt;http://localhost:8000&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://localhost:8001"&gt;https://localhost:8001&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Windows using Windows containers
&lt;/h3&gt;

&lt;p&gt;From your Windows terminal, use the following command to generate the cert and configure your local machine (make sure to replace “my password” with something unique):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet dev-certs https &lt;span class="nt"&gt;-ep&lt;/span&gt; %USERPROFILE%&lt;span class="se"&gt;\\&lt;/span&gt;.aspnet&lt;span class="se"&gt;\\&lt;/span&gt;https&lt;span class="se"&gt;\\&lt;/span&gt;aspnetapp.pfx &lt;span class="nt"&gt;-p&lt;/span&gt; mypassword
dotnet dev-certs https &lt;span class="nt"&gt;--trust&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterwards, execute the docker pull/run commands to run the container image with ASP.NET Core configured for HTTPS (make sure your password matches the one you assigned for the certificate):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull mcr.microsoft.com/dotnet/samples:aspnetapp

docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:80 &lt;span class="nt"&gt;-p&lt;/span&gt; 8001:443 &lt;span class="nt"&gt;-e&lt;/span&gt; 
&lt;span class="nv"&gt;ASPNETCORE_URLS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://+;http://+"&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;ASPNETCORE_HTTPS_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8001 &lt;span class="nt"&gt;-e&lt;/span&gt; 
&lt;span class="nv"&gt;ASPNETCORE_Kestrel__Certificates__Default__Password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mypassword"&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; 
&lt;span class="nv"&gt;ASPNETCORE_Kestrel__Certificates__Default__Path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="se"&gt;\h&lt;/span&gt;ttps&lt;span class="se"&gt;\a&lt;/span&gt;spnetapp.pfx &lt;span class="nt"&gt;-v&lt;/span&gt; 
%USERPROFILE%&lt;span class="se"&gt;\.&lt;/span&gt;aspnet&lt;span class="se"&gt;\h&lt;/span&gt;ttps:C:&lt;span class="se"&gt;\h&lt;/span&gt;ttps&lt;span class="se"&gt;\ &lt;/span&gt;
mcr.microsoft.com/dotnet/samples:aspnetapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to learn more about configuring Windows using a Linux container, you can reference the &lt;a href="https://github.com/dotnet/dotnet-docker/blob/main/samples/host-aspnetcore-https.md"&gt;Microsoft documentation&lt;/a&gt; for details.&lt;/p&gt;

&lt;h3&gt;
  
  
  MacOs/Linux
&lt;/h3&gt;

&lt;p&gt;From your Mac/Linux terminal, you can execute this command to generate a certificate and configure your local machine (make sure to replace “my password” with something unique):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet dev-certs https &lt;span class="nt"&gt;-ep&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/.aspnet/https/aspnetapp.pfx &lt;span class="nt"&gt;-p&lt;/span&gt; mypassword
dotnet dev-certs https –trust
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should note that depending on which Linux distribution you’re utilizing, the command: &lt;code&gt;dotnet dev-certs https -trust&lt;/code&gt; may not work, and you may need to find an alternative way by researching the specific distribution’s documentation.&lt;/p&gt;

&lt;p&gt;Then, execute the following command to run the container image with ASP.NET Core and configure with HTTPS (make sure your password matches the one you assigned for the certificate):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull mcr.microsoft.com/dotnet/samples:aspnetapp

docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:80 &lt;span class="nt"&gt;-p&lt;/span&gt; 8001:443 &lt;span class="nt"&gt;-e&lt;/span&gt; 
ASPNETCORE&lt;span class="se"&gt;\_&lt;/span&gt;&lt;span class="nv"&gt;URLS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://+;http://+"&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; 
ASPNETCORE&lt;span class="se"&gt;\_&lt;/span&gt;HTTPS&lt;span class="se"&gt;\_&lt;/span&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8001 &lt;span class="nt"&gt;-e&lt;/span&gt; ASPNETCORE&lt;span class="se"&gt;\_&lt;/span&gt;Kestrel&lt;span class="se"&gt;\_\_&lt;/span&gt;Certificates&lt;span class="se"&gt;\_\_&lt;/span&gt;Default&lt;span class="se"&gt;\_\_&lt;/span&gt;&lt;span class="nv"&gt;Password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mypassword"&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; ASPNETCORE&lt;span class="se"&gt;\_&lt;/span&gt;Kestrel&lt;span class="se"&gt;\_\_&lt;/span&gt;Certificates&lt;span class="se"&gt;\_\_&lt;/span&gt;Default&lt;span class="se"&gt;\_\_&lt;/span&gt;&lt;span class="nv"&gt;Path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/https/aspnetapp.pfx &lt;span class="nt"&gt;-v&lt;/span&gt; 
&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/.aspnet/https:/https/ mcr.microsoft.com/dotnet/samples:aspnetapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Within this demonstration, you were able to get familiar with Docker and fetch, build, and run a prebuilt ASP.NET Core container image and serve the container over to HTTPS. You also were able to touch on some of the core concepts such as the images and using a DockerFile and .dockerignore file. Nice work!&lt;/p&gt;

&lt;p&gt;In a future blog post, we’ll review 3 different ways to create a Docker image for .NET, so stay tuned!&lt;/p&gt;

&lt;p&gt;Cover photo by &lt;a href="https://www.pexels.com/photo/close-up-photography-of-black-and-green-computer-keyboard-keys-51415/"&gt;Pexels&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
