Add tekton pipelines

This commit is contained in:
2024-04-02 19:15:40 +02:00
parent 217a105a5c
commit e97a9f7f24
23 changed files with 711 additions and 76 deletions

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,24 @@
apiVersion: v2
name: tekton-pipelines
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

View File

@ -0,0 +1 @@
TODO: Write some notes

View File

@ -0,0 +1,51 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "tekton-pipelines.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "tekton-pipelines.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "tekton-pipelines.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "tekton-pipelines.labels" -}}
helm.sh/chart: {{ include "tekton-pipelines.chart" . }}
{{ include "tekton-pipelines.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "tekton-pipelines.selectorLabels" -}}
app.kubernetes.io/name: {{ include "tekton-pipelines.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

View File

@ -0,0 +1,30 @@
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: hetzner-cleanup
namespace: {{ .Values.pipelineNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
spec:
params:
- name: environment
type: string
- name: namespace
type: string
tasks:
- name: cleanup-hetzner-infra
retries: 3
taskRef:
resolver: cluster
params:
- name: kind
value: task
- name: name
value: cleanup-hetzner-infra
- name: namespace
value: tekton-pipelines
params:
- name: environment
value: $(params.environment)
- name: namespace
value: $(params.namespace)

View File

@ -0,0 +1,99 @@
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: hetzner-k3s
namespace: {{ .Values.pipelineNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
spec:
params:
- name: environment
type: string
- name: namespace
type: string
workspaces:
- name: ssh-keys
- name: inventory
- name: kubeconfig-output
tasks:
- name: generate-ssh-keys
taskRef:
resolver: cluster
params:
- name: kind
value: task
- name: name
value: generate-ssh-keys
- name: namespace
value: tekton-pipelines
workspaces:
- name: ssh-keys
workspace: ssh-keys
params:
- name: environment
value: $(params.environment)
- name: namespace
value: $(params.namespace)
- name: prepare-hetzner-infra
retries: 3
runAfter:
- generate-ssh-keys
taskRef:
resolver: cluster
params:
- name: kind
value: task
- name: name
value: prepare-hetzner-infra
- name: namespace
value: tekton-pipelines
workspaces:
- name: outputs
workspace: inventory
params:
- name: environment
value: $(params.environment)
- name: namespace
value: $(params.namespace)
- name: bootstrap-k3s
retries: 3
runAfter:
- prepare-hetzner-infra
taskRef:
resolver: cluster
params:
- name: kind
value: task
- name: name
value: bootstrap-k3s
- name: namespace
value: tekton-pipelines
params:
- name: environment
value: $(params.environment)
- name: namespace
value: $(params.namespace)
workspaces:
- name: outputs
workspace: kubeconfig-output
- name: deploy-helmfile-base
runAfter:
- bootstrap-k3s
retries: 3
taskRef:
resolver: cluster
params:
- name: kind
value: task
- name: name
value: deploy-helmfile-base
- name: namespace
value: tekton-pipelines
params:
- name: environment
value: $(params.environment)
- name: namespace
value: $(params.namespace)
workspaces:
- name: outputs
workspace: kubeconfig-output

View File

@ -0,0 +1,36 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
namespace: {{ .Values.pipelineRunNamespace }}
name: secret-manager
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["*"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: secret-manager
namespace: {{ .Values.pipelineRunNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: secret-manager
namespace: {{ .Values.pipelineRunNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: secret-manager
namespace: {{ .Values.pipelineRunNamespace }}
roleRef:
kind: ClusterRole
name: secret-manager
apiGroup: rbac.authorization.k8s.io

View File

@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.pipelineRunNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}

View File

@ -0,0 +1,26 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: shell-operator
namespace: {{ .Values.pipelineRunNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
{{- include "tekton-pipelines.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "tekton-pipelines.labels" . | nindent 8 }}
spec:
serviceAccountName: shell-operator
containers:
- name: shell-operator
env:
- name: SP_TEKTON_RUNTIME_NS
value: {{ .Values.pipelineRunNamespace }}
imagePullPolicy: Always
image: git.badhouseplants.net/softplayer/softplayer-controller:latest

View File

@ -0,0 +1,39 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
namespace: {{ .Values.pipelineRunNamespace }}
name: shell-operator
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["*"]
- apiGroups: ["tekton.dev"]
resources: ["pipelineruns"]
verbs: ["*"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: shell-operator
namespace: {{ .Values.pipelineRunNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: shell-operator
namespace: {{ .Values.pipelineRunNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: shell-operator
namespace: {{ .Values.pipelineRunNamespace }}
roleRef:
kind: ClusterRole
name: shell-operator
apiGroup: rbac.authorization.k8s.io

View File

@ -0,0 +1,97 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: bootstrap-k3s
namespace: {{ .Values.pipelineNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
spec:
params:
- name: namespace
type: string
- name: environment
type: string
steps:
- name: get-ssh-key-and-inventory
image: alpine/k8s:1.29.2
script: |-
#!/bin/sh
kubectl get secret "$(params.environment)"-ssh \
--namespace "$(params.namespace)" -o yaml \
| yq '.data.ssh_key' \
| base64 -d > /tmp/outputs/ssh_key
kubectl get secret "$(params.environment)"-ssh \
--namespace "$(params.namespace)" -o yaml \
| yq '.data."ssh_key.pub"' \
| base64 -d > /tmp/outputs/ssh_key.pub
kubectl get secret "$(params.environment)"-inventory \
--namespace "$(params.namespace)" -o yaml \
| yq '.data."inventory.yaml"' \
| base64 -d > /tmp/outputs/inventory.yaml
chmod 0600 /tmp/outputs/ssh_key
chmod 0600 /tmp/outputs/ssh_key.pub
- name: prepare-servers
image: git.badhouseplants.net/softplayer/softplayer-coskgne:latest
env:
- name: SP_ENV
value: $(params.environment)
- name: SP_CUSTOMER
value: $(params.namespace)
- name: ANSIBLE_INVENTORY
value: /tmp/outputs/inventory.yaml
- name: ANSIBE_PRIVATE_KEY_FILE
value: /tmp/outputs/ssh_key
- name: ANSIBLE_HOST_KEY_CHECKING
value: "false"
script: |
#!/bin/sh
ansible-playbook /src/playbooks/systems/system-bootstrap/playbook.yml
- name: prepare-k3s
env:
- name: SP_ENV
value: $(params.environment)
- name: SP_CUSTOMER
value: $(params.namespace)
- name: ANSIBLE_INVENTORY
value: /tmp/outputs/inventory.yaml
- name: ANSIBE_PRIVATE_KEY_FILE
value: /tmp/outputs/ssh_key
- name: ANSIBLE_HOST_KEY_CHECKING
value: "false"
image: git.badhouseplants.net/softplayer/softplayer-coskgne:latest
script: |-
#!/bin/sh
ansible-playbook /src/playbooks/systems/k3s-bootstrap/playbook.yml
- name: prepare-kubeconfig
env:
- name: SP_ENV
value: $(params.environment)
- name: SP_CUSTOMER
value: $(params.namespace)
- name: ANSIBLE_INVENTORY
value: /tmp/outputs/inventory.yaml
- name: ANSIBE_PRIVATE_KEY_FILE
value: /tmp/outputs/ssh_key
- name: ANSIBLE_HOST_KEY_CHECKING
value: "false"
image: git.badhouseplants.net/softplayer/softplayer-coskgne:latest
script: |-
#!/bin/sh
ansible-playbook /src/playbooks/other/k8s-create-user/playbook.yml
- name: save-kubeconfig
image: alpine/k8s:1.29.2
script: |-
#!/bin/sh
kubectl delete secret \
"$(params.environment)"-config \
--namespace "$(params.namespace)"
kubectl create secret generic \
"$(params.environment)"-config \
--namespace "$(params.namespace)" \
--from-file=kubeconfig=/tmp/outputs/admin-default-config
workspaces:
- name: outputs
description: A folder to store outputs
optional: false
mountPath: /tmp/outputs

View File

@ -0,0 +1,44 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: cleanup-hetzner-infra
namespace: {{ .Values.pipelineNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
spec:
params:
- name: namespace
type: string
- name: environment
type: string
steps:
- name: create-hetzner-infra
image: git.badhouseplants.net/softplayer/softplayer-coskgne:latest
env:
- name: SP_STATE
value: absent
- name: SP_ENV
value: $(params.environment)
- name: SP_CUSTOMER
value: $(params.namespace)
- name: SOPS_AGE_KEY
value: AGE-SECRET-KEY-1VXYUK7MAGR6KMZJ6ZMPD35EQ9LVXXKQ2HHE6Z8T828WWT03EH8LS6G9AS8
script: |-
#!/bin/sh
mkdir -p /tmp/outputs
ssh-keygen -t rsa -f /tmp/outputs/ssh_key -N ""
ansible-playbook /src/playbooks/providers/hetzner/playbook.yml || true
- name: remove-secrets
image: alpine/k8s:1.29.2
script: |-
#!/bin/sh
kubectl delete secret \
"$(params.environment)-inventory" \
--namespace "$(params.namespace)"
kubectl delete secret \
"$(params.environment)-ssh" \
--namespace "$(params.namespace)"
kubectl delete secret \
"$(params.environment)-config" \
--namespace "$(params.namespace)"

View File

@ -0,0 +1,39 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: deploy-helmfile-base
namespace: {{ .Values.pipelineNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
spec:
params:
- name: namespace
type: string
- name: environment
type: string
steps:
- name: get-ssh-key
image: alpine/k8s:1.29.2
script: |-
#!/bin/sh
kubectl get secret "$(params.environment)"-config \
--namespace "$(params.namespace)" -o yaml \
| yq '.data.kubeconfig' \
| base64 -d > /tmp/outputs/config
chmod 0600 /tmp/outputs/config
- name: deploy-helmfile
image: ghcr.io/helmfile/helmfile:v0.163.1
env:
- name: KUBECONFIG
value: /tmp/outputs/config
script: |-
#!/bin/sh
mkdir -p /src
git clone https://git.badhouseplants.net/softplayer/softplayer-helmfile.git /src/helmfile
cd /src/helmfile/workload && helmfile sync
workspaces:
- name: outputs
description: A folder to store outputs
optional: false
mountPath: /tmp/outputs

View File

@ -0,0 +1,49 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: generate-ssh-keys
namespace: tekton-pipelines
namespace: {{ .Values.pipelineNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
spec:
description: |-
This task should prepare a ssh key that will be used for
bootstrapping wotkload nodes. If ssh-key secret already
exists, should not run
params:
- name: namespace
type: string
- name: environment
type: string
steps:
- name: check-whether-a-key-exists
image: alpine/k8s:1.29.2
script: |-
#!/bin/bash
if kubectl get secret "$(params.environment)-ssh"; then
echo 1 > /tmp/outputs/ready
fi
- name: prepare-ssh-key
image: git.badhouseplants.net/softplayer/softplayer-coskgne:latest
script: |-
#!/bin/bash
if ! [ -f /tmp/outputs/ready ]; then
ansible-playbook /src/playbooks/other/ssh-key-gen/playbook.yml
fi
- name: save-ssh-keys
image: alpine/k8s:1.29.2
script: |-
#!/bin/sh
if ! [ -f /tmp/outputs/ready ]; then
kubectl create secret generic \
"$(params.environment)"-ssh \
--namespace "$(params.namespace)" \
--from-file /tmp/outputs
fi
workspaces:
- name: ssh-keys
description: A folder to store ssh keys
optional: false
mountPath: /tmp/outputs

View File

@ -0,0 +1,54 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: prepare-hetzner-infra
namespace: {{ .Values.pipelineNamespace }}
labels:
{{- include "tekton-pipelines.labels" . | nindent 4 }}
spec:
params:
- name: namespace
type: string
- name: environment
type: string
steps:
- name: get-ssh-key
image: alpine/k8s:1.29.2
script: |-
#!/bin/sh
kubectl get secret "$(params.environment)"-ssh \
--namespace "$(params.namespace)" -o yaml \
| yq '.data."ssh_key.pub"' \
| base64 -d > /tmp/outputs/ssh_key.pub
chmod 0600 /tmp/outputs/ssh_key.pub
- name: create-hetzner-infra
image: git.badhouseplants.net/softplayer/softplayer-coskgne:latest
env:
- name: SP_STATE
value: present
- name: SP_ENV
value: $(params.environment)
- name: SP_CUSTOMER
value: $(params.namespace)
- name: SOPS_AGE_KEY
value: {{ .Values.providers.hetzner.ageKey }}
script: |-
#!/bin/sh
ansible-playbook /src/playbooks/providers/hetzner/playbook.yml
- name: save-inventory
image: alpine/k8s:1.29.2
script: |-
#!/bin/sh
kubectl delete secret \
"$(params.environment)"-inventory \
--namespace "$(params.namespace)"
kubectl create secret generic \
"$(params.environment)"-inventory \
--namespace "$(params.namespace)" \
--from-file /tmp/outputs/inventory.yaml
workspaces:
- name: outputs
description: A folder to store outputs
optional: false
mountPath: /tmp/outputs

View File

@ -0,0 +1,8 @@
#U+00eU+002 U+002Default values for tekton-pipelines.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
providers:
hetzner:
ageKey: test
pipelineNamespace: tekton-pipelines
pipelineRunNamespace: tekton-runtime