diff --git a/install.yml b/install.yml new file mode 100644 index 0000000..86fd31e --- /dev/null +++ b/install.yml @@ -0,0 +1,28 @@ +--- +# Playbook Kubernetes Install + +- name: Talos configs + become: no + gather_facts: false + hosts: + - talos + roles: + - role: talos_configs_create + - role: talos_configs_apply + +- name: Talos bootstrap + become: no + gather_facts: false + hosts: + - talos_first_nodes + roles: + - role: talos_bootstrap + +- name: Install services on K8S + become: no + gather_facts: false + hosts: + - talos_first_nodes + roles: + - role: metallb + - role: traefik diff --git a/playbook.yml b/playbook.yml deleted file mode 100644 index c3e0bda..0000000 --- a/playbook.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -# Playbook Kubernetes - -- name: Kubernetes Play - gather_facts: false - hosts: - - talos - roles: - - role: talos_configs - - role: machine_status diff --git a/roles/talos_configs/defaults/main.yaml b/roles/common/defaults/main.yml similarity index 86% rename from roles/talos_configs/defaults/main.yaml rename to roles/common/defaults/main.yml index 1a3a686..36edda0 100644 --- a/roles/talos_configs/defaults/main.yaml +++ b/roles/common/defaults/main.yml @@ -1,3 +1,4 @@ +--- kubernetes_version: v1.26.7 talos_version: v1.5.1 ansible_root_dir: "{{ inventory_dir | ansible.builtin.dirname }}" @@ -6,7 +7,10 @@ talos_generic_config_dir: "{{ ansible_root_dir }}/configs/talos" talos_cluster_config_dir: "{{ ansible_root_dir }}/configs/{{ cluster_name }}" talos_cluster_secrets_file: "{{ talos_cluster_config_dir }}/talos-secrets.yaml" talos_control_lb_hostname: "control.{{ cluster_name }}" +talos_workers_lb_hostname: "workers.{{ cluster_name }}" talos_node_config_file: "{{ talos_cluster_config_dir }}/talos-{{ inventory_hostname }}.yaml" talosconfig: "{{ talos_cluster_config_dir }}/talosconfig.yaml" kubeconfig: "{{ talos_cluster_config_dir }}/kubeconfig.yaml" talos_image_version: v1.4.7 +kubectl_host: localhost +talosctl_host: localhost diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml new file mode 100644 index 0000000..398c5b8 --- /dev/null +++ b/roles/common/handlers/main.yml @@ -0,0 +1,2 @@ +- name: Import Talos handlers + ansible.builtin.import_tasks: handlers/talos.yml diff --git a/roles/common/handlers/talos.yml b/roles/common/handlers/talos.yml new file mode 100644 index 0000000..4fffebc --- /dev/null +++ b/roles/common/handlers/talos.yml @@ -0,0 +1,17 @@ +--- + +- name: Talos wait for health + when: "'talos_first_nodes' in group_names" + delegate_to: "{{ talosctl_host }}" + become: no + ansible.builtin.command: + cmd: >- + talosctl health + --wait-timeout 5m + register: _talosctl_health + until: "_talosctl_health is not failed" + retries: 10 + delay: 10 + changed_when: false + environment: + TALOSCONFIG: "{{ talosconfig }}" \ No newline at end of file diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml new file mode 100644 index 0000000..bf0447a --- /dev/null +++ b/roles/common/tasks/main.yml @@ -0,0 +1,3 @@ +--- +# Don't add tasks to 'common'. +# This role is a dependency for lots of roles so these tasks would be executed all the time. diff --git a/roles/machine_status/tasks/main.yml b/roles/machine_status/tasks/main.yml index 1132b0a..256fef9 100644 --- a/roles/machine_status/tasks/main.yml +++ b/roles/machine_status/tasks/main.yml @@ -1,27 +1,24 @@ --- -- name: Get machine status - delegate_to: localhost - become: no - ansible.builtin.command: - cmd: "talosctl get machinestatus --endpoints '{{ ansible_remote }}' --nodes '{{ ansible_remote }}' --output json" - register: _machine_status_cmd - failed_when: _machine_status_cmd.rc not in [0, 1] - changed_when: no - -- name: Get machine status - insecure - when: "_machine_status_cmd.rc == 1" - delegate_to: localhost - become: false - ansible.builtin.command: - cmd: "talosctl get machinestatus --endpoints '{{ ansible_remote }}' --nodes '{{ ansible_remote }}' --insecure --output json" - register: _machine_status_cmd_insec - changed_when: no - -- name: Parse machine status - ansible.builtin.set_fact: - talos_machine_status: "{{ _machine_status_cmd_insec.stdout | default(_machine_status_cmd.stdout) | from_json }}" +- name: Import talos_machine_status tasks + ansible.builtin.import_tasks: "{{ role_path }}/../../shared/tasks/talos_machine_status.yml" - name: Show machine status ansible.builtin.debug: var: talos_machine_status + +- name: Talosctl get members + delegate_to: "{{ talosctl_host }}" + become: no + when: "'talos_first_nodes' in group_names" + ansible.builtin.command: + cmd: talosctl get members + changed_when: false + environment: + TALOSCONFIG: "{{ talosconfig }}" + register: _talosctl_get_members + +- name: Show members + when: "first_node | default(false)" + ansible.builtin.debug: + var: _talosctl_get_members.stdout_lines \ No newline at end of file diff --git a/roles/metallb/meta/main.yml b/roles/metallb/meta/main.yml new file mode 100644 index 0000000..fdda41b --- /dev/null +++ b/roles/metallb/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: common diff --git a/roles/metallb/tasks/main.yml b/roles/metallb/tasks/main.yml new file mode 100644 index 0000000..f6d8e6b --- /dev/null +++ b/roles/metallb/tasks/main.yml @@ -0,0 +1,56 @@ +--- + +- name: Namespace for MetalLB + delegate_to: "{{ kubectl_host }}" + kubernetes.core.k8s: + kubeconfig: "{{ kubeconfig }}" + definition: + kind: Namespace + metadata: + name: metallb-system + labels: + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/warn: privileged + +- name: Helm add MetalLB repo + delegate_to: "{{ kubectl_host }}" + run_once: true + kubernetes.core.helm_repository: + name: metallb + repo_url: "https://metallb.github.io/metallb" + +- name: Helm deploy MetalLB + delegate_to: "{{ kubectl_host }}" + kubernetes.core.helm: + kubeconfig: "{{ kubeconfig }}" + name: metallb + chart_ref: metallb/metallb + release_namespace: metallb-system + create_namespace: false + wait: true + # https://github.com/metallb/metallb/blob/main/charts/metallb/values.yaml + +- name: Addresss pool for MetalLB + delegate_to: "{{ kubectl_host }}" + kubernetes.core.k8s: + kubeconfig: "{{ kubeconfig }}" + definition: + apiVersion: metallb.io/v1beta1 + kind: IPAddressPool + metadata: + name: all-nodes + namespace: metallb-system + spec: + addresses: "{{ ingress_ips | product(['/32']) | map('join') | list }}" + +- name: L2Advertisement for MetalLB + delegate_to: "{{ kubectl_host }}" + kubernetes.core.k8s: + kubeconfig: "{{ kubeconfig }}" + definition: + apiVersion: metallb.io/v1beta1 + kind: L2Advertisement + metadata: + name: advertisement + namespace: metallb-system diff --git a/roles/talos_bootstrap/meta/main.yml b/roles/talos_bootstrap/meta/main.yml new file mode 100644 index 0000000..fdda41b --- /dev/null +++ b/roles/talos_bootstrap/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: common diff --git a/roles/talos_bootstrap/tasks/main.yml b/roles/talos_bootstrap/tasks/main.yml new file mode 100644 index 0000000..5e21bc8 --- /dev/null +++ b/roles/talos_bootstrap/tasks/main.yml @@ -0,0 +1,66 @@ +--- + +- name: Get Talos etcd status + delegate_to: "{{ talosctl_host }}" + ansible.builtin.command: + cmd: talosctl etcd status + changed_when: false + environment: + TALOSCONFIG: "{{ talosconfig }}" + register: _talosctl_etcd_status + failed_when: "_talosctl_etcd_status.rc not in [0,1]" + +- name: Talosctl bootstrap + when: "_talosctl_etcd_status.rc == 1" + delegate_to: "{{ talosctl_host }}" + ansible.builtin.command: + cmd: talosctl bootstrap + changed_when: true + environment: + TALOSCONFIG: "{{ talosconfig }}" + notify: Talos wait for health + +- name: Flush handlers + ansible.builtin.meta: flush_handlers + +- name: Talosctl kubeconfig + delegate_to: "{{ talosctl_host }}" + ansible.builtin.command: + cmd: >- + talosctl kubeconfig + --force + changed_when: false + environment: + TALOSCONFIG: "{{ talosconfig }}" + KUBECONFIG: "{{ kubeconfig }}" + +- name: Kubectl get ndoes + delegate_to: "{{ kubectl_host }}" + ansible.builtin.command: + cmd: kubectl get nodes + environment: + KUBECONFIG: "{{ kubeconfig }}" + register: _kubectl_get_nodes + changed_when: false + +- name: Show Kubectl get nodes output + ansible.builtin.debug: + var: _kubectl_get_nodes.stdout_lines + +#- name: Get nodes +# when: 'first_node | default(false)" +# delegate_to: "{{ kubectl_host }}" +# become: no +# kubernetes.core.k8s_info: +# kind: Node +# kubeconfig: "{{ kubeconfig }}" +# register: _k8s_nodes + +#- name: Show nodes +# when: "first_node | default(false)" +# ansible.builtin.debug: +# msg: "{{ _k8s_node.metadata.name }}" +# loop: "{{ _k8s_nodes.resources }}" +# loop_control: +# loop_var: _k8s_node +# label: "{{ _k8s_node.metadata.name }}" \ No newline at end of file diff --git a/roles/talos_configs_apply/meta/main.yml b/roles/talos_configs_apply/meta/main.yml new file mode 100644 index 0000000..fdda41b --- /dev/null +++ b/roles/talos_configs_apply/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: common diff --git a/roles/talos_configs/tasks/apply_node_config.yml b/roles/talos_configs_apply/tasks/apply_node_config.yml similarity index 55% rename from roles/talos_configs/tasks/apply_node_config.yml rename to roles/talos_configs_apply/tasks/apply_node_config.yml index 65d5849..ada5208 100644 --- a/roles/talos_configs/tasks/apply_node_config.yml +++ b/roles/talos_configs_apply/tasks/apply_node_config.yml @@ -1,7 +1,7 @@ --- - name: Apply Talos node config - delegate_to: localhost + delegate_to: "{{ talosctl_host }}" become: no ansible.builtin.command: cmd: >- @@ -9,5 +9,16 @@ --file '{{ talos_node_config_file }}' --nodes '{{ ansible_remote }}' --endpoints '{{ ansible_remote }}' + --mode auto {% if talos_machine_status.spec.stage == 'maintenance' %} --insecure{% endif %} changed_when: true + environment: + TALOSCONFIG: "{{ talosconfig }}" + +- name: Wait for Talos port 50000 + delegate_to: "{{ talosctl_host }}" + become: no + ansible.builtin.wait_for: + host: "{{ ansible_remote }}" + port: 50000 + delay: 5 \ No newline at end of file diff --git a/roles/talos_configs_apply/tasks/main.yml b/roles/talos_configs_apply/tasks/main.yml new file mode 100644 index 0000000..fe752e5 --- /dev/null +++ b/roles/talos_configs_apply/tasks/main.yml @@ -0,0 +1,14 @@ +--- +- name: Directory for configs + delegate_to: "{{ talosctl_host }}" + become: false + ansible.builtin.file: + path: "{{ talos_cluster_config_dir }}" + state: directory + mode: u=rwX,go= + +- name: Import talos_machine_status tasks + ansible.builtin.import_tasks: "{{ role_path }}/../../shared/tasks/talos_machine_status.yml" + +- name: Import apply_node_config tasks + ansible.builtin.import_tasks: apply_node_config.yml diff --git a/roles/talos_configs/handlers/main.yml b/roles/talos_configs_create/handlers/main.yml similarity index 73% rename from roles/talos_configs/handlers/main.yml rename to roles/talos_configs_create/handlers/main.yml index 048fbc7..b1b4366 100644 --- a/roles/talos_configs/handlers/main.yml +++ b/roles/talos_configs_create/handlers/main.yml @@ -1,9 +1,8 @@ --- - name: Encrypt secrets - delegate_to: localhost - become: no - run_once: yes + delegate_to: "{{ talosctl_host }}" + when: "'talos_first_nodes' in group_names" ansible.builtin.command: cmd: >- ansible-vault encrypt @@ -14,9 +13,8 @@ - name: Update talosconfig - endpoints listen: Update talosconfig - delegate_to: localhost - become: no - run_once: yes + delegate_to: "{{ talosctl_host }}" + when: "'talos_first_nodes' in group_names" ansible.builtin.command: cmd: >- talosctl config endpoints '{{ talos_control_lb_hostname }}' @@ -24,9 +22,8 @@ - name: Update talosconfig - nodes listen: Update talosconfig - delegate_to: localhost - become: no - run_once: yes + delegate_to: "{{ talosctl_host }}" + when: "'talos_first_nodes' in group_names" ansible.builtin.command: cmd: >- talosctl config nodes '{{ talos_control_lb_hostname }}' diff --git a/roles/talos_configs_create/meta/main.yml b/roles/talos_configs_create/meta/main.yml new file mode 100644 index 0000000..fdda41b --- /dev/null +++ b/roles/talos_configs_create/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: common diff --git a/roles/talos_configs/tasks/create_control_configs.yml b/roles/talos_configs_create/tasks/create_control_configs.yml similarity index 95% rename from roles/talos_configs/tasks/create_control_configs.yml rename to roles/talos_configs_create/tasks/create_control_configs.yml index 4f2db49..66ba9c5 100644 --- a/roles/talos_configs/tasks/create_control_configs.yml +++ b/roles/talos_configs_create/tasks/create_control_configs.yml @@ -1,7 +1,7 @@ --- - name: Create Talos control node config - delegate_to: localhost + delegate_to: "{{ talosctl_host }}" become: no ansible.builtin.command: cmd: >- diff --git a/roles/talos_configs/tasks/create_secrets.yml b/roles/talos_configs_create/tasks/create_secrets.yml similarity index 74% rename from roles/talos_configs/tasks/create_secrets.yml rename to roles/talos_configs_create/tasks/create_secrets.yml index 76efd4d..7904bcd 100644 --- a/roles/talos_configs/tasks/create_secrets.yml +++ b/roles/talos_configs_create/tasks/create_secrets.yml @@ -1,9 +1,8 @@ --- - name: Create secrets file for Talos - delegate_to: localhost - become: no - run_once: yes + delegate_to: "{{ talosctl_host }}" + when: "'talos_first_nodes' in group_names" ansible.builtin.command: cmd: >- talosctl gen secrets diff --git a/roles/talos_configs/tasks/create_talosconfig.yml b/roles/talos_configs_create/tasks/create_talosconfig.yml similarity index 82% rename from roles/talos_configs/tasks/create_talosconfig.yml rename to roles/talos_configs_create/tasks/create_talosconfig.yml index e633af6..4c1433c 100644 --- a/roles/talos_configs/tasks/create_talosconfig.yml +++ b/roles/talos_configs_create/tasks/create_talosconfig.yml @@ -1,9 +1,8 @@ --- - name: Create talosctl config - delegate_to: localhost - become: no - run_once: yes + delegate_to: "{{ talosctl_host }}" + when: "'talos_first_nodes' in group_names" ansible.builtin.command: cmd: >- talosctl gen config '{{ cluster_name }}' 'https://{{ talos_control_lb_hostname }}:6443' diff --git a/roles/talos_configs/tasks/create_worker_configs.yml b/roles/talos_configs_create/tasks/create_worker_configs.yml similarity index 95% rename from roles/talos_configs/tasks/create_worker_configs.yml rename to roles/talos_configs_create/tasks/create_worker_configs.yml index 39e2a2d..e229e25 100644 --- a/roles/talos_configs/tasks/create_worker_configs.yml +++ b/roles/talos_configs_create/tasks/create_worker_configs.yml @@ -1,7 +1,7 @@ --- - name: Create Talos worker node config - delegate_to: localhost + delegate_to: "{{ talosctl_host }}" become: no ansible.builtin.command: cmd: >- diff --git a/roles/talos_configs/tasks/main.yml b/roles/talos_configs_create/tasks/main.yml similarity index 81% rename from roles/talos_configs/tasks/main.yml rename to roles/talos_configs_create/tasks/main.yml index 0d4c88d..4c461ae 100644 --- a/roles/talos_configs/tasks/main.yml +++ b/roles/talos_configs_create/tasks/main.yml @@ -1,6 +1,6 @@ --- - name: Directory for configs - delegate_to: localhost + delegate_to: "{{ talosctl_host }}" become: false ansible.builtin.file: path: "{{ talos_cluster_config_dir }}" @@ -20,6 +20,3 @@ - name: Import create_worker_configs tasks when: "'talos_worker_nodes' in group_names" ansible.builtin.import_tasks: create_worker_configs.yml - -- name: Import apply_node_config tasks - ansible.builtin.import_tasks: ../../talos_configs/tasks/apply_node_config.yml diff --git a/roles/talos_reset/meta/main.yml b/roles/talos_reset/meta/main.yml new file mode 100644 index 0000000..fdda41b --- /dev/null +++ b/roles/talos_reset/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: common diff --git a/roles/talos_reset/tasks/main.yml b/roles/talos_reset/tasks/main.yml new file mode 100644 index 0000000..3109acb --- /dev/null +++ b/roles/talos_reset/tasks/main.yml @@ -0,0 +1,24 @@ +--- + +- name: Reset Talos + delegate_to: "{{ talosctl_host }}" + become: no + ansible.builtin.command: + cmd: >- + talosctl reset + --graceful=false + --wait=false + --reboot + --endpoints '{{ ansible_remote }}' + --nodes '{{ ansible_remote }}' + changed_when: true + environment: + TALOSCONFIG: "{{ talosconfig }}" + +- name: Wait for Talos port 50000 + delegate_to: "{{ talosctl_host }}" + become: no + ansible.builtin.wait_for: + host: "{{ ansible_remote }}" + port: 50000 + delay: 10 diff --git a/roles/talos_upgrade/meta/main.yml b/roles/talos_upgrade/meta/main.yml new file mode 100644 index 0000000..fdda41b --- /dev/null +++ b/roles/talos_upgrade/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: common diff --git a/roles/talos_upgrade/tasks/main.yml b/roles/talos_upgrade/tasks/main.yml new file mode 100644 index 0000000..c8b5dbc --- /dev/null +++ b/roles/talos_upgrade/tasks/main.yml @@ -0,0 +1,16 @@ +--- + +- name: Upgrade Talos + delegate_to: "{{ talosctl_host }}" + become: no + ansible.builtin.command: + cmd: >- + talosctl upgrade + --image="ghcr.io/siderolabs/installer:{{ talos_version }}" + --endpoints '{{ ansible_remote }}' + --nodes '{{ ansible_remote }}' + changed_when: false + environment: + TALOSCONFIG: "{{ talosconfig }}" + + diff --git a/roles/traefik/meta/main.yml b/roles/traefik/meta/main.yml new file mode 100644 index 0000000..fdda41b --- /dev/null +++ b/roles/traefik/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: common diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml new file mode 100644 index 0000000..13ca01a --- /dev/null +++ b/roles/traefik/tasks/main.yml @@ -0,0 +1,50 @@ +--- + +- name: Helm add Traefik repo + delegate_to: "{{ kubectl_host }}" + run_once: true + kubernetes.core.helm_repository: + name: traefik + repo_url: "https://traefik.github.io/charts" + +- name: Helm deploy Traefik + delegate_to: "{{ kubectl_host }}" + kubernetes.core.helm: + kubeconfig: "{{ kubeconfig }}" + name: metallb + chart_ref: traefik/traefik + release_namespace: traefik + create_namespace: true + wait: true + # https://github.com/metallb/metallb/blob/main/charts/metallb/values.yaml + values: + deployment: + kind: DaemonSet + logs: + general: + level: INFO + service: + spec: + externalTrafficPolicy: Local + loadBalancerIP: "{{ ingress_ips[0] }}" + annotations: + external-dns.alpha.kubernetes.io/hostname: "{{ talos_workers_lb_hostname }}" + ports: + web: + proxyProtocol: + trustedIPs: "{{ ingress_ips[0] }}" + forwardedHeaders: + trustedIPs: "{{ ingress_ips[0] }}" + providers: + kubernetesIngress: + publishedService: + enabled: true + tolerations: + - effect: NoSchedule + operator: Exists + +- name: Verify Traefik IP is working + delegate_to: "{{ kubectl_host }}" + ansible.builtin.uri: + url: "http://{{ ingress_ips[0] }}/" + status_code: [200, 404] \ No newline at end of file diff --git a/roles/vps_names/tasks/main.yml b/roles/vps_names/tasks/main.yml new file mode 100644 index 0000000..44897b4 --- /dev/null +++ b/roles/vps_names/tasks/main.yml @@ -0,0 +1,4 @@ +--- + +# @TODO https://api2.hostbillapp.com/accounts/searchServiceByIP.html + diff --git a/shared/tasks/talos_machine_status.yml b/shared/tasks/talos_machine_status.yml new file mode 100644 index 0000000..f41f572 --- /dev/null +++ b/shared/tasks/talos_machine_status.yml @@ -0,0 +1,39 @@ +--- +# +# These tasks set fact: talos_machine_status +# + +- name: Get machine status + delegate_to: "{{ talosctl_host }}" + become: no + ansible.builtin.command: + cmd: >- + talosctl get machinestatus + --endpoints '{{ ansible_remote }}' + --nodes '{{ ansible_remote }}' + --output json + register: _machine_status_cmd + failed_when: _machine_status_cmd.rc not in [0, 1] + changed_when: no + environment: + TALOSCONFIG: "{{ talosconfig }}" + +- name: Get machine status - insecure + when: "_machine_status_cmd.rc == 1" + delegate_to: "{{ talosctl_host }}" + become: false + ansible.builtin.command: + cmd: >- + talosctl get machinestatus + --endpoints '{{ ansible_remote }}' + --nodes '{{ ansible_remote }}' + --output json + --insecure + register: _machine_status_cmd_insec + changed_when: no + environment: + TALOSCONFIG: "{{ talosconfig }}" + +- name: Parse machine status + ansible.builtin.set_fact: + talos_machine_status: "{{ _machine_status_cmd_insec.stdout | default(_machine_status_cmd.stdout) | from_json }}" diff --git a/talos_reset.yml b/talos_reset.yml new file mode 100644 index 0000000..27585fa --- /dev/null +++ b/talos_reset.yml @@ -0,0 +1,8 @@ +--- + +- name: Reset Talos + gather_facts: false + hosts: + - talos + roles: + - role: talos_reset diff --git a/talos_upgrade.yml b/talos_upgrade.yml new file mode 100644 index 0000000..3208c56 --- /dev/null +++ b/talos_upgrade.yml @@ -0,0 +1,8 @@ +--- + +- name: Reset Talos + gather_facts: false + hosts: + - talos + roles: + - role: talos_upgrade