Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

guide: CI/CD with Tekton #59

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions doc/kuadrantctl-ci-cd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# kuadrantctl - CI/CD with Tekton and Argo CD

This guide demonstrates setting up a CI/CD pipeline using Tekton to deploy Kubernetes Gateway API and Kuadrant resources generated by `kuadrantctl`, from an OpenAPI specification. In this example, these resources are applied directly to the cluster where Tekton is running.

Prerequisites:

- Kuadrant, and all of its pre-requisites, is installed onto a cluster
- (Tekton Pipelines[https://tekton.dev/]) installed on your Kubernetes or OpenShift cluster.
- (`kubectl`[https://kubernetes.io/docs/reference/kubectl/]) configured to communicate with your cluster (i.e you have a kubectl config available with access to your cluster)
- (Tekton CLI `tkn`[https://tekton.dev/docs/cli/]) (optional) for easier interaction with Tekton resources.
david-martin marked this conversation as resolved.
Show resolved Hide resolved

Setup:

First, create a dedicated namespace:

```bash
kubectl create namespace petstore
```

Step 1: Create a Persistent Volume Claim

To store Tekton build artifacts, create a PVC in the petstore namespace:

```bash
kubectl apply -n petstore -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tekton-kuadrantctl-pvc
namespace: petstore
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
```

Step 2: Define the Tekton Task

Define the task that outlines steps to clone a repository, generate Kuadrant and Kubernetes resources using `kuadrantctl`, and apply them directly to the cluster:

```bash
kubectl apply -f - <<'EOF'
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: run-kuadrantctl
namespace: petstore
spec:
params:
- name: gitRepoUrl
description: URL of the git repository to clone
- name: gitRevision
description: Git revision to checkout (branch, tag, sha)
workspaces:
- name: source
description: Workspace to checkout the git repo
- name: kubeconfig
description: Workspace containing kubeconfig for Kubernetes cluster access
steps:
- name: clean-workspace
image: alpine:latest
script: |
sh -c 'rm -rf $(workspaces.source.path)/* $(workspaces.source.path)/.[!.]* $(workspaces.source.path)/..?*'
- name: clone
image: alpine/git:latest
script: |
git clone $(params.gitRepoUrl) $(workspaces.source.path)
cd $(workspaces.source.path)
git checkout $(params.gitRevision)
- name: download-kuadrantctl
image: curlimages/curl:latest
script: |
ARCH=$(uname -m)
case $ARCH in
x86_64) BIN_ARCH="amd64";;
arm64) BIN_ARCH="arm64";;
aarch64) BIN_ARCH="arm64";;
*) echo "Unsupported architecture: $ARCH" && exit 1 ;;
esac
cd $(workspaces.source.path)
curl -LO "https://github.com/Kuadrant/kuadrantctl/releases/download/v0.2.0/kuadrantctl-v0.2.0-linux-$BIN_ARCH.tar.gz"
tar -xzf kuadrantctl-v0.2.0-linux-$BIN_ARCH.tar.gz
- name: run-kuadrantctl
image: alpine:latest
jasonmadigan marked this conversation as resolved.
Show resolved Hide resolved
script: |
# Install yq silently
apk add --no-cache curl > /dev/null
curl -s -L https://github.com/mikefarah/yq/releases/download/v4.6.1/yq_linux_arm64 -o /usr/bin/yq > /dev/null && chmod +x /usr/bin/yq

cd $(workspaces.source.path)
mkdir -p generated-resources
./kuadrantctl generate kuadrant authpolicy --oas openapi.yaml | yq eval -P | tee generated-resources/authpolicy.yaml
./kuadrantctl generate kuadrant ratelimitpolicy --oas openapi.yaml | yq eval -P | tee generated-resources/ratelimitpolicy.yaml
./kuadrantctl generate gatewayapi httproute --oas openapi.yaml | yq eval -P | tee generated-resources/httproute.yaml
- name: apply-resources
image: lachlanevenson/k8s-kubectl
script: |
apk add --no-cache gettext > /dev/null
cd $(workspaces.source.path)
export KUADRANT_ZONE_ROOT_DOMAIN=example.com # domain name used in the HTTPRoute for the petstore sample app
for file in ./generated-resources/*.yaml; do
envsubst < "$file" | kubectl apply -n petstore -f -
done
EOF
```

We're using Tekton here with a kubectl to apply resources to a cluster. We would generally recommend looking at a tool such as (ArgoCD)[https://argo-cd.readthedocs.io/en/stable/] to implement continuous delivery via a GitOps approach. In this scenario, you would:

- Use `kuadrantctl` to generate Kubernetes/Kuadrant resources as part a Tekton pipeline
- Commit these new resources in to a git respository
- Use ArgoCD to sync these changes via a Git respository to a Kubernetes or OpenShift cluster

Step 3: Create a Kubeconfig Secret

Provide Tekton access to your Kubernetes cluster by creating a secret with your kubeconfig in the `petstore` namespace:

```bash
kubectl create secret generic kubeconfig-secret --from-file=kubeconfig=/path/to/.kube/config -n petstore
```

Create an associated `ClusterRole` and `ClusterRoleBinding`:

```bash
kubectl apply -n petstore -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kuadrant-ci-example-full-access
rules:
- apiGroups: ["*"]
jasonmadigan marked this conversation as resolved.
Show resolved Hide resolved
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kuadrant-ci-example-full-access-binding
subjects:
- kind: ServiceAccount
name: default
namespace: petstore
roleRef:
kind: ClusterRole
name: kuadrant-ci-example-full-access
apiGroup: rbac.authorization.k8s.io
EOF
```

Step 4: Trigger the `TaskRun`

Execute the task within the `petstore` namespace, referencing the kubeconfig secret for cluster access:

In this example, we'll run this task with our Kuadrant Petstore app: https://github.com/kuadrant/api-petstore

```bash
kubectl apply -n petstore -f - <<EOF
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: run-kuadrantctl-taskrun
namespace: petstore
spec:
taskRef:
name: run-kuadrantctl
params:
- name: gitRepoUrl
value: "https://github.com/kuadrant/api-petstore.git"
- name: gitRevision
value: "main"
workspaces:
- name: source
persistentVolumeClaim:
claimName: tekton-kuadrantctl-pvc
- name: kubeconfig
secret:
secretName: kubeconfig-secret
EOF
```

## Cleanup

To cleanup, remove the `petstore` namespace.
Loading