From 04b60567015972184e0f99b936d233ff82abd999 Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Sun, 31 Aug 2025 11:05:07 -0500 Subject: [PATCH] Workshop feedback Signed-off-by: Andrew Block --- content/modules/ROOT/nav.adoc | 2 +- .../ROOT/pages/01-getting-started.adoc | 34 ++++--- .../modules/ROOT/pages/02-argocd-rbac.adoc | 88 +++++++++---------- .../modules/ROOT/pages/03-configuration.adoc | 75 ++++++++-------- .../ROOT/pages/04-applicationsets.adoc | 65 +++++++------- content/modules/ROOT/pages/05-conclusion.adoc | 2 +- content/modules/ROOT/pages/index.adoc | 2 +- 7 files changed, 130 insertions(+), 138 deletions(-) diff --git a/content/modules/ROOT/nav.adoc b/content/modules/ROOT/nav.adoc index bd53747..9ec295d 100644 --- a/content/modules/ROOT/nav.adoc +++ b/content/modules/ROOT/nav.adoc @@ -19,7 +19,7 @@ ** xref:03-configuration.adoc#enable-terminal[Enable Terminal] ** xref:03-configuration.adoc#config-conclusion[Conclusion] -* xref:04-applicationsets.adoc[4. ApplicatonSets] +* xref:04-applicationsets.adoc[4. ApplicationSets] ** xref:04-applicationsets.adoc#app-of-apps[App-of-Apps] ** xref:04-applicationsets.adoc#appsets[ApplicationSets] *** xref:04-applicationsets.adoc#appsets-static[Static Generation] diff --git a/content/modules/ROOT/pages/01-getting-started.adoc b/content/modules/ROOT/pages/01-getting-started.adoc index 165cc75..5928973 100644 --- a/content/modules/ROOT/pages/01-getting-started.adoc +++ b/content/modules/ROOT/pages/01-getting-started.adoc @@ -50,8 +50,8 @@ command to login as {user}. {login_command} ---- -When you login you will see a prompt about using an insecure connection as the Kubernetes API -in this workshop is using a default certificate, type `y` to accept and the login will continue. +When you login, you will see a prompt about using an insecure connection as the Kubernetes API +in this workshop is using a default certificate. Type `y` to accept and the login will continue. *Once completed you should see the following in the terminal:* @@ -94,7 +94,7 @@ console. In this workshop, we will only use the Argo CD web console. Click on the following link to access the Argo CD user interface: -link:https://argocd-server-{user}-argocd.{openshift_cluster_ingress_domain}[{https://argocd-server-{user}-argocd.{openshift_cluster_ingress_domain},window='_blank'] +link:https://argocd-server-{user}-argocd.{openshift_cluster_ingress_domain}[https://argocd-server-{user}-argocd.{openshift_cluster_ingress_domain},window='_blank'] Click on the `Log In Via OpenShift` button and use the same username and password that you used to login in with OpenShift. @@ -114,9 +114,8 @@ image::argocd-login2.png[ArgoCDLogin2, 600] [#argocd-cli] == Argo CD CLI -The Argo CD CLI enables users to interact with Argo CD via a command line. It is useful for both scripts -and general usage. There are two ways to login into the CLI, the preferred way is to login using your Argo CD -credential so that Argo CD RBAC is applied. +The Argo CD CLI enables users to interact with Argo CD via a command line. It is useful as a way to integrate Argo CD into scripts as well as for general usage. There are two ways to login into the CLI. The preferred way is to login using your Argo CD +account so that Argo CD RBAC is applied. The second way is to use the `--core` switch which logs in using the Kubernetes context. This can be useful as a fallback if for some reason the Argo CD CLI is not working as expected. Also link:https://argo-cd.readthedocs.io/en/stable/operator-manual/core[Argo CD Core, window="_blank"] is @@ -124,12 +123,12 @@ a lightweight version of Argo CD that does not include the Server component and available. In this case logging in with core mode is the only option. [NOTE] -Normally when using Argo CD with OIDC the login would be done with using the `--sso` switch -which starts up a local web server to handle the OIDC callback on localhost. However since -our terminal is running in a pod in OpenShift this is not possible. Therefore here we will +Normally when using Argo CD with OIDC, the login would be accomplished using the `--sso` switch +which starts up a local web server to handle the OIDC callback on localhost. However, since +our terminal is running in a pod in OpenShift, this is not possible. Therefore here we will use the `--core` switch since you own the Argo CD instance and thus RBAC is not an issue. -To login into Argo CD execute the following: +To login into Argo CD, execute the following: [.console-input] [source,sh,subs="attributes",role=execute] @@ -144,7 +143,7 @@ Context 'kubernetes' updated ---- [NOTE] -If you get an error about requiring `0400` or `0600` permissions you can +If you get an error about requiring `0400` or `0600` permissions, you can correct it by executing `chmod 0600 .config/argocd/config`. Test your login with the following command to list projects: @@ -175,23 +174,22 @@ argocd --help [#gitops-architecture] == OpenShift GitOps Architecture -In this section we will do a brief overview of the OpenShift GitOps architecture which is depicted in the diagram below. +In this section, we will perform a brief overview of the OpenShift GitOps architecture which is depicted in the diagram below. image::argocd-architecture.png[] [NOTE] -In the diagram above, everything contained within the dotted line is running in OpenShift whereas outside the line are external +In the diagram above, everything contained within the dotted line is running in OpenShift, whereas outside the line are external dependencies or interactions. The OpenShift GitOps operator is used to deploy, manage and upgrade an installation of Argo CD which runs in a specified namespace. The Argo CD installation contains several components, running as individual deployments, which are as follows: -1. *Application Controller*. This component is responsible for deploying Kubernetes resources and watching the resources for change, -to do so it interacts with the Kubernetes API. -2. *Repo Server*. This component manages access to the manifests via a git repository, it is responsible for -fetching the manifests (i.e. yaml files). These manifests can be built from raw yaml, helm or kustomize but -additional tools can be used via a plugin architecture. For improved performance, it caches these manifests +1. *Application Controller*. This component is responsible for deploying Kubernetes resources and watching the resources for changes. +To do so, it interacts with the Kubernetes API. +2. *Repo Server*. This component manages access to the manifests via a git or helm repository. It is responsible for +fetching the manifests (i.e. yaml files). These manifests can be built from raw yaml, helm or kustomize. Additional tools can be used via a plugin architecture. For improved performance, it caches these manifests in the redis component. 3. *Server*. This provides the user interface as well as a REST API. 4. *Dex (optional)*. Provides authentication via OpenShift OAuth2, in this workshop it is not used as we diff --git a/content/modules/ROOT/pages/02-argocd-rbac.adoc b/content/modules/ROOT/pages/02-argocd-rbac.adoc index 43b1df5..75bd918 100644 --- a/content/modules/ROOT/pages/02-argocd-rbac.adoc +++ b/content/modules/ROOT/pages/02-argocd-rbac.adoc @@ -4,13 +4,13 @@ include::_attributes.adoc[] [#rbac-introduction] == Introduction -In this module we will review and configure access to the provided Argo CD instance. +In this module, we will review and configure access to the provided Argo CD instance. Argo CD has it's own Role Based Access Control (RBAC) that is separate and distinct from Kubernetes RBAC. When you interact -with Argo CD via the Argo CD UI, CLI or API the Argo CD RBAC is enforced. If you interact with Argo CD resources directly -using the OpenShift Console or `kubectl`/`oc` then only the Kubernetes RBAC is used. +with Argo CD via the Argo CD UI, CLI or API, Argo CD RBAC is enforced. If you interact with Argo CD resources directly +using the OpenShift Console or `kubectl`/`oc`, then only the Kubernetes RBAC is used. -Additionally the application-controller in Argo CD, as shown previously in the GitOps Architecture, interacts with the +Additionally, the application-controller in Argo CD, as shown previously in the GitOps Architecture, interacts with the Kubernetes API and is governed by Kubernetes RBAC. Argo CD can only deploy and manage the Kubernetes resources that the application-controller has been given permission to use in Kubernetes RBAC. @@ -39,7 +39,7 @@ Next click on the `Edit YAML` button: image::argocd-create-app.png[] -This will take you to a YAML editor, paste the following Application YAML: +This will take you to a YAML editor. Paste the following Application YAML: [.console-input] [source,yaml,subs="attributes",role=execute] @@ -64,16 +64,16 @@ spec: selfHeal: true ---- -Press `Save` to go back to the form view and then press `Create`, notice you receive the following error message: +Press `Save` to go back to the form view and then press `Create`. Notice you receive the following error message: image::argocd-permission-denied.png[] -What's the issue? Let's start by looking at what groups you are member of, in the Argo CD user interface select the User Info section in the left +What's the issue? Let's start by looking at what groups you are member of. In the Argo CD user interface, select the User Info section in the left sidebar: image::argocd-groups.png[] -Notice that the only non-system group that you are a member of is `team{usernum}`, check the Global RBAC to see what groups have been +Notice that the only non-system group that you are a member of is `team{usernum}`. Check the Global RBAC to see what groups have been granted permissions: [.console-input] @@ -92,10 +92,10 @@ oc get argocd argocd -n {user}-argocd -o=jsonpath="{.spec.rbac}" | yq . -P scopes: '[groups]' ---- -By default with OpenShift GitOps the RBAC included in a default instance of Argo CD only grants permissions to a user with cluster-admin permissions and +By default with OpenShift GitOps, the RBAC included in a default instance of Argo CD only grants permissions to a user with cluster-admin permissions and we are not a member of that group. -We could remediate the problem by defining permissions for the `team{usernum}` group here in the Global RBAC but let's start with a bottom-up +We could remediate the problem by defining permissions for the `team{usernum}` group here in the Global RBAC. But, let's start with a bottom-up approach by creating a new Argo CD Project with the needed permissions and then circle back to the Global RBAC. [#rbac-projects] @@ -115,7 +115,7 @@ link:https://argo-cd.readthedocs.io/en/stable/user-guide/projects[documentation] * defining project roles to provide application RBAC (bound to OIDC groups and/or JWT tokens) [IMPORTANT] -Argo CD includes a `default` project when it is installed, it is strongly recommended that this never be used and administrators create +Argo CD includes a `default` project when it is installed. It is strongly recommended that this Project should not be used and instead, have administrators create Projects as needed to support their specific use cases. Let's see what projects are available in Argo CD: @@ -133,7 +133,7 @@ NAME AGE default 168m ---- -As expected, since this is a default Argo CD instance we only have the `default` AppProject. To view the definition of the `default` project +As expected, since this is a default Argo CD instance, we only have the `default` AppProject. To view the definition of the `default` project run the following: [.console-input] @@ -161,14 +161,14 @@ spec: - '*' ---- -Note the `default` Project has no restrictions associated with it, Applications using this Project can deploy any resource, namespace or cluster +Note the `default` Project has no restrictions associated with it. Applications using this Project can deploy any resource, namespace or cluster that Argo CD itself has access to. Also note that no permissions have been defined here either which means that unless we have permissions -defined in the Global RBAC, which we already checked, we cannot deploy any Applications with the `default` project. +defined in the Global RBAC (which we already checked), we cannot deploy any Applications with the `default` project. [NOTE] Remember that Argo CD only has access to the Kubernetes resources that the `argocd-argocd-application-controller` ServiceAccount has been -given access to in Kubernetes. So even though the Project may not restrict access to everything Argo CD is still potentially restricted -by the Kubernetes permissions it has been granted, +given access to in Kubernetes. So even though the Project may not restrict access to everything, Argo CD is still potentially restricted +by the Kubernetes permissions it has been granted. Since we don't want to use the `default` Project, we will create a new Project to deploy Applications @@ -227,17 +227,15 @@ spec: sourceRepos: <6> - https://github.com/OpenShiftDemos/advanced-gitops-workshop - https://github.com/gitops-examples/getting-started -[.console-output] -[source,bash,subs="attributes+,+macros"] ---- Review the items defined by the `workshop` AppProject: -<1> First deny all cluster scoped resources, i.e. resources that don't have a namespace such as ClusterRole. This prevents users from deploying cluster level resources like ClusterRole +<1> First deny all cluster scoped resources, i.e. resources that don't have a namespace such as ClusterRole. This prevents users from deploying cluster level resources, like ClusterRole <2> We define a friendly description for the project -<3> The destinations that Applications that belong to this AppProject are permitted to deploy resources. Specifically we permit the `{user}-dev`, `{user}-stage` and `{user}-prod` namespaces in the local cluster Kubernetes server `https://kubernetes.default.svc`. We could wildcard the namespaces with a single destination using `{user}-*`, however we do not want to have `{user}-argocd` as a valid destination. +<3> The destinations that Applications that belong to this AppProject are permitted to deploy resources. Specifically, we permit the `{user}-dev`, `{user}-stage` and `{user}-prod` namespaces in the local cluster Kubernetes server `https://kubernetes.default.svc`. We could wildcard the namespaces with a single destination using `{user}-*`, however we do not want to have `{user}-argocd` as a valid destination. <4> Certain namespace scoped resources that are typically the purview of the platform team are blacklisted -<5> Project scoped `roles` are defined that provide fine-grained permissions. This will be looked at in more detail shortly +<5> Project scoped `roles` are defined that provide fine-grained permissions. This will be described in further detail shortly <6> The `sourceRepos` limits which git repositories can be used in Applications. Let's look at the roles that were defined in the next section. @@ -269,7 +267,7 @@ Now let's focus on the RBAC defined in the `workshop` Project that we created: Here we are defining a single role: <1> This role is linked to the group `team{usernum}` which your user is a member of. -<2> The name of the role is `admin`, note that this role is scoped specifically to this Project +<2> The name of the role is `admin`. Note that this role is scoped specifically to this Project <3> The policies, i.e permissions, that are applied by this role. Let's break down the first policy into it's constituent parts: @@ -285,23 +283,23 @@ workshop/*, <5> allow <6> ---- -<1> The letter `p` indicates that a policy is being defined, this is how we assign +<1> The letter `p` indicates that a policy is being defined. This is how we assign permissions to roles. <2> Next is the role this policy will be part of. In this case it is the `admin` role which is scoped to the `workshop` Project. <3> Then the resource type for which we are giving permissions to, in this case `applications`. Various Argo CD resource types are supported including `applications`, `clusters`, and link:https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/#rbac-resources-and-actions[more, window="_blank"]. -<4> After resource we define the actions for the policy, in this case we use a wildcard, '*', to permit all actions. Many +<4> After resource types, we define the actions for the policy. In this case, we use a wildcard, '*', to permit all actions. Many different link:https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/#rbac-resources-and-actions[actions, window="_blank"] are available. -<5> Next is the specific Argo CD resource, this can be a wildcard like `*` for all resources or a named resource such as specific Applications. In this case +<5> Next is the specific Argo CD resource. This can be a wildcard like `*` for all resources or a named resource such as specific Applications. In this case, we have `workshop/*` which allows all Applications that belong to the `workshop` Project. -<6> Finally whether we `allow` or `deny` the permission, in this case we `allow` to grant permissions. +<6> Finally, whether we `allow` or `deny` the permission. In this case, we `allow` to grant permissions. The second policy line with the `exec` permission enables usage of the terminal in the Argo CD user interface which we will see in the next module. -Now let's try to create Application again using the same steps as previously, it is the same Application yaml as previously +Now, let's try to create Application again using the same steps that were previously described. It is the same Application yaml as before but the project is changed from `default` to `workshop` [.console-input] @@ -331,23 +329,23 @@ Wait for the Application to become Healthy and Synced as follows: image::argocd-bgd-app.png[] -Now let's check out Global permissions, click on Settings and then Projects: +Now, let's check out Global permissions. Click on Settings and then Projects: image::argocd-settings-project.png[] -Note that we only see a single Project here, `workshop`, but not the `default`. Similarly if you -go back to Settings and click on Clusters no clusters will be visible. +Note that we only see a single Project here, `workshop`, but not the `default`. Similarly, if you +go back to Settings and click on Clusters, no clusters will be visible. -This is because we have only granted permissions scoped to this Project, let's look at the Global RBAC and +This is because we have only granted permissions scoped to this Project. Let's look at the Global RBAC and how to configure it. [#rbac-global] == Argo CD Global RBAC The global permissions for Argo CD are defined in the Argo CD Custom Resource (CR) when using the Argo CD Operator or OpenShift GitOps. If you are -not using the operator then these global roles are defined in the `argocd-rbac-cm` ConfigMap. +not using the operator, then these global roles are defined in the `argocd-rbac-cm` ConfigMap. -By default with OpenShift GitOps the RBAC included in a default instance of Argo CD only grants permissions to a user with cluster-admin permissions. Run +By default with OpenShift GitOps, the RBAC included in a default instance of Argo CD only grants permissions to a user with cluster-admin permissions. Run the following command to see how your Argo CD instance is currently configured with respect to RBAC: [.console-input] @@ -368,22 +366,22 @@ the following command to see how your Argo CD instance is currently configured w A few items to note about this global configuration: -* First the `policy.default` is set to an empty string so that users are denied access to resources by default with permissions needing +* First, the `policy.default` is set to an empty string so that users are denied access to resources by default with permissions needing to be explicitly enabled. -* Next we have the policy section where we define policies and assign them to groups. +* Next, we have the policy section where we define policies and assign them to groups. ** Users in the `system:cluster-admins` group are assigned to the `role:admin` role, this group only applies to the `kube-admin` user. ** The next line operates similarly but grants the `role:admin` role to any users in the `cluster-admins` group. -* Finally scopes are set to include groups. Argo CD uses OIDC for authentication and this -matches OIDC link:https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims[scopes, window="_blank"], scopes selected +* Finally, scopes are set to include groups. Argo CD uses OIDC for authentication and this +matches OIDC link:https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims[scopes, window="_blank"]. Scopes selected here can be used to match groups in the policy section. [IMPORTANT] -Any permissions given in the `policy:default` cannot be removed by additional roles using a `deny` permission hence why we +Any permissions given in the `policy:default` cannot be removed by additional roles using a `deny` permission; hence why we use an empty string so no permissions are granted. The workshop author prefers to explicitly define a `role:none` for this purpose to avoid ambiguity as we will see shortly. -Earlier we checked that no Global permissions were set for our user, let's go ahead and change that by giving ourselves `admin` -access to the instance. To do this we will add a new group to the RBAC definition using the following patch: +Earlier, we checked that no Global permissions were set for our user. Let's go ahead and change that by giving ourselves `admin` +access to the instance. To do this, we will add a new group to the RBAC definition using the following patch: [source,yaml,subs="+macros,attributes+"] ---- @@ -396,7 +394,7 @@ include::ROOT:example$rbac/argocd_rbac_patch.yaml[] sed "s/%USERNUM%/{usernum}/" ~/workshop/content/modules/ROOT/examples/rbac/argocd_rbac_patch.yaml | oc patch -n user{usernum}-argocd argocd argocd --type=merge --patch-file=/dev/stdin ---- -Check the results of this patch by executing the previous command to fetch the RBAC: +Check the results of this patch by executing the previous command to fetch the RBAC configuration: [.console-input] [source,sh,subs="attributes",role=execute] @@ -416,7 +414,7 @@ oc get argocd argocd -n {user}-argocd -o=jsonpath="{.spec.rbac}" | yq . -P ---- A new group has been added to the policy section granting users in `team{usernum}` the `admin` role. The letter `p` -is used to defined policies as we saw in the Project RBAC, here the letter `g` is used to assign a group to a role. +is used to defined policies as we saw in the Project RBAC. The letter `g` in this instance is used to assign a group to a role. Note that what is considered a `group` for matching purposes is controlled by the `scope` that was reviewed earlier. While `groups` is the most commonly set scope, having scopes like `email` @@ -438,7 +436,7 @@ could potentially break the workshop. [#rbac-conclusion] == Conclusion -In this module we learned how Argo CD RBAC works and how to configure the RBAC at both the Global and Project scopes. +In this module, we learned how Argo CD RBAC works and how to configure the RBAC at both the Global and Project scopes. We also learned how Argo CD Projects are configured, how they can be used to restrict what Applications can do and how to assign permissions to groups. @@ -451,6 +449,6 @@ And then in the dialog type `bgd` as the name and click OK to delete the Applica image::argocd-delete-app-dialog.png[] [NOTE] -Foreground and Background delete will remove all of the resources associated with the Application, Non-cascading will -leave the resources in place. Non-cascading can be useful when you need to temporarily remove an Application for some +Foreground and Background delete will remove all of the resources associated with the Application. Non-cascading will +leave the resources in place and can be useful when you need to temporarily remove an Application for some reason such as migrating or restructuring Applications. diff --git a/content/modules/ROOT/pages/03-configuration.adoc b/content/modules/ROOT/pages/03-configuration.adoc index 90faad8..b7e6df2 100644 --- a/content/modules/ROOT/pages/03-configuration.adoc +++ b/content/modules/ROOT/pages/03-configuration.adoc @@ -1,14 +1,14 @@ = GitOps Configuration include::_attributes.adoc[] -Argo CD includes a very large number of configuration options, in this module we will review some of the -key options that advanced GitOps practitioners need to be aware of. However before we get started -lets quickly review how Argo CD manages it's configuration and where it is stored. +Argo CD includes a very large number of configuration options. In this module, we will review some of the +key options that advanced GitOps practitioners need to be aware of. However, before we get started, +let's quickly review how Argo CD manages its configuration and where it is stored. [#config-introduction] == Introduction -If you install Argo CD with a Helm chart you will find that it stores the configuration in the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/argocd-cm-yaml/[argocd-cm, window="_blank] +Whether you installed Argo CD with a Helm chart or the OpenShift GitOps operator, you will find that the resulting configuration is stored in the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/argocd-cm-yaml/[argocd-cm, window="_blank] ConfigMap. Review this as follows: [.console-input] @@ -17,11 +17,9 @@ ConfigMap. Review this as follows: oc get configmap argocd-cm -n {user}-argocd -o yaml | oc neat ---- -This ConfigMap has a number of fields but the bulk of the configuration is for Dex to authenticate to OpenShift. +This ConfigMap has a number of fields, but the bulk of the configuration is used to define how Dex authenticates to OpenShift. -With the Helm chart you could edit the ConfigMap directly but here you cannot because it is operator managed as we installed -Argo CD with the OpenShift GitOps operator. Any changes that are made directly to the ConfigMap will be automatically reverted -by the operator. You can see this is the case by noting the ConfigMap is owned by the operator: +With the Helm chart, you could edit the ConfigMap directly. However, when using the OpenShift GitOps operator with Argo CD, any changes that are made directly to the ConfigMap will be automatically reverted. You can see this is the case by noting the ConfigMap is owned by the operator: [.console-input] [source,yaml,subs="attributes",role=execute] @@ -68,7 +66,7 @@ oc explain argocd.spec.controller This shows the options available for managing the Argo CD Application Controller. The operator does not support all of the configuration options that can be made in the ConfigMap, just the -most common ones. To address this the `extraConfig` field exists that enables directly setting Argo CD +most common ones. To address this, the `extraConfig` field exists that enables directly setting Argo CD configuration and the operator will transpose them as is into the `argocd-cm` ConfigMap. [.console-input] @@ -102,9 +100,9 @@ the health check, *resources without a defined health check will be skipped once Argo CD supports a number of health statuses as per the documentation: -1. _Healthy_. Indicates a resource is in a good state, will automatically be used if no health check is available. +1. _Healthy_. Indicates a resource is in a good state. Will automatically be used if no health check is available. 2. _Suspended_. The resource is suspended and waiting for some external event to resume (e.g. suspended CronJob or paused Deployment) -3. _Progressing_. The resource is not healthy yet but still making progress and might be healthy soon +3. _Progressing_. The resource is not healthy yet, but still making progress and might be healthy soon 4. _Missing_. The resource is missing and not available. 5. _Degraded_. The resource is degraded 6. _Unknown_. The health of the resource could not be determined @@ -122,10 +120,10 @@ folder. 3. _Custom_. These are health checks that you create yourself and configure in Argo CD. This can be done for resources that do not have a health check defined or used to override a Native or Included health check. -To understand the importance of health checks, let's deploy the bgd Application again but this time with a PersistentVolumeClaim (PVC). Also there is a sync wave +To understand the importance of health checks, let's deploy the bgd Application again but this time with a PersistentVolumeClaim (PVC). Also, there is a sync wave defined with the PVC being the first resource deployed. -In the link:https://argocd-server-{user}-argocd.{openshift_cluster_ingress_domain}[Argo CD UI, window="_blank"] create a new Application as follows: +In the link:https://argocd-server-{user}-argocd.{openshift_cluster_ingress_domain}[Argo CD UI, window="_blank"], create a new Application as follows: [.console-input] [source,yaml,subs="attributes",role=execute] @@ -133,12 +131,12 @@ In the link:https://argocd-server-{user}-argocd.{openshift_cluster_ingress_domai sed "s/%USER%/{user}/" ~/workshop/content/modules/ROOT/examples/health/application-bgd.yaml | oc apply -f - ---- -You should see a new Application tile called `health-test` appear but that this tile never gets synced as it is stuck in -`Progressing`. +You should see a new Application tile called `health-test` appear but that this tile never gets synced as it is stuck in the +`Progressing` state. image::health-test-tile-progressing.png[] -Click on the `health-test` tile and note that the PVC seems to be stuck in `Progressing`. +Click on the `health-test` tile and note that the PVC seems to be stuck `Progressing`. image::health-test-pvc-progressing.png[] @@ -157,22 +155,21 @@ NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTR storage Pending gp3-csi 6m52s ---- -Notice the PVC is in a `Pending` state, this is because the storage class we are using is late binding. This means -the PVC only shifts to the `Bound` state when it is mounted. Since we used a sync wave to apply the PVC first we can +Notice the PVC is in a `Pending` state. This is because the storage class we are using is using the late binding strategy which shifts the state to `Bound` only when it is mounted. Since we used a sync wave to apply the PVC first, we can see that it is blocking other items from progressing. You can see the sync waves associated with each item by clicking the list icon in the upper right corner. image::health-test-sync-wave.png[] -Note that the `storage` PVS has a default sync wave of `-` which means `0`, whereas all other resources are set to a sync wave +Note that the `storage` PVC has a default sync wave of `-` which means `0`, whereas all other resources are set to a sync wave of `1` so the PVC is applied first. This situation occurs because the default health check considers a PVC with a `Pending` status to be in the `Progressing` state. Let's -correct this by overriding the health check to be considered `Healthy` when `Pending` with a custom health check. We will use the Argo CD +correct this by overriding the health check to be considered `Healthy` when it is `Pending` by defining a custom health check. We will use the Argo CD Command Line Interface (CLI) to iteratively test our health check. -First start by getting a local copy of the PVC manifest: +First, start by getting a local copy of the PVC manifest: [.console-input] [source,yaml,subs="attributes",role=execute] @@ -180,7 +177,7 @@ First start by getting a local copy of the PVC manifest: oc get pvc storage -n {user}-dev -o yaml > ~/pvc.yaml ---- -Next get a copy of the Argo CD `ConfigMap` where the settings are stored: +Next, get a copy of the Argo CD `ConfigMap` where the settings are stored: [.console-input] [source,yaml,subs="attributes",role=execute] @@ -189,11 +186,11 @@ oc get configmap argocd-cm -n {user}-argocd -o yaml > ~/argocd-cm.yaml ---- [NOTE] -Remember that the Argo CD Operator manages Argo CD configuration in the Argo CD CustomResource, the operator +Remember that the Argo CD Operator manages Argo CD configuration in the Argo CD CustomResource. The operator manages the `argocd-cm` ConfigMap and applies the settings from the operator automatically. If you install -Argo CD with a Helm chart then the `argocd-cm` is managed directly. +Argo CD with a Helm chart, then the `argocd-cm` is managed directly. -Finally use the Argo CD CLI to verify the current health check behavior: +Finally, use the Argo CD CLI to verify the current health check behavior: [.console-input] [source,yaml,subs="attributes",role=execute] ---- @@ -209,8 +206,8 @@ STATUS: Progressing MESSAGE ---- -Note the command confirms that Argo CD considers the PVC to be `Progressing`, let's change that with the following -custom health check writtin in LUA to override the default one: +The command confirms that Argo CD considers the PVC to be `Progressing`. Let's change that with the following +custom health check written in LUA to override the default one: [source,yaml,subs="+macros,attributes+"] ---- @@ -231,8 +228,8 @@ hs.message = "Waiting for PVC status" return hs ---- -In this health check, in section <1> we return a `Healthy` status for both the `Pending` and `Bound` phases, if the status -is `Lost` we return a `Degraded` status and finally if there is no `status` or `phase` we return an `Unknown` status. You can +In this health check, in section <1> we return a `Healthy` status for both the `Pending` and `Bound` phases. If the status +is `Lost`, we return a `Degraded` status and finally if there is no `status` or `phase`, we return an `Unknown` status. You can view how this compares to the native health check for PVCs link:https://github.com/argoproj/gitops-engine/blob/093aef0dad58015619479509f0d2ac71cc9cefd7/pkg/health/health_pvc.go#L28[here, window="_blank"]. Insert this new health check to the local `argocd-cm` ConfigMap we are testing with the following command: @@ -272,7 +269,7 @@ resource.customizations.health.PersistentVolumeClaim: | return hs ---- -Now test the status that is returned using the Argo CD CLI again but using our new configmap with the updated PVC health check: +Now, test the status that is returned using the Argo CD CLI again but using our new ConfigMap with the updated PVC health check: [.console-input] [source,yaml,subs="attributes",role=execute] @@ -308,12 +305,12 @@ In twenty to thirty seconds you should see the Refresh complete and the Applicat image::argocd-health-test-synced.png[] -In this section we have reviewed how health checks work, why they are important and how to iteratively build and test them. +In this section, we have reviewed how health checks work, why they are important and how to iteratively build and test them. [#enable-appset] == Enabling ApplicationSets -By default the OpenShift GitOps operator does not enable ApplicationSets, confirm by reviewing +By default, the OpenShift GitOps operator does not enable ApplicationSets. This can be confirmed by reviewing the existing deployments in the `{user}-argocd` namespace. [.console-input] @@ -338,7 +335,7 @@ Note the absence of an applicationset-controller. You may be wondering why there is no `application-controller` Deployment as per our earlier architecture section. This is because the `application-controller` is deployed as a StatefulSet rather then a Deployment. -To enable ApplicationSets we will apply the following patch to the ArgoCD CR: +To enable ApplicationSets, we will apply the following patch to the ArgoCD CR: [source,yaml,subs="+macros,attributes+"] ---- @@ -346,7 +343,7 @@ include::ROOT:example$enable-applicationset/enable-applicationset-patch.yaml[] ---- [NOTE] -There are more configuraton options available then just `enabled`, feel free to explore them +There are more configuration options available then just `enabled`. Feel free to explore them by running `oc explain argocd.spec.applicationSet`. Apply the patch: @@ -385,8 +382,8 @@ The Argo CD user interface, when viewing a pod, can optionally show a link:https tab similar to what you see in the OpenShift console. This can be useful for organizations which use the Argo CD UI as the primary means for managing Kubernetes resources. -While we previously gave permissions for the terminal in the previous module, by default this is not enabled. To verify this, -in the health application that was deployed previously click on the pod. +While we previously gave permissions for the terminal in the previous module, by default, this is not enabled. To verify this, +in the health application that was deployed previously, click on the pod. image::argocd-select-pod.png[] @@ -403,7 +400,7 @@ to this ConfigMap so some care should be taken when using this feature. [IMPORTANT] Before using `extraConfig`, you should always validate the option you want to set is not in fact -available in the Operator. Also as a reminder never edit the `argocd-cm` ConfigMap directly, the operator will +available in the Operator. Also as a reminder, never edit the `argocd-cm` ConfigMap directly, the operator will revert any manual changes. Review the patch that we are going to apply: @@ -421,7 +418,7 @@ Apply the patch: oc patch -n {user}-argocd argocd argocd --type=merge --patch-file=/home/lab-user/workshop/content/modules/ROOT/examples/pod-exec/enable-terminal-patch.yaml ---- -Verify that you can now see the terminal tab for the pod resource, note that you will need to close the Pod view and then re-open it: +Verify that you can now see the terminal tab for the pod resource. Note that you will need to close the Pod view and then re-open it: image::argocd-terminal.png[] @@ -432,7 +429,7 @@ to enable the terminal. These permissions have already been applied by specifyin [#config-conclusion] == Conclusion -In this module we have learned how to configure Argo CD, the importance of health checks and handling +In this module, we have learned how to configure Argo CD, the importance of health checks and handling configuration options not available in the Operator. Clean-up your work by deleting the `health-test` Application using the default `Foreground` deletion option. diff --git a/content/modules/ROOT/pages/04-applicationsets.adoc b/content/modules/ROOT/pages/04-applicationsets.adoc index c59f1c6..a3a208f 100644 --- a/content/modules/ROOT/pages/04-applicationsets.adoc +++ b/content/modules/ROOT/pages/04-applicationsets.adoc @@ -1,7 +1,7 @@ = ApplicationSets include::_attributes.adoc[] -In this module you will learn how to deploy multiple applications from a single Application using the App-of-Apps pattern +In this module, you will learn how to deploy multiple applications from a single Application using the App-of-Apps pattern and the newer ApplicationSets in Argo CD. [#app-of-apps] @@ -16,10 +16,10 @@ Applications from a single Application and is useful in use cases such as cluste Before we can deploy the App-of-Apps, we first need to deploy a health check for the Application resource which is not included as a health check in Argo CD at this time. [NOTE] -This is because in Argo CD 1.x the default Application health check was removed, the author of this workshop link:https://github.com/argoproj/argo-cd/issues/16870[disagrees, window="_blank"] with +This is because in Argo CD 1.x the default Application health check was removed. The author of this workshop link:https://github.com/argoproj/argo-cd/issues/16870[disagrees, window="_blank"] with that decision but unfortunately this is the current state. -To add the Application Health check use the following command: +To add the Application Health check, use the following command: [.console-input] [source,yaml,subs="attributes",role=execute] @@ -33,7 +33,7 @@ oc patch -n {user}-argocd argocd argocd --type=merge --patch-file=/home/lab-user argocd.argoproj.io/argocd patched ---- -Next review the applications that the App-of-Apps will be deploying: +Next, review the applications that the App-of-Apps will be deploying: [.console-input] [source,bash,subs="attributes+,+macros"] @@ -52,9 +52,9 @@ total 12 ---- There are three Applications defined, one for each environment, with kustomize being used to manage them. If you look at each -of these Applications note that each environment is tied to a different kustomize overlay matching the destination. This +of these Applications, note that each environment is tied to a different kustomize overlay matching the destination. This provides an opportunity to tweak the manifests for anything specific to an environment. For example, if you look at the overlays -for the `stage` and `prod` environments we are patching the vertx-gateway deployment to have two replicas instead of the default +for the `stage` and `prod` environments, we are patching the vertx-gateway deployment to have two replicas instead of the default one replica defined in the base. [source,yaml,subs="+macros,attributes+"] @@ -81,7 +81,7 @@ three environment specific Applications that were deployed by the `coolstore` Ap image::app-of-apps-tiles.png[] -Click on the `coolstore` tile, notice that it has three resources that it deployed which were the environment specific Applications. +Click on the `coolstore` tile. Notice that it has three resources that it deployed which were the environment specific Applications. image::app-of-apps-resources.png[] @@ -92,15 +92,14 @@ Now before we clean-up the Applications have a closer look at the `coolstore` Ap include::ROOT:example$app-of-apps/coolstore-app-of-apps.yaml[] ---- -Notice there is a finalizer defined, this is required if you want the Application to delete the resources it deployed when -using the App-of-Apps pattern as per the link:https://argo-cd.readthedocs.io/en/latest/user-guide/app_deletion/#about-the-deletion-finalizer[documentation, window="_blank"]. +Notice there is a finalizer defined. This is required if you want an Application to delete the resources it deployed as per the link:https://argo-cd.readthedocs.io/en/latest/user-guide/app_deletion/#about-the-deletion-finalizer[documentation, window="_blank"]. [NOTE] The kustomize section is used to transform the destination for the Application for your specific user. This is only needed -here as all users are using the same repository, typically this would not be required. +here as all users are using the same repository. Typically, this would not be required. -In this section we have seen how we can use App-of-Apps to deploy multiple Applications stored in git. However this list of -Applications is static, what if we want to create Applications dynamically based on external sources? This is where +In this section, we have seen how we can use App-of-Apps to deploy multiple Applications stored in git. However, this list of +Applications is static. What if we want to create Applications dynamically based on external sources? This is where ApplicationSets come into play. Delete the Application: @@ -126,8 +125,8 @@ more generators that power the creation of Applications. Argo CD currently inclu Some common examples of these link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators[generators,window="_blank"] include: * Using the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-List[List,window="_blank"] generator for generating applications for different environments. We will look at an example of this shortly -* Leveraging the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Git/[git,window="_blank"] generator to create Applications based on the contents of a git repo, we will look at this in Module 4 as a more dynamic way to generate apps for environments. -* Using the https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Pull-Request/[Pull Request,window="_blank"] generator to provision new environments on the fly to run automated tests before merging the code. +* Leveraging the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Git/[git,window="_blank"] generator to create Applications based on the contents of a git repo. We will look at this in Module 4 as a more dynamic way to generate apps for environments. +* Using the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Pull-Request/[Pull Request,window="_blank"] generator to provision new environments on the fly to run automated tests before merging the code. * Using the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Cluster/[Cluster,window="_blank"] generator to provision an Application across multiple clusters. * Using the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Matrix[Matrix,window="_blank"] and link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Merge[Merge,window="_blank"] to combine the results from multiple generators. @@ -135,8 +134,8 @@ and link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset [#appsets-static] === Static Generation with List Generator -First let's look at a simple example of an Application that uses a List generator to create Applications for different environments -for the `coolstore` Application. This will be a similar use case to what we saw with App-of-Apps but done +First, let's look at a simple example of an Application that uses a List generator to create Applications for different environments +for the `coolstore` Application. This will be a similar use case to what we saw with App-of-Apps but accomplished with ApplicationSets. Deploy the ApplicationSet using the following command: @@ -147,7 +146,7 @@ Deploy the ApplicationSet using the following command: sed 's/$USER/{user}/' ~/workshop/content/modules/ROOT/examples/applicationsets/coolstore-list-appset.yaml | oc apply -n {user}-argocd -f - ---- -Next have a look at the ApplicationSet that was deployed with this command: +Next, have a look at the ApplicationSet that was deployed with this command: [.console-input] [source,sh,subs="attributes",role=execute] @@ -192,7 +191,7 @@ spec: selfHeal: true ---- <1> We are using the `list` generator which enables us to provide a static list of elements to dynamically -generate applications, basically it is 1:1 per element +generate applications. Basically it is 1:1 per element <2> Each element has one value, `environment`, which will be templated into the resulting Application object. <3> The `template` section is where we define the Application resource that the ApplicationSet will create <4> Here is an example of referencing the `environment` value to template the name. @@ -201,7 +200,7 @@ Confirm the three Applications, one for each environment, were created: image::appset-apps-tiles.png[] -When the ApplicationSet generates the Applications it assumes ownership of them, validate this with the following: +When the ApplicationSet generates the Applications, it assumes ownership of them. Validate this with the following: [.console-input] [source,sh,subs="attributes",role=execute] @@ -226,14 +225,14 @@ oc get app coolstore-dev -o=jsonpath='{.metadata.ownerReferences}' -n {user}-arg ] ---- -As we can see ApplicationSets provide an easy way to generate Application objects statically but now let's have a look -where they really shine, dynamic generation based on external sources. +As we can see, ApplicationSets provide an easy way to generate Application objects statically. Now let's have a look +where they really shine: dynamic generation based on external sources. [#appsets-dynamic] === Dynamic Generation with git Generator -In this example we will deploy the front-end of the coolstore using an ApplicationSet with the git generator. The -git generator supports two modes, file and directory. In our case we will leverage the directory mode to +In this example, we will deploy the front-end of the coolstore using an ApplicationSet with the git generator. The +git generator supports two modes: file and directory. In our case, we will leverage the directory mode to point the generator at a set of kustomize overlays in the repository. For those not familiar with kustomize, a common pattern when deploying an application with kustomize for multiple @@ -275,8 +274,8 @@ find ~/workshop/content/modules/ROOT/examples/coolstore-web -print | sort|sed -e | | | | | | | | | | |--kustomization.yaml ---- -Let's deploy these applications using an ApplicationSet using the git generator. However -the git generator is somewhat more complex then the previous static list example so let's test +Let's deploy these applications using an ApplicationSet with the git generator. However, +the git generator is somewhat more complex than the previous static list example. So, let's test it locally first to verify that it works. Output the ApplicationSet to a file replacing the workshop $USER variable with your user: @@ -342,14 +341,14 @@ spec: selfHeal: true ---- <1> We are using the git generator to create an Application for every directory in the target repository and path -<2> The target path, each sub-directory in this path will be used to create an application. In our case the `dev` and `prod` overlays +<2> The target path. Each sub-directory in this path will be used to create an application. In our case, the `dev` and `prod` overlays <3> The target repository <4> Additional values to pass to the template -<5> The basename of the path for which the Application is being generated, either `dev` or `prod` in this case +<5> The basename of the path for which the Application is being generated. Either `dev` or `prod` in this case <6> The full path in the repo for the current directory <7> Example of using the passed in value for `{user}` -Next test the definition by generating the ApplicationSet locally using the `argocd` CLI: +Next, test the definition by generating the ApplicationSet locally using the `argocd` CLI: [.console-input] [source,sh,subs="attributes",role=execute] @@ -366,9 +365,9 @@ NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCP {user}-argocd/app-stage in-cluster {user}-stage workshop Auto-Prune https://github.com/OpenShiftDemos/advanced-gitops-workshop content/modules/ROOT/examples/coolstore-web/overlays/stage main ---- -Note that three Applications are being generated, one for each environment. +Note that three Applications are being generated. One for each environment. -To see the YAML for each Application run the following: +To see the YAML for each Application, run the following: [.console-input] [source,sh,subs="attributes",role=execute] @@ -379,7 +378,7 @@ argocd appset generate ~/appset.yaml -o yaml [IMPORTANT] Using the CLI to generate Applications is very useful when debugging complex ApplicationSets since you do not have to spend the time deploying it to the cluster and looking at the Status block to -understand why it isn't working. +understand what may not be working. Now that the generation has been verified, go ahead and deploy it: @@ -413,7 +412,7 @@ We can also verify that the applications have been created and are healthy in Ar image::coolstore-tiles.png[] -Also in OpenShift check the Topology for `{user}-dev` and click on the Route to view the running Application: +Also in OpenShift, check the Topology for `{user}-dev` and click on the Route to view the running Application: image::coolstore-topology.png[] @@ -424,6 +423,6 @@ image::coolstore-web.png[] [#appsets-conclusion] == Conclusion -In this module we learned how to deploy multiple Applications quickly and easily using the App-of-Apps pattern +In this module, we learned how to deploy multiple Applications quickly and easily using the App-of-Apps pattern and ApplicationSets. We saw how ApplicationSets can be used to generate Applications dynamically based on external input. diff --git a/content/modules/ROOT/pages/05-conclusion.adoc b/content/modules/ROOT/pages/05-conclusion.adoc index 07b7f31..54e970a 100644 --- a/content/modules/ROOT/pages/05-conclusion.adoc +++ b/content/modules/ROOT/pages/05-conclusion.adoc @@ -1,7 +1,7 @@ = Conclusion include::_attributes.adoc[] -Thanks for participating in this workshop, we hope you enjoyed it. +Thanks for participating in this workshop. We hope you enjoyed it. == Resources diff --git a/content/modules/ROOT/pages/index.adoc b/content/modules/ROOT/pages/index.adoc index 27424f0..8db5a45 100644 --- a/content/modules/ROOT/pages/index.adoc +++ b/content/modules/ROOT/pages/index.adoc @@ -3,7 +3,7 @@ :!sectids: OpenShift GitOps is based on the upstream -https://argoproj.github.io/argo-cd/[Argo CD,window='_blank'] project. ArgoCD is +https://argoproj.github.io/argo-cd/[Argo CD,window='_blank'] project. Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. It follows the **GitOps** pattern of using Git repositories as the source of