Concourse: Learn to fly (Part 3)

This is part 3 of my little Concourse-CI series.
Part 1 has shown what Concourse actually is, and in Part 2 I’ve created a first Pipeline that pulled a Git Repository, created a Container Image based on the Dockerfile within that Repo, and finally pushed that image into my local Harbor Registry.
Part 3 however will show how to add the functionality to update my running Kubernetes Deployment with that new image too.
To do this, I need to add another Resource (for Kubernetes) and add another Job that updates the Deployment on my Kubernetes Cluster.

Kubernetes Preparation

Before I can continue with Concourse, I need to do some prep-work on K8s – creating the actual Deployment and creating a ServiceAccount for Concourse.

K8s Deployment

My Deployment YAML:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: learn-to-fly
name: learn-to-fly
spec:
replicas: 1
selector:
matchLabels:
app: learn-to-fly
template:
metadata:
labels:
app: learn-to-fly
spec:
containers:
- image: harbor.vraccoon.lab/library/learn-to-fly@IMAGE
name: learn-to-fly
---
apiVersion: v1
kind: Service
metadata:
labels:
app: learn-to-fly
name: svc-learn-to-fly
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: learn-to-fly
type: LoadBalancer
apiVersion: apps/v1 kind: Deployment metadata: labels: app: learn-to-fly name: learn-to-fly spec: replicas: 1 selector: matchLabels: app: learn-to-fly template: metadata: labels: app: learn-to-fly spec: containers: - image: harbor.vraccoon.lab/library/learn-to-fly@IMAGE name: learn-to-fly --- apiVersion: v1 kind: Service metadata: labels: app: learn-to-fly name: svc-learn-to-fly spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: learn-to-fly type: LoadBalancer
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: learn-to-fly
  name: learn-to-fly
spec:
  replicas: 1
  selector:
    matchLabels:
      app: learn-to-fly
  template:
    metadata:
      labels:
        app: learn-to-fly
    spec:
      containers:
      - image: harbor.vraccoon.lab/library/learn-to-fly@IMAGE
        name: learn-to-fly

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: learn-to-fly
  name: svc-learn-to-fly
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: learn-to-fly
  type: LoadBalancer

It’s a very simple Deployment file.
Just note Line 18 – the actual image digest is missing, because I’m replacing this line during runtime with whatever is the newest digest of my Harbor Image.

Concourse Service Account

Creating the Service Account is again pretty straight forward. I’ll assign it cluster-admin permissions, just because it’s already there and easier that way.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-concourse
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crb-concourse-cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: sa-concourse
namespace: default
apiVersion: v1 kind: ServiceAccount metadata: name: sa-concourse --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: crb-concourse-cluster-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: sa-concourse namespace: default
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sa-concourse

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: crb-concourse-cluster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: sa-concourse
  namespace: default

Get the Service Account’s secret:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
vraccoon@ubu:~$ kubectl get sa sa-concourse -o json | jq .secrets[0].name
"sa-concourse-token-h85dd"
vraccoon@ubu:~$ kubectl get sa sa-concourse -o json | jq .secrets[0].name "sa-concourse-token-h85dd"
vraccoon@ubu:~$ kubectl get sa sa-concourse -o json | jq .secrets[0].name
"sa-concourse-token-h85dd"

Next, get the Token and decode it:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
vraccoon@ubu:~$ kubectl get secrets sa-concourse-token-h85dd -o json | jq .data.token -r | base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaHB.....
vraccoon@ubu:~$ kubectl get secrets sa-concourse-token-h85dd -o json | jq .data.token -r | base64 -d eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaHB.....
vraccoon@ubu:~$ kubectl get secrets sa-concourse-token-h85dd -o json | jq .data.token -r | base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaHB.....

I’ll take a note of that token. I’ll need it in a bit for the K8s Resource in Concourse.

Continue the Pipeline

The preparations are done, let’s get back to our Pipeline.

Kubernetes Resource Type

Concourse doesn’t bring a K8s resource type out of the box, so I have to define the resource “myself”. I’m going to use jgriff’s k8s-resource type for this.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
resource_types:
- name: k8s-resource
type: docker-image
source:
repository: jgriff/k8s-resource
resource_types: - name: k8s-resource type: docker-image source: repository: jgriff/k8s-resource
resource_types:
  - name: k8s-resource
    type: docker-image
    source:
      repository: jgriff/k8s-resource

Line 2 – Name of this Resource type, this is how I name it
Line 5 – This is the reference to the repository. It basically maps to a specific container image

Kubernetes Resource

The Kubernetes Resource from its build structure looks very similar to what I have already with Harbor:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: r-k8s-cluster
type: k8s-resource
icon: kubernetes
source:
url: https://tkg-c1.vraccoon.lab:8443
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaH <truncated-for-brevity>
certificate_authority: |
-----BEGIN CERTIFICATE-----
MIIC+zCCAeOgAwIBAgIUTk0x/4jOgNuKF9L+CHwIo6xP9EkwDQYJKoZIhvcNAQEL
<truncated-for-brevity>
uqGvpS5fz6Y0bgX6TrNsqeFh2ADwZIPcj7/8EerophOGIqD7eJ76GiKlRaLx+0M=
-----END CERTIFICATE-----
- name: r-k8s-cluster type: k8s-resource icon: kubernetes source: url: https://tkg-c1.vraccoon.lab:8443 token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaH <truncated-for-brevity> certificate_authority: | -----BEGIN CERTIFICATE----- MIIC+zCCAeOgAwIBAgIUTk0x/4jOgNuKF9L+CHwIo6xP9EkwDQYJKoZIhvcNAQEL <truncated-for-brevity> uqGvpS5fz6Y0bgX6TrNsqeFh2ADwZIPcj7/8EerophOGIqD7eJ76GiKlRaLx+0M= -----END CERTIFICATE-----
  - name: r-k8s-cluster
    type: k8s-resource
    icon: kubernetes
    source:
      url: https://tkg-c1.vraccoon.lab:8443
      token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaH <truncated-for-brevity>
      certificate_authority: |
                                -----BEGIN CERTIFICATE-----
                                MIIC+zCCAeOgAwIBAgIUTk0x/4jOgNuKF9L+CHwIo6xP9EkwDQYJKoZIhvcNAQEL
                                <truncated-for-brevity>
                                uqGvpS5fz6Y0bgX6TrNsqeFh2ADwZIPcj7/8EerophOGIqD7eJ76GiKlRaLx+0M=
                                -----END CERTIFICATE-----

Line 1 – Just the Name of my resource
Line 2 – The name of the resource-type, I’ve specified earlier
Line 3 – Just an Icon (they are from Material Design Icons)
Line 5 – The url of my Kubernetes Cluster. Make sure, that this FQDN/IP is covered in the Certificate in line 7
Line 6 – The Service account Token, I’ve collected earlier
Line 7 – The Certificate which has to be trusted for this K8s Cluster

Job

This Job is a bit more nested than the one for Harbor in my last post.
This time, the Job consists of a Plan with three steps:

  1. Get the Git Repo
    Similar to before, I need to get the Git Repo. This feels kind of redundant, and it technically is, because I’m pulling the Repo again. In theory I could hand it over from my first job. But in order to pass files from one job to another, I need an S3 compatible storage set up between them. And this felt a bit to much for a Git Repo with just a hand full of text files.
  2. Task to modify the deployment
    This task fires up a script, that checks my local Harbor for the latest image digest and then replace the image value in the k8s deployment file.
    If I’d only write “image: learn-to-fly:latest” in my deployment yaml, Kubernetes would not recognize any change (even though the image version in Harbor were updated). This because K8s only compares these strings.
    An alternative could be to use a versioning resource in concourse to set proper version tags on the image (already during the push), instead of working with the actual digest as I do.
  3. “Put” the deployment in Place
    This is where the Kubernetes resource comes into play. It simply applies the modified deployment file to Kubernetes.
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: j-update-deployment
serial: true
plan:
- get: r-git
trigger: true
passed:
- j-create-and-push-image
- task: t-modify-deployment
config:
platform: linux
image_resource:
type: docker-image
source: {repository: mwendler/jq}
inputs:
- name: r-git
outputs:
- name: e-modified-deployment
run:
path: r-git/k8s/get-digest.sh
- put: r-k8s-cluster
params:
kubectl: apply -f e-modified-deployment/deployment.yml
namespace: default
- name: j-update-deployment serial: true plan: - get: r-git trigger: true passed: - j-create-and-push-image - task: t-modify-deployment config: platform: linux image_resource: type: docker-image source: {repository: mwendler/jq} inputs: - name: r-git outputs: - name: e-modified-deployment run: path: r-git/k8s/get-digest.sh - put: r-k8s-cluster params: kubectl: apply -f e-modified-deployment/deployment.yml namespace: default
- name: j-update-deployment
    serial: true
    plan:
      - get: r-git
        trigger: true
        passed:
          - j-create-and-push-image
      - task: t-modify-deployment
        config:
          platform: linux
          image_resource:
            type: docker-image
            source: {repository: mwendler/jq}
          inputs:
            - name: r-git
          outputs:
            - name: e-modified-deployment
          run:
            path: r-git/k8s/get-digest.sh
      - put: r-k8s-cluster
        params:
          kubectl: apply -f e-modified-deployment/deployment.yml
          namespace: default

Line 1 – The name of the Job. This is also what is displayed in the GUI.
Line 4 – Get the Git Resource (aka clone the Repo)
Lines 6-7 – This step will only trigger, when the previous Job (from part 2 of this series) has successfully passed.
Line 8 – Name of the step from type “task”
Lines 10-12 – Define the generell config of this task
Line 13 – Defines the actual container in which this task is going to run. In my case, I simply needed a container image with jq installed, as this is required by my script.
Lines 14-15 – This defines the input to this task, which is whatever the step called “r-git” outputs. This output is then mounted into the container of this task.
Lines 16-17 – This is the relative directory where this task puts its output to.
Lines 18-19 – Command to run my script. The git repo was cloned and handed over in the input “r-git” directory. Within this directory, you’d find the repo structure. In my repo is a folder called k8s, which contains the script to modify the output –> the relative path in my case is <input-name>/<git-structure>.
The get-digest script itself just queries harbor for the latest digest of our container image and uses sed to replace the image value in the deployment file (which is sitting in the very same directory). After that, it’ll put the deployment.yml into the output directory, which is definied as e-modified-deployment
Lines 20 – Using put on the Kubernetes resource
Lines 22 – running kubectl apply on the deployment.yml in my output directory.

Create the Pipeline

I’ve saved my entire Pipeline in a file called pipe-create-and-push-image.yml. Let’s push it to Concourse and unpause the pipeline.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
vraccoon@ubu:~$ fly -t local-concourse set-pipeline -p create-and-push-image -c pipe-create-and-push-image -n
resources:
resource r-git has been added:
+ icon: github
+ name: r-git
+ source:
+ branch: master
+ uri: https://github.com/vRaccoon/learn-to-fly.git
+ type: git
resource r-harbor has been added:
+ icon: oci
+ name: r-harbor
+ source:
+ ca_certs:
+ - cert: |
+ -----BEGIN CERTIFICATE-----
+ MIIDUTCCAjmgAwIBAgIVAM62WHzfLCadYf0ugejAyBO0eCaaMA0GCSqGSIb3DQEB
+ CwUAMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKDAdQaXZvdGFsMB4XDTIwMTEyMDIw
+ MTEzOFoXDTI0MTEyMTIwMTEzOFowHzELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB1Bp
+ dm90YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0EeKE1SMb58cH
+ HHtavZN5cY0Ia4eCzPBlpUap7YZqKKUFI5BSUw4fXpGIqKYSzH3EVefrBx7JvqSh
+ 247ADN92RoiWaN31NGey1Hhk35m63tVQ+336AORP0vQzHexD1CeNGtE8w7GBsOEI
+ XNuuvbY/zFbsxy29XpUYpUuBpQPGUwNR3fI5IgeTjf1HsRYq49EnAh8LfnYyH1r+
+ I5OIUsNYx85fMS+/QEla+XfjvjAS6omwtr4A+VFQQJMMAnykHXial0J7+JjiyYyd
+ GgmbSnrcXBSaWPmuTv7QbCtYSqO7eCs6GV9/lokR2q3ZyNtELo5vFPns06v4slMB
+ CTKc4d+xAgMBAAGjgYMwgYAwHQYDVR0OBBYEFKhM9OHRYvNFFGgyYKR29zkvzVN5
+ MB8GA1UdIwQYMBaAFKhM9OHRYvNFFGgyYKR29zkvzVN5MB0GA1UdJQQWMBQGCCsG
+ AQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+ BjANBgkqhkiG9w0BAQsFAAOCAQEAl0Rnl1nRDCSUdHWy6BPxSWWEQwYoPd/Z2QBO
+ vizn8AFn6YG0thscNfsuJW4Cz4UoDbkazmt9tybB9Wv8BVROfJdeucOdLtGd+4QU
+ jWabPWoI0v2QqBg9Y/1h9w99Cm77i/57O+vtDpgbP1RL6yDdv3sznsx4xpor59Gi
+ 2crv5RwexJp/TzGfrlwfLWzgFJ1t2hhoTBZQXTXpOKA8/dP3p3+3W8uat3UvfnNL
+ dF3mvm7+giRIk2Kl80sCyp5Poubuq+Qb95MUsR+CukpTUdpKFVBQhzWWUTt9cm5E
+ PLCaQHLMrcjlpQlMzMu+EB4XB4gm1IeZnpxE2Gyio3AmWApfHQ==
+ -----END CERTIFICATE-----
+ domain: harbor.vraccoon.lab
+ password: Password123!
+ repository: harbor.vraccoon.lab/library/learn-to-fly
+ username: admin
+ type: docker-image
resource r-k8s-cluster has been added:
+ icon: kubernetes
+ name: r-k8s-cluster
+ source:
+ certificate_authority: |
+ -----BEGIN CERTIFICATE-----
+ MIIC+zCCAeOgAwIBAgIUTk0x/4jOgNuKF9L+CHwIo6xP9EkwDQYJKoZIhvcNAQEL
+ BQAwDTELMAkGA1UEAxMCY2EwHhcNMjAxMTIxMjEwMTU5WhcNMjQxMTIxMjEwMTU5
+ WjANMQswCQYDVQQDEwJjYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ AM6AU+fod1Y6+UIgxV7TumyWl9KA18KPrAPNubbmXWtmgbODwwMHyAN2ILxey54N
+ k5FQbyPzpoRXw9QuM4CXesDTddnD9HeazW9pAz4QqBbZpWNG3pm+7VmCcgLcaNGg
+ aeWA8+Wzu/W8M4QDUOViemEMwapRsL+pYRLSHqiXhai5UiISlOSClaR3HhNWDFwj
+ 756awTKA46/nOTzGtZ82mY9Mdyo+/maAKbQIEpEoexeMVq20Q0wZPhhG90/u4ABL
+ EVr4M8LN2wJLDDGj4R905OY2Va0/wMyKZM/gY80vvrYMn/Ggy9MuU3W3c0E57vXM
+ 59W3LXZN+KFu3ciNSBxmfyECAwEAAaNTMFEwHQYDVR0OBBYEFLpcrAFza6UHTSUz
+ usNtvI4ZrayYMB8GA1UdIwQYMBaAFLpcrAFza6UHTSUzusNtvI4ZrayYMA8GA1Ud
+ EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHos9S9l36kq7VPT7XUfPzUS
+ YkfF2BoJvBSRVe+UuWoKbF9oeASpzUBvEZmi6nNYHgsX6ZbBVnkDPhenKs/n7YAN
+ 9svtxeG0lWYG982zFOaUTZxfXKE9eijA5yDrzEM1j3SsazuDG+yi5q240Hxozz23
+ b17nD0OX7RZOhNuHfBgwO62rHzSL10ElXigCApva+KeEtUPJPK/JourSRQju9Edw
+ 5JauqehF8Jgua6EcIA5KFujBfmipfhM6iu8LPetgd8DGm+GuaxVPn1u2WhwHQaZJ
+ uqGvpS5fz6Y0bgX6TrNsqeFh2ADwZIPcj7/8EerophOGIqD7eJ76GiKlRaLx+0M=
+ -----END CERTIFICATE-----
+ token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaHBPNGlPdlFfMGFoRUg3aFUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNhLWNvbmNvdXJzZS10b2tlbi1oODVkZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzYS1jb25jb3Vyc2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmNDc0Mzk0NS0xNTQ4LTQ2MDQtYTY2YS03Nzk3YTIxNzhmOGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpzYS1jb25jb3Vyc2UifQ.ZNMh65KCr5_tdciA-yIoMGPVY7TQ-xrpveQ3tLDb8Tv-Ys-EBXg2B7H7vjeYDwI6y5rlzQy7t4iGO798C5KpkRtzET9NrclCzzyzTPXazZdWqvfq4vkIexyOQBESPLV5VJ05eN-nsG-krgp07ADrqoRCPXW4T3hQGtHgBYIdhE5T-WrGuDgjQMq5AVY-UWYh-vdj1WANd0ePhjtCXlIWi5hKFXGtxHOgPEWBXdm45RGte8kPkEncNXxggU28MdaP1QWdd2CNGFkAeZq1Rqi_WuTvO1Q_6clLNYzz7mZTdlKqW8d5JsMy5J-HJ1qddEtGfAgJh3sJ4Pe_2Fl0CUjwiQ
+ url: https://tkg-c1.vraccoon.lab:8443
+ type: k8s-resource
resource types:
resource type k8s-resource has been added:
+ name: k8s-resource
+ source:
+ repository: jgriff/k8s-resource
+ type: docker-image
jobs:
job j-create-and-push-image has been added:
+ name: j-create-and-push-image
+ plan:
+ - get: r-git
+ trigger: true
+ - params:
+ build: r-git/docker
+ put: r-harbor
+ public: true
+ serial: true
job j-update-deployment has been added:
+ name: j-update-deployment
+ plan:
+ - get: r-git
+ passed:
+ - j-create-and-push-image
+ trigger: true
+ - config:
+ image_resource:
+ source:
+ repository: mwendler/jq
+ type: docker-image
+ inputs:
+ - name: r-git
+ outputs:
+ - name: e-modified-deployment
+ platform: linux
+ run:
+ path: r-git/k8s/get-digest.sh
+ task: t-modify-deployment
+ - params:
+ kubectl: apply -f e-modified-deployment/deployment.yml
+ namespace: default
+ put: r-k8s-cluster
+ public: true
+ serial: true
pipeline created!
you can view your pipeline here: http://cmgmt.vraccoon.lab:8080/teams/main/pipelines/create-and-push-image
the pipeline is currently paused. to unpause, either:
- run the unpause-pipeline command:
fly -t local-concourse unpause-pipeline -p create-and-push-image
- click play next to the pipeline in the web ui
vraccoon@ubu:~$ fly -t local-concourse unpause-pipeline -p create-and-push-image
unpaused 'create-and-push-image'
vraccoon@ubu:~$ fly -t local-concourse set-pipeline -p create-and-push-image -c pipe-create-and-push-image -n resources: resource r-git has been added: + icon: github + name: r-git + source: + branch: master + uri: https://github.com/vRaccoon/learn-to-fly.git + type: git resource r-harbor has been added: + icon: oci + name: r-harbor + source: + ca_certs: + - cert: | + -----BEGIN CERTIFICATE----- + MIIDUTCCAjmgAwIBAgIVAM62WHzfLCadYf0ugejAyBO0eCaaMA0GCSqGSIb3DQEB + CwUAMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKDAdQaXZvdGFsMB4XDTIwMTEyMDIw + MTEzOFoXDTI0MTEyMTIwMTEzOFowHzELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB1Bp + dm90YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0EeKE1SMb58cH + HHtavZN5cY0Ia4eCzPBlpUap7YZqKKUFI5BSUw4fXpGIqKYSzH3EVefrBx7JvqSh + 247ADN92RoiWaN31NGey1Hhk35m63tVQ+336AORP0vQzHexD1CeNGtE8w7GBsOEI + XNuuvbY/zFbsxy29XpUYpUuBpQPGUwNR3fI5IgeTjf1HsRYq49EnAh8LfnYyH1r+ + I5OIUsNYx85fMS+/QEla+XfjvjAS6omwtr4A+VFQQJMMAnykHXial0J7+JjiyYyd + GgmbSnrcXBSaWPmuTv7QbCtYSqO7eCs6GV9/lokR2q3ZyNtELo5vFPns06v4slMB + CTKc4d+xAgMBAAGjgYMwgYAwHQYDVR0OBBYEFKhM9OHRYvNFFGgyYKR29zkvzVN5 + MB8GA1UdIwQYMBaAFKhM9OHRYvNFFGgyYKR29zkvzVN5MB0GA1UdJQQWMBQGCCsG + AQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB + BjANBgkqhkiG9w0BAQsFAAOCAQEAl0Rnl1nRDCSUdHWy6BPxSWWEQwYoPd/Z2QBO + vizn8AFn6YG0thscNfsuJW4Cz4UoDbkazmt9tybB9Wv8BVROfJdeucOdLtGd+4QU + jWabPWoI0v2QqBg9Y/1h9w99Cm77i/57O+vtDpgbP1RL6yDdv3sznsx4xpor59Gi + 2crv5RwexJp/TzGfrlwfLWzgFJ1t2hhoTBZQXTXpOKA8/dP3p3+3W8uat3UvfnNL + dF3mvm7+giRIk2Kl80sCyp5Poubuq+Qb95MUsR+CukpTUdpKFVBQhzWWUTt9cm5E + PLCaQHLMrcjlpQlMzMu+EB4XB4gm1IeZnpxE2Gyio3AmWApfHQ== + -----END CERTIFICATE----- + domain: harbor.vraccoon.lab + password: Password123! + repository: harbor.vraccoon.lab/library/learn-to-fly + username: admin + type: docker-image resource r-k8s-cluster has been added: + icon: kubernetes + name: r-k8s-cluster + source: + certificate_authority: | + -----BEGIN CERTIFICATE----- + MIIC+zCCAeOgAwIBAgIUTk0x/4jOgNuKF9L+CHwIo6xP9EkwDQYJKoZIhvcNAQEL + BQAwDTELMAkGA1UEAxMCY2EwHhcNMjAxMTIxMjEwMTU5WhcNMjQxMTIxMjEwMTU5 + WjANMQswCQYDVQQDEwJjYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB + AM6AU+fod1Y6+UIgxV7TumyWl9KA18KPrAPNubbmXWtmgbODwwMHyAN2ILxey54N + k5FQbyPzpoRXw9QuM4CXesDTddnD9HeazW9pAz4QqBbZpWNG3pm+7VmCcgLcaNGg + aeWA8+Wzu/W8M4QDUOViemEMwapRsL+pYRLSHqiXhai5UiISlOSClaR3HhNWDFwj + 756awTKA46/nOTzGtZ82mY9Mdyo+/maAKbQIEpEoexeMVq20Q0wZPhhG90/u4ABL + EVr4M8LN2wJLDDGj4R905OY2Va0/wMyKZM/gY80vvrYMn/Ggy9MuU3W3c0E57vXM + 59W3LXZN+KFu3ciNSBxmfyECAwEAAaNTMFEwHQYDVR0OBBYEFLpcrAFza6UHTSUz + usNtvI4ZrayYMB8GA1UdIwQYMBaAFLpcrAFza6UHTSUzusNtvI4ZrayYMA8GA1Ud + EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHos9S9l36kq7VPT7XUfPzUS + YkfF2BoJvBSRVe+UuWoKbF9oeASpzUBvEZmi6nNYHgsX6ZbBVnkDPhenKs/n7YAN + 9svtxeG0lWYG982zFOaUTZxfXKE9eijA5yDrzEM1j3SsazuDG+yi5q240Hxozz23 + b17nD0OX7RZOhNuHfBgwO62rHzSL10ElXigCApva+KeEtUPJPK/JourSRQju9Edw + 5JauqehF8Jgua6EcIA5KFujBfmipfhM6iu8LPetgd8DGm+GuaxVPn1u2WhwHQaZJ + uqGvpS5fz6Y0bgX6TrNsqeFh2ADwZIPcj7/8EerophOGIqD7eJ76GiKlRaLx+0M= + -----END CERTIFICATE----- + token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaHBPNGlPdlFfMGFoRUg3aFUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNhLWNvbmNvdXJzZS10b2tlbi1oODVkZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzYS1jb25jb3Vyc2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmNDc0Mzk0NS0xNTQ4LTQ2MDQtYTY2YS03Nzk3YTIxNzhmOGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpzYS1jb25jb3Vyc2UifQ.ZNMh65KCr5_tdciA-yIoMGPVY7TQ-xrpveQ3tLDb8Tv-Ys-EBXg2B7H7vjeYDwI6y5rlzQy7t4iGO798C5KpkRtzET9NrclCzzyzTPXazZdWqvfq4vkIexyOQBESPLV5VJ05eN-nsG-krgp07ADrqoRCPXW4T3hQGtHgBYIdhE5T-WrGuDgjQMq5AVY-UWYh-vdj1WANd0ePhjtCXlIWi5hKFXGtxHOgPEWBXdm45RGte8kPkEncNXxggU28MdaP1QWdd2CNGFkAeZq1Rqi_WuTvO1Q_6clLNYzz7mZTdlKqW8d5JsMy5J-HJ1qddEtGfAgJh3sJ4Pe_2Fl0CUjwiQ + url: https://tkg-c1.vraccoon.lab:8443 + type: k8s-resource resource types: resource type k8s-resource has been added: + name: k8s-resource + source: + repository: jgriff/k8s-resource + type: docker-image jobs: job j-create-and-push-image has been added: + name: j-create-and-push-image + plan: + - get: r-git + trigger: true + - params: + build: r-git/docker + put: r-harbor + public: true + serial: true job j-update-deployment has been added: + name: j-update-deployment + plan: + - get: r-git + passed: + - j-create-and-push-image + trigger: true + - config: + image_resource: + source: + repository: mwendler/jq + type: docker-image + inputs: + - name: r-git + outputs: + - name: e-modified-deployment + platform: linux + run: + path: r-git/k8s/get-digest.sh + task: t-modify-deployment + - params: + kubectl: apply -f e-modified-deployment/deployment.yml + namespace: default + put: r-k8s-cluster + public: true + serial: true pipeline created! you can view your pipeline here: http://cmgmt.vraccoon.lab:8080/teams/main/pipelines/create-and-push-image the pipeline is currently paused. to unpause, either: - run the unpause-pipeline command: fly -t local-concourse unpause-pipeline -p create-and-push-image - click play next to the pipeline in the web ui vraccoon@ubu:~$ fly -t local-concourse unpause-pipeline -p create-and-push-image unpaused 'create-and-push-image'
vraccoon@ubu:~$ fly -t local-concourse set-pipeline -p create-and-push-image -c pipe-create-and-push-image -n
resources:
  resource r-git has been added:
+ icon: github
+ name: r-git
+ source:
+   branch: master
+   uri: https://github.com/vRaccoon/learn-to-fly.git
+ type: git

  resource r-harbor has been added:
+ icon: oci
+ name: r-harbor
+ source:
+   ca_certs:
+   - cert: |
+       -----BEGIN CERTIFICATE-----
+       MIIDUTCCAjmgAwIBAgIVAM62WHzfLCadYf0ugejAyBO0eCaaMA0GCSqGSIb3DQEB
+       CwUAMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKDAdQaXZvdGFsMB4XDTIwMTEyMDIw
+       MTEzOFoXDTI0MTEyMTIwMTEzOFowHzELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB1Bp
+       dm90YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0EeKE1SMb58cH
+       HHtavZN5cY0Ia4eCzPBlpUap7YZqKKUFI5BSUw4fXpGIqKYSzH3EVefrBx7JvqSh
+       247ADN92RoiWaN31NGey1Hhk35m63tVQ+336AORP0vQzHexD1CeNGtE8w7GBsOEI
+       XNuuvbY/zFbsxy29XpUYpUuBpQPGUwNR3fI5IgeTjf1HsRYq49EnAh8LfnYyH1r+
+       I5OIUsNYx85fMS+/QEla+XfjvjAS6omwtr4A+VFQQJMMAnykHXial0J7+JjiyYyd
+       GgmbSnrcXBSaWPmuTv7QbCtYSqO7eCs6GV9/lokR2q3ZyNtELo5vFPns06v4slMB
+       CTKc4d+xAgMBAAGjgYMwgYAwHQYDVR0OBBYEFKhM9OHRYvNFFGgyYKR29zkvzVN5
+       MB8GA1UdIwQYMBaAFKhM9OHRYvNFFGgyYKR29zkvzVN5MB0GA1UdJQQWMBQGCCsG
+       AQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+       BjANBgkqhkiG9w0BAQsFAAOCAQEAl0Rnl1nRDCSUdHWy6BPxSWWEQwYoPd/Z2QBO
+       vizn8AFn6YG0thscNfsuJW4Cz4UoDbkazmt9tybB9Wv8BVROfJdeucOdLtGd+4QU
+       jWabPWoI0v2QqBg9Y/1h9w99Cm77i/57O+vtDpgbP1RL6yDdv3sznsx4xpor59Gi
+       2crv5RwexJp/TzGfrlwfLWzgFJ1t2hhoTBZQXTXpOKA8/dP3p3+3W8uat3UvfnNL
+       dF3mvm7+giRIk2Kl80sCyp5Poubuq+Qb95MUsR+CukpTUdpKFVBQhzWWUTt9cm5E
+       PLCaQHLMrcjlpQlMzMu+EB4XB4gm1IeZnpxE2Gyio3AmWApfHQ==
+       -----END CERTIFICATE-----
+     domain: harbor.vraccoon.lab
+   password: Password123!
+   repository: harbor.vraccoon.lab/library/learn-to-fly
+   username: admin
+ type: docker-image

  resource r-k8s-cluster has been added:
+ icon: kubernetes
+ name: r-k8s-cluster
+ source:
+   certificate_authority: |
+     -----BEGIN CERTIFICATE-----
+     MIIC+zCCAeOgAwIBAgIUTk0x/4jOgNuKF9L+CHwIo6xP9EkwDQYJKoZIhvcNAQEL
+     BQAwDTELMAkGA1UEAxMCY2EwHhcNMjAxMTIxMjEwMTU5WhcNMjQxMTIxMjEwMTU5
+     WjANMQswCQYDVQQDEwJjYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+     AM6AU+fod1Y6+UIgxV7TumyWl9KA18KPrAPNubbmXWtmgbODwwMHyAN2ILxey54N
+     k5FQbyPzpoRXw9QuM4CXesDTddnD9HeazW9pAz4QqBbZpWNG3pm+7VmCcgLcaNGg
+     aeWA8+Wzu/W8M4QDUOViemEMwapRsL+pYRLSHqiXhai5UiISlOSClaR3HhNWDFwj
+     756awTKA46/nOTzGtZ82mY9Mdyo+/maAKbQIEpEoexeMVq20Q0wZPhhG90/u4ABL
+     EVr4M8LN2wJLDDGj4R905OY2Va0/wMyKZM/gY80vvrYMn/Ggy9MuU3W3c0E57vXM
+     59W3LXZN+KFu3ciNSBxmfyECAwEAAaNTMFEwHQYDVR0OBBYEFLpcrAFza6UHTSUz
+     usNtvI4ZrayYMB8GA1UdIwQYMBaAFLpcrAFza6UHTSUzusNtvI4ZrayYMA8GA1Ud
+     EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHos9S9l36kq7VPT7XUfPzUS
+     YkfF2BoJvBSRVe+UuWoKbF9oeASpzUBvEZmi6nNYHgsX6ZbBVnkDPhenKs/n7YAN
+     9svtxeG0lWYG982zFOaUTZxfXKE9eijA5yDrzEM1j3SsazuDG+yi5q240Hxozz23
+     b17nD0OX7RZOhNuHfBgwO62rHzSL10ElXigCApva+KeEtUPJPK/JourSRQju9Edw
+     5JauqehF8Jgua6EcIA5KFujBfmipfhM6iu8LPetgd8DGm+GuaxVPn1u2WhwHQaZJ
+     uqGvpS5fz6Y0bgX6TrNsqeFh2ADwZIPcj7/8EerophOGIqD7eJ76GiKlRaLx+0M=
+     -----END CERTIFICATE-----
+   token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5FcFR0aE9YR2pacFlKWFB4Sm5MNFBLVW9HaHBPNGlPdlFfMGFoRUg3aFUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNhLWNvbmNvdXJzZS10b2tlbi1oODVkZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzYS1jb25jb3Vyc2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmNDc0Mzk0NS0xNTQ4LTQ2MDQtYTY2YS03Nzk3YTIxNzhmOGEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpzYS1jb25jb3Vyc2UifQ.ZNMh65KCr5_tdciA-yIoMGPVY7TQ-xrpveQ3tLDb8Tv-Ys-EBXg2B7H7vjeYDwI6y5rlzQy7t4iGO798C5KpkRtzET9NrclCzzyzTPXazZdWqvfq4vkIexyOQBESPLV5VJ05eN-nsG-krgp07ADrqoRCPXW4T3hQGtHgBYIdhE5T-WrGuDgjQMq5AVY-UWYh-vdj1WANd0ePhjtCXlIWi5hKFXGtxHOgPEWBXdm45RGte8kPkEncNXxggU28MdaP1QWdd2CNGFkAeZq1Rqi_WuTvO1Q_6clLNYzz7mZTdlKqW8d5JsMy5J-HJ1qddEtGfAgJh3sJ4Pe_2Fl0CUjwiQ
+   url: https://tkg-c1.vraccoon.lab:8443
+ type: k8s-resource

resource types:
  resource type k8s-resource has been added:
+ name: k8s-resource
+ source:
+   repository: jgriff/k8s-resource
+ type: docker-image

jobs:
  job j-create-and-push-image has been added:
+ name: j-create-and-push-image
+ plan:
+ - get: r-git
+   trigger: true
+ - params:
+     build: r-git/docker
+   put: r-harbor
+ public: true
+ serial: true

  job j-update-deployment has been added:
+ name: j-update-deployment
+ plan:
+ - get: r-git
+   passed:
+   - j-create-and-push-image
+   trigger: true
+ - config:
+     image_resource:
+       source:
+         repository: mwendler/jq
+       type: docker-image
+     inputs:
+     - name: r-git
+     outputs:
+     - name: e-modified-deployment
+     platform: linux
+     run:
+       path: r-git/k8s/get-digest.sh
+   task: t-modify-deployment
+ - params:
+     kubectl: apply -f e-modified-deployment/deployment.yml
+     namespace: default
+   put: r-k8s-cluster
+ public: true
+ serial: true

pipeline created!
you can view your pipeline here: http://cmgmt.vraccoon.lab:8080/teams/main/pipelines/create-and-push-image

the pipeline is currently paused. to unpause, either:
  - run the unpause-pipeline command:
    fly -t local-concourse unpause-pipeline -p create-and-push-image
  - click play next to the pipeline in the web ui



vraccoon@ubu:~$ fly -t local-concourse unpause-pipeline -p create-and-push-image
unpaused 'create-and-push-image'

The Pipeline should start automatically after a few seconds:

Checking the results

Let’s check if the deployment was successful. And if so, which specific image was used:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
vraccoon@ubu:~$ kubectl get deployment learn-to-fly
NAME READY UP-TO-DATE AVAILABLE AGE
learn-to-fly 1/1 1 1 113m
vraccoon@ubu:~$ kubectl get deployment learn-to-fly -o json | jq .spec.template.spec.containers[0].image
"harbor.vraccoon.lab/library/learn-to-fly@sha256:4024d59c1f26037e5a50f7db8e78b404c6801a85b794da6dadc1d1bf7ae093a8"
vraccoon@ubu:~$ kubectl get deployment learn-to-fly NAME READY UP-TO-DATE AVAILABLE AGE learn-to-fly 1/1 1 1 113m vraccoon@ubu:~$ kubectl get deployment learn-to-fly -o json | jq .spec.template.spec.containers[0].image "harbor.vraccoon.lab/library/learn-to-fly@sha256:4024d59c1f26037e5a50f7db8e78b404c6801a85b794da6dadc1d1bf7ae093a8"
vraccoon@ubu:~$ kubectl get deployment learn-to-fly
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
learn-to-fly   1/1     1            1           113m

vraccoon@ubu:~$ kubectl get deployment learn-to-fly -o json | jq .spec.template.spec.containers[0].image
"harbor.vraccoon.lab/library/learn-to-fly@sha256:4024d59c1f26037e5a50f7db8e78b404c6801a85b794da6dadc1d1bf7ae093a8"

Compare this to what I have in Harbor:

As you can see, there are multiple artifacts already. So it might make sense to set up some kind of retention policy here too, otherwise Harbor might get overwhelmed at some time.
But the important part is the digest of the artifact with the label “latest”. This digest is the same as the one seen in Kubernetes. Which means, the Pipeline works as intended =D

This concludes my mini series on Concourse. I hope it was helpful =)

Leave a Reply

Your email address will not be published. Required fields are marked *