231 lines
9.1 KiB
YAML
231 lines
9.1 KiB
YAML
---
|
|
# Full platform install — **after** Talos bootstrap (`talosctl bootstrap` + working kubeconfig).
|
|
# Do not run until `kubectl get --raw /healthz` returns ok (see talos/README.md §3, CLUSTER-BUILD Phase A).
|
|
# Run from repo **ansible/** directory: ansible-playbook playbooks/noble.yml
|
|
#
|
|
# Tags: repos, cilium, metrics, longhorn, metallb, kube_vip, traefik, cert_manager, newt,
|
|
# argocd, kyverno, kyverno_policies, platform, velero, all (default)
|
|
- name: Noble cluster — platform stack (Ansible-managed)
|
|
hosts: localhost
|
|
connection: local
|
|
gather_facts: false
|
|
vars:
|
|
noble_repo_root: "{{ playbook_dir | dirname | dirname }}"
|
|
noble_kubeconfig: "{{ lookup('env', 'KUBECONFIG') | default(noble_repo_root + '/talos/kubeconfig', true) }}"
|
|
environment:
|
|
KUBECONFIG: "{{ noble_kubeconfig }}"
|
|
pre_tasks:
|
|
# Helm/kubectl use $KUBECONFIG; a missing file yields "connection refused" to localhost:8080.
|
|
- name: Stat kubeconfig path from KUBECONFIG or default
|
|
ansible.builtin.stat:
|
|
path: "{{ noble_kubeconfig }}"
|
|
register: noble_kubeconfig_stat
|
|
tags: [always]
|
|
|
|
- name: Fall back to repo talos/kubeconfig when $KUBECONFIG is unset or not a file
|
|
ansible.builtin.set_fact:
|
|
noble_kubeconfig: "{{ noble_repo_root }}/talos/kubeconfig"
|
|
when: not noble_kubeconfig_stat.stat.exists | default(false)
|
|
tags: [always]
|
|
|
|
- name: Stat kubeconfig after fallback
|
|
ansible.builtin.stat:
|
|
path: "{{ noble_kubeconfig }}"
|
|
register: noble_kubeconfig_stat2
|
|
tags: [always]
|
|
|
|
- name: Require a real kubeconfig file
|
|
ansible.builtin.assert:
|
|
that:
|
|
- noble_kubeconfig_stat2.stat.exists | default(false)
|
|
- noble_kubeconfig_stat2.stat.isreg | default(false)
|
|
fail_msg: >-
|
|
No kubeconfig file at {{ noble_kubeconfig }}.
|
|
Fix: export KUBECONFIG=/actual/path/from/talosctl-kubeconfig (see talos/README.md),
|
|
or copy the admin kubeconfig to {{ noble_repo_root }}/talos/kubeconfig.
|
|
Do not use documentation placeholders as the path.
|
|
tags: [always]
|
|
|
|
- name: Ensure temp dir for kubeconfig API override
|
|
ansible.builtin.file:
|
|
path: "{{ noble_repo_root }}/ansible/.ansible-tmp"
|
|
state: directory
|
|
mode: "0700"
|
|
when: noble_k8s_api_server_override | default('') | length > 0
|
|
tags: [always]
|
|
|
|
- name: Copy kubeconfig for API server override (original file unchanged)
|
|
ansible.builtin.copy:
|
|
src: "{{ noble_kubeconfig }}"
|
|
dest: "{{ noble_repo_root }}/ansible/.ansible-tmp/kubeconfig.patched"
|
|
mode: "0600"
|
|
when: noble_k8s_api_server_override | default('') | length > 0
|
|
tags: [always]
|
|
|
|
- name: Resolve current cluster name (for set-cluster)
|
|
ansible.builtin.command:
|
|
argv:
|
|
- kubectl
|
|
- config
|
|
- view
|
|
- --minify
|
|
- -o
|
|
- jsonpath={.clusters[0].name}
|
|
environment:
|
|
KUBECONFIG: "{{ noble_repo_root }}/ansible/.ansible-tmp/kubeconfig.patched"
|
|
register: noble_k8s_cluster_name
|
|
changed_when: false
|
|
when: noble_k8s_api_server_override | default('') | length > 0
|
|
tags: [always]
|
|
|
|
- name: Point patched kubeconfig at reachable apiserver
|
|
ansible.builtin.command:
|
|
argv:
|
|
- kubectl
|
|
- config
|
|
- set-cluster
|
|
- "{{ noble_k8s_cluster_name.stdout }}"
|
|
- --server={{ noble_k8s_api_server_override }}
|
|
- --kubeconfig={{ noble_repo_root }}/ansible/.ansible-tmp/kubeconfig.patched
|
|
when: noble_k8s_api_server_override | default('') | length > 0
|
|
changed_when: true
|
|
tags: [always]
|
|
|
|
- name: Use patched kubeconfig for this play
|
|
ansible.builtin.set_fact:
|
|
noble_kubeconfig: "{{ noble_repo_root }}/ansible/.ansible-tmp/kubeconfig.patched"
|
|
when: noble_k8s_api_server_override | default('') | length > 0
|
|
tags: [always]
|
|
|
|
- name: Verify Kubernetes API is reachable from this host
|
|
ansible.builtin.command:
|
|
argv:
|
|
- kubectl
|
|
- get
|
|
- --raw
|
|
- /healthz
|
|
- --request-timeout=15s
|
|
environment:
|
|
KUBECONFIG: "{{ noble_kubeconfig }}"
|
|
register: noble_k8s_health_first
|
|
failed_when: false
|
|
changed_when: false
|
|
tags: [always]
|
|
|
|
# talosctl kubeconfig often sets server to the VIP; off-LAN you can reach a control-plane IP but not 192.168.50.230.
|
|
- name: Auto-fallback API server when VIP is unreachable (temp kubeconfig)
|
|
tags: [always]
|
|
when:
|
|
- noble_k8s_api_server_auto_fallback | default(true) | bool
|
|
- noble_k8s_api_server_override | default('') | length == 0
|
|
- not (noble_skip_k8s_health_check | default(false) | bool)
|
|
- (noble_k8s_health_first.rc | default(1)) != 0 or (noble_k8s_health_first.stdout | default('') | trim) != 'ok'
|
|
- ('network is unreachable' in (noble_k8s_health_first.stderr | default('') | lower)) or
|
|
('no route to host' in (noble_k8s_health_first.stderr | default('') | lower))
|
|
block:
|
|
- name: Ensure temp dir for kubeconfig auto-fallback
|
|
ansible.builtin.file:
|
|
path: "{{ noble_repo_root }}/ansible/.ansible-tmp"
|
|
state: directory
|
|
mode: "0700"
|
|
|
|
- name: Copy kubeconfig for API auto-fallback
|
|
ansible.builtin.copy:
|
|
src: "{{ noble_kubeconfig }}"
|
|
dest: "{{ noble_repo_root }}/ansible/.ansible-tmp/kubeconfig.auto-fallback"
|
|
mode: "0600"
|
|
|
|
- name: Resolve cluster name for kubectl set-cluster
|
|
ansible.builtin.command:
|
|
argv:
|
|
- kubectl
|
|
- config
|
|
- view
|
|
- --minify
|
|
- -o
|
|
- jsonpath={.clusters[0].name}
|
|
environment:
|
|
KUBECONFIG: "{{ noble_repo_root }}/ansible/.ansible-tmp/kubeconfig.auto-fallback"
|
|
register: noble_k8s_cluster_fb
|
|
changed_when: false
|
|
|
|
- name: Point temp kubeconfig at fallback apiserver
|
|
ansible.builtin.command:
|
|
argv:
|
|
- kubectl
|
|
- config
|
|
- set-cluster
|
|
- "{{ noble_k8s_cluster_fb.stdout }}"
|
|
- --server={{ noble_k8s_api_server_fallback | default('https://192.168.50.20:6443', true) }}
|
|
- --kubeconfig={{ noble_repo_root }}/ansible/.ansible-tmp/kubeconfig.auto-fallback
|
|
changed_when: true
|
|
|
|
- name: Use kubeconfig with fallback API server for this play
|
|
ansible.builtin.set_fact:
|
|
noble_kubeconfig: "{{ noble_repo_root }}/ansible/.ansible-tmp/kubeconfig.auto-fallback"
|
|
|
|
- name: Re-verify Kubernetes API after auto-fallback
|
|
ansible.builtin.command:
|
|
argv:
|
|
- kubectl
|
|
- get
|
|
- --raw
|
|
- /healthz
|
|
- --request-timeout=15s
|
|
environment:
|
|
KUBECONFIG: "{{ noble_kubeconfig }}"
|
|
register: noble_k8s_health_after_fallback
|
|
failed_when: false
|
|
changed_when: false
|
|
|
|
- name: Mark that API was re-checked after kubeconfig fallback
|
|
ansible.builtin.set_fact:
|
|
noble_k8s_api_fallback_used: true
|
|
|
|
- name: Normalize API health result for preflight (scalars; avoids dict merge / set_fact stringification)
|
|
ansible.builtin.set_fact:
|
|
noble_k8s_health_rc: "{{ noble_k8s_health_after_fallback.rc | default(1) if (noble_k8s_api_fallback_used | default(false) | bool) else (noble_k8s_health_first.rc | default(1)) }}"
|
|
noble_k8s_health_stdout: "{{ noble_k8s_health_after_fallback.stdout | default('') if (noble_k8s_api_fallback_used | default(false) | bool) else (noble_k8s_health_first.stdout | default('')) }}"
|
|
noble_k8s_health_stderr: "{{ noble_k8s_health_after_fallback.stderr | default('') if (noble_k8s_api_fallback_used | default(false) | bool) else (noble_k8s_health_first.stderr | default('')) }}"
|
|
tags: [always]
|
|
|
|
- name: Fail when API check did not return ok
|
|
ansible.builtin.fail:
|
|
msg: "{{ lookup('template', 'templates/api_health_hint.j2') }}"
|
|
when:
|
|
- not (noble_skip_k8s_health_check | default(false) | bool)
|
|
- (noble_k8s_health_rc | int) != 0 or (noble_k8s_health_stdout | default('') | trim) != 'ok'
|
|
tags: [always]
|
|
|
|
roles:
|
|
- role: helm_repos
|
|
tags: [repos, helm]
|
|
- role: noble_cilium
|
|
tags: [cilium, cni]
|
|
- role: noble_metrics_server
|
|
tags: [metrics, metrics_server]
|
|
- role: noble_longhorn
|
|
tags: [longhorn, storage]
|
|
- role: noble_metallb
|
|
tags: [metallb, lb]
|
|
- role: noble_kube_vip
|
|
tags: [kube_vip, vip]
|
|
- role: noble_traefik
|
|
tags: [traefik, ingress]
|
|
- role: noble_cert_manager
|
|
tags: [cert_manager, certs]
|
|
- role: noble_newt
|
|
tags: [newt]
|
|
- role: noble_argocd
|
|
tags: [argocd, gitops]
|
|
- role: noble_kyverno
|
|
tags: [kyverno, policy]
|
|
- role: noble_kyverno_policies
|
|
tags: [kyverno_policies, policy]
|
|
- role: noble_platform
|
|
tags: [platform, observability, apps]
|
|
- role: noble_velero
|
|
tags: [velero, backups]
|
|
- role: noble_landing_urls
|
|
tags: [landing, platform, observability, apps]
|