首页 文章

如何在另一个任务中将一个任务的返回值用于ansible中的另一个主机

提问于
浏览
0

我正在尝试使用ansible为包含2个mysql主机的主机组设置mysql主从复制 .

这是我的场景:

我在第一个主机中运行一个任务并跳过第二个主机,因此第一个任务(即主复制状态)返回一些值,如位置,文件等 .

然后,我在第二个主机上运行另一个任务(跳过第一个主机),此任务使用第一个任务的返回值,如master.Position,master.File等 .

现在,当我运行playbook时,第一个任务的变量似乎不适用于第二个任务

Inventory 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

Tasks on Master

- name: Mysql - Check master replication status.
  mysql_replication: mode=getmaster
  register: master

- debug: var=master

Tasks on 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

Master Output

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
    }
}

Slave Output

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

正如您所见,由于未定义的变量,第二个主机的第二个任务失败 . 但是,第一个主机的第一个任务中存在所需的变量 .

如何在另一个任务中使用第二个主机中第一个主机返回的变量?

P.S:我已经看到了使用{{hostvars ['inventory_hostname'] ['variable']}}的方法 . 但是我对这种方法很困惑,因为需要直接添加inventory_hostname或IP地址 . 我一直在寻找一个可用于不同库存文件和剧本的通用模板 .

1 回答

  • 2

    我能够通过将变量定义为新的 dummy host 然后在整个playbook中使用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 ['master_value_holder'] ['master_log_file']访问变量

    Tasks on 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 }}"
    

    Tasks for Slave

    - 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
    

    Output

    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]
    

    从上面的输出中可以看出,主复制状态现在可用于两个主机 .

相关问题