|
1 | 1 | = ApplicationSets |
2 | 2 | include::_attributes.adoc[] |
3 | 3 |
|
4 | | -... |
| 4 | +With Argo CD there are often situations where you want to deploy or generate multiple versions of the same Application with variations. These variations can be static, |
| 5 | +i.e. a basic list of differing elements, or dynamic based on external inputs such as git repositories. |
| 6 | + |
| 7 | +This is where the Argo CD link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset[ApplicationSet,window="_blank"] feature |
| 8 | +comes into play. ApplicationSets enables you to generate Application resources using templating. Each ApplicationSet can include one or |
| 9 | +more generators that power the creation of Applications. Argo CD currently includes many different generators and enables users to create custom generators via a Plugin architecture. |
| 10 | + |
| 11 | +There are a number of link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators[generators,window="_blank"] available, some common examples of these generators include: |
| 12 | + |
| 13 | +* 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 |
| 14 | +* 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. |
| 15 | +* 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. |
| 16 | +* 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. |
| 17 | +* Using the link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Matrix[Matrix,window="_blank"] |
| 18 | +and link:https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Merge[Merge,window="_blank"] to combine the results from multiple generators. |
| 19 | +
|
| 20 | +== Static Generation with List Generator |
| 21 | +
|
| 22 | +Let's look at a simple example of an Application that uses a List generator to create the development and production Applications |
| 23 | +for the `coolstore-app` Application we deployed earlier. |
| 24 | +
|
| 25 | +Deploy the ApplicationSet using the following command: |
| 26 | +
|
| 27 | +[.console-input] |
| 28 | +[source,sh,subs="attributes",role=execute] |
| 29 | +---- |
| 30 | +sed 's/$USER/{user}/' ~/workshop/content/modules/ROOT/examples/coolstore-gitops-appset.yaml | sed 's/$SUBDOMAIN/{subdomain}/' | oc apply -f - -n {user}-argocd |
| 31 | +---- |
| 32 | +
|
| 33 | +Next have a look at the ApplicationSet that was deployed with this command: |
| 34 | +
|
| 35 | +[.console-input] |
| 36 | +[source,sh,subs="attributes",role=execute] |
| 37 | +---- |
| 38 | +oc get appset coolstore-apps -o yaml -n {user}-argocd | oc neat |
| 39 | +---- |
| 40 | +
|
| 41 | +[.console-output] |
| 42 | +[source,yaml,subs="attributes+,+macros"] |
| 43 | +---- |
| 44 | +apiVersion: argoproj.io/v1alpha1 |
| 45 | +kind: ApplicationSet |
| 46 | +metadata: |
| 47 | + name: coolstore-apps |
| 48 | + namespace: {user}-argocd |
| 49 | + finalizers: |
| 50 | + - resources-finalizer.argocd.argoproj.io <1> |
| 51 | +spec: |
| 52 | + generators: |
| 53 | + - list: <2> |
| 54 | + elements: |
| 55 | + - environment: dev <3> |
| 56 | + - environment: prod |
| 57 | + goTemplate: true |
| 58 | + goTemplateOptions: |
| 59 | + - missingkey=error |
| 60 | + template: <4> |
| 61 | + metadata: |
| 62 | + name: coolstore-app-{{.environment}} <5> |
| 63 | + namespace: {user}-argocd |
| 64 | + spec: |
| 65 | + destination: |
| 66 | + name: in-cluster |
| 67 | + namespace: {user}-{{.environment}} |
| 68 | + project: {user} |
| 69 | + source: |
| 70 | + path: content/modules/ROOT/files/gitops/module-02 |
| 71 | + repoURL: https://gitea-gitea.{subdomain}/{user}/workshop.git |
| 72 | + targetRevision: HEAD |
| 73 | + syncPolicy: |
| 74 | + automated: |
| 75 | + prune: true |
| 76 | + selfHeal: true |
| 77 | +---- |
| 78 | +<1> Argo CD will automatically delete the Applications when the ApplicationSet is deleted. Including a finalizer ensures that the |
| 79 | +resources the Application deployed will also be deleted. See more information link:https://argo-cd.readthedocs.io/en/stable/user-guide/app_deletion/#about-the-deletion-finalizer[here,window="_blank"]. |
| 80 | +<2> We are using the `list` generator which enables us to provide a static list of elements to dynamically |
| 81 | +generate applications, basically it is 1:1 per element |
| 82 | +<3> Each element has one value, `environment`, which will be templated into the resulting Application object. |
| 83 | +<4> The `template` section is where we define the Application resource that the ApplicationSet will create |
| 84 | +<5> Here is an example of referencing the `environment` value to template the name. |
| 85 | +
|
| 86 | +Note that while we created these Applications earlier, the ApplicationSet will now assume ownership of them, This |
| 87 | +can be validated with the following command: |
| 88 | +
|
| 89 | +[.console-input] |
| 90 | +[source,sh,subs="attributes",role=execute] |
| 91 | +---- |
| 92 | +oc get app coolstore-app-dev -o=jsonpath='{.metadata.ownerReferences}' -n {user}-argocd | jq -s . |
| 93 | +---- |
| 94 | +
|
| 95 | +[.console-output] |
| 96 | +[source,yaml,subs="attributes+,+macros"] |
| 97 | +---- |
| 98 | +[ |
| 99 | + [ |
| 100 | + { |
| 101 | + "apiVersion": "argoproj.io/v1alpha1", |
| 102 | + "blockOwnerDeletion": true, |
| 103 | + "controller": true, |
| 104 | + "kind": "ApplicationSet", |
| 105 | + "name": "coolstore-apps", |
| 106 | + "uid": "1cb40de5-09a0-440e-a12e-28941e9c81b1" |
| 107 | + } |
| 108 | + ] |
| 109 | +] |
| 110 | +---- |
| 111 | +
|
| 112 | +As we can see ApplicationSets provide an easy way to generate Application objects statically but now let's have a look |
| 113 | +at dynamic generation. |
| 114 | +
|
| 115 | +== Dynamic Generation with git Generator |
| 116 | +
|
| 117 | +A common pattern when deploying an application to multiple environments is to have a repository that contains the following structure: |
| 118 | +
|
| 119 | +* *base*: the common assets that we want to deploy |
| 120 | +* *overlays*: |
| 121 | + ** *dev*: specific values that will override the ones in the base for the "dev" environment |
| 122 | + ** *prod*: specific values that will override the ones in the base for the "prod" environment |
| 123 | +
|
| 124 | +Let's deploy these applications using an ApplicationSet as we did previously but this time we will use a git generator. |
| 125 | +
|
| 126 | +[.console-input] |
| 127 | +[source,sh,subs="attributes",role=execute] |
| 128 | +---- |
| 129 | +sed 's/$USER/{user}/' ~/workshop/content/modules/ROOT/examples/web-nodejs-appset.yaml | sed 's/$SUBDOMAIN/{subdomain}/' | oc apply -f - -n {user}-argocd |
| 130 | +---- |
| 131 | +
|
| 132 | +Let's have a quick look at our new ApplicationSet: |
| 133 | +
|
| 134 | +[.console-input] |
| 135 | +[source,sh,subs="attributes",role=execute] |
| 136 | +---- |
| 137 | +oc get appset web-nodejs -o yaml -n {user}-argocd | oc neat |
| 138 | +---- |
| 139 | +
|
| 140 | +[.console-output] |
| 141 | +[source,yaml,subs="attributes+,+macros"] |
| 142 | +---- |
| 143 | +apiVersion: argoproj.io/v1alpha1 |
| 144 | +kind: ApplicationSet |
| 145 | +metadata: |
| 146 | + name: web-nodejs |
| 147 | + namespace: {user}-argocd |
| 148 | + finalizers: |
| 149 | + - resources-finalizer.argocd.argoproj.io <1> |
| 150 | +spec: |
| 151 | + generators: |
| 152 | + - git: <1> |
| 153 | + directories: |
| 154 | + - path: globex/overlays/* <2> |
| 155 | + repoURL: https://gitea-gitea.{subdomain}/{user}/gitops.git <3> |
| 156 | + revision: HEAD |
| 157 | + values: |
| 158 | + user: {user} <4> |
| 159 | + goTemplate: true |
| 160 | + goTemplateOptions: |
| 161 | + - missingkey=error |
| 162 | + template: |
| 163 | + metadata: |
| 164 | + name: app-{{.path.basename}} <5> |
| 165 | + namespace: '{{ .values.user }}-argocd' |
| 166 | + spec: |
| 167 | + destination: |
| 168 | + name: in-cluster |
| 169 | + namespace: '{{ .values.user }}-{{.path.basename}}' |
| 170 | + project: '{{ .values.user }}' |
| 171 | + source: |
| 172 | + kustomize: |
| 173 | + patches: |
| 174 | + - patch: |- |
| 175 | + - op: replace |
| 176 | + path: /spec/template/spec/containers/0/env/0/value |
| 177 | + value: 'gateway-vertx-{{ .values.user }}-{{.path.basename}}' |
| 178 | + target: |
| 179 | + kind: Deployment |
| 180 | + name: web-nodejs |
| 181 | + path: '{{.path.path}}' <6> |
| 182 | + repoURL: https://gitea-gitea.{subdomain}/{user}/gitops.git |
| 183 | + targetRevision: main |
| 184 | + syncPolicy: |
| 185 | + automated: |
| 186 | + prune: true |
| 187 | +---- |
| 188 | +<1> We are using the git generator to create an Application for every directory in the target repository and path |
| 189 | +<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 |
| 190 | +<3> The target repository |
| 191 | +<4> Additional values to pass to the template |
| 192 | +<5> The basename of the path for which the Application is being generated, either `dev` or `prod` in this case |
| 193 | +<6> the full path in the repo for the current directory |
| 194 | +
|
| 195 | +Check that the Applications have been created: |
| 196 | +
|
| 197 | +[.console-input] |
| 198 | +[source,sh,subs="attributes",role=execute] |
| 199 | +---- |
| 200 | +oc get apps -n {user}-argocd |
| 201 | +---- |
| 202 | +
|
| 203 | +[.console-output] |
| 204 | +[source,yaml,subs="attributes+,+macros"] |
| 205 | +---- |
| 206 | +app-dev Synced Healthy |
| 207 | +app-prod Synced Progressing |
| 208 | +coolstore-app-dev Synced Healthy |
| 209 | +coolstore-app-prod Synced Healthy |
| 210 | +dev-tools Synced Healthy |
| 211 | +pipeline-helm Synced Healthy |
| 212 | +---- |
| 213 | +
|
| 214 | +[NOTE] |
| 215 | +The `app-prod` application may be `Progressing` for awhile or show as `Degraded`, this is because we have not yet deployed the updated |
| 216 | +image generated by the Pipeline in production. We will perform this step in the next section. |
| 217 | +
|
| 218 | +We can verify that the applications have been created in the Shared OpenShift GitOps by checking the Application tiles. |
| 219 | +
|
| 220 | +* Go to OpenShift GitOps and select the "app-dev" application in the main page to access the details. |
| 221 | +
|
| 222 | +* On the top-left side, click on *"App details"* to access the information about the application, such as the git repository, the branch where the files are located, the target cluster and namespace where the application is deployed, etc. |
| 223 | +
|
| 224 | +If we pay closer attention, there are 3 items worth mentioning to understand the multi-environment management: |
| 225 | +
|
| 226 | +* *REPO_URL:* the git repository where our the resources we want to deploy are defined |
| 227 | +
|
| 228 | +* *TARGET REVISION:* the branch to use |
| 229 | +
|
| 230 | +* *PATH:* the folder that contains the specific values for that environment. Here for example, for the "DEV" environment, we use the file located in "globex/overlays/dev". |
| 231 | +
|
| 232 | +You can see more details by opening the "gitops" repository in gitea, and navigating to "globex" folder. |
| 233 | +
|
| 234 | +== Combining Generators |
0 commit comments