sync
This commit is contained in:
12
ansible/playbooks/roles/cluster-kubeconfig/tasks/main.yml
Normal file
12
ansible/playbooks/roles/cluster-kubeconfig/tasks/main.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
# role: cluster-kubeconfig
|
||||
# description: Generic role for any Kubernetes cluster kubeconfig management
|
||||
# author: mk-labs
|
||||
# version: 1.0.0
|
||||
|
||||
- name: Setup kubeconfig for {{ cluster_name }} cluster
|
||||
ansible.builtin.include_role:
|
||||
name: kubeconfig-manager
|
||||
vars:
|
||||
cluster_name: "{{ cluster_name }}"
|
||||
kubeconfig_source_path: "{{ kubeconfig_source_path | default('/etc/kubernetes/admin.conf') }}"
|
||||
48
ansible/playbooks/roles/cluster-network-setup/tasks/main.yml
Normal file
48
ansible/playbooks/roles/cluster-network-setup/tasks/main.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
# role: cluster-network-setup
|
||||
# description: Combined DNS and Load Balancer setup for Kubernetes clusters
|
||||
# author: mk-labs
|
||||
# version: 1.0.0
|
||||
|
||||
- name: Setup DNS entry for cluster
|
||||
ansible.builtin.include_role:
|
||||
name: dns-manager
|
||||
vars:
|
||||
cluster_endpoint: "{{ cluster_endpoint }}"
|
||||
cluster_vip: "{{ cluster_vip }}"
|
||||
|
||||
- name: Setup Traefik load balancer for cluster
|
||||
ansible.builtin.include_role:
|
||||
name: traefik-manager
|
||||
vars:
|
||||
cluster_name: "{{ cluster_name }}"
|
||||
cluster_endpoint: "{{ cluster_endpoint }}"
|
||||
control_plane_nodes: "{{ control_plane_nodes }}"
|
||||
when: traefik_enabled | default(true)
|
||||
|
||||
- name: Wait for DNS propagation
|
||||
ansible.builtin.wait_for:
|
||||
timeout: 30
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Test cluster endpoint connectivity
|
||||
ansible.builtin.wait_for:
|
||||
host: "{{ cluster_endpoint }}"
|
||||
port: "{{ cluster_api_port | default(6443) }}"
|
||||
timeout: 60
|
||||
delegate_to: localhost
|
||||
register: connectivity_test
|
||||
failed_when: false
|
||||
|
||||
- name: Display network setup results
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
🌐 Network Setup Complete for {{ cluster_name }}:
|
||||
|
||||
DNS Entry: {{ cluster_endpoint }} → {{ cluster_vip }}
|
||||
Load Balancer: {{ 'Configured' if traefik_enabled | default(true) else 'Skipped' }}
|
||||
Connectivity: {{ 'Success' if connectivity_test.failed == false else 'Failed - Check firewall/network' }}
|
||||
|
||||
Next steps:
|
||||
1. Verify: kubectl --kubeconfig ~/.kube/config-{{ cluster_name }} cluster-info
|
||||
2. Switch context: kubectl config use-context {{ cluster_name }}-admin
|
||||
18
ansible/playbooks/roles/dns-manager/defaults/main.yml
Normal file
18
ansible/playbooks/roles/dns-manager/defaults/main.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
# Default variables for dns-manager role
|
||||
|
||||
# DNS Configuration
|
||||
dns_management_enabled: true
|
||||
use_hosts_file_fallback: false
|
||||
dns_ttl: 360
|
||||
dns_propagation_wait: 2
|
||||
create_ptr_record: true
|
||||
|
||||
# Cluster Configuration (to be provided by calling role)
|
||||
# cluster_endpoint: "fastpass.local.mk-labs.cloud"
|
||||
# cluster_vip: "10.1.71.53"
|
||||
|
||||
# DNS Server Configuration (from group_vars)
|
||||
# dns_server: "monorail"
|
||||
# base_domain: "local.mk-labs.cloud"
|
||||
# vault_technitium_api_key: "{{ vault_technitium_api_key }}"
|
||||
17
ansible/playbooks/roles/dns-manager/tasks/main.yml
Normal file
17
ansible/playbooks/roles/dns-manager/tasks/main.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# role: dns-manager
|
||||
# description: Reusable role for managing DNS entries across clusters using Technitium DNS
|
||||
# author: mk-labs
|
||||
# version: 1.0.0
|
||||
|
||||
- name: Create DNS entry using Technitium DNS task
|
||||
ansible.builtin.include_tasks: "{{ playbook_dir }}/tasks/add_technitium_dns_entry.yml"
|
||||
|
||||
- name: Wait for DNS propagation
|
||||
ansible.builtin.pause:
|
||||
seconds: "{{ dns_propagation_wait | default(10) }}"
|
||||
when: dns_management_enabled | default(true)
|
||||
|
||||
- name: Look up A (IPv4) records for example.org
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ query('community.dns.lookup', 'fastpass') }}"
|
||||
@@ -0,0 +1,38 @@
|
||||
Role Name
|
||||
=========
|
||||
|
||||
A brief description of the role goes here.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
- hosts: servers
|
||||
roles:
|
||||
- { role: username.rolename, x: 42 }
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
# FastPass Additional Control Plane Role Defaults
|
||||
|
||||
# Kubernetes services for control plane
|
||||
kubernetes_services_control_plane:
|
||||
- kubernetes_API
|
||||
- etcd
|
||||
- kubelet
|
||||
- kube-scheduler
|
||||
- kube-controller-manager
|
||||
|
||||
# Join token configuration
|
||||
join_token_ttl: "24h"
|
||||
certificate_key_ttl: "2h"
|
||||
|
||||
# Default cluster configuration
|
||||
pod_network_cidr: "10.244.0.0/16"
|
||||
service_cidr: "10.96.0.0/12"
|
||||
|
||||
# Kubelet configuration
|
||||
kubelet_cgroup_driver: "systemd"
|
||||
container_runtime_endpoint: "unix:///run/containerd/containerd.sock"
|
||||
@@ -0,0 +1,2 @@
|
||||
---
|
||||
# handlers file for fastpass-additional-control-plane
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: Ryan Blundon
|
||||
description: FastPass Additional Control Plane - Deploy additional control plane nodes to existing FastPass Kubernetes cluster
|
||||
company: Homelab
|
||||
|
||||
license: MIT
|
||||
|
||||
min_ansible_version: "2.9"
|
||||
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- focal
|
||||
- jammy
|
||||
- name: Debian
|
||||
versions:
|
||||
- bullseye
|
||||
- bookworm
|
||||
|
||||
galaxy_tags:
|
||||
- kubernetes
|
||||
- k8s
|
||||
- controlplane
|
||||
- cluster
|
||||
- fastpass
|
||||
- kubeadm
|
||||
|
||||
dependencies:
|
||||
- role: dns-manager
|
||||
when: cluster_name is defined
|
||||
- role: kubeconfig-manager
|
||||
when: cluster_name is defined
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# role: fastpass-additional-control-plane
|
||||
# description: FastPass Additional Control Plane - Deploy additional control plane nodes to existing FastPass Kubernetes cluster
|
||||
# author: Ryan Blundon
|
||||
# version: 1.0.0
|
||||
# date: 2025-10-05
|
||||
|
||||
# This role joins additional nodes to an existing Kubernetes cluster as control plane nodes
|
||||
# It follows the same patterns as fastpass-first-control-plane but uses kubeadm join instead of kubeadm init
|
||||
|
||||
- name: Display role information
|
||||
ansible.builtin.debug:
|
||||
msg: "Starting FastPass Additional Control Plane deployment for {{ inventory_hostname }}"
|
||||
|
||||
- name: Setup DNS record for cluster
|
||||
ansible.builtin.include_role:
|
||||
name: dns-manager
|
||||
vars:
|
||||
host_name: "{{ cluster_name }}"
|
||||
|
||||
- name: Open services for control plane
|
||||
become: true
|
||||
when: ansible_os_family == "Debian"
|
||||
block:
|
||||
- name: Open firewall ports for control plane
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
name: "{{ item }}"
|
||||
loop: "{{ kubernetes_services_control_plane }}"
|
||||
@@ -0,0 +1,3 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
localhost
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- fastpass-additional-control-plane
|
||||
@@ -0,0 +1,2 @@
|
||||
---
|
||||
# vars file for fastpass-additional-control-plane
|
||||
@@ -1,11 +1,16 @@
|
||||
---
|
||||
# role: fastpass-first-control-plane
|
||||
# description: FastPass First Control Plane
|
||||
# author: mk-labs
|
||||
# author: Ryan Blundon
|
||||
# version: 1.0.0
|
||||
# date: 2025-09-27
|
||||
|
||||
# Open sevices for control plane
|
||||
- name: Setup DNS record for cluster
|
||||
ansible.builtin.include_role:
|
||||
name: dns-manager
|
||||
vars:
|
||||
host_name: "{{ cluster_name }}"
|
||||
|
||||
- name: Open services for control plane
|
||||
become: true
|
||||
when: ansible_os_family == "Debian"
|
||||
@@ -14,8 +19,7 @@
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
name: "{{ item }}"
|
||||
loop:
|
||||
"{{ kubernetes_services_control_plane }}"
|
||||
loop: "{{ kubernetes_services_control_plane }}"
|
||||
|
||||
- name: Create initial kubelet config file
|
||||
become: true
|
||||
@@ -23,20 +27,27 @@
|
||||
dest: /var/lib/kubelet/config.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
mode: "0644"
|
||||
content: |
|
||||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
kind: KubeletConfiguration
|
||||
cgroupDriver: systemd
|
||||
containerRuntimeEndpoint: unix:///run/containerd/containerd.sock
|
||||
|
||||
# - name: Initialize Kubernetes cluster
|
||||
# become: true
|
||||
# ansible.builtin.command: kubeadm init --ignore-preflight-errors=NumCPU,Mem --control-plane-endpoint=fastpass # {{ cluster_name }}
|
||||
# args:
|
||||
# creates: /etc/kubernetes/admin.conf
|
||||
# register: kubeadm_init
|
||||
# changed_when: kubeadm_init.rc == 0
|
||||
- name: Initialize Kubernetes cluster
|
||||
become: true
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- kubeadm
|
||||
- init
|
||||
- --apiserver-advertise-address={{ ip_address }}
|
||||
- --control-plane-endpoint={{ cluster_name }}
|
||||
- --pod-network-cidr={{ pod_network_cidr }}
|
||||
- --service-cidr={{ service_cidr }}
|
||||
args:
|
||||
creates: /etc/kubernetes/admin.conf
|
||||
register: kubeadm_init
|
||||
changed_when: kubeadm_init.rc == 0
|
||||
|
||||
- name: Ensure kubelet is enabled and started
|
||||
become: true
|
||||
@@ -44,23 +55,49 @@
|
||||
name: kubelet
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
- name: Debug ansible_env.HOME
|
||||
|
||||
- name: Setup kubeconfig for FastPass cluster
|
||||
ansible.builtin.include_role:
|
||||
name: kubeconfig-manager
|
||||
|
||||
# - name: Download tigera-operator manifest
|
||||
# delegate_to: localhost
|
||||
# ansible.builtin.get_url:
|
||||
# url: https://raw.githubusercontent.com/projectcalico/calico/{{ calico_version }}/manifests/tigera-operator.yaml
|
||||
# dest: /tmp/tigera-operator.yaml
|
||||
# mode: "0644"
|
||||
|
||||
# - name: Install tigera-operator from downloaded file
|
||||
# delegate_to: localhost
|
||||
# kubernetes.core.k8s:
|
||||
# kubeconfig: "{{ local_home }}/.kube/config"
|
||||
# state: present
|
||||
# src: /tmp/tigera-operator.yaml
|
||||
|
||||
# - name: Download Calico CRDs
|
||||
# delegate_to: localhost
|
||||
# ansible.builtin.get_url:
|
||||
# url: https://raw.githubusercontent.com/projectcalico/calico/{{ calico_version }}/manifests/custom-resources.yaml
|
||||
# dest: /tmp/custom-resources.yaml
|
||||
# mode: "0644"
|
||||
|
||||
# - name: Install Calico CRDs from downloaded file
|
||||
# delegate_to: localhost
|
||||
# kubernetes.core.k8s:
|
||||
# kubeconfig: "{{ local_home }}/.kube/config"
|
||||
# state: present
|
||||
# src: /tmp/custom-resources.yaml
|
||||
|
||||
- name: Download Flannel CNI
|
||||
delegate_to: localhost
|
||||
ansible.builtin.debug:
|
||||
var: ansible_env.HOME
|
||||
ansible.builtin.get_url:
|
||||
url: https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
|
||||
dest: /tmp/kube-flannel.yaml
|
||||
mode: "0644"
|
||||
|
||||
|
||||
- name: Create .kube directory for user
|
||||
- name: Install Flannel CNI from downloaded file
|
||||
delegate_to: localhost
|
||||
ansible.builtin.file:
|
||||
path: "{{ ansible_env.HOME }}/.kube"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy admin.conf to user's .kube directory on controller
|
||||
ansible.builtin.fetch:
|
||||
src: /etc/kubernetes/admin.conf
|
||||
dest: "{{ ansible_env.HOME }}/.kube/config-fastpass" # {{cluster_name}}"
|
||||
mode: '0644'
|
||||
|
||||
kubernetes.core.k8s:
|
||||
kubeconfig: "{{ local_home }}/.kube/config"
|
||||
state: present
|
||||
src: /tmp/kube-flannel.yaml
|
||||
|
||||
38
ansible/playbooks/roles/fastpass-worker-nodes/README.md
Normal file
38
ansible/playbooks/roles/fastpass-worker-nodes/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
Role Name
|
||||
=========
|
||||
|
||||
A brief description of the role goes here.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
- hosts: servers
|
||||
roles:
|
||||
- { role: username.rolename, x: 42 }
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
||||
@@ -0,0 +1,3 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# defaults file for fastpass-worker-nodes
|
||||
@@ -0,0 +1,3 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for fastpass-worker-nodes
|
||||
35
ansible/playbooks/roles/fastpass-worker-nodes/meta/main.yml
Normal file
35
ansible/playbooks/roles/fastpass-worker-nodes/meta/main.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
|
||||
min_ansible_version: 2.1
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
@@ -0,0 +1,3 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for fastpass-worker-nodes
|
||||
@@ -0,0 +1,3 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
localhost
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- fastpass-worker-nodes
|
||||
@@ -0,0 +1,3 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# vars file for fastpass-worker-nodes
|
||||
86
ansible/playbooks/roles/kubeconfig-manager/README.md
Normal file
86
ansible/playbooks/roles/kubeconfig-manager/README.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Kubeconfig Manager Role
|
||||
|
||||
A reusable Ansible role for managing kubeconfig files across multiple Kubernetes clusters.
|
||||
|
||||
## Features
|
||||
|
||||
- Fetches kubeconfig from remote Kubernetes nodes
|
||||
- Merges multiple cluster configs into a single `~/.kube/config` file
|
||||
- Creates backups before merging
|
||||
- Provides unique cluster, context, and user names
|
||||
- Works with any Kubernetes cluster (vanilla K8s, OpenShift, etc.)
|
||||
|
||||
## Requirements
|
||||
|
||||
- Ansible 2.9+
|
||||
- Access to Kubernetes cluster admin.conf file
|
||||
- Local kubectl installation (optional, for testing)
|
||||
|
||||
## Role Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `cluster_name` | `kubernetes` | Name of the cluster (required) |
|
||||
| `kubeconfig_source_path` | `/etc/kubernetes/admin.conf` | Path to kubeconfig on remote host |
|
||||
| `context_suffix` | `admin` | Suffix for context name |
|
||||
|
||||
## Example Usage
|
||||
|
||||
### In a playbook:
|
||||
|
||||
```yaml
|
||||
- name: Setup kubeconfig for FastPass cluster
|
||||
hosts: fastpass_control_plane[0]
|
||||
roles:
|
||||
- role: kubeconfig-manager
|
||||
vars:
|
||||
cluster_name: "fastpass"
|
||||
|
||||
- name: Setup kubeconfig for Hub cluster
|
||||
hosts: hub_cluster
|
||||
roles:
|
||||
- role: kubeconfig-manager
|
||||
vars:
|
||||
cluster_name: "hub"
|
||||
kubeconfig_source_path: "/etc/kubernetes/admin.conf"
|
||||
```
|
||||
|
||||
### As an included role:
|
||||
|
||||
```yaml
|
||||
- name: Manage kubeconfig
|
||||
ansible.builtin.include_role:
|
||||
name: kubeconfig-manager
|
||||
vars:
|
||||
cluster_name: "{{ my_cluster_name }}"
|
||||
```
|
||||
|
||||
## Generated Structure
|
||||
|
||||
The role creates contexts with this naming pattern:
|
||||
- **Cluster**: `{{ cluster_name }}`
|
||||
- **Context**: `{{ cluster_name }}-admin`
|
||||
- **User**: `{{ cluster_name }}-admin`
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
~/.kube/
|
||||
├── config # Merged kubeconfig
|
||||
├── config-fastpass # Individual cluster configs
|
||||
├── config-hub
|
||||
├── config-internal
|
||||
└── config.backup.1234567890 # Timestamped backups
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
None
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author
|
||||
|
||||
mk-labs
|
||||
11
ansible/playbooks/roles/kubeconfig-manager/defaults/main.yml
Normal file
11
ansible/playbooks/roles/kubeconfig-manager/defaults/main.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# Default variables for kubeconfig-manager role
|
||||
|
||||
# Source path for the kubeconfig file on the remote host
|
||||
kubeconfig_source_path: "/etc/kubernetes/admin.conf"
|
||||
|
||||
# Cluster name - should be provided by the calling playbook
|
||||
cluster_name: "kubernetes"
|
||||
|
||||
# Context suffix for the cluster
|
||||
context_suffix: "admin"
|
||||
34
ansible/playbooks/roles/kubeconfig-manager/tasks/main.yml
Normal file
34
ansible/playbooks/roles/kubeconfig-manager/tasks/main.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# role: kubeconfig-manager
|
||||
# description: Reusable role for managing kubeconfig files across multiple clusters
|
||||
# author: mk-labs
|
||||
# version: 1.0.0
|
||||
|
||||
- name: Get local user environment
|
||||
delegate_to: localhost
|
||||
ansible.builtin.set_fact:
|
||||
local_home: "{{ lookup('env', 'HOME') }}"
|
||||
local_user: "{{ lookup('env', 'USER') }}"
|
||||
|
||||
- name: Debug local environment
|
||||
delegate_to: localhost
|
||||
ansible.builtin.debug:
|
||||
msg: "Local user: {{ local_user }}, Home directory: {{ local_home }}"
|
||||
|
||||
- name: Create .kube directory
|
||||
delegate_to: localhost
|
||||
ansible.builtin.file:
|
||||
path: "{{ local_home }}/.kube"
|
||||
state: directory
|
||||
owner: "{{ local_user }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Copy kubeconfig from remote host
|
||||
ansible.builtin.fetch:
|
||||
src: "{{ kubeconfig_source_path | default('/etc/kubernetes/admin.conf') }}"
|
||||
dest: "{{ local_home }}/.kube/config-{{ cluster_name }}"
|
||||
flat: true
|
||||
mode: "0644"
|
||||
|
||||
- name: Include kubeconfig merge tasks
|
||||
ansible.builtin.include_tasks: merge-kubeconfig.yml
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
# Kubeconfig merging tasks
|
||||
|
||||
- name: Check if main kubeconfig exists
|
||||
delegate_to: localhost
|
||||
ansible.builtin.stat:
|
||||
path: "{{ local_home }}/.kube/config"
|
||||
register: main_kubeconfig
|
||||
|
||||
- name: Create backup of existing kubeconfig
|
||||
delegate_to: localhost
|
||||
ansible.builtin.copy:
|
||||
src: "{{ local_home }}/.kube/config"
|
||||
dest: "{{ local_home }}/.kube/config.backup.{{ ansible_date_time.epoch }}"
|
||||
mode: "0644"
|
||||
when: main_kubeconfig.stat.exists
|
||||
|
||||
- name: Read new cluster kubeconfig
|
||||
delegate_to: localhost
|
||||
ansible.builtin.slurp:
|
||||
src: "{{ local_home }}/.kube/config-{{ cluster_name }}"
|
||||
register: new_kubeconfig_content
|
||||
|
||||
- name: Parse new kubeconfig
|
||||
delegate_to: localhost
|
||||
ansible.builtin.set_fact:
|
||||
new_kubeconfig: "{{ new_kubeconfig_content.content | b64decode | from_yaml }}"
|
||||
|
||||
- name: Update cluster name in kubeconfig
|
||||
delegate_to: localhost
|
||||
ansible.builtin.set_fact:
|
||||
updated_kubeconfig:
|
||||
apiVersion: "{{ new_kubeconfig.apiVersion }}"
|
||||
kind: "{{ new_kubeconfig.kind }}"
|
||||
clusters:
|
||||
- name: "{{ cluster_name }}"
|
||||
cluster: "{{ new_kubeconfig.clusters[0].cluster }}"
|
||||
contexts:
|
||||
- name: "{{ cluster_name }}-admin"
|
||||
context:
|
||||
cluster: "{{ cluster_name }}"
|
||||
user: "{{ cluster_name }}-admin"
|
||||
users:
|
||||
- name: "{{ cluster_name }}-admin"
|
||||
user: "{{ new_kubeconfig.users[0].user }}"
|
||||
current-context: "{{ cluster_name }}-admin"
|
||||
|
||||
- name: Merge with existing kubeconfig or create new one
|
||||
delegate_to: localhost
|
||||
block:
|
||||
- name: Read existing kubeconfig
|
||||
ansible.builtin.slurp:
|
||||
src: "{{ local_home }}/.kube/config"
|
||||
register: existing_kubeconfig_content
|
||||
when: main_kubeconfig.stat.exists
|
||||
|
||||
- name: Parse existing kubeconfig
|
||||
ansible.builtin.set_fact:
|
||||
existing_kubeconfig: "{{ existing_kubeconfig_content.content | b64decode | from_yaml }}"
|
||||
when: main_kubeconfig.stat.exists
|
||||
|
||||
- name: Merge kubeconfigs
|
||||
ansible.builtin.set_fact:
|
||||
merged_kubeconfig:
|
||||
apiVersion: "{{ existing_kubeconfig.apiVersion | default('v1') }}"
|
||||
kind: "{{ existing_kubeconfig.kind | default('Config') }}"
|
||||
clusters: "{{ (existing_kubeconfig.clusters | default([])) + updated_kubeconfig.clusters }}"
|
||||
contexts: "{{ (existing_kubeconfig.contexts | default([])) + updated_kubeconfig.contexts }}"
|
||||
users: "{{ (existing_kubeconfig.users | default([])) + updated_kubeconfig.users }}"
|
||||
current-context: "{{ updated_kubeconfig['current-context'] }}"
|
||||
when: main_kubeconfig.stat.exists
|
||||
|
||||
- name: Use new kubeconfig as merged config
|
||||
ansible.builtin.set_fact:
|
||||
merged_kubeconfig: "{{ updated_kubeconfig }}"
|
||||
when: not main_kubeconfig.stat.exists
|
||||
|
||||
- name: Write merged kubeconfig
|
||||
delegate_to: localhost
|
||||
ansible.builtin.copy:
|
||||
content: "{{ merged_kubeconfig | to_nice_yaml }}"
|
||||
dest: "{{ local_home }}/.kube/config"
|
||||
mode: "0644"
|
||||
owner: "{{ local_user }}"
|
||||
|
||||
- name: Display available contexts
|
||||
delegate_to: localhost
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
Kubeconfig updated successfully!
|
||||
|
||||
Available contexts:
|
||||
{% for context in merged_kubeconfig.contexts %}
|
||||
- {{ context.name }}
|
||||
{% endfor %}
|
||||
|
||||
Current context: {{ merged_kubeconfig['current-context'] }}
|
||||
|
||||
To switch contexts, use:
|
||||
kubectl config use-context <context-name>
|
||||
|
||||
To list all contexts:
|
||||
kubectl config get-contexts
|
||||
@@ -74,43 +74,3 @@
|
||||
- name: 7 Install containerd
|
||||
ansible.builtin.include_role:
|
||||
name: containerd
|
||||
|
||||
# - name: Create kubelet config directory
|
||||
# ansible.builtin.file:
|
||||
# path: /var/lib/kubelet
|
||||
# state: directory
|
||||
# owner: root
|
||||
# group: root
|
||||
# mode: '0755'
|
||||
|
||||
# - name: Create initial kubelet config file
|
||||
# ansible.builtin.copy:
|
||||
# dest: /var/lib/kubelet/config.yaml
|
||||
# owner: root
|
||||
# group: root
|
||||
# mode: '0644'
|
||||
# content: |
|
||||
# apiVersion: kubelet.config.k8s.io/v1beta1
|
||||
# kind: KubeletConfiguration
|
||||
# cgroupDriver: systemd
|
||||
# containerRuntimeEndpoint: unix:///run/containerd/containerd.sock
|
||||
|
||||
# - name: Install CNI plugins via dnf
|
||||
# ansible.builtin.dnf:
|
||||
# name: containernetworking-plugins
|
||||
# state: present
|
||||
|
||||
# - name: Verify CNI plugins installation
|
||||
# ansible.builtin.shell: ls -la /opt/cni/bin/ || echo "CNI plugins not found in /opt/cni/bin/"
|
||||
# register: cni_plugins
|
||||
# ignore_errors: true
|
||||
|
||||
# - name: Display installed CNI plugins
|
||||
# ansible.builtin.debug:
|
||||
# msg: "CNI plugins status: {{ cni_plugins.stdout }}"
|
||||
|
||||
# - name: Enable kubelet service (but don't start yet)
|
||||
# ansible.builtin.systemd:
|
||||
# name: kubelet
|
||||
# enabled: true
|
||||
# state: stopped
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# requirements.yml
|
||||
collections:
|
||||
- name: community.general
|
||||
version: 11.1.0
|
||||
|
||||
- name: nccurry.openshift
|
||||
version: 1.4.0
|
||||
|
||||
- name: somaz94.ansible_k8s_iac_tool
|
||||
version: 1.1.6
|
||||
|
||||
- name: prometheus.prometheus
|
||||
version: 0.27.0
|
||||
12
ansible/playbooks/roles/traefik-manager/defaults/main.yml
Normal file
12
ansible/playbooks/roles/traefik-manager/defaults/main.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
# Default variables for traefik-manager role
|
||||
|
||||
# Traefik Configuration
|
||||
traefik_config_dir: "/etc/traefik"
|
||||
traefik_host: "{{ traefik_server | default(groups['traefik_servers'][0] | default('localhost')) }}"
|
||||
cluster_api_port: 6443
|
||||
|
||||
# Cluster Configuration (to be provided by calling role)
|
||||
# cluster_name: "fastpass"
|
||||
# cluster_endpoint: "fastpass.local.mk-labs.cloud"
|
||||
# control_plane_nodes: ["space-mountain", "big-thunder-mountain", "splash-mountain"]
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
# Handlers for traefik-manager role
|
||||
|
||||
- name: reload traefik
|
||||
ansible.builtin.systemd:
|
||||
name: traefik
|
||||
state: reloaded
|
||||
delegate_to: "{{ traefik_host }}"
|
||||
45
ansible/playbooks/roles/traefik-manager/tasks/main.yml
Normal file
45
ansible/playbooks/roles/traefik-manager/tasks/main.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
# role: traefik-manager
|
||||
# description: Reusable role for managing Traefik load balancer configuration
|
||||
# author: mk-labs
|
||||
# version: 1.0.0
|
||||
|
||||
- name: Create Traefik configuration directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ traefik_config_dir }}/dynamic"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
delegate_to: "{{ traefik_host }}"
|
||||
|
||||
- name: Generate Traefik TCP router configuration for Kubernetes API
|
||||
ansible.builtin.template:
|
||||
src: k8s-api-router.yml.j2
|
||||
dest: "{{ traefik_config_dir }}/dynamic/{{ cluster_name }}-api.yml"
|
||||
mode: "0644"
|
||||
delegate_to: "{{ traefik_host }}"
|
||||
notify: reload traefik
|
||||
|
||||
- name: Generate Traefik service configuration for control plane nodes
|
||||
ansible.builtin.template:
|
||||
src: k8s-api-service.yml.j2
|
||||
dest: "{{ traefik_config_dir }}/dynamic/{{ cluster_name }}-service.yml"
|
||||
mode: "0644"
|
||||
delegate_to: "{{ traefik_host }}"
|
||||
notify: reload traefik
|
||||
|
||||
- name: Verify Traefik configuration syntax
|
||||
ansible.builtin.command: |
|
||||
traefik --configfile={{ traefik_config_dir }}/traefik.yml --dry-run
|
||||
delegate_to: "{{ traefik_host }}"
|
||||
register: traefik_syntax_check
|
||||
failed_when: traefik_syntax_check.rc != 0
|
||||
changed_when: false
|
||||
|
||||
- name: Display Traefik configuration status
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
✅ Traefik configuration created successfully:
|
||||
- Router: {{ cluster_name }}-api
|
||||
- Service: {{ cluster_name }}-backend
|
||||
- Endpoint: {{ cluster_endpoint }}:{{ cluster_api_port }}
|
||||
- Backend nodes: {{ control_plane_nodes | join(', ') }}
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
# Traefik TCP Router for {{ cluster_name }} Kubernetes API
|
||||
tcp:
|
||||
routers:
|
||||
{{ cluster_name }}-api:
|
||||
rule: "HostSNI(`{{ cluster_endpoint }}`)"
|
||||
service: "{{ cluster_name }}-backend"
|
||||
tls:
|
||||
passthrough: true
|
||||
entryPoints:
|
||||
- "k8s-api"
|
||||
|
||||
services:
|
||||
{{ cluster_name }}-backend:
|
||||
loadBalancer:
|
||||
servers:
|
||||
{% for node in control_plane_nodes %}
|
||||
- address: "{{ hostvars[node]['ansible_default_ipv4']['address'] }}:{{ cluster_api_port }}"
|
||||
{% endfor %}
|
||||
healthCheck:
|
||||
path: "/healthz"
|
||||
interval: "10s"
|
||||
timeout: "3s"
|
||||
Reference in New Issue
Block a user