如何使用先前任务中定义的变量用于条件省略该主机的任务?
How to use a variable defined in a previous task for use in a task where the conditional omits that host?
实际上,我有两台服务器,我试图从其中一台的命令中获取使用输出,以配置另一台,反之亦然。我花了几个小时阅读这篇文章,发现 hostvars
进程和虚拟主机似乎是我想要的。无论我如何尝试实施此过程,我仍然会收到未定义的变量,and/or 来自主机的失败不在任务的模式中:
这是相关块,只有主机 mux-ds1
和 mux-ds2
在 dispatchers
组中:
---
- name: Play that sets up the sql database during the build process on all mux dispatchers.
hosts: mux_dispatchers
remote_user: ansible
vars:
ansible_ssh_pipelining: yes
tasks:
- name: Check and save database master bin log file and position on mux-ds2.
shell: sudo /usr/bin/mysql mysql -e "show master status \G" | grep -E 'File:|Position:' | cut -d{{':'}} -f2 | awk '{print }'
become: yes
become_method: sudo
register: syncds2
when: ( inventory_hostname == 'mux-ds2' )
- name: Print current ds2 database master bin log file.
debug:
var: "syncds2.stdout_lines[0]"
- name: Print current ds2 database master bin position.
debug:
var: "syncds2.stdout_lines[1]"
- name: Add mux-ds2 some variables to a dummy host allowing us to use these variables on mux-ds1.
add_host:
name: "ds2_bin"
bin_20: "{{ syncds2.stdout_lines }}"
- debug:
var: "{{ hostvars['ds2_bin']['bin_21'] }}"
- name: Compare master bin variable output for ds1's database and if different, configure for it.
shell: sudo /usr/bin/mysql mysql -e "stop slave; change master to master_log_file='"{{ hostvars['ds2_bin']['bin_21'][0] }}"', master_log_pos="{{ hostvars['ds2_bin']['bin_21'][1] }}"; start slave"
become: yes
become_method: sudo
register: syncds1
when: ( inventory_hostname == 'mux-ds1' )
基本上一切正常,直到我尝试使用调试模块从虚拟主机查看变量的值,但它告诉我该变量仍然未定义,即使它已在原始变量中定义。这应该是解决此类问题的系统:
TASK [Print current ds2 database master bin log file.] **************************************************
ok: [mux-ds1] => {
"syncds2.stdout_lines[0]": "VARIABLE IS NOT DEFINED!"
}
ok: [mux-ds2] => {
"syncds2.stdout_lines[0]": "mysql-bin.000001"
}
TASK [Print current ds2 database master bin position.] **************************************************
ok: [mux-ds1] => {
"syncds2.stdout_lines[1]": "VARIABLE IS NOT DEFINED!"
}
ok: [mux-ds2] => {
"syncds2.stdout_lines[1]": "107"
}
上面的工作如我所愿,并且为 mux-ds2
.
正确填充和引用了变量
TASK [Add mux-ds2 some variables to a dummy host allowing us to use these variables on mux-ds1.] ********
fatal: [mux-ds1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stdout_lines'\n\nThe error appears to be in '/home/ansible/ssn-project/playbooks/i_mux-sql-config.yml': line 143, column 8, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Add mux-ds2 some variables to a dummy host allowing us to use these variables on mux-ds1.\n ^ here\n"}
这就是问题所在,变量似乎再次神奇地未定义,考虑到此过程旨在结束 -运行 这个问题,这很奇怪。我什至无法完成第二组调试任务。
请注意,这最终是为了同步两个 master/master 复制 mysql 数据库。我也是用 shell 模块做的,因为必须使用的 mysql 版本不能高于 5.8,而 ansible 模块需要 5.9,这是一个耻辱。 mux-ds2
将以相反的方式完成相同的过程,假设这可以正常工作。
要么我在这个实现中犯了一个错误,导致它无法运行,要么我使用了错误的实现来实现我想要的。我现在花了太多时间试图独自解决这个问题,并且会很感激任何可行的解决方案。提前致谢!
当 simple delegation of tasks and the usage of the special variable hostvars
能够从不同的节点获取事实时,您似乎正在走一条复杂的路线,应该会给您期望的结果。
这是一个例子——只关注重要的部分——所以,你可能想在里面添加 become
和 become_user
:
- shell: >-
sudo /usr/bin/mysql mysql -e "show master status \G"
| grep -E 'File:|Position:'
| cut -d{{':'}} -f2
| awk '{print }'
delegate_to: mux-ds2
run_once: true
register: syncds2
- shell: >-
sudo /usr/bin/mysql mysql -e "stop slave;
change master to
master_log_file='"{{ hostvars['mux-ds2'].syncds2.stdout_lines.0 }}"',
master_log_pos="{{ hostvars['mux-ds2'].syncds2.stdout_lines.1 }}";
start slave"
delegate_to: mux-ds1
run_once: true
这是一个示例,运行 一些虚拟 shell
任务,给定剧本:
- hosts: node1, node2
gather_facts: no
tasks:
- shell: |
echo 'line 0'
echo 'line 1'
delegate_to: node2
run_once: true
register: master_config
- shell: |
echo '{{ hostvars.node2.master_config.stdout_lines.0 }}'
echo '{{ hostvars.node2.master_config.stdout_lines.1 }}'
delegate_to: node1
run_once: true
register: master_replicate_config
- debug:
var: master_replicate_config.stdout_lines
delegate_to: node1
run_once: true
这将产生:
PLAY [node1, node2] **********************************************************
TASK [shell] *****************************************************************
changed: [node1 -> node2(None)]
TASK [shell] *****************************************************************
changed: [node1]
TASK [debug] *****************************************************************
ok: [node1] =>
master_replicate_config.stdout_lines:
- line 0
- line 1
实际上,我有两台服务器,我试图从其中一台的命令中获取使用输出,以配置另一台,反之亦然。我花了几个小时阅读这篇文章,发现 hostvars
进程和虚拟主机似乎是我想要的。无论我如何尝试实施此过程,我仍然会收到未定义的变量,and/or 来自主机的失败不在任务的模式中:
这是相关块,只有主机 mux-ds1
和 mux-ds2
在 dispatchers
组中:
---
- name: Play that sets up the sql database during the build process on all mux dispatchers.
hosts: mux_dispatchers
remote_user: ansible
vars:
ansible_ssh_pipelining: yes
tasks:
- name: Check and save database master bin log file and position on mux-ds2.
shell: sudo /usr/bin/mysql mysql -e "show master status \G" | grep -E 'File:|Position:' | cut -d{{':'}} -f2 | awk '{print }'
become: yes
become_method: sudo
register: syncds2
when: ( inventory_hostname == 'mux-ds2' )
- name: Print current ds2 database master bin log file.
debug:
var: "syncds2.stdout_lines[0]"
- name: Print current ds2 database master bin position.
debug:
var: "syncds2.stdout_lines[1]"
- name: Add mux-ds2 some variables to a dummy host allowing us to use these variables on mux-ds1.
add_host:
name: "ds2_bin"
bin_20: "{{ syncds2.stdout_lines }}"
- debug:
var: "{{ hostvars['ds2_bin']['bin_21'] }}"
- name: Compare master bin variable output for ds1's database and if different, configure for it.
shell: sudo /usr/bin/mysql mysql -e "stop slave; change master to master_log_file='"{{ hostvars['ds2_bin']['bin_21'][0] }}"', master_log_pos="{{ hostvars['ds2_bin']['bin_21'][1] }}"; start slave"
become: yes
become_method: sudo
register: syncds1
when: ( inventory_hostname == 'mux-ds1' )
基本上一切正常,直到我尝试使用调试模块从虚拟主机查看变量的值,但它告诉我该变量仍然未定义,即使它已在原始变量中定义。这应该是解决此类问题的系统:
TASK [Print current ds2 database master bin log file.] **************************************************
ok: [mux-ds1] => {
"syncds2.stdout_lines[0]": "VARIABLE IS NOT DEFINED!"
}
ok: [mux-ds2] => {
"syncds2.stdout_lines[0]": "mysql-bin.000001"
}
TASK [Print current ds2 database master bin position.] **************************************************
ok: [mux-ds1] => {
"syncds2.stdout_lines[1]": "VARIABLE IS NOT DEFINED!"
}
ok: [mux-ds2] => {
"syncds2.stdout_lines[1]": "107"
}
上面的工作如我所愿,并且为 mux-ds2
.
TASK [Add mux-ds2 some variables to a dummy host allowing us to use these variables on mux-ds1.] ********
fatal: [mux-ds1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stdout_lines'\n\nThe error appears to be in '/home/ansible/ssn-project/playbooks/i_mux-sql-config.yml': line 143, column 8, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Add mux-ds2 some variables to a dummy host allowing us to use these variables on mux-ds1.\n ^ here\n"}
这就是问题所在,变量似乎再次神奇地未定义,考虑到此过程旨在结束 -运行 这个问题,这很奇怪。我什至无法完成第二组调试任务。
请注意,这最终是为了同步两个 master/master 复制 mysql 数据库。我也是用 shell 模块做的,因为必须使用的 mysql 版本不能高于 5.8,而 ansible 模块需要 5.9,这是一个耻辱。 mux-ds2
将以相反的方式完成相同的过程,假设这可以正常工作。
要么我在这个实现中犯了一个错误,导致它无法运行,要么我使用了错误的实现来实现我想要的。我现在花了太多时间试图独自解决这个问题,并且会很感激任何可行的解决方案。提前致谢!
当 simple delegation of tasks and the usage of the special variable hostvars
能够从不同的节点获取事实时,您似乎正在走一条复杂的路线,应该会给您期望的结果。
这是一个例子——只关注重要的部分——所以,你可能想在里面添加 become
和 become_user
:
- shell: >-
sudo /usr/bin/mysql mysql -e "show master status \G"
| grep -E 'File:|Position:'
| cut -d{{':'}} -f2
| awk '{print }'
delegate_to: mux-ds2
run_once: true
register: syncds2
- shell: >-
sudo /usr/bin/mysql mysql -e "stop slave;
change master to
master_log_file='"{{ hostvars['mux-ds2'].syncds2.stdout_lines.0 }}"',
master_log_pos="{{ hostvars['mux-ds2'].syncds2.stdout_lines.1 }}";
start slave"
delegate_to: mux-ds1
run_once: true
这是一个示例,运行 一些虚拟 shell
任务,给定剧本:
- hosts: node1, node2
gather_facts: no
tasks:
- shell: |
echo 'line 0'
echo 'line 1'
delegate_to: node2
run_once: true
register: master_config
- shell: |
echo '{{ hostvars.node2.master_config.stdout_lines.0 }}'
echo '{{ hostvars.node2.master_config.stdout_lines.1 }}'
delegate_to: node1
run_once: true
register: master_replicate_config
- debug:
var: master_replicate_config.stdout_lines
delegate_to: node1
run_once: true
这将产生:
PLAY [node1, node2] **********************************************************
TASK [shell] *****************************************************************
changed: [node1 -> node2(None)]
TASK [shell] *****************************************************************
changed: [node1]
TASK [debug] *****************************************************************
ok: [node1] =>
master_replicate_config.stdout_lines:
- line 0
- line 1