Target Kubernetes nodes using Ansible
This week I needed to update the NTP settings on a Kubernetes cluster. I could have used an Ansible inventory (as decribed here), but instead choose to make a dynamic Ansible inventory, by querying the nodes from Kubernetes.
You can find the full playbook described here if you like.

Creating a dynamic Ansible inventory
The playbook I’ll use contains two Ansible plays. The first will query the Kubernetes nodes in the cluster and add those to the Ansible inventory, basically creating a dynamic inventory. The second will use the inventory to copy out the new NTP configuration and restart the NTP service.
Get Kubernetes nodes using Ansible
The first step is to query Kubernetes for the nodes in the cluster, for which I’ll use the lookup module. Then I’ll use the Ansible add_host module to add the hosts to my (now dynamic) Ansible inventory.
- name: Get Kubernetes nodes
hosts: localhost
tasks:
- name: Get Kubernetes nodes
set_fact:
nodes: "{{ lookup('k8s', api_version='v1', kind='node') }}"
- name: Add host to inventory
add_host:
hostname: "{{ item }}"
groups:
- Nodes
with_list: "{{ nodes | json_query('[*].status.addresses[0].address') }}"The first play shown above runs against the local host. Therefor the local Kubernetes credentials (./kube/config) will be used to connect to the Kubernetes cluster.
In the first task I set the variable nodes by using lookupto query the Kubernetes module for all nodes. This will return a great amount of detail about the Kubernetes nodes. However, we’re only interested in the IP addresses of the nodes, so we’ll need to extract those.
In the add_host module I use a with_list option to loop through the nodes variable and query the IP address using json_query. This json_query will return a list of IP addresses for my Kubernetes nodes, which the add_host will add to my inventory and also to the inventory group Nodes.
Update NTP servers
Now that I’ve dynamically created my Ansible Inventory, I can use the inventory to execute tasks against the hosts. In my case I’ll run the following tasks to update the NTP settings.
- name: Set NTP servers
hosts: Nodes
become: true
tasks:
- name: Make sure NTP is installed
apt:
name: ntp
state: present
- name: Copy NTP server configruation
template: src=ntp.conf dest=/etc/ntp.conf
- name: Stop NTP client
service: name=ntp state=stopped
- name: Sync time initialy
shell: ntpd -gq
- name: Make sure NTP is started up
service: name=ntp state=started enabled=yesAs you can see on line 2, I’m targeting the Nodes group, which we created in our previous play. In the tasks, I do the following:
- Install NTP using apt
- Copy the
ntp.conffrom the template directory to the nodes - Stop the NTP client
- Sync the node time using
ntpd -gqwhich will also correct for large time offsets - Start the NTP client
That concludes the playbook.
Conclusion
We’ve seen how easy it is to create a dynamic Ansible inventory, by using a Ansible module (in this case the Kubernetes / k8s module) and use the output to create our dynamic inventory. We can then use that inventory to execute our regular playbook.
Hope you’ve found this useful and see you in the next blog!