如何用Ansible为Docker Swarm集群节点分配标签并解决YAML错误
Alright, let's fix your issues and get those Swarm node labels assigned properly!
First: Fix the YAML Syntax Error
Your original playbook has two key issues causing the syntax error:
- The Docker node module uses the
labelsparameter (plural), notlabel(singular) - YAML relies on strict indentation—make sure all task elements are properly aligned under the task entry
Solution 1: Batch Assign Labels Using Inventory Variables (Cleanest Approach)
This method ties labels directly to your existing hosts file, letting you manage everything in one centralized place.
Step 1: Update Your hosts File
Add a custom variable (like swarm_label) to each node to define its target label:
[target-machines] 10.xx.xx.1 ansible_sudo_pass=xyz ansible_ssh_pass=xyz ansible_ssh_user=xyz swarm_label=abc1 10.xx.xx.2 ansible_sudo_pass=abc ansible_ssh_pass=abc ansible_ssh_user=abc swarm_label=abc2 10.xx.xx.3 ansible_sudo_pass=def ansible_ssh_pass=def ansible_ssh_user=def swarm_label=abc3
(Note: Replace IPs/credentials with your actual values, and fill in the third node's details if missing from your original hosts file)
Step 2: Write the Ansible Playbook
This playbook loops through your target-machines group, maps each inventory node to its Swarm hostname, and assigns the corresponding label:
- name: Assign Docker Swarm node labels hosts: localhost connection: local gather_facts: false tasks: # Optional: Fetch Swarm node list to validate we're targeting valid nodes - name: Get Swarm hostnames command: docker node ls --format "{{ '{{ .Hostname }}' }}" register: swarm_hostnames - name: Apply labels to each Swarm node docker_node: hostname: "{{ item.inventory_hostname }}" # Match this to your Swarm node's actual hostname labels: "{{ item.swarm_label }}": true state: present loop: "{{ groups['target-machines'] | map('extract', hostvars) | list }}" when: item.inventory_hostname in swarm_hostnames.stdout_lines
- If your Swarm nodes use different hostnames than your inventory entries, add another custom variable like
swarm_hostnameto your hosts file and replaceitem.inventory_hostnamewith that value - The
whenclause ensures we only target nodes that exist in your Swarm cluster
Solution 2: Static Label Mapping (No Hosts File Changes)
If you don't want to modify your hosts file, define a static list of node-label pairs directly in the playbook:
- name: Assign Docker Swarm node labels hosts: localhost connection: local gather_facts: false vars: node_label_map: - swarm_hostname: vm-test # Replace with node1's actual Swarm hostname label: abc1 - swarm_hostname: vm-test2 # Replace with node2's actual Swarm hostname label: abc2 - swarm_hostname: vm-test3 # Replace with node3's actual Swarm hostname label: abc3 tasks: - name: Apply labels to each node docker_node: hostname: "{{ item.swarm_hostname }}" labels: "{{ item.label }}": true state: present loop: "{{ node_label_map }}"
Key Notes
- Ensure the machine running Ansible (localhost) has access to your Docker Swarm cluster (the current user should be authorized to run
docker nodecommands) - To verify labels were applied correctly, run
docker node inspect <node-hostname> | grep -A5 Labelson your Swarm manager
内容的提问来源于stack exchange,提问作者Naman Arora

