如何在Ansible AWX多选调查的Playbook中运行带条件变量的循环
问题根因
- 变量冲突:你在playbook的vars块里手动定义了
host: [],直接覆盖了AWX传入的host列表变量,导致所有判断逻辑的数据源首先就出错了。 - 变量类型不匹配:AWX传入的
host是列表类型,但你写的所有三目判断逻辑都是把host当成单个字符串和固定值对比,列表和字符串的对比永远返回false,你的所有三目表达式最后没有兜底的else分支,所以直接抛出了表达式无返回值的报错。 - 循环逻辑错误:你给创建用户的任务配置的循环对象是
database_name,但你实际需要遍历的是传入的主机列表,循环对象完全错误。 - 配置维护性差:嵌套多层的三目表达式写法不仅可读性极低,还存在多处笔误(比如database的判断里出现
else '3321' if host == 'spades'这类逻辑错误),非常容易触发配置错误。
正确实现方案
我们改用字典映射来管理所有主机的配置,逻辑清晰不容易出错,然后直接循环AWX传入的主机列表即可:
- hosts: 127.0.0.1 vars: # 统一管理所有主机的配置映射,新增主机直接加条目即可 db_config_map: yan_local: port: 3306 login_host: 10.42.0.38 database: yan dbpass_var: dbpassword_yan DEV_Backgammon: port: 3310 login_host: 172.31.0.176 database: backgammon dbpass_var: dbpassword_qa DEV_Spades: port: 3320 login_host: 172.31.0.176 database: spades dbpass_var: dbpassword_qa DEV_Rummy: port: 3330 login_host: 172.31.0.176 database: rummy dbpass_var: dbpassword_qa QA1_Backgammon: port: 3311 login_host: 172.31.0.176 database: backgammon dbpass_var: dbpassword_qa QA1_Spades: port: 3321 login_host: 172.31.0.176 database: spades dbpass_var: dbpassword_qa QA1_Rummy: port: 3331 login_host: 172.31.0.176 database: rummy dbpass_var: dbpassword_qa QA1_Domino: port: 3341 login_host: 172.31.0.176 database: backgammon dbpass_var: dbpassword_qa QA1_CasualRummy: port: 3351 login_host: 172.31.0.176 database: rummy dbpass_var: dbpassword_qa QA2_Backgammon: port: 3313 login_host: 172.31.0.176 database: backgammon dbpass_var: dbpassword_qa QA2_Spades: port: 3323 login_host: 172.31.0.176 database: spades dbpass_var: dbpassword_qa Stage_Backgammon: port: 3312 login_host: 172.31.0.176 database: backgammon dbpass_var: dbpassword_qa Stage_Spades: port: 3322 login_host: 172.31.0.176 database: spades dbpass_var: dbpassword_qa Stage_Rummy: port: 3332 login_host: 172.31.0.176 database: rummy dbpass_var: dbpassword_qa # 数据库密码公共变量 dbpassword_yan: "{{ lookup('amazon.aws.aws_secret', 'qa/ansible', region='us-west-2') | from_json | json_query('password') }}" dbpassword_qa: "{{ lookup('amazon.aws.aws_secret', 'qa/ansible', region='us-west-2') | from_json | json_query('db_pass') }}" # 预读取数据库管理用户名 db_admin_user: "{{ lookup('amazon.aws.aws_secret', 'qa/ansible', region='us-west-2') | from_json | json_query('user') }}" tasks: - name: 安装依赖包 pip: name: "{{ item }}" state: present with_items: - PyMySQL - boto - boto3 - botocore - jmespath - name: 遍历创建数据库用户 community.mysql.mysql_user: login_host: "{{ db_config_map[item].login_host }}" login_port: "{{ db_config_map[item].port }}" login_user: "{{ db_admin_user }}" login_password: "{{ lookup('vars', db_config_map[item].dbpass_var) }}" host: '%' password: "{{ password }}" name: "{{ username }}" priv: "{{ db_config_map[item].database }}.*:{{ permissions }}" state: present when: username not in ["root22", "root23"] loop: "{{ host }}" # 直接循环AWX传入的主机列表 - name: 输出配置结果 debug: msg: "已在{{ db_config_map[item].login_host }}:{{ db_config_map[item].port }}/{{ db_config_map[item].database }}创建用户{{ username }}" loop: "{{ host }}"
注意事项
- 请先核对
db_config_map里的所有配置和你原来的需求一致,已经按照你写的三目逻辑修正了之前的笔误。 - 不要在vars块里重新定义
host变量,避免覆盖AWX传入的值。 - 后续新增主机只需要在
db_config_map里新增对应条目即可,不需要修改任务逻辑。
内容的提问来源于stack exchange,提问作者Yan Khusid
相关产品推荐
相关产品推荐

