From 9385b80f487b5f3d5780706840bae99484847930 Mon Sep 17 00:00:00 2001 From: Alvaro Lopez Medina Date: Fri, 7 Nov 2025 17:50:02 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20Improve=20Attack=20of=20the=20Pi?= =?UTF-8?q?pelines=20section?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1-sealed-secrets.md | 12 ++--- .../2-app-of-apps.md | 49 +++++++++---------- .../3-the-pipelines.md | 4 +- docs/2-attack-of-the-pipelines/3a-jenkins.md | 22 ++++----- docs/2-attack-of-the-pipelines/3b-tekton.md | 8 +-- .../3c-create-new-group.md | 12 ++--- 6 files changed, 53 insertions(+), 54 deletions(-) diff --git a/docs/2-attack-of-the-pipelines/1-sealed-secrets.md b/docs/2-attack-of-the-pipelines/1-sealed-secrets.md index 79184530..36612271 100644 --- a/docs/2-attack-of-the-pipelines/1-sealed-secrets.md +++ b/docs/2-attack-of-the-pipelines/1-sealed-secrets.md @@ -2,10 +2,10 @@ When we say GitOps, we say _"if it's not in Git, it's NOT REAL"_. But how are we going to store our sensitive data like credentials in Git repositories, where many people can access?! Sure, Kubernetes provides a way to manage secrets, but the problem is that it stores the sensitive information as a base64 string - anyone can decode the base64 string! Therefore, we cannot store `Secret` manifest files openly. We use an open-source tool called Sealed Secrets to address this problem. -Sealed Secrets allows us to _seal_ Kubernetes secrets by using a utility called `kubeseal`. The `SealedSecrets` are Kubernetes resources that contain encrypted `Secret` object that only the controller can decrypt. Therefore, a `SealedSecret` is safe to store even in a public repository. +Sealed Secrets allows us to _seal_ Kubernetes secrets by using a utility called `kubeseal`. The `SealedSecrets` are Kubernetes resources that contain an encrypted `Secret` object that only the controller can decrypt. Therefore, a `SealedSecret` is safe to store even in a public repository.

- ⛷️ NOTE ⛷️ - If you switch to a different Dev Spaces Workspaces environment, please run below commands before going forward. + ⛷️ NOTE ⛷️ - If you switch to a different Dev Spaces Workspace environment, please run below commands before going forward.

```bash @@ -16,7 +16,7 @@ git pull ### Sealed Secrets in action -1. The observant among you will have noticed that in the previous exercise we created a secret for git and added it to the cluster WITHOUT putting it in git...😳 Let's start by fixing this and sealing our Git credentials so they can be safely checked in to the code. First, we'll create the secret in a tmp directory. Make sure you have your gitlab user and PAT from the previous exercise set in your environment +1. The observant among you will have noticed that in the previous exercise we created a secret for git and added it to the cluster WITHOUT putting it in git...😳 Let's start by fixing this and sealing our Git credentials so they can be safely checked into the code. First, we'll create the secret in a tmp directory. Make sure you have your gitlab user and PAT from the previous exercise set in your environment ```bash echo ${GITLAB_USER} @@ -67,7 +67,7 @@ EOF cat /tmp/sealed-git-auth.yaml ``` - We should now see the secret is sealed, so it is safe for us to store in our repository. It should look something a bit like this, but with longer password and username output. + We should now see the secret is sealed, so it is safe for us to store in our repository. It should look something like this, but with longer password and username output.

@@ -107,7 +107,7 @@ EOF
         source_ref: "1.0.3"
         values:
           secrets:
-            # Additional secrets will be added to this list along the exercises.
+            # Additional secrets will be added to this list throughout the exercises.
             - name: git-auth
               type: kubernetes.io/basic-auth
               annotations:
@@ -148,7 +148,7 @@ EOF
 
     ![argocd-git-auth-synced.png](images/argocd-git-auth-synced.png)
 
-9. You can also verify it's been synced to Jenkins now by opening `Jenkins -> Manage Jenkins -> Manage Credentials` to view the `-ci-cd-git-auth` credential
+9. You can also verify it's been synced to Jenkins now by opening `Jenkins -> Manage Jenkins -> Credentials` to view the `-ci-cd-git-auth` credential
 
     ```bash#test
     echo https://$(oc get route jenkins --template='{{ .spec.host }}' -n ${TEAM_NAME}-ci-cd)
diff --git a/docs/2-attack-of-the-pipelines/2-app-of-apps.md b/docs/2-attack-of-the-pipelines/2-app-of-apps.md
index 24055015..5124a257 100644
--- a/docs/2-attack-of-the-pipelines/2-app-of-apps.md
+++ b/docs/2-attack-of-the-pipelines/2-app-of-apps.md
@@ -2,15 +2,15 @@
 
 We need a way to bundle up all of our applications and deploy them into each environment. Each PetBattle application has its own Git repository and Helm chart, making it easier to code and deploy independently from other apps.
 
-A developer can get the same experience and end result installing an application chart using `helm install` as our fully automated pipeline. This is important from a useability perspective. Argo CD has great support for all sorts of packaging formats that suit Kubernetes deployments, `Kustomize`, `Helm`, as well as just raw YAML files. Because Helm is a template language, we can mutate the Helm chart templates and their generated Kubernetes objects with various values allowing us to configure them with a custom configuration per environment.
+A developer can get the same experience and end result installing an application chart using `helm install` as our fully automated pipeline. This is important from a usability perspective. Argo CD has great support for all sorts of packaging formats that suit Kubernetes deployments, `Kustomize`, `Helm`, as well as just raw YAML files. Because Helm is a template language, we can mutate the Helm chart templates and their generated Kubernetes objects with various values allowing us to configure them with a custom configuration per environment.
 
-We deploy each of our applications using an Argo CD `application` definition. We use one Argo CD `application` definition for every environment in which we wish to deploy the application. We make use of Argo CD `app of apps pattern` to bundle all of these all up; some might call this an application suite or a system! In PetBattle we generate the app-of-apps definitions using a Helm chart.
+We deploy each of our applications using an Argo CD `application` definition. We use one Argo CD `application` definition for every environment in which we wish to deploy the application. We make use of Argo CD `app-of-apps pattern` to bundle all of these up; some might call this an application suite or a system! In Pet Battle we generate the app-of-apps definitions using a Helm chart.
 
 ### Deploying Pet Battle - Keycloak
 
 > In this exercise we'll deploy PetBattle and a supporting piece of tech it uses (Keycloak) using the same pattern. We'll deploy PetBattle to two environments - `test` and `stage` by configuring the values files in `pet-battle/stage/values.yaml` && `pet-battle/test/values.yaml`
 
-1. In your IDE - open `tech-exercises/values.yaml` file at the root of this project and **swap** `enabled: false` to `enabled: true` as shown below for each of the app-of-pb definitions:
+1. In your IDE - open `tech-exercise/values.yaml` file at the root of this project and **swap** `enabled: false` to `enabled: true` as shown below for each of the app-of-pb definitions:
 
     

@@ -102,6 +102,7 @@ We deploy each of our applications using an Argo CD `application` definition. We
           image_version: latest # container image version
           hpa:
             enabled: false
+          servicemonitor: false
 
       pet-battle:
         name: pet-battle
@@ -118,7 +119,7 @@ We deploy each of our applications using an Argo CD `application` definition. We
     ```bash#test
     # test
     if [[ $(yq e '.applications[] | select(.name=="pet-battle-api") | length' /projects/tech-exercise/pet-battle/test/values.yaml) < 1 ]]; then
-        yq e '.applications.pet-battle-api = {"name": "pet-battle-api","enabled": true,"source": "https://petbattle.github.io/helm-charts","chart_name": "pet-battle-api","source_ref": "1.5.0","values": {"image_name": "pet-battle-api","image_version": "latest", "hpa": {"enabled": false}}}' -i /projects/tech-exercise/pet-battle/test/values.yaml
+        yq e '.applications.pet-battle-api = {"name": "pet-battle-api","enabled": true,"source": "https://petbattle.github.io/helm-charts","chart_name": "pet-battle-api","source_ref": "1.5.0","values": {"image_name": "pet-battle-api","image_version": "latest", "hpa": {"enabled": false}}, "servicemonitor": false }' -i /projects/tech-exercise/pet-battle/test/values.yaml
     fi
     if [[ $(yq e '.applications[] | select(.name=="pet-battle") | length' /projects/tech-exercise/pet-battle/test/values.yaml) < 1 ]]; then
         yq e '.applications.pet-battle = {"name": "pet-battle","enabled": true,"source": "https://petbattle.github.io/helm-charts","chart_name": "pet-battle","source_ref": "1.0.6","values": {"image_version": "latest"}}' -i /projects/tech-exercise/pet-battle/test/values.yaml
@@ -128,7 +129,7 @@ We deploy each of our applications using an Argo CD `application` definition. We
     sed -i '/^# Pet Battle Apps/d' /projects/tech-exercise/pet-battle/test/values.yaml
     # stage
     if [[ $(yq e '.applications[] | select(.name=="pet-battle-api") | length' /projects/tech-exercise/pet-battle/stage/values.yaml) < 1 ]]; then
-        yq e '.applications.pet-battle-api = {"name": "pet-battle-api","enabled": true,"source": "https://petbattle.github.io/helm-charts","chart_name": "pet-battle-api","source_ref": "1.5.0","values": {"image_name": "pet-battle-api","image_version": "latest", "hpa": {"enabled": false}}}' -i /projects/tech-exercise/pet-battle/stage/values.yaml
+        yq e '.applications.pet-battle-api = {"name": "pet-battle-api","enabled": true,"source": "https://petbattle.github.io/helm-charts","chart_name": "pet-battle-api","source_ref": "1.5.0","values": {"image_name": "pet-battle-api","image_version": "latest", "hpa": {"enabled": false}}, "servicemonitor": false }' -i /projects/tech-exercise/pet-battle/stage/values.yaml
     fi
     if [[ $(yq e '.applications[] | select(.name=="pet-battle") | length' /projects/tech-exercise/pet-battle/stage/values.yaml) < 1 ]]; then
         yq e '.applications.pet-battle = {"name": "pet-battle","enabled": true,"source": "https://petbattle.github.io/helm-charts","chart_name": "pet-battle","source_ref": "1.0.6","values": {"image_version": "latest"}}' -i /projects/tech-exercise/pet-battle/stage/values.yaml
@@ -138,7 +139,7 @@ We deploy each of our applications using an Argo CD `application` definition. We
     sed -i '/^# Pet Battle Apps/d' /projects/tech-exercise/pet-battle/stage/values.yaml
     ```
 
-2. The frontend needs to have some configuration applied to it. This could be packaged up in the helm chart or baked into the image - BUT we should really apply configuration as *code*. We should build our apps once so they can be initialized in many environments with configuration supplied at runtime. For the frontend, this means supplying the information about where the API live. We use ArgoCD to manage our application deployments, hence we should update the values supplied to this chart as such.
+2. The frontend needs to have some configuration applied to it. This could be packaged up in the helm chart or baked into the image - BUT we should really apply configuration as *code*. We should build our apps once so they can be initialized in many environments with configuration supplied at runtime. For the frontend, this means supplying the information about where the API lives. We use ArgoCD to manage our application deployments, hence we should update the values supplied to this chart as such.
 
     ```bash#test
     export JSON="'"'{
@@ -239,30 +240,28 @@ We deploy each of our applications using an Argo CD `application` definition. We
 
     ![test-pet-battle-apps-topology.png](images/test-pet-battle-apps-topology.png)
 
-    
- 🔐🔐 If you have not seen the Keycloak Test or Stage dashboard, visit the following URL to test the access and accept the respective SSL certificate 🔐🔐 +### Accessing the Pet Battle Application - ```bash#test - https://keycloak--test./auth - https://keycloak--stage./auth - ``` +As we saw when configuring the `pet-battle` application in the `values.yaml` file, it consists of three components: - ![test-pet-battle-apps-first.png](images/keycloak.png) +* **Pet Battle API**: API that serves the Pet Battle application. +* **Pet Battle**: Frontend application. +* **Keycloak**: Serves the authentication and authorization for the Pet Battle application. -
- 🔐🔐 If you have not seen the Pet Battle API service, visit the following URL to test the access and accept the respective SSL certificate 🔐🔐 +Let's see how to access each of these components: - ```bash#test - https://pet-battle-api--test. - https://pet-battle-api--stage. - ``` +1. 🔐🔐 **Keycloak** 🔐🔐 + * https://keycloak--test./auth + * https://keycloak--stage./auth + + ![test-pet-battle-apps-first.png](images/keycloak.png) -
- 😻😻 Finally, select the Pet Battle URL link highlighted above and you should see ... 😻😻 +2. 🔗🔗 **Pet Battle API** 🔗🔗 + * https://pet-battle-api--test. + * https://pet-battle-api--stage. - ```bash#test - https://pet-battle--test. - https://pet-battle--stage. - ``` +3. 😻😻 **Pet Battle** 😻😻 + * https://pet-battle--test. + * https://pet-battle--stage. ![test-pet-battle-apps-first.png](images/test-pet-battle-apps-first.png) diff --git a/docs/2-attack-of-the-pipelines/3-the-pipelines.md b/docs/2-attack-of-the-pipelines/3-the-pipelines.md index 6a012c1c..23a99dc2 100644 --- a/docs/2-attack-of-the-pipelines/3-the-pipelines.md +++ b/docs/2-attack-of-the-pipelines/3-the-pipelines.md @@ -1,6 +1,6 @@ ## Pipelines -Why creating pipelines: +Why create pipelines: * Assurance - drive up code quality and remove the need for dedicated deployment / release management teams * Freedom - allow developers to take ownership of how and when code gets built and shipped @@ -33,7 +33,7 @@ Choose your own adventure! Each group will get to perform similar tasks: | * We need to fork PetBattle (clone from GitHub and push to GitLab) | * We need to fork PetBattle API (clone from GitHub and push to GitLab) | | * Update `Jenkinsfile` task to leave out some stuff for participants | * Update Tekton task to leave out some stuff for participants | | * Add a webhook into GitLab repositories for triggering jobs | * Add webhook into GitLab repositories for triggering jobs | -| * Update `pet-battle/stage/values.yaml` && `pet-battle/test/values.yaml` with services information. (That's where two teams integrate their work.) | * Update `pet-battle/stage/values.yaml` && `pet-battle/test/values.yaml` with services information. (That's where two teams integrate their work.) +| * Update `pet-battle/stage/values.yaml` && `pet-battle/test/values.yaml` with services information. (That's where two groups integrate their work.) | * Update `pet-battle/stage/values.yaml` && `pet-battle/test/values.yaml` with services information. (That's where two groups integrate their work.) | * By updating version files (pom.xml etc), kick off the pipelines | * By updating version files (pom.xml etc), kick off the pipelines | | [jenkins](2-attack-of-the-pipelines/3a-jenkins.md) | [tekton](2-attack-of-the-pipelines/3b-tekton.md) | diff --git a/docs/2-attack-of-the-pipelines/3a-jenkins.md b/docs/2-attack-of-the-pipelines/3a-jenkins.md index bb138798..424c45be 100644 --- a/docs/2-attack-of-the-pipelines/3a-jenkins.md +++ b/docs/2-attack-of-the-pipelines/3a-jenkins.md @@ -4,10 +4,10 @@