Refactor Argo CD application management by removing noble-kyverno and noble-platform configurations, transitioning to Ansible-driven installations. Update documentation to clarify the optional nature of app-of-apps and the role of kustomization.yaml as an empty resource holder. Ensure users are informed about the need to delete stale Applications when migrating from previous configurations.
This commit is contained in:
18
ansible/roles/helm_repos/defaults/main.yml
Normal file
18
ansible/roles/helm_repos/defaults/main.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
noble_helm_repos:
|
||||
- { name: cilium, url: "https://helm.cilium.io/" }
|
||||
- { name: metallb, url: "https://metallb.github.io/metallb" }
|
||||
- { name: longhorn, url: "https://charts.longhorn.io" }
|
||||
- { name: traefik, url: "https://traefik.github.io/charts" }
|
||||
- { name: jetstack, url: "https://charts.jetstack.io" }
|
||||
- { name: fossorial, url: "https://charts.fossorial.io" }
|
||||
- { name: argo, url: "https://argoproj.github.io/argo-helm" }
|
||||
- { name: metrics-server, url: "https://kubernetes-sigs.github.io/metrics-server/" }
|
||||
- { name: sealed-secrets, url: "https://bitnami-labs.github.io/sealed-secrets" }
|
||||
- { name: external-secrets, url: "https://charts.external-secrets.io" }
|
||||
- { name: hashicorp, url: "https://helm.releases.hashicorp.com" }
|
||||
- { name: prometheus-community, url: "https://prometheus-community.github.io/helm-charts" }
|
||||
- { name: grafana, url: "https://grafana.github.io/helm-charts" }
|
||||
- { name: fluent, url: "https://fluent.github.io/helm-charts" }
|
||||
- { name: headlamp, url: "https://kubernetes-sigs.github.io/headlamp/" }
|
||||
- { name: kyverno, url: "https://kyverno.github.io/kyverno/" }
|
||||
16
ansible/roles/helm_repos/tasks/main.yml
Normal file
16
ansible/roles/helm_repos/tasks/main.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Add Helm repositories
|
||||
ansible.builtin.command:
|
||||
cmd: "helm repo add {{ item.name }} {{ item.url }}"
|
||||
loop: "{{ noble_helm_repos }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
register: helm_repo_add
|
||||
changed_when: helm_repo_add.rc == 0
|
||||
failed_when: >-
|
||||
helm_repo_add.rc != 0 and
|
||||
('already exists' not in (helm_repo_add.stderr | default('')))
|
||||
|
||||
- name: helm repo update
|
||||
ansible.builtin.command: helm repo update
|
||||
changed_when: true
|
||||
20
ansible/roles/noble_argocd/tasks/main.yml
Normal file
20
ansible/roles/noble_argocd/tasks/main.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: Install Argo CD
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- argocd
|
||||
- argo/argo-cd
|
||||
- --namespace
|
||||
- argocd
|
||||
- --create-namespace
|
||||
- --version
|
||||
- "9.4.17"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/bootstrap/argocd/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
65
ansible/roles/noble_cert_manager/tasks/main.yml
Normal file
65
ansible/roles/noble_cert_manager/tasks/main.yml
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
- name: Create cert-manager namespace
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/cert-manager/namespace.yaml"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install cert-manager
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- cert-manager
|
||||
- jetstack/cert-manager
|
||||
- --namespace
|
||||
- cert-manager
|
||||
- --version
|
||||
- v1.20.0
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/cert-manager/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Check Cloudflare DNS API token Secret (required for ClusterIssuers)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- -n
|
||||
- cert-manager
|
||||
- get
|
||||
- secret
|
||||
- cloudflare-dns-api-token
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
register: noble_cf_secret
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Warn when Cloudflare Secret is missing
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Secret cert-manager/cloudflare-dns-api-token not found.
|
||||
Create it per clusters/noble/apps/cert-manager/README.md before ClusterIssuers can succeed.
|
||||
when:
|
||||
- noble_cert_manager_require_cloudflare_secret | bool
|
||||
- noble_cf_secret.rc != 0
|
||||
|
||||
- name: Apply ClusterIssuers (staging + prod)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -k
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/cert-manager"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
25
ansible/roles/noble_cilium/tasks/main.yml
Normal file
25
ansible/roles/noble_cilium/tasks/main.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
- name: Install Cilium (required CNI for Talos cni:none)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- cilium
|
||||
- cilium/cilium
|
||||
- --namespace
|
||||
- kube-system
|
||||
- --version
|
||||
- "1.16.6"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/cilium/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Wait for Cilium DaemonSet
|
||||
ansible.builtin.command: kubectl -n kube-system rollout status ds/cilium --timeout=300s
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: false
|
||||
11
ansible/roles/noble_kube_vip/tasks/main.yml
Normal file
11
ansible/roles/noble_kube_vip/tasks/main.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Apply kube-vip (Kubernetes API VIP)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -k
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/kube-vip"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
32
ansible/roles/noble_kyverno/tasks/main.yml
Normal file
32
ansible/roles/noble_kyverno/tasks/main.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
- name: Create Kyverno namespace
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/kyverno/namespace.yaml"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install Kyverno operator
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- kyverno
|
||||
- kyverno/kyverno
|
||||
- -n
|
||||
- kyverno
|
||||
- --version
|
||||
- "3.7.1"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/kyverno/values.yaml"
|
||||
- --wait
|
||||
- --timeout
|
||||
- 15m
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
21
ansible/roles/noble_kyverno_policies/tasks/main.yml
Normal file
21
ansible/roles/noble_kyverno_policies/tasks/main.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
- name: Install Kyverno policy chart (PSS baseline, Audit)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- kyverno-policies
|
||||
- kyverno/kyverno-policies
|
||||
- -n
|
||||
- kyverno
|
||||
- --version
|
||||
- "3.7.1"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/kyverno/policies-values.yaml"
|
||||
- --wait
|
||||
- --timeout
|
||||
- 10m
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
29
ansible/roles/noble_longhorn/tasks/main.yml
Normal file
29
ansible/roles/noble_longhorn/tasks/main.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
- name: Apply Longhorn namespace (PSA) from kustomization
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -k
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/longhorn"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install Longhorn chart
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- longhorn
|
||||
- longhorn/longhorn
|
||||
- -n
|
||||
- longhorn-system
|
||||
- --create-namespace
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/longhorn/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
37
ansible/roles/noble_metallb/tasks/main.yml
Normal file
37
ansible/roles/noble_metallb/tasks/main.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
- name: Apply MetalLB namespace (Pod Security labels)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/metallb/namespace.yaml"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install MetalLB chart
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- metallb
|
||||
- metallb/metallb
|
||||
- --namespace
|
||||
- metallb-system
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Apply IPAddressPool and L2Advertisement
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -k
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/metallb"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
19
ansible/roles/noble_metrics_server/tasks/main.yml
Normal file
19
ansible/roles/noble_metrics_server/tasks/main.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
- name: Install metrics-server
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- metrics-server
|
||||
- metrics-server/metrics-server
|
||||
- -n
|
||||
- kube-system
|
||||
- --version
|
||||
- "3.13.0"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/metrics-server/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
37
ansible/roles/noble_newt/tasks/main.yml
Normal file
37
ansible/roles/noble_newt/tasks/main.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
- name: Skip Newt when not enabled
|
||||
ansible.builtin.debug:
|
||||
msg: "noble_newt_install is false — create newt-pangolin-auth Secret and set noble_newt_install=true to deploy Newt."
|
||||
when: not (noble_newt_install | bool)
|
||||
|
||||
- name: Create Newt namespace
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/newt/namespace.yaml"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
when: noble_newt_install | bool
|
||||
changed_when: true
|
||||
|
||||
- name: Install Newt chart
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- newt
|
||||
- fossorial/newt
|
||||
- --namespace
|
||||
- newt
|
||||
- --version
|
||||
- "1.2.0"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/newt/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
when: noble_newt_install | bool
|
||||
changed_when: true
|
||||
147
ansible/roles/noble_platform/tasks/main.yml
Normal file
147
ansible/roles/noble_platform/tasks/main.yml
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
# Mirrors former **noble-platform** Argo Application: Helm releases + plain manifests under clusters/noble/apps.
|
||||
- name: Apply clusters/noble/apps kustomize (namespaces, Grafana Loki datasource, Vault extras)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -k
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install Sealed Secrets
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- sealed-secrets
|
||||
- sealed-secrets/sealed-secrets
|
||||
- --namespace
|
||||
- sealed-secrets
|
||||
- --version
|
||||
- "2.18.4"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/sealed-secrets/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install External Secrets Operator
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- external-secrets
|
||||
- external-secrets/external-secrets
|
||||
- --namespace
|
||||
- external-secrets
|
||||
- --version
|
||||
- "2.2.0"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/external-secrets/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install Vault
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- vault
|
||||
- hashicorp/vault
|
||||
- --namespace
|
||||
- vault
|
||||
- --version
|
||||
- "0.32.0"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/vault/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install kube-prometheus-stack
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- kube-prometheus
|
||||
- prometheus-community/kube-prometheus-stack
|
||||
- -n
|
||||
- monitoring
|
||||
- --version
|
||||
- "82.15.1"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/kube-prometheus-stack/values.yaml"
|
||||
- --wait
|
||||
- --timeout
|
||||
- 30m
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install Loki
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- loki
|
||||
- grafana/loki
|
||||
- -n
|
||||
- loki
|
||||
- --version
|
||||
- "6.55.0"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/loki/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install Fluent Bit
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- fluent-bit
|
||||
- fluent/fluent-bit
|
||||
- -n
|
||||
- logging
|
||||
- --version
|
||||
- "0.56.0"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/fluent-bit/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install Headlamp
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- headlamp
|
||||
- headlamp/headlamp
|
||||
- --version
|
||||
- "0.40.1"
|
||||
- -n
|
||||
- headlamp
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/headlamp/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
27
ansible/roles/noble_post_deploy/tasks/main.yml
Normal file
27
ansible/roles/noble_post_deploy/tasks/main.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
- name: Vault — manual steps (not automated)
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
1. kubectl -n vault get pods (wait for Running)
|
||||
2. kubectl -n vault exec -it vault-0 -- vault operator init (once; save keys)
|
||||
3. Unseal per clusters/noble/apps/vault/README.md
|
||||
4. ./clusters/noble/apps/vault/configure-kubernetes-auth.sh
|
||||
5. kubectl apply -f clusters/noble/apps/external-secrets/examples/vault-cluster-secret-store.yaml
|
||||
|
||||
- name: Optional — apply Vault ClusterSecretStore for External Secrets
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/external-secrets/examples/vault-cluster-secret-store.yaml"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
when: noble_apply_vault_cluster_secret_store | default(false) | bool
|
||||
changed_when: true
|
||||
|
||||
- name: Argo CD optional root Application (empty app-of-apps)
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Optional: kubectl apply -f clusters/noble/bootstrap/argocd/root-application.yaml
|
||||
after editing repoURL. Core workloads are not synced by Argo — see bootstrap/argocd/apps/README.md
|
||||
30
ansible/roles/noble_traefik/tasks/main.yml
Normal file
30
ansible/roles/noble_traefik/tasks/main.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
- name: Create Traefik namespace
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- apply
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/traefik/namespace.yaml"
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Install Traefik
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- helm
|
||||
- upgrade
|
||||
- --install
|
||||
- traefik
|
||||
- traefik/traefik
|
||||
- --namespace
|
||||
- traefik
|
||||
- --version
|
||||
- "39.0.6"
|
||||
- -f
|
||||
- "{{ noble_repo_root }}/clusters/noble/apps/traefik/values.yaml"
|
||||
- --wait
|
||||
environment:
|
||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||
changed_when: true
|
||||
3
ansible/roles/talos_bootstrap/defaults/main.yml
Normal file
3
ansible/roles/talos_bootstrap/defaults/main.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
# Set **true** to run `talhelper genconfig -o out` under **talos/** (requires talhelper + talconfig).
|
||||
noble_talos_genconfig: false
|
||||
36
ansible/roles/talos_bootstrap/tasks/main.yml
Normal file
36
ansible/roles/talos_bootstrap/tasks/main.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
- name: Generate Talos machine configs (talhelper genconfig)
|
||||
when: noble_talos_genconfig | bool
|
||||
block:
|
||||
- name: Validate talconfig
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talhelper
|
||||
- validate
|
||||
- talconfig
|
||||
- talconfig.yaml
|
||||
args:
|
||||
chdir: "{{ noble_repo_root }}/talos"
|
||||
changed_when: false
|
||||
|
||||
- name: Generate Talos configs (out/)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talhelper
|
||||
- genconfig
|
||||
- -o
|
||||
- out
|
||||
args:
|
||||
chdir: "{{ noble_repo_root }}/talos"
|
||||
changed_when: true
|
||||
|
||||
- name: Post genconfig — next steps
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Configs are in talos/out/. Apply to nodes, bootstrap, and kubeconfig per talos/README.md
|
||||
before running playbooks/noble.yml.
|
||||
|
||||
- name: Skip when noble_talos_genconfig is false
|
||||
ansible.builtin.debug:
|
||||
msg: "No-op: pass -e noble_talos_genconfig=true to run talhelper genconfig."
|
||||
when: not (noble_talos_genconfig | bool)
|
||||
38
ansible/roles/talos_phase_a/defaults/main.yml
Normal file
38
ansible/roles/talos_phase_a/defaults/main.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
# **noble_repo_root** and **noble_talos_dir** are set by **playbooks/talos_phase_a.yml** (repo root and **talos/**).
|
||||
|
||||
# Run **talhelper genconfig -o out** before apply (needs talhelper + talsecret per talos/README.md §1).
|
||||
noble_talos_genconfig: true
|
||||
|
||||
# **auto** — probe nodes (maintenance vs joined TLS); **insecure** — always **--insecure**; **secure** — always **TALOSCONFIG** (Phase A already done / talos/README §2 B).
|
||||
noble_talos_apply_mode: auto
|
||||
|
||||
# Skip if cluster is already bootstrapped (re-run playbook safely).
|
||||
noble_talos_skip_bootstrap: false
|
||||
|
||||
# After **apply-config**, nodes often reboot — wait for Talos **apid** (:50000) before **bootstrap** / **kubeconfig**.
|
||||
noble_talos_wait_for_apid: true
|
||||
noble_talos_apid_wait_delay: 20
|
||||
noble_talos_apid_wait_timeout: 900
|
||||
|
||||
# **talosctl bootstrap -n** — first control plane (neon).
|
||||
noble_talos_bootstrap_node_ip: "192.168.50.20"
|
||||
|
||||
# **talosctl kubeconfig -n** (node that answers Talos/K8s for cert fetch).
|
||||
noble_talos_kubeconfig_node: "192.168.50.20"
|
||||
|
||||
# **talosctl kubeconfig -e** — Talos endpoint (node IP before VIP is reachable; VIP when LAN works).
|
||||
noble_talos_kubeconfig_endpoint: "192.168.50.20"
|
||||
|
||||
# After kubeconfig, patch **kubectl** server if VIP in file is unreachable (**group_vars** / same as noble.yml).
|
||||
# noble_k8s_api_server_override: ""
|
||||
|
||||
# Must match **cluster.name** / kubeconfig cluster entry (often **noble**).
|
||||
noble_talos_kubectl_cluster_name: noble
|
||||
|
||||
# Inventory: IP + filename under **talos/out/** — align with **talos/talconfig.yaml**.
|
||||
noble_talos_nodes:
|
||||
- { ip: "192.168.50.20", machine: "noble-neon.yaml" }
|
||||
- { ip: "192.168.50.30", machine: "noble-argon.yaml" }
|
||||
- { ip: "192.168.50.40", machine: "noble-krypton.yaml" }
|
||||
- { ip: "192.168.50.10", machine: "noble-helium.yaml" }
|
||||
209
ansible/roles/talos_phase_a/tasks/main.yml
Normal file
209
ansible/roles/talos_phase_a/tasks/main.yml
Normal file
@@ -0,0 +1,209 @@
|
||||
---
|
||||
# Order matches talos/README.md: genconfig → apply all nodes → bootstrap → kubeconfig.
|
||||
|
||||
- name: Validate talconfig and generate **out/** (talhelper genconfig)
|
||||
when: noble_talos_genconfig | bool
|
||||
block:
|
||||
- name: talhelper validate
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talhelper
|
||||
- validate
|
||||
- talconfig
|
||||
- talconfig.yaml
|
||||
args:
|
||||
chdir: "{{ noble_talos_dir }}"
|
||||
changed_when: false
|
||||
|
||||
- name: talhelper genconfig -o out
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talhelper
|
||||
- genconfig
|
||||
- -o
|
||||
- out
|
||||
args:
|
||||
chdir: "{{ noble_talos_dir }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Stat talos/out/talosconfig
|
||||
ansible.builtin.stat:
|
||||
path: "{{ noble_talos_dir }}/out/talosconfig"
|
||||
register: noble_talos_talosconfig
|
||||
|
||||
- name: Require talos/out/talosconfig
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- noble_talos_talosconfig.stat.exists | default(false)
|
||||
fail_msg: >-
|
||||
Missing {{ noble_talos_dir }}/out/talosconfig. Run **talhelper genconfig -o out** in **talos/** (talsecret per talos/README.md §1),
|
||||
or set **noble_talos_genconfig=true** on this playbook.
|
||||
|
||||
# Maintenance API (**--insecure**) vs joined cluster (**tls: certificate required**) — talos/README §2 A vs B.
|
||||
- name: Set apply path from noble_talos_apply_mode (manual)
|
||||
ansible.builtin.set_fact:
|
||||
noble_talos_apply_insecure: "{{ noble_talos_apply_mode == 'insecure' }}"
|
||||
when: noble_talos_apply_mode | default('auto') in ['insecure', 'secure']
|
||||
|
||||
- name: Probe Talos API — apply-config dry-run (insecure / maintenance)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talosctl
|
||||
- apply-config
|
||||
- --insecure
|
||||
- -n
|
||||
- "{{ noble_talos_nodes[0].ip }}"
|
||||
- -f
|
||||
- "{{ noble_talos_dir }}/out/{{ noble_talos_nodes[0].machine }}"
|
||||
- --dry-run
|
||||
register: noble_talos_probe_insecure
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: noble_talos_apply_mode | default('auto') == 'auto'
|
||||
|
||||
- name: Probe Talos API — apply-config dry-run (TLS / joined)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talosctl
|
||||
- apply-config
|
||||
- -n
|
||||
- "{{ noble_talos_nodes[0].ip }}"
|
||||
- -f
|
||||
- "{{ noble_talos_dir }}/out/{{ noble_talos_nodes[0].machine }}"
|
||||
- --dry-run
|
||||
environment:
|
||||
TALOSCONFIG: "{{ noble_talos_dir }}/out/talosconfig"
|
||||
register: noble_talos_probe_secure
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when:
|
||||
- noble_talos_apply_mode | default('auto') == 'auto'
|
||||
- noble_talos_probe_insecure.rc != 0
|
||||
|
||||
- name: Resolve apply mode — maintenance (insecure)
|
||||
ansible.builtin.set_fact:
|
||||
noble_talos_apply_insecure: true
|
||||
when:
|
||||
- noble_talos_apply_mode | default('auto') == 'auto'
|
||||
- noble_talos_probe_insecure.rc == 0
|
||||
|
||||
- name: Resolve apply mode — joined (TALOSCONFIG, no insecure)
|
||||
ansible.builtin.set_fact:
|
||||
noble_talos_apply_insecure: false
|
||||
when:
|
||||
- noble_talos_apply_mode | default('auto') == 'auto'
|
||||
- noble_talos_probe_insecure.rc != 0
|
||||
- noble_talos_probe_secure.rc == 0
|
||||
|
||||
- name: Fail when Talos API mode cannot be determined
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
Cannot run **talosctl apply-config --dry-run** on {{ noble_talos_nodes[0].ip }}.
|
||||
Insecure: rc={{ noble_talos_probe_insecure.rc }} {{ noble_talos_probe_insecure.stderr | default('') }}.
|
||||
TLS: rc={{ noble_talos_probe_secure.rc | default('n/a') }} {{ noble_talos_probe_secure.stderr | default('') }}.
|
||||
Check LAN to :50000, node power, and that **out/talosconfig** matches these nodes.
|
||||
Override: **-e noble_talos_apply_mode=secure** (joined) or **insecure** (maintenance ISO).
|
||||
when:
|
||||
- noble_talos_apply_mode | default('auto') == 'auto'
|
||||
- noble_talos_probe_insecure.rc != 0
|
||||
- noble_talos_probe_secure is not defined or noble_talos_probe_secure.rc != 0
|
||||
|
||||
- name: Show resolved Talos apply-config mode
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
apply-config: {{ 'maintenance (--insecure)' if noble_talos_apply_insecure | bool else 'joined (TALOSCONFIG)' }}
|
||||
(noble_talos_apply_mode={{ noble_talos_apply_mode | default('auto') }})
|
||||
|
||||
- name: Apply machine config to each node (first install — insecure)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talosctl
|
||||
- apply-config
|
||||
- --insecure
|
||||
- -n
|
||||
- "{{ item.ip }}"
|
||||
- --file
|
||||
- "{{ noble_talos_dir }}/out/{{ item.machine }}"
|
||||
loop: "{{ noble_talos_nodes }}"
|
||||
loop_control:
|
||||
label: "{{ item.ip }}"
|
||||
when: noble_talos_apply_insecure | bool
|
||||
changed_when: true
|
||||
|
||||
- name: Apply machine config to each node (cluster already has TLS — no insecure)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talosctl
|
||||
- apply-config
|
||||
- -n
|
||||
- "{{ item.ip }}"
|
||||
- --file
|
||||
- "{{ noble_talos_dir }}/out/{{ item.machine }}"
|
||||
environment:
|
||||
TALOSCONFIG: "{{ noble_talos_dir }}/out/talosconfig"
|
||||
loop: "{{ noble_talos_nodes }}"
|
||||
loop_control:
|
||||
label: "{{ item.ip }}"
|
||||
when: not (noble_talos_apply_insecure | bool)
|
||||
changed_when: true
|
||||
|
||||
# apply-config triggers reboots; apid on :50000 must accept connections before talosctl bootstrap / kubeconfig.
|
||||
- name: Wait for Talos machine API (apid) on bootstrap node
|
||||
ansible.builtin.wait_for:
|
||||
host: "{{ noble_talos_bootstrap_node_ip }}"
|
||||
port: 50000
|
||||
delay: "{{ noble_talos_apid_wait_delay | int }}"
|
||||
timeout: "{{ noble_talos_apid_wait_timeout | int }}"
|
||||
state: started
|
||||
when: noble_talos_wait_for_apid | default(true) | bool
|
||||
|
||||
- name: Bootstrap cluster (once per cluster)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talosctl
|
||||
- bootstrap
|
||||
- -n
|
||||
- "{{ noble_talos_bootstrap_node_ip }}"
|
||||
environment:
|
||||
TALOSCONFIG: "{{ noble_talos_dir }}/out/talosconfig"
|
||||
register: noble_talos_bootstrap_cmd
|
||||
when: not (noble_talos_skip_bootstrap | bool)
|
||||
changed_when: noble_talos_bootstrap_cmd.rc == 0
|
||||
failed_when: >-
|
||||
noble_talos_bootstrap_cmd.rc != 0 and
|
||||
('etcd data directory is not empty' not in (noble_talos_bootstrap_cmd.stderr | default('')))
|
||||
|
||||
- name: Write Kubernetes admin kubeconfig
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- talosctl
|
||||
- kubeconfig
|
||||
- "{{ noble_talos_kubeconfig_out }}"
|
||||
- --force
|
||||
- -n
|
||||
- "{{ noble_talos_kubeconfig_node }}"
|
||||
- -e
|
||||
- "{{ noble_talos_kubeconfig_endpoint }}"
|
||||
- --merge=false
|
||||
environment:
|
||||
TALOSCONFIG: "{{ noble_talos_dir }}/out/talosconfig"
|
||||
changed_when: true
|
||||
|
||||
- name: Optional — set kubectl cluster server to reachable API (VIP unreachable from this host)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubectl
|
||||
- config
|
||||
- set-cluster
|
||||
- "{{ noble_talos_kubectl_cluster_name }}"
|
||||
- --server={{ noble_k8s_api_server_override }}
|
||||
- --kubeconfig={{ noble_talos_kubeconfig_out }}
|
||||
when: noble_k8s_api_server_override | default('') | length > 0
|
||||
changed_when: true
|
||||
|
||||
- name: Next — platform stack
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Kubeconfig written to {{ noble_talos_kubeconfig_out }}.
|
||||
Export KUBECONFIG={{ noble_talos_kubeconfig_out }} and run: ansible-playbook playbooks/noble.yml
|
||||
(or: ansible-playbook playbooks/deploy.yml for the full pipeline).
|
||||
Reference in New Issue
Block a user