Archify Sync GitOps template
A Copier template for deploying Archify Sync with Argo CD: an app-of-apps, the server's Helm chart and its values, optional secrets through External Secrets and an optional static NFS volume for PostgreSQL.
This commit is contained in:
commit
e2adb79e2d
15 files changed
+572
No files matched your search
@@ -0,0 +1,34 @@
|
||||
{% macro render() %}
|
||||
---
|
||||
# Applied once by hand (or by the connect step); after that the copy in
|
||||
# 0300-applications keeps it in step with git. Named apart from other
|
||||
# app-of-apps that share the Argo CD namespace.
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: 0000-archify-sync-app-of-apps
|
||||
namespace: {{ argocd.get('namespace', 'argocd') }}
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
spec:
|
||||
project: {{ argocd.get('project', 'default') }}
|
||||
source:
|
||||
repoURL: {{ argocd.get('repo_url', 'https://git.example.com/you/archify-sync-gitops.git') }}
|
||||
targetRevision: {{ argocd.get('target_revision', 'HEAD') }}
|
||||
path: cluster/0300-applications
|
||||
directory:
|
||||
recurse: true
|
||||
destination:
|
||||
server: {{ argocd.get('destination_server', 'https://kubernetes.default.svc') }}
|
||||
namespace: {{ argocd.get('namespace', 'argocd') }}
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
{% endmacro %}
|
||||
{%- set result = render() -%}
|
||||
{%- for line in result.split('\n') -%}
|
||||
{% if line | trim | length != 0 -%}
|
||||
{{ line }}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
@@ -0,0 +1,34 @@
|
||||
{% macro render() %}
|
||||
---
|
||||
# The app-of-apps managing itself: the bootstrap copy is applied once, then this
|
||||
# one (inside the recursed tree) keeps it in step with git. Named apart from
|
||||
# other app-of-apps that share the Argo CD namespace.
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: 0000-archify-sync-app-of-apps
|
||||
namespace: {{ argocd.get('namespace', 'argocd') }}
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
spec:
|
||||
project: {{ argocd.get('project', 'default') }}
|
||||
source:
|
||||
repoURL: {{ argocd.get('repo_url', 'https://git.example.com/you/archify-sync-gitops.git') }}
|
||||
targetRevision: {{ argocd.get('target_revision', 'HEAD') }}
|
||||
path: cluster/0300-applications
|
||||
directory:
|
||||
recurse: true
|
||||
destination:
|
||||
server: {{ argocd.get('destination_server', 'https://kubernetes.default.svc') }}
|
||||
namespace: {{ argocd.get('namespace', 'argocd') }}
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
{% endmacro %}
|
||||
{%- set result = render() -%}
|
||||
{%- for line in result.split('\n') -%}
|
||||
{% if line | trim | length != 0 -%}
|
||||
{{ line }}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{% macro render() %}
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: 0100-archify-sync-secrets
|
||||
namespace: {{ argocd.get('namespace', 'argocd') }}
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
annotations:
|
||||
# Before the server: its pods need the Secret this app makes.
|
||||
argocd.argoproj.io/sync-wave: "0"
|
||||
spec:
|
||||
project: {{ argocd.get('project', 'default') }}
|
||||
# The server's secrets from your secret store through External Secrets.
|
||||
source:
|
||||
repoURL: {{ argocd.get('repo_url', 'https://git.example.com/you/archify-sync-gitops.git') }}
|
||||
targetRevision: {{ argocd.get('target_revision', 'HEAD') }}
|
||||
path: cluster/0500-resources/0100-archify-sync-secrets
|
||||
directory:
|
||||
recurse: true
|
||||
destination:
|
||||
server: {{ argocd.get('destination_server', 'https://kubernetes.default.svc') }}
|
||||
namespace: {{ archify_sync.get('namespace', 'archify-sync') }}
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
{% endmacro %}
|
||||
{%- set result = render() -%}
|
||||
{%- for line in result.split('\n') -%}
|
||||
{% if line | trim | length != 0 -%}
|
||||
{{ line }}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{% macro render() %}
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: 0150-archify-sync-storage
|
||||
namespace: {{ argocd.get('namespace', 'argocd') }}
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
annotations:
|
||||
# Before the server: its database needs the claim this app makes.
|
||||
argocd.argoproj.io/sync-wave: "0"
|
||||
spec:
|
||||
project: {{ argocd.get('project', 'default') }}
|
||||
# The database volume: a static NFS volume, an export owned by uid 70.
|
||||
source:
|
||||
repoURL: {{ argocd.get('repo_url', 'https://git.example.com/you/archify-sync-gitops.git') }}
|
||||
targetRevision: {{ argocd.get('target_revision', 'HEAD') }}
|
||||
path: cluster/0500-resources/0150-archify-sync-storage
|
||||
directory:
|
||||
recurse: true
|
||||
destination:
|
||||
server: {{ argocd.get('destination_server', 'https://kubernetes.default.svc') }}
|
||||
namespace: {{ archify_sync.get('namespace', 'archify-sync') }}
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
{% endmacro %}
|
||||
{%- set result = render() -%}
|
||||
{%- for line in result.split('\n') -%}
|
||||
{% if line | trim | length != 0 -%}
|
||||
{{ line }}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
{% macro render() %}
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: 0200-archify-sync
|
||||
namespace: {{ argocd.get('namespace', 'argocd') }}
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
project: {{ argocd.get('project', 'default') }}
|
||||
# Archify Sync: the chart from the server repository, the values from this one.
|
||||
# One pod by design (the live copy of each model is held by one server), so
|
||||
# updates are Recreate; editors work offline for those seconds and catch up.
|
||||
sources:
|
||||
- repoURL: {{ archify_sync.get('chart_repo', 'https://gitea.lego-cloud.eu/vscode-extensions/archify-vscode-ext-sync.git') }}
|
||||
targetRevision: {{ archify_sync.get('chart_revision', 'main') }}
|
||||
path: {{ archify_sync.get('chart_path', 'charts/archify-sync') }}
|
||||
helm:
|
||||
# The release name is part of the database URL in the ExternalSecret (0100).
|
||||
releaseName: archify-sync
|
||||
valueFiles:
|
||||
- $values/cluster/0500-resources/0200-archify-sync/archify-sync/values.yml
|
||||
- repoURL: {{ argocd.get('repo_url', 'https://git.example.com/you/archify-sync-gitops.git') }}
|
||||
targetRevision: {{ argocd.get('target_revision', 'HEAD') }}
|
||||
ref: values
|
||||
destination:
|
||||
server: {{ argocd.get('destination_server', 'https://kubernetes.default.svc') }}
|
||||
namespace: {{ archify_sync.get('namespace', 'archify-sync') }}
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
{% endmacro %}
|
||||
{%- set result = render() -%}
|
||||
{%- for line in result.split('\n') -%}
|
||||
{% if line | trim | length != 0 -%}
|
||||
{{ line }}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
{%- set es = archify_sync.get('external_secrets', {}) -%}
|
||||
# Secret `archify-sync-secrets` from your secret store through External Secrets.
|
||||
# ESO's own templating is escaped below so it reaches the cluster as written.
|
||||
#
|
||||
# The store needs two entries (named in external_secrets):
|
||||
# postgres_password_key password of the bundled postgres role `archify`;
|
||||
# letters and digits only (it goes into a URL)
|
||||
# oidc_client_secret_key secret of the archify-sync client at the identity provider
|
||||
#
|
||||
# The URL names the chart's database Service, `<release>-postgresql`; the release is
|
||||
# `archify-sync` (0200-archify-sync).
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: archify-sync-secrets
|
||||
namespace: {{ archify_sync.get('namespace', 'archify-sync') }}
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: {{ es.get('store') }}
|
||||
kind: {{ es.get('store_kind', 'ClusterSecretStore') }}
|
||||
target:
|
||||
name: archify-sync-secrets
|
||||
template:
|
||||
engineVersion: v2
|
||||
data:
|
||||
password: "{% raw %}{{ .postgresPassword }}{% endraw %}"
|
||||
url: "postgres://archify:{% raw %}{{ .postgresPassword }}{% endraw %}@archify-sync-postgresql:5432/archify"
|
||||
client-secret: "{% raw %}{{ .oidcClientSecret }}{% endraw %}"
|
||||
data:
|
||||
- secretKey: postgresPassword
|
||||
remoteRef:
|
||||
key: {{ es.get('postgres_password_key', 'archify-sync-postgres-password') }}
|
||||
- secretKey: oidcClientSecret
|
||||
remoteRef:
|
||||
key: {{ es.get('oidc_client_secret_key', 'archify-sync-oidc-client-secret') }}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
{%- set pull = archify_sync.get('external_secrets', {}).get('image_pull', {}) -%}
|
||||
{%- set es = archify_sync.get('external_secrets', {}) -%}
|
||||
{%- set user = pull.get('username') | tojson -%}
|
||||
# The image pull secret for a private registry: its password from your secret store.
|
||||
# ESO's own templating is escaped below so it reaches the cluster as written.
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: {{ archify_sync.image.pull_secret }}
|
||||
namespace: {{ archify_sync.get('namespace', 'archify-sync') }}
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: {{ es.get('store') }}
|
||||
kind: {{ es.get('store_kind', 'ClusterSecretStore') }}
|
||||
target:
|
||||
name: {{ archify_sync.image.pull_secret }}
|
||||
creationPolicy: Owner
|
||||
template:
|
||||
engineVersion: v2
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
data:
|
||||
.dockerconfigjson: '{{ '{{' }} dict "auths" (dict {{ pull.get('registry') | tojson }} (dict "username" {{ user }} "password" .password "auth" (printf "{{ pull.get('username') }}:%s" .password | b64enc))) | toJson {{ '}}' }}'
|
||||
data:
|
||||
- secretKey: password
|
||||
remoteRef:
|
||||
key: {{ pull.get('password_key') }}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
{% macro render() %}
|
||||
{%- set database = archify_sync.get('database', {}) %}
|
||||
{%- set namespace = archify_sync.get('namespace', 'archify-sync') %}
|
||||
---
|
||||
# Static NFS volume: an export owned by postgres:17-alpine's uid 70 with mode 0700,
|
||||
# shared with maproot. Shares that map every user to root are refused by PostgreSQL.
|
||||
# Retain: deleting the app never deletes the data.
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: {{ namespace }}-database
|
||||
labels:
|
||||
app.kubernetes.io/part-of: archify-sync
|
||||
spec:
|
||||
capacity:
|
||||
storage: {{ database.get('size', '8Gi') }}
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
storageClassName: ""
|
||||
nfs:
|
||||
server: {{ database.get('nfs_server') }}
|
||||
path: {{ database.get('nfs_path') }}
|
||||
claimRef:
|
||||
namespace: {{ namespace }}
|
||||
name: archify-sync-database
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: archify-sync-database
|
||||
namespace: {{ namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/part-of: archify-sync
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: ""
|
||||
volumeName: {{ namespace }}-database
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ database.get('size', '8Gi') }}
|
||||
{% endmacro %}
|
||||
{%- set result = render() -%}
|
||||
{%- for line in result.split('\n') -%}
|
||||
{% if line | trim | length != 0 -%}
|
||||
{{ line }}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
{% macro render() %}
|
||||
{%- set image = archify_sync.get('image', {}) %}
|
||||
{%- set database = archify_sync.get('database', {}) %}
|
||||
{%- set oidc = archify_sync.get('oidc', {}) %}
|
||||
{%- set metrics = archify_sync.get('metrics', {}) %}
|
||||
{%- set host = archify_sync.get('host', 'archify.example.com') %}
|
||||
# Values for charts/archify-sync of the server repository.
|
||||
image:
|
||||
repository: {{ image.get('repository', 'registry.example.com/archify-sync') }}
|
||||
tag: {{ image.get('tag', '0.1.0') | string | tojson }}
|
||||
pullPolicy: IfNotPresent
|
||||
{%- if image.get('pull_secret') %}
|
||||
imagePullSecrets:
|
||||
- name: {{ image.get('pull_secret') }}
|
||||
{%- endif %}
|
||||
|
||||
# TLS ends at your ingress or edge proxy; people reach the server here.
|
||||
publicUrl: https://{{ host }}
|
||||
|
||||
# The bundled PostgreSQL, its password and URL from Secret archify-sync-secrets
|
||||
# (0100 with External Secrets, or made by hand).
|
||||
postgresql:
|
||||
enabled: true
|
||||
existingSecret: archify-sync-secrets
|
||||
{%- if database.get('nfs_path') %}
|
||||
# The static NFS volume from 0150-archify-sync-storage.
|
||||
existingClaim: archify-sync-database
|
||||
{%- else %}
|
||||
{%- if database.get('storage_class') %}
|
||||
storageClass: {{ database.get('storage_class') }}
|
||||
{%- endif %}
|
||||
storage: {{ database.get('size', '8Gi') }}
|
||||
{%- endif %}
|
||||
|
||||
config:
|
||||
name: Archify Sync
|
||||
membersCanInvite: {{ archify_sync.get('members_can_invite', false) | tojson }}
|
||||
logJson: true
|
||||
|
||||
{%- if oidc.get('is_enabled', false) %}
|
||||
oidc:
|
||||
enabled: true
|
||||
issuer: {{ oidc.get('issuer', 'https://sso.example.com/realms/home') }}
|
||||
clientId: {{ oidc.get('client_id', 'archify-sync') }}
|
||||
existingSecret: archify-sync-secrets
|
||||
existingSecretKey: client-secret
|
||||
label: {{ oidc.get('label', 'Keycloak') | tojson }}
|
||||
allowedGroups: {{ oidc.get('allowed_groups', []) | tojson }}
|
||||
adminGroups: {{ oidc.get('admin_groups', []) | tojson }}
|
||||
{%- endif %}
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: {{ archify_sync.get('ingress_class', 'nginx') }}
|
||||
host: {{ host }}
|
||||
annotations:
|
||||
# Edits travel over a WebSocket that stays open for hours.
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: 8m
|
||||
|
||||
metrics:
|
||||
enabled: {{ metrics.get('is_enabled', true) | tojson }}
|
||||
serviceMonitor:
|
||||
enabled: {{ metrics.get('service_monitor', false) | tojson }}
|
||||
{% endmacro %}
|
||||
{%- set result = render() -%}
|
||||
{%- for line in result.split('\n') -%}
|
||||
{% if line | trim | length != 0 -%}
|
||||
{{ line }}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
Reference in new issue
Block a user