我如何 运行 在 ansible playbook 中使用 multi select 调查的 ansible AWX 中的条件变量进行简单循环?
How can i run simple loop with conditional variables in ansible playbook from ansible AWX with multi select survey?
目标是在多个数据库中创建用户,每个数据库都有自己的端口、ip 和 priv 集。在主机中,我只传递名称并根据名称定义所有变量。
这是来自 AWX 的变量 JSON:
{
“用户名”:“ansible”,
“密码”:“123456”,
“主持人”: [
"yan_local",
“QA1_Backgammon”
],
“权限”:“SELECT,显示视图”
}
没有只有一台主机的循环部分,它工作正常
我正在尝试循环,但它不起作用
这是我的代码:
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
}```
我建议根据以下内容更改变量的定义:
---
- hosts: localhost
gather_facts: false
vars:
host: QA1_Backgammon
json_awx:
username: ansible
password: 123456
host:
- yan_local
- QA1_Backgammon
permissions: "SELECT,SHOW VIEW"
dbhosts:
- name: yan_local
login_port: 3306
login_host: '10.42.0.38'
login_user: 'login'
login_password: 'password'
database: yan
host: '%'
- name: QA1_Backgammon
login_port: 3311
login_host: '172.31.0.176'
login_user: 'login'
login_password: 'password'
database: backgammon
host: '%'
tasks:
- name: Set dbh variable
vars:
entry: "{{ dbhosts
| selectattr('name','equalto',item)
| flatten
| combine({ 'permissions':json_awx.permissions,
'username':json_awx.username,
'password':json_awx.password }) }}"
set_fact:
dbh: "{{ dbh
| default([])
+ [ entry ] }}"
loop: "{{ json_awx.host }}"
- name: Create database user
debug:
msg:
login_host: "{{ item.login_host }}"
login_port: "{{ item.login_port }}"
login_user: "{{ item.login_user }}"
login_password: "{{ item.login_password }}"
host: "{{ item.host }}"
password: "{{ item.password }}"
name: "{{ item.username }}"
priv: "{{ item.database }}.*:{{ item.permissions }}"
loop: "{{ dbh }}"
when:
- item.username != 'root22'
- item.username != 'root23'
- item.name == host
和输出
PLAY [localhost] **********************************************************************************
TASK [Set dbh variable] ***************************************************************************
ok: [localhost] => (item=yan_local)
ok: [localhost] => (item=QA1_Backgammon)
TASK [Create database user] ***********************************************************************
skipping: [localhost] => (item={'name': 'yan_local', 'login_port': 3306, 'login_host': '10.42.0.38', 'login_user': 'login', 'login_password': 'password', 'database': 'yan', 'host': '%', 'permissions': 'SELECT,SHOW VIEW', 'username': 'ansible', 'password': 123456})
ok: [localhost] => (item={'name': 'QA1_Backgammon', 'login_port': 3311, 'login_host': '172.31.0.176', 'login_user': 'login', 'login_password': 'password', 'database': 'backgammon', 'host': '%', 'permissions': 'SELECT,SHOW VIEW', 'username': 'ansible', 'password': 123456}) => {
"msg": {
"host": "%",
"login_host": "172.31.0.176",
"login_password": "password",
"login_port": "3311",
"login_user": "login",
"name": "ansible",
"password": "123456",
"priv": "backgammon.*:SELECT,SHOW VIEW"
}
}
PLAY RECAP ****************************************************************************************
答案是:
我可以对 [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.
提供的值
目标是在多个数据库中创建用户,每个数据库都有自己的端口、ip 和 priv 集。在主机中,我只传递名称并根据名称定义所有变量。
这是来自 AWX 的变量 JSON:
{ “用户名”:“ansible”, “密码”:“123456”, “主持人”: [ "yan_local", “QA1_Backgammon” ], “权限”:“SELECT,显示视图” }
没有只有一台主机的循环部分,它工作正常
我正在尝试循环,但它不起作用
这是我的代码:
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
}```
我建议根据以下内容更改变量的定义:
---
- hosts: localhost
gather_facts: false
vars:
host: QA1_Backgammon
json_awx:
username: ansible
password: 123456
host:
- yan_local
- QA1_Backgammon
permissions: "SELECT,SHOW VIEW"
dbhosts:
- name: yan_local
login_port: 3306
login_host: '10.42.0.38'
login_user: 'login'
login_password: 'password'
database: yan
host: '%'
- name: QA1_Backgammon
login_port: 3311
login_host: '172.31.0.176'
login_user: 'login'
login_password: 'password'
database: backgammon
host: '%'
tasks:
- name: Set dbh variable
vars:
entry: "{{ dbhosts
| selectattr('name','equalto',item)
| flatten
| combine({ 'permissions':json_awx.permissions,
'username':json_awx.username,
'password':json_awx.password }) }}"
set_fact:
dbh: "{{ dbh
| default([])
+ [ entry ] }}"
loop: "{{ json_awx.host }}"
- name: Create database user
debug:
msg:
login_host: "{{ item.login_host }}"
login_port: "{{ item.login_port }}"
login_user: "{{ item.login_user }}"
login_password: "{{ item.login_password }}"
host: "{{ item.host }}"
password: "{{ item.password }}"
name: "{{ item.username }}"
priv: "{{ item.database }}.*:{{ item.permissions }}"
loop: "{{ dbh }}"
when:
- item.username != 'root22'
- item.username != 'root23'
- item.name == host
和输出
PLAY [localhost] **********************************************************************************
TASK [Set dbh variable] ***************************************************************************
ok: [localhost] => (item=yan_local)
ok: [localhost] => (item=QA1_Backgammon)
TASK [Create database user] ***********************************************************************
skipping: [localhost] => (item={'name': 'yan_local', 'login_port': 3306, 'login_host': '10.42.0.38', 'login_user': 'login', 'login_password': 'password', 'database': 'yan', 'host': '%', 'permissions': 'SELECT,SHOW VIEW', 'username': 'ansible', 'password': 123456})
ok: [localhost] => (item={'name': 'QA1_Backgammon', 'login_port': 3311, 'login_host': '172.31.0.176', 'login_user': 'login', 'login_password': 'password', 'database': 'backgammon', 'host': '%', 'permissions': 'SELECT,SHOW VIEW', 'username': 'ansible', 'password': 123456}) => {
"msg": {
"host": "%",
"login_host": "172.31.0.176",
"login_password": "password",
"login_port": "3311",
"login_user": "login",
"name": "ansible",
"password": "123456",
"priv": "backgammon.*:SELECT,SHOW VIEW"
}
}
PLAY RECAP ****************************************************************************************
答案是:
我可以对 [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.
提供的值