首页 > 解决方案 > 如何通过多选调查从ansible AWX的ansible playbook中运行带有条件变量的简单循环?

问题描述

目标是在多个数据库中创建用户,每个数据库都有自己的端口、ip 和 priv 集。在主机中,我只传递名称并根据名称定义所有变量。

这是来自 AWX 的 JSON 变量:

{“用户名”:“ansible”,“密码”:“123456”,“主机”:[“yan_local”,“QA1_Backgammon”],“权限”:“SELECT,SHOW VIEW”}

没有只有一台主机的循环部分,它工作正常

我正在尝试做一个循环,但它不工作

这是我的代码:

  hosts: 127.0.0.1
  vars:
     port: "{{ '3306' if host == 'yan_local' else '3310' if host == 'DEV_Backgammon' else '3320' if host == 'DEV_Spades' else '3330' if host == 'DEV_Rummy' else '3311' if host == 'QA1_Backgammon' else '3321' if host == 'QA1_Spades' else '3331' if host == 'QA1_Rummy' else '3341' if host == 'QA1_Domino' else '3351' if host == 'QA1_CasualRummy' else '3313' if host == 'QA2_Backgammon' else '3323' if host == 'QA2_Spades' else '3312' if host == 'Stage_Backgammon' else '3322' if host == 'Stage_Spades' else '3332' if host == 'Stage_Rummy' }}"
     database_name: "{{ '10.42.0.38' if host == 'yan_local' else '172.31.0.176' if host == 'DEV_Backgammon' else '172.31.0.176' if host == 'DEV_Spades' else '172.31.0.176' if host == 'DEV_Rummy' else '172.31.0.176' if host == 'QA1_Backgammon' else '172.31.0.176' if host == 'QA1_Spades' else '172.31.0.176' if host == 'QA1_Rummy' else '172.31.0.176' if host == 'QA1_Domino' else '172.31.0.176' if host == 'QA1_CasualRummy' else '172.31.0.176' if host == 'QA2_Backgammon' else '172.31.0.176' if host == 'QA2_Spades' else '172.31.0.176' if host == 'Stage_Backgammon' else '172.31.0.176' if host == 'Stage_Spades' else '172.31.0.176' if host == 'Stage_Rummy' }}"
     database: "{{ 'yan' if host == 'yan_local' else 'backgammon' if host == 'DEV_Backgammon' else 'spades' if host == 'DEV_Spades' else 'rummy' if host == 'DEV_Rummy' else 'backgammon' if host == 'QA1_Backgammon' else '3321' if host == 'spades' else 'rummy' if host == 'QA1_Rummy' else 'backgammon' if host == 'QA1_Domino' else 'rummy' if host == 'QA1_CasualRummy' else 'backgammon' if host == 'QA2_Backgammon' else '3323' if host == 'spades' else 'backgammon' if host == 'Stage_Backgammon' else 'spades' if host == 'Stage_Spades' else '3332' if host == 'rummy' }}"
     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') }}"
     dbpassword: "{{ lookup('vars', 'dbpassword_yan') if host == 'yan_local' else lookup('vars', 'dbpassword_qa') if host != 'yan_local' }}"
     host: []

  tasks:
  - name:  
    pip:
       name: "{{ item }}"
       state: present
    with_items:
          - PyMySQL
          - boto
          - boto3
          - botocore
          - jmespath   
          
    
  - name: Database details
    debug: 
       msg: '{{ database_name }}/{{ database }}-{{ host }}:{{ port }}'
     
  - name: Create database user with name "{{ username }}" and password "{{ password }}" 
    community.mysql.mysql_user:
        login_host: "{{ item }}"
        login_port: "{{ '3306' if host == 'yan_local' else '3310' if host == 'DEV_Backgammon' else '3320' if host == 'DEV_Spades' else '3330' if host == 'DEV_Rummy' else '3311' if host == 'QA1_Backgammon' else '3321' if host == 'QA1_Spades' else '3331' if host == 'QA1_Rummy' else '3341' if host == 'QA1_Domino' else '3351' if host == 'QA1_CasualRummy' else '3313' if host == 'QA2_Backgammon' else '3323' if host == 'QA2_Spades' else '3312' if host == 'Stage_Backgammon' else '3322' if host == 'Stage_Spades' else '3332' if host == 'Stage_Rummy' }}"
        login_user: "{{ lookup('amazon.aws.aws_secret', 'qa/ansible', region='us-west-2') | from_json | json_query('user') }}"
        login_password: "{{ dbpassword }}"
        host: '%'
        password: "{{ password }}"
        name: "{{ username }}"
        priv: "{{ 'yan' if host == 'yan_local' else 'backgammon' if host == 'DEV_Backgammon' else 'spades' if host == 'DEV_Spades' else 'rummy' if host == 'DEV_Rummy' else 'backgammon' if host == 'QA1_Backgammon' else '3321' if host == 'spades' else 'rummy' if host == 'QA1_Rummy' else 'backgammon' if host == 'QA1_Domino' else 'rummy' if host == 'QA1_CasualRummy' else 'backgammon' if host == 'QA2_Backgammon' else '3323' if host == 'spades' else 'backgammon' if host == 'Stage_Backgammon' else 'spades' if host == 'Stage_Spades' else '3332' if host == 'rummy' }}.*:{{ permissions }}"
        state: present
    when: username != "root23" and username != "root22"
    loop: "{{ database_name }}"

    
  - name: Database details
    debug: 
       msg: '{{ database_name }}/{{ database }}-{{ host }}:{{ port }}'```

I'm getting error:

```{
  "msg": "The task includes an option with an undefined variable. The error was: {{ '10.42.0.38' if host == 'yan_local' else '172.31.0.176' if host == 'DEV_Backgammon' else '172.31.0.176' if host == 'DEV_Spades' else '172.31.0.176' if host == 'DEV_Rummy' else '172.31.0.176' if host == 'QA1_Backgammon' else '172.31.0.176' if host == 'QA1_Spades' else '172.31.0.176' if host == 'QA1_Rummy' else '172.31.0.176' if host == 'QA1_Domino' else '172.31.0.176' if host == 'QA1_CasualRummy' else '172.31.0.176' if host == 'QA2_Backgammon' else '172.31.0.176' if host == 'QA2_Spades' else '172.31.0.176' if host == 'Stage_Backgammon' else '172.31.0.176' if host == 'Stage_Spades' else '172.31.0.176' if host == 'Stage_Rummy' }}: the inline if-expression on line 1 evaluated to false and no else section was defined.\n\nThe error appears to be in '/runner/project/sql-playbook.yml': line 25, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n  - name: Database details\n    ^ here\n",
  "_ansible_no_log": false
}```

标签: ansibleansible-awx

解决方案


答案是:

我可以为 [host] 数组中的每个项目执行 set_facts 并使用 when 条件创建另一个数组,例如:

    set_fact: 
     dbs: "{{dbs|default([]) + [{'host': {'port': 3332, 'database': 'rummy', 'database_name': '172.31.0.176', 'dbpassword': dbpassword_qa }}] }}"
    when: item == 'Stage_Rummy'    
    loop:
      "{{host}}"

  - name: set_facts
    set_fact: 
     dbs: "{{dbs|default([]) + [{'host': {'port': 3322, 'database': 'spades', 'database_name': '172.31.0.176', 'dbpassword': dbpassword_qa }}] }}"
    when: item == 'Stage_Spades'    
    loop:
      "{{host}}"

  - name: set_facts
    set_fact: 
     dbs: "{{dbs|default([]) + [{'host': {'port': 3306, 'database': 'yan', 'database_name': '10.42.0.184', 'dbpassword': dbpassword_yan }}] }}"
    when: item == 'yan_local'    
    loop:
      "{{host}}"    

然后我可以遍历新数组:

    community.mysql.mysql_user:
        login_host: "{{ item.host.database_name }}"
        login_port: "{{ item.host.port }}"
        login_user: "{{ lookup('amazon.aws.aws_secret', 'qa/ansible', region='us-west-2') | from_json | json_query('user') }}"
        login_password: "{{ item.host.dbpassword }}"
        host: '%'
        password: "{{ password }}"
        name: "{{ username }}"
        priv: '{{ item.host.database }}.*:{{ permissions }}'
        state: present
    when: username != "root" and username != "root22"
    loop:
       "{{ dbs }}"

假设我只从 AWX 传输 yan_local,它只会触发第三个任务并首先忽略 2 个,或者它将包含所有 3 个主机,然后它将使用这 3 个主机创建数组 dbs。

{dbs|default([]) 语法将创建新数组,如果不存在空值并添加从 set_facts 提供的值。


推荐阅读