This commit is contained in:
2026-10-19 12:51:18 -04:00
parent 1bbb5b9898
commit 321f7d8c00
22 changed files with 922 additions and 302 deletions
+76 -199
View File
@@ -1,199 +1,76 @@
---
# tasks file for ansible-role-wikideck
- name: Create WikiDeck namespace
k8s:
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: wikideck
- name: Create PVC for MariaDB
k8s:
state: present
definition:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb
namespace: wikideck
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Ti
- name: Create Deployment for MariaDB
k8s:
state: present
definition:
apiVersion: v1
kind: Deployment
metadata:
name: mariadb
namespace: wikideck
labels:
app: mariadb
spec:
replicas: 1
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
image: mariadb
volumeMounts:
- name: data
mountPath: /var/lib/mysql
ports:
- containerPort: 3306
env:
- name: MARIADB_ROOT_PASSWORD
value: "{{ mariadb_root_password }}"
- name: MARIADB_DATABASE
value: wikideck
- name: MARIADB_USER
value: wikideck
- name: MARIADB_PASSWORD
value: "{{ wikideck_mariadb_password }}"
volumes:
- name: data
persistentVolumeClaim:
claimName: mariadb
- name: Create Service for MariaDB
k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: mariadb
namespace: wikideck
spec:
selector:
app: mariadb
ports:
- port: 3306
name: mariadb
type: ClusterIP
- name: Create PVC for WikiDeck Mine
k8s:
state: present
definition:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wikideck-mine
namespace: wikideck
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Ti
- name: Create Deployment for WikiDeck Mine
k8s:
state: present
definition:
apiVersion: v1
kind: Deployment
metadata:
name: wikideck-mine
namespace: wikideck
labels:
app: wikideck-mine
spec:
replicas: 1
selector:
matchLabels:
app: wikideck-mine
template:
metadata:
labels:
app: wikideck-mine
spec:
containers:
- name: wikideck-mine
image: ericomeehan/wikideck-mine
volumeMounts:
- name: data
mountPath: /data
ports:
- containerPort: 80
env:
- name: ROLE
value: mine
- name: DATA_PATH
value: /data
- name: DIFFICULTY_REQUIREMENT
value: 10
- name: MINE_LOG_FILE
value: /tmp/mine.log
- name: MARIADB_HOST
value: mariadb
- name: MARIADB_DATABASE
value: mine
- name: MARIADB_USER
value: mine
- name: MARIADB_PASSWORD
value: "{{ wikideck_mine_mariadb_password }}"
volumes:
- name: data
persistentVolumeClaim:
claimName: wikideck-mine
- name: Create Service for WikiDeck Mine
k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: wikideck-mine
namespace: wikideck
spec:
selector:
app: wikideck-mine
ports:
- port: 80
name: http
type: ClusterIP
- name: Create Ingress
k8s:
state: present
definition:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: ca-issuer
name: wikideck-mine
namespace: wikideck
spec:
ingressClassName: nginx
rules:
- host: wikideck.eom.dev
http:
paths:
- pathType: Prefix
path: /mine
backend:
service:
name: wikideck-mine
port:
number: 80
tls:
- hosts:
- wikideck.eom.dev
secretName: wikideck
# SPDX-License-Identifier: MIT-0
---
- name: Validate role configuration
ansible.builtin.import_tasks: validate.yml
- name: Create application namespace
kubernetes.core.k8s:
kubeconfig: "{{ wikideck_kubeconfig | default(omit, true) }}"
context: "{{ wikideck_kube_context | default(omit, true) }}"
state: present
apply: true
definition:
apiVersion: v1
kind: Namespace
metadata:
name: "{{ wikideck_namespace }}"
when: wikideck_create_namespace | bool
- name: Create persistent chain storage
kubernetes.core.k8s:
kubeconfig: "{{ wikideck_kubeconfig | default(omit, true) }}"
context: "{{ wikideck_kube_context | default(omit, true) }}"
state: present
apply: true
definition: "{{ lookup('ansible.builtin.template', 'pvc.yml.j2') | from_yaml }}"
# WaitForFirstConsumer claims cannot bind until the pod is scheduled.
wait: false
when: wikideck_existing_claim | length == 0
- name: Create workload identity and internal service
kubernetes.core.k8s:
kubeconfig: "{{ wikideck_kubeconfig | default(omit, true) }}"
context: "{{ wikideck_kube_context | default(omit, true) }}"
state: present
apply: true
definition: "{{ lookup('ansible.builtin.template', item) | from_yaml }}"
loop:
- serviceaccount.yml.j2
- service.yml.j2
- name: Configure network isolation before starting the application
kubernetes.core.k8s:
kubeconfig: "{{ wikideck_kubeconfig | default(omit, true) }}"
context: "{{ wikideck_kube_context | default(omit, true) }}"
state: "{{ 'present' if wikideck_network_policy_enabled else 'absent' }}"
definition: "{{ lookup('ansible.builtin.template', 'networkpolicy.yml.j2') | from_yaml }}"
- name: Deploy the single-writer application
kubernetes.core.k8s:
kubeconfig: "{{ wikideck_kubeconfig | default(omit, true) }}"
context: "{{ wikideck_kube_context | default(omit, true) }}"
state: present
apply: true
definition: "{{ lookup('ansible.builtin.template', 'deployment.yml.j2') | from_yaml }}"
wait: "{{ wikideck_wait | bool }}"
wait_timeout: "{{ wikideck_wait_timeout | int }}"
- name: Configure optional TLS ingress
kubernetes.core.k8s:
kubeconfig: "{{ wikideck_kubeconfig | default(omit, true) }}"
context: "{{ wikideck_kube_context | default(omit, true) }}"
state: present
apply: true
definition: "{{ lookup('ansible.builtin.template', 'ingress.yml.j2') | from_yaml }}"
when: wikideck_ingress_enabled | bool
- name: Remove role ingress when disabled
kubernetes.core.k8s:
kubeconfig: "{{ wikideck_kubeconfig | default(omit, true) }}"
context: "{{ wikideck_kube_context | default(omit, true) }}"
state: absent
api_version: networking.k8s.io/v1
kind: Ingress
namespace: "{{ wikideck_namespace }}"
name: "{{ wikideck_name }}"
when: not wikideck_ingress_enabled | bool
+77
View File
@@ -0,0 +1,77 @@
# SPDX-License-Identifier: MIT-0
---
- name: Validate deployment settings
ansible.builtin.assert:
that:
- wikideck_image is string and wikideck_image | length > 0
- wikideck_image is match('^[^\s@]+(:[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}|@sha256:[a-f0-9]{64})$')
- wikideck_name is string and wikideck_name is match('^[a-z]([a-z0-9-]*[a-z0-9])?$')
- wikideck_name | length <= 50
- wikideck_namespace is string and wikideck_namespace is match('^[a-z0-9]([a-z0-9-]*[a-z0-9])?$')
- wikideck_namespace | length <= 63
- wikideck_image_pull_policy in ['Always', 'IfNotPresent', 'Never']
- wikideck_wait_timeout | string is match('^[1-9][0-9]*$')
- wikideck_resources is mapping
- wikideck_resources.requests is defined and wikideck_resources.requests is mapping
- wikideck_resources.limits is defined and wikideck_resources.limits is mapping
- wikideck_resources.requests.cpu is defined and wikideck_resources.requests.memory is defined
- wikideck_resources.limits.cpu is defined and wikideck_resources.limits.memory is defined
- wikideck_node_selector is mapping
- wikideck_affinity is mapping
- wikideck_ingress_annotations is mapping
- wikideck_storage_size is string and wikideck_storage_size | length > 0
- wikideck_storage_access_modes | length > 0
- wikideck_storage_access_modes | difference(['ReadWriteOnce', 'ReadWriteOncePod']) | length == 0
- wikideck_storage_class is none or wikideck_storage_class is string
- wikideck_existing_claim is string
- wikideck_existing_claim | length == 0 or wikideck_existing_claim is match('^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$')
- wikideck_public_origin is string
- wikideck_public_origin | length == 0 or wikideck_public_origin is match('^https://[a-z0-9.-]+(:[0-9]+)?$')
- wikideck_ingress_enabled is boolean
- wikideck_network_policy_enabled is boolean
- wikideck_offline is boolean
- wikideck_create_namespace is boolean
- wikideck_wait is boolean
fail_msg: >-
Provide a tagged or digest-pinned wikideck_image and valid Kubernetes names.
Resources need CPU/memory requests and limits; storage must be single-writer.
PUBLIC_ORIGIN must be an HTTPS origin without a path or trailing slash.
- name: Validate TLS ingress settings
ansible.builtin.assert:
that:
- wikideck_ingress_host is string and wikideck_ingress_host | length > 0
- wikideck_ingress_host | length <= 253
- wikideck_ingress_host is match('^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$')
- wikideck_tls_secret_name is string and wikideck_tls_secret_name | length > 0
- wikideck_public_origin == 'https://' ~ wikideck_ingress_host
fail_msg: >-
Ingress requires a DNS hostname, a TLS Secret name, and wikideck_public_origin
set to https:// followed by exactly wikideck_ingress_host.
when: wikideck_ingress_enabled | bool
- name: Validate list settings
ansible.builtin.assert:
that:
- lookup('ansible.builtin.vars', item) is sequence
- lookup('ansible.builtin.vars', item) is not string
- lookup('ansible.builtin.vars', item) is not mapping
fail_msg: "{{ item }} must be a list."
loop:
- wikideck_image_pull_secrets
- wikideck_tolerations
- wikideck_storage_access_modes
- wikideck_network_policy_ingress_from
- wikideck_network_policy_dns_to
- wikideck_network_policy_https_to
- name: Require explicit network policy peers
ansible.builtin.assert:
that:
- item is mapping
- item | length > 0
fail_msg: Use an explicit podSelector, namespaceSelector, or ipBlock rather than an empty peer.
loop: >-
{{ wikideck_network_policy_ingress_from + wikideck_network_policy_dns_to
+ wikideck_network_policy_https_to }}
when: wikideck_network_policy_enabled | bool