如何在Ansible循环中获取inventory的ansible_host配置UFW防火墙
问题
我有多台不同IP的服务器,想用Ansible给MySQL服务器配置UFW防火墙,只允许自有服务器(后续可能改成webserver组)访问。最初清单里只有FQDN,后来加了ansible_host的IP地址,因为防火墙不解析主机名。但我不知道怎么在使用query("inventory_hostnames", "all")的循环中获取ansible_host的值。
我的清单:
all: vars: ansible_ssh_user: me children: sqlserver: hosts: sqlserver.my-domain.de: ansible_ssh_user: mysql_me_user ansible_host: 1.1.1.1 webserver: hosts: webserver1.my-domain.de: ansible_host: 2.2.2.2 webserver2.my-domain.de: ansible_host: 3.3.3.3
我尝试的playbook:
- hosts: '{{target|default("sqlserver")}}' roles: - { name: oefenweb.ufw, become: yes } # 需要root权限,但角色本身没定义become vars: ufw_logging: true ufw_rules: - rule: allow to_port: 22 protocol: tcp tasks: - name: 开放MySQL端口给自有服务器 ufw: rule: allow to_port: 3306 protocol: tcp from_ip: '{{ item }}' loop: '{{ hosts|default(query("inventory_hostnames", "all")) }}' tags: test become: true
解决方案
要获取主机对应的ansible_host值,不能直接用inventory_hostnames返回的主机名列表,得结合hostvars变量提取IP地址,以下是两种实用方案:
方案一:针对指定组(如webserver)配置
如果后续要改成仅允许webserver组访问,直接针对该组处理更精准:
- name: 允许webserver组访问MySQL 3306端口 ufw: rule: allow to_port: 3306 protocol: tcp from_ip: '{{ hostvars[item].ansible_host }}' loop: '{{ query("inventory_hostnames", "webserver") }}' become: true
方案二:针对所有自有服务器(排除当前MySQL服务器)
如果需要允许所有自有服务器访问,但要避免给当前MySQL服务器本身添加不必要的规则:
- name: 允许所有自有服务器访问MySQL 3306端口(排除自身) ufw: rule: allow to_port: 3306 protocol: tcp from_ip: '{{ hostvars[item].ansible_host }}' loop: '{{ query("inventory_hostnames", "all") | difference([inventory_hostname]) }}' become: true
关键说明
hostvars[item].ansible_host:通过循环得到的主机名(item),直接从主机变量中取出对应的IP地址difference([inventory_hostname]):过滤掉当前执行任务的MySQL服务器,避免给自己开放端口- 后续切换访问组时,只需要把
query里的组名(比如"all"或"webserver")替换成目标组即可
内容的提问来源于stack exchange,提问作者Kleidersack
相关产品推荐
相关产品推荐

