mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 10:13:58 +00:00
303 lines
10 KiB
YAML
303 lines
10 KiB
YAML
---
|
|
|
|
- name: Skip k3s configuration when disabled
|
|
ansible.builtin.meta: end_host
|
|
when: not (k3s_enabled | default(true) | bool)
|
|
|
|
- name: Skip k3s configuration when state is absent
|
|
ansible.builtin.meta: end_host
|
|
when: k3s_state == "absent"
|
|
|
|
- name: Set k3s service name
|
|
ansible.builtin.set_fact:
|
|
k3s_service_name: "{{ 'k3s' if k3s_role == 'server' else 'k3s-agent' }}"
|
|
|
|
- name: Check if controller has conf/k3s.cfg (optional)
|
|
ansible.builtin.stat:
|
|
path: "{{ role_path }}/../../../conf/k3s.cfg"
|
|
register: _k3s_prole_cfg_stat
|
|
delegate_to: localhost
|
|
|
|
- name: Load service namespace from k3s.cfg (controller)
|
|
ansible.builtin.set_fact:
|
|
k3s_prole_service_namespace_cfg: >-
|
|
{{ lookup(
|
|
'ansible.builtin.ini',
|
|
'SERVICE_NAMESPACE section=Global file=' ~ (role_path ~ '/../../../conf/k3s.cfg'),
|
|
default='',
|
|
errors='ignore'
|
|
) if _k3s_prole_cfg_stat.stat.exists else '' }}
|
|
changed_when: false
|
|
|
|
- name: Load service hostname from k3s.cfg (controller)
|
|
ansible.builtin.set_fact:
|
|
k3s_prole_service_hostname_user_cfg: >-
|
|
{{ lookup(
|
|
'ansible.builtin.ini',
|
|
'SERVICE_HOSTNAME section=User file=' ~ (role_path ~ '/../../../conf/k3s.cfg'),
|
|
default='',
|
|
errors='ignore'
|
|
) if _k3s_prole_cfg_stat.stat.exists else '' }}
|
|
k3s_prole_service_hostname_global_cfg: >-
|
|
{{ lookup(
|
|
'ansible.builtin.ini',
|
|
'SERVICE_HOSTNAME section=Global file=' ~ (role_path ~ '/../../../conf/k3s.cfg'),
|
|
default='',
|
|
errors='ignore'
|
|
) if _k3s_prole_cfg_stat.stat.exists else '' }}
|
|
changed_when: false
|
|
|
|
- name: Normalize service hostname variable
|
|
ansible.builtin.set_fact:
|
|
k3s_service_hostname: >-
|
|
{{ (k3s_prole_service_hostname_user_cfg | default('') | trim)
|
|
if ((k3s_prole_service_hostname_user_cfg | default('') | trim) | length > 0
|
|
and (k3s_prole_service_hostname_user_cfg | trim) != '${SERVICE_HOSTNAME}')
|
|
else (k3s_prole_service_hostname_global_cfg | default('') | trim)
|
|
if ((k3s_prole_service_hostname_global_cfg | default('') | trim) | length > 0
|
|
and (k3s_prole_service_hostname_global_cfg | trim) != '${SERVICE_HOSTNAME}')
|
|
else (k3s_service_hostname | default('svc.prole.org')) }}
|
|
changed_when: false
|
|
|
|
- name: Resolve Kong namespaces from k3s.cfg (avoid implicit default namespace)
|
|
ansible.builtin.set_fact:
|
|
_k3s_service_namespace_resolved: >-
|
|
{{ (k3s_prole_service_namespace_cfg | default(''))
|
|
if (k3s_prole_service_namespace_cfg | default('') | length > 0 and k3s_prole_service_namespace_cfg != '${SERVICE_NAMESPACE}')
|
|
else 'default' }}
|
|
changed_when: false
|
|
|
|
- name: Normalize Kong namespace variables
|
|
ansible.builtin.set_fact:
|
|
k3s_kong_namespace: >-
|
|
{{ (k3s_kong_namespace | default(''))
|
|
if (k3s_kong_namespace | default('') | length > 0 and k3s_kong_namespace != '${SERVICE_NAMESPACE}')
|
|
else _k3s_service_namespace_resolved }}
|
|
changed_when: false
|
|
|
|
- name: Normalize svc-check Kong namespace variable
|
|
ansible.builtin.set_fact:
|
|
k3s_svc_check_kong_namespace: >-
|
|
{{ (k3s_svc_check_kong_namespace | default(''))
|
|
if (k3s_svc_check_kong_namespace | default('') | length > 0 and k3s_svc_check_kong_namespace != '${SERVICE_NAMESPACE}')
|
|
else k3s_kong_namespace }}
|
|
changed_when: false
|
|
|
|
- name: Validate resolved Kong namespace variables
|
|
ansible.builtin.assert:
|
|
that:
|
|
- k3s_kong_namespace | length > 0
|
|
- k3s_svc_check_kong_namespace | length > 0
|
|
fail_msg: >-
|
|
Resolved Kong namespace variables are empty. Ensure `SERVICE_NAMESPACE` is set in `conf/k3s.cfg`
|
|
or explicitly set `k3s_kong_namespace` / `k3s_svc_check_kong_namespace` in Ansible inventory.
|
|
|
|
- name: Pre-stage critical images (registry:2, kong, etc.)
|
|
ansible.builtin.include_tasks: prestage_images.yml
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_prestage_images | bool
|
|
tags: [images]
|
|
|
|
- name: Create ArgoCD hostPath directories on myrddin.prole.org (/synology/d001)
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
mode: "0777"
|
|
loop:
|
|
- /synology/d001/argocd
|
|
- /synology/d001/argocd/home
|
|
- /synology/d001/argocd/tmp
|
|
when:
|
|
- k3s_state == "present"
|
|
- inventory_hostname == 'myrddin.prole.org'
|
|
|
|
- name: Create ArgoCD hostPath directories on merlin.prole.org (/synology/d002)
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
mode: "0777"
|
|
loop:
|
|
- /synology/d002/argocd
|
|
- /synology/d002/argocd/data
|
|
- /synology/d002/argocd/tmp
|
|
when:
|
|
- k3s_state == "present"
|
|
- inventory_hostname == 'merlin.prole.org'
|
|
|
|
- name: Create ArgoCD hostPath directories on pi.prole.org (/synology/d003)
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
mode: "0777"
|
|
loop:
|
|
- /synology/d003/argocd
|
|
- /synology/d003/argocd/gpg-keyring
|
|
- /synology/d003/argocd/tmp
|
|
- /synology/d003/argocd/helm-working-dir
|
|
- /synology/d003/argocd/var-files
|
|
- /synology/d003/argocd/plugins
|
|
when:
|
|
- k3s_state == "present"
|
|
- inventory_hostname == 'pi.prole.org'
|
|
|
|
- name: Wait for k3s Kubernetes API to become ready
|
|
ansible.builtin.command: k3s kubectl get --raw='/readyz'
|
|
register: _k3s_readyz
|
|
changed_when: false
|
|
retries: 60
|
|
delay: 5
|
|
until: _k3s_readyz.rc == 0
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
run_once: true
|
|
|
|
- name: Load optional workloads threshold from prole.cfg (controller)
|
|
ansible.builtin.set_fact:
|
|
k3s_optional_workloads_min_nodes_cfg: >-
|
|
{{ lookup(
|
|
'ansible.builtin.ini',
|
|
'OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES section=Global file=' ~ (role_path ~ '/../../../conf/k3s.cfg'),
|
|
default='',
|
|
errors='ignore'
|
|
) if _k3s_prole_cfg_stat.stat.exists else '' }}
|
|
changed_when: false
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
run_once: true
|
|
|
|
- name: Validate optional-workloads policy config is present
|
|
ansible.builtin.assert:
|
|
that:
|
|
- _k3s_prole_cfg_stat.stat.exists
|
|
- (k3s_optional_workloads_min_nodes_cfg | string | trim | length) > 0
|
|
- (k3s_optional_workloads_min_nodes_cfg | int) > 0
|
|
fail_msg: >-
|
|
Missing or invalid optional-workloads policy configuration.
|
|
Expected [Global] OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES in conf/k3s.cfg
|
|
(got '{{ k3s_optional_workloads_min_nodes_cfg | default('') }}').
|
|
changed_when: false
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
run_once: true
|
|
|
|
- name: Query cluster nodes for optional-workloads policy
|
|
ansible.builtin.command: k3s kubectl get nodes --no-headers
|
|
register: _k3s_nodes_list
|
|
changed_when: false
|
|
failed_when: false
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
run_once: true
|
|
|
|
- name: Log optional-workloads policy node query failure (treat as insufficient capacity)
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
Could not query Kubernetes nodes for optional-workloads policy.
|
|
Treating as ready_schedulable_nodes=0 so optional workloads will be disabled for this run.
|
|
rc={{ _k3s_nodes_list.rc | default('n/a') }} stderr={{ _k3s_nodes_list.stderr | default('') | trim }}
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
- _k3s_nodes_list is defined
|
|
- (_k3s_nodes_list.rc | default(1) | int) != 0
|
|
run_once: true
|
|
|
|
- name: Evaluate optional-workloads policy (ready + schedulable)
|
|
ansible.builtin.include_tasks: optional_workloads_policy_eval.yml
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
run_once: true
|
|
|
|
- name: Log optional-workloads policy decision
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
optional_workloads_allowed={{ optional_workloads_allowed }}
|
|
(ready_schedulable_nodes={{ ready_schedulable_nodes }} min_required={{ optional_workloads_min_ready_schedulable_nodes }})
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
run_once: true
|
|
|
|
- name: Apply merlin-local-iscsi StorageClass (monitoring)
|
|
ansible.builtin.shell: |
|
|
k3s kubectl apply --validate=false -f - <<'EOF'
|
|
apiVersion: storage.k8s.io/v1
|
|
kind: StorageClass
|
|
metadata:
|
|
name: merlin-local-iscsi
|
|
provisioner: kubernetes.io/no-provisioner
|
|
volumeBindingMode: WaitForFirstConsumer
|
|
reclaimPolicy: Retain
|
|
EOF
|
|
register: _merlin_local_iscsi_apply
|
|
changed_when: >-
|
|
(_merlin_local_iscsi_apply.stdout | default('') | lower) is search('configured')
|
|
or (_merlin_local_iscsi_apply.stdout | default('') | lower) is search('created')
|
|
failed_when: false
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
- optional_workloads_allowed | default(false) | bool
|
|
run_once: true
|
|
|
|
- name: Log monitoring StorageClass apply failure (non-fatal)
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
Failed to apply monitoring StorageClass (non-fatal): rc={{ _merlin_local_iscsi_apply.rc | default('n/a') }}
|
|
stderr={{ _merlin_local_iscsi_apply.stderr | default('') | trim }}
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
- optional_workloads_allowed | default(false) | bool
|
|
- _merlin_local_iscsi_apply is defined
|
|
- (_merlin_local_iscsi_apply.rc | default(0) | int) != 0
|
|
run_once: true
|
|
|
|
- name: Skip monitoring StorageClass when optional workloads are disallowed
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
Skipping monitoring StorageClass because optional workloads are disallowed:
|
|
optional_workloads_allowed={{ optional_workloads_allowed | default(false) }}
|
|
(ready_schedulable_nodes={{ ready_schedulable_nodes | default('unknown') }} min_required={{ optional_workloads_min_ready_schedulable_nodes | default('unknown') }})
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
- not (optional_workloads_allowed | default(false) | bool)
|
|
run_once: true
|
|
|
|
- name: Fetch kubeconfig to controller for controller-side installs
|
|
ansible.builtin.include_tasks: fetch_kubeconfig.yml
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
run_once: true
|
|
|
|
- name: Ensure CloudNative-PG operator and kubectl plugin
|
|
ansible.builtin.include_tasks: cnpg.yml
|
|
when: k3s_state == "present"
|
|
|
|
- name: Ensure cert-manager is installed for ACME
|
|
ansible.builtin.include_tasks: certmgr.yml
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
|
|
- name: Configure ACME issuer and certificate for service hostname
|
|
ansible.builtin.include_tasks: acme_cert.yml
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
|
|
- name: Ensure Kong is present and refreshed
|
|
ansible.builtin.include_tasks: kong.yml
|
|
when:
|
|
- k3s_state == "present"
|
|
- k3s_role == 'server'
|
|
|