0

I am using Ansible to configure a k8s cluster with several nodes. I have a playbook which checks if a variable representing the kubeadm join command has already been defined. If it has not, it generates the kubeadm join command on the node in the manager group, then checks the output of kubectl get nodes --no-headers to identify nodes already joined. I intend to compare that output to the members of the workers group in inventory.yml, but I am struggling with the regex.

I have two questions:

  1. Is this the best way to do this? I don't want to blindly execute the command on the nodes in workers since this will fail if the nodes are already joined, and further this fails idempotency.
  2. If this is a good way to do this, can I get some help understanding where my regex is failing?

inventory.yml

workers:
    hosts:
        kube02.local:
        kube03.local:

manager:
    hosts:
        kube01.local:

kube:
    children:
        workers:
        manager:

relevant part of the playbook

   
- name: Creates join command by creating a token and printing the command
  ansible.builtin.shell: kubeadm token create --print-join-command
  register: k8s_join_command
  when: (k8s_join_command is undefined) and (inventory_hostname in groups['manager'])
  
- name: Creates variable from output of `kubectl get nodes --no-headers` on manager
  become: no 
  ansible.builtin.shell: kubectl get nodes --no-headers
  register: cluster_members
  when: inventory_hostname in groups['manager']

- name: Debug cluster members
  ansible.builtin.debug:
    msg: "{{ cluster_members.stdout_lines | type_debug }}"
  when: k8s_join_command is defined

- name: Debug cluster members regex for matching against
  ansible.builtin.debug:
    msg: "{{ cluster_members.stdout_lines | ansible.builtin.regex_replace('^(?P<name>kube[0-9]{2}).*$', '\\g<name>\\.local', multiline=True, ignorecase=True) }}"
  when: (inventory_hostname in groups['manager']) and (k8s_join_command is defined) and (cluster_members is defined)

output of playbook execution

TASK [k8s : Debug cluster members regex for matching against] **************************************************************************
skipping: [kube02.local]
skipping: [kube03.local]
ok: [kube01.local] => {
    "msg": [
        "kube01   Ready   control-plane   7d14h   v1.27.3",
        "kube02   Ready   <none>          7d1h    v1.27.3",
        "kube03   Ready   <none>          7d1h    v1.27.3"
    ]
}

TASK [k8s : Creates variable from output of `kubectl get nodes --no-headers` on manager] ***********************************************
skipping: [kube02.local]
skipping: [kube03.local]
changed: [kube01.local]

TASK [k8s : Debug cluster members] *****************************************************************************************************
ok: [kube02.local] => {
    "msg": "AnsibleUndefined"
}
ok: [kube03.local] => {
    "msg": "AnsibleUndefined"
}
ok: [kube01.local] => {
    "msg": "list"
}

TASK [k8s : Debug cluster members regex for matching against] **************************************************************************
skipping: [kube02.local]
skipping: [kube03.local]
ok: [kube01.local] => {
    "msg": [
        "kube01   Ready   control-plane   7d14h   v1.27.3",
        "kube02   Ready   <none>          7d1h    v1.27.3",
        "kube03   Ready   <none>          7d1h    v1.27.3"
    ]
}

I'd expect to have output of the last task that is something like below, which I could then use to exclude kube01.local and execute the relevant command on kube02.local and kube03.local

TASK [k8s : Debug cluster members regex for matching against] **************************************************************************
skipping: [kube02.local]
skipping: [kube03.local]
ok: [kube01.local] => {
    "msg": [
        "kube01.local",
        "kube02.local",
        "kube03.local"
    ]
}

I've tried countless permutations of my regex, all of which are successful in my testing outside of Ansible, and all of which fail in a variety of ways in Ansible.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.