Ansible如何仅在指定的primary主机上执行带with_items的任务?
Ansible任务仅在标记为primary的主机执行的问题
现有配置
group_vars/my_app 中的变量定义
ldap: - { name: machine1.domain.com, machine: primary } - { name: machine2.domain.com, machine: secondary } - { name: machine3.domain.com, machine: tertiary } - { name: machine4.domain.com, machine: quaternary }
Inventory 文件内容
[ldap] machine1.domain.com machine2.domain.com machine3.domain.com machine4.domain.com
需求
针对ldap组所有主机运行playbook,但其中一个替换任务仅需在ldap变量中标记为primary的主机上执行,原任务代码如下:
- name: Patch only first machine replace: dest: "/opt/data1.ldif" regexp: "{{item.regexp}}" replace: "{{item.line}}" with_items: - { regexp: '__ANSIBLE_BIND_PASSWD__', line: "{{secrets[env][role].bpasswd}}" } - { regexp: '__ANSIBLE_ADMIN_PASSWD__', line: "{{secrets[env][role].apasswd}}" } when: ??? no_log: True
最初考虑通过遍历ldap列表并加条件判断,但任务已经使用with_items处理替换规则,不确定是否需要用with_nested。
解决方案
不需要使用嵌套循环,直接通过when条件筛选主机即可,有两种简洁的实现方式:
方式一:直接在when中使用过滤器筛选
利用Ansible的过滤器从ldap列表中提取所有primary主机的名称,再判断当前主机是否在该列表内:
- name: Patch only primary LDAP machine replace: dest: "/opt/data1.ldif" regexp: "{{item.regexp}}" replace: "{{item.line}}" with_items: - { regexp: '__ANSIBLE_BIND_PASSWD__', line: "{{secrets[env][role].bpasswd}}" } - { regexp: '__ANSIBLE_ADMIN_PASSWD__', line: "{{secrets[env][role].apasswd}}" } when: ansible_fqdn in (ldap | selectattr('machine', 'equalto', 'primary') | map(attribute='name') | list) no_log: True
方式二:预先定义primary主机变量
先在group_vars/my_app中定义一个专门的变量存储primary主机名:
# 在group_vars/my_app中添加 primary_ldap_host: "{{ ldap | selectattr('machine', 'equalto', 'primary') | map(attribute='name') | first }}"
然后任务的when条件直接判断当前主机是否匹配:
- name: Patch only primary LDAP machine replace: dest: "/opt/data1.ldif" regexp: "{{item.regexp}}" replace: "{{item.line}}" with_items: - { regexp: '__ANSIBLE_BIND_PASSWD__', line: "{{secrets[env][role].bpasswd}}" } - { regexp: '__ANSIBLE_ADMIN_PASSWD__', line: "{{secrets[env][role].apasswd}}" } when: ansible_fqdn == primary_ldap_host no_log: True
逻辑说明
任务中的with_items负责遍历替换规则,而主机的筛选通过when条件独立控制,这样既保留了原任务的替换逻辑,又确保只有标记为primary的主机会执行该任务,避免了嵌套循环带来的冗余执行逻辑。
内容的提问来源于stack exchange,提问作者echodrome
相关产品推荐
相关产品推荐

