如何在ansible中为不同的主机在另一个任务中使用一个任务的return值
How to use return values of one task in another task for a different host in ansible
我正在尝试为由 2 个 mysql 主机组成的主机组设置 mysql 主从复制和 ansible。
这是我的场景:
我运行在第一个主机中执行一个任务并跳过第二个主机,所以第一个任务(即主复制状态)returns一些值,如位置、文件等
然后,我 运行 第二台主机中的另一个任务(跳过第一台主机),该任务使用第一台任务的 return 值,如 master.Position、master.File等
现在,当我 运行 剧本时,第一个任务的变量似乎在第二个任务中不起作用
库存文件
[mysql]
stagmysql01 ansible_host=1.1.1.1 ansible_ssh_user=ansible ansible_connection=ssh
stagmysql02 ansible_host=1.1.1.2 ansible_ssh_user=ansible ansible_connection=ssh
Master 上的任务
- name: Mysql - Check master replication status.
mysql_replication: mode=getmaster
register: master
- debug: var=master
Slave 上的任务
- name: Mysql - Configure replication on the slave.
mysql_replication:
mode: changemaster
master_host: "{{ replication_master }}"
master_user: "{{ replication_user }}"
master_password: "{{ replication_pass }}"
master_log_file: "{{ master.File }}"
master_log_pos: "{{ master.Position }}"
ignore_errors: True
主输出
TASK [Mysql_Base : Mysql - Check master replication status.] ****************
skipping: [stagmysql02]
ok: [stagmysql01]
TASK [Mysql_Base : debug] ***************************************************
ok: [stagmysql01] => {
"master": {
"Binlog_Do_DB": "",
"Binlog_Ignore_DB": "mysql,performance_schema",
"Executed_Gtid_Set": "",
"File": "mysql-bin.000003",
"Is_Master": true,
"Position": 64687163,
"changed": false,
"failed": false
}
}
ok: [stagmysql02] => {
"master": {
"changed": false,
"skip_reason": "Conditional result was False",
"skipped": true
}
}
从机输出
TASK [Mysql_Base : Mysql - Configure replication on the slave.] *************
skipping: [stagmysql01]
fatal: [stagmysql02]: FAILED! => {"failed": true, "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'File'\n\nThe error appears to have been in '/root/ansible/roles/Mysql_Base/tasks/replication.yml': line 30, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Mysql - Configure replication on the slave.\n ^ here\n\nexception type: <class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: 'dict object' has no attribute 'File'"}
...ignoring
正如您在上面看到的那样,由于未定义的变量,第二个主机的第二个任务失败了。但是,第一台主机的第一项任务中存在所需的变量。
如何在另一个任务中使用从第 1 台主机到第 2 台主机的变量 return?
P.S:我看到了使用{{ hostvars[[=52=]]['variable'] }}的方法。
但是我对这种方法很困惑,因为需要直接添加 inventory_hostname 或 IP 地址。我一直在寻找可用于不同库存文件和剧本的通用模板。
我能够通过将变量定义为新的 虚拟主机 然后在整个剧本中使用它来解决我的问题 hostvars .
How do I set register a variable to persist between plays in ansible?中的一个答案中已经提到了类似的解决方案
但是直到我发布这个问题我才注意到它。
这是我在 ansible 任务中所做的:
- 我创建了一个虚拟主机 master_value_holder 并定义了
所需的变量。 (这里我需要 master_log_file 和
master_log_Postion)
- 使用 hostvars[[=52=]]['master_log_file']
访问变量
Master 上的任务
- name: Mysql - Check master replication status.
mysql_replication: mode=getmaster
register: master
- name: "Add master return values to a dummy host"
add_host:
name: "master_value_holder"
master_log_file: "{{ master.File }}"
master_log_pos: "{{ master.Position }}"
从属任务
- name: Mysql - Displaying master replication status
debug: msg="Master Bin Log File is {{ hostvars['master_value_holder']['master_log_file'] }} and Master Bin Log Position is {{ hostvars['master_value_holder']['master_log_pos'] }}"
- name: Mysql - Configure replication on the slave.
mysql_replication:
mode: changemaster
master_host: "{{ replication_master }}"
master_user: "{{ replication_user }}"
master_password: "{{ replication_pass }}"
master_log_file: "{{ hostvars['master_value_holder']['master_log_file'] }}"
master_log_pos: "{{ hostvars['master_value_holder']['master_log_pos'] }}"
when: ansible_eth0.ipv4.address != replication_master and not slave.Slave_SQL_Running
输出
TASK [Mysql_Base : Mysql - Check master replication status.] ****************
skipping: [stagmysql02]
ok: [stagmysql01]
TASK [AZ-Mysql_Base : Add master return values to a dummy host] ****************
changed: [stagmysql01]
TASK [AZ-Mysql_Base : Mysql - Displaying master replication status] ************
ok: [stagmysql01] => {
"msg": "Master Bin Log File is mysql-bin.000001 and Master Bin Log Position is 154"
}
ok: [stagmysql02] => {
"msg": "Master Bin Log File is mysql-bin.000001 and Master Bin Log Position is 154"
}
TASK [AZ-Mysql_Base : Mysql - Configure replication on the slave.] *************
skipping: [stagmysql01]
skipping: [stagmysql02]
从上面的输出可以看出,主复制状态现在可用于两台主机。
我正在尝试为由 2 个 mysql 主机组成的主机组设置 mysql 主从复制和 ansible。
这是我的场景:
我运行在第一个主机中执行一个任务并跳过第二个主机,所以第一个任务(即主复制状态)returns一些值,如位置、文件等
然后,我 运行 第二台主机中的另一个任务(跳过第一台主机),该任务使用第一台任务的 return 值,如 master.Position、master.File等
现在,当我 运行 剧本时,第一个任务的变量似乎在第二个任务中不起作用
库存文件
[mysql]
stagmysql01 ansible_host=1.1.1.1 ansible_ssh_user=ansible ansible_connection=ssh
stagmysql02 ansible_host=1.1.1.2 ansible_ssh_user=ansible ansible_connection=ssh
Master 上的任务
- name: Mysql - Check master replication status.
mysql_replication: mode=getmaster
register: master
- debug: var=master
Slave 上的任务
- name: Mysql - Configure replication on the slave.
mysql_replication:
mode: changemaster
master_host: "{{ replication_master }}"
master_user: "{{ replication_user }}"
master_password: "{{ replication_pass }}"
master_log_file: "{{ master.File }}"
master_log_pos: "{{ master.Position }}"
ignore_errors: True
主输出
TASK [Mysql_Base : Mysql - Check master replication status.] ****************
skipping: [stagmysql02]
ok: [stagmysql01]
TASK [Mysql_Base : debug] ***************************************************
ok: [stagmysql01] => {
"master": {
"Binlog_Do_DB": "",
"Binlog_Ignore_DB": "mysql,performance_schema",
"Executed_Gtid_Set": "",
"File": "mysql-bin.000003",
"Is_Master": true,
"Position": 64687163,
"changed": false,
"failed": false
}
}
ok: [stagmysql02] => {
"master": {
"changed": false,
"skip_reason": "Conditional result was False",
"skipped": true
}
}
从机输出
TASK [Mysql_Base : Mysql - Configure replication on the slave.] *************
skipping: [stagmysql01]
fatal: [stagmysql02]: FAILED! => {"failed": true, "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'File'\n\nThe error appears to have been in '/root/ansible/roles/Mysql_Base/tasks/replication.yml': line 30, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Mysql - Configure replication on the slave.\n ^ here\n\nexception type: <class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: 'dict object' has no attribute 'File'"}
...ignoring
正如您在上面看到的那样,由于未定义的变量,第二个主机的第二个任务失败了。但是,第一台主机的第一项任务中存在所需的变量。
如何在另一个任务中使用从第 1 台主机到第 2 台主机的变量 return?
P.S:我看到了使用{{ hostvars[[=52=]]['variable'] }}的方法。 但是我对这种方法很困惑,因为需要直接添加 inventory_hostname 或 IP 地址。我一直在寻找可用于不同库存文件和剧本的通用模板。
我能够通过将变量定义为新的 虚拟主机 然后在整个剧本中使用它来解决我的问题 hostvars .
How do I set register a variable to persist between plays in ansible?中的一个答案中已经提到了类似的解决方案 但是直到我发布这个问题我才注意到它。
这是我在 ansible 任务中所做的:
- 我创建了一个虚拟主机 master_value_holder 并定义了 所需的变量。 (这里我需要 master_log_file 和 master_log_Postion)
- 使用 hostvars[[=52=]]['master_log_file'] 访问变量
Master 上的任务
- name: Mysql - Check master replication status.
mysql_replication: mode=getmaster
register: master
- name: "Add master return values to a dummy host"
add_host:
name: "master_value_holder"
master_log_file: "{{ master.File }}"
master_log_pos: "{{ master.Position }}"
从属任务
- name: Mysql - Displaying master replication status
debug: msg="Master Bin Log File is {{ hostvars['master_value_holder']['master_log_file'] }} and Master Bin Log Position is {{ hostvars['master_value_holder']['master_log_pos'] }}"
- name: Mysql - Configure replication on the slave.
mysql_replication:
mode: changemaster
master_host: "{{ replication_master }}"
master_user: "{{ replication_user }}"
master_password: "{{ replication_pass }}"
master_log_file: "{{ hostvars['master_value_holder']['master_log_file'] }}"
master_log_pos: "{{ hostvars['master_value_holder']['master_log_pos'] }}"
when: ansible_eth0.ipv4.address != replication_master and not slave.Slave_SQL_Running
输出
TASK [Mysql_Base : Mysql - Check master replication status.] ****************
skipping: [stagmysql02]
ok: [stagmysql01]
TASK [AZ-Mysql_Base : Add master return values to a dummy host] ****************
changed: [stagmysql01]
TASK [AZ-Mysql_Base : Mysql - Displaying master replication status] ************
ok: [stagmysql01] => {
"msg": "Master Bin Log File is mysql-bin.000001 and Master Bin Log Position is 154"
}
ok: [stagmysql02] => {
"msg": "Master Bin Log File is mysql-bin.000001 and Master Bin Log Position is 154"
}
TASK [AZ-Mysql_Base : Mysql - Configure replication on the slave.] *************
skipping: [stagmysql01]
skipping: [stagmysql02]
从上面的输出可以看出,主复制状态现在可用于两台主机。