首页 > 解决方案 > Ansible:从结果中获取值

问题描述

我无法从 ansible 获取变量。我可能会误解这一切,但是;

我有一个游戏,创建 3 个 mysql 实例,我想从 mysql 日志中的临时通道中设置新的根通道。

我可以用一个实例来做到这一点,但是当我尝试遍历我的 3 个实例时,它会杀了我。

表演:




   - name: "Percona new install password retrieval"
     block:
   - name: Parse temporary password from mysql log
     become: yes
     shell: "cat /var/log/mysql-instance{{ item }}/error.log | sed -n 's/.*temporary password is generated for root@localhost: //p'"
     register: temppass
     with_sequence: start=1 end=3
     tags: hest888

   - debug: var=temppass.results
     tags: hest888

这将获取临时密码并存储在变量 temppass 中。temppass.results 显示:

  ok: [X-sql08] => {
      "temppass.results": [
          {
              "_ansible_ignore_errors": null,
              "_ansible_item_label": "1",
              "_ansible_item_result": true,
              "_ansible_no_log": false,
              "_ansible_parsed": true,
              "changed": true,
              "cmd": "grep 'A temporary password is generated for root@localhost' /var/log/mysql-instance1/error.log | awk -F ' ' '{print $(NF)}'",
              "delta": "0:00:00.004820",
              "end": "2020-01-21 16:37:54.164040",
              "failed": false,
              "invocation": {
                  "module_args": {
                      "_raw_params": "grep 'A temporary password is generated for root@localhost' /var/log/mysql-instance1/error.log | awk -F ' ' '{print $(NF)}'",
                      "_uses_shell": true,
                      "argv": null,
                      "chdir": null,
                      "creates": null,
                      "executable": null,
                      "removes": null,
                      "stdin": null,
                      "warn": true
                }
            },
            "item": "1",
            "rc": 0,
            "start": "2020-01-21 16:37:54.159220",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "(7FJWDd8uEfs",
            "stdout_lines": [
                "(7FJWDd8uEfs"
            ]
        },
        {
            "_ansible_ignore_errors": null,
            "_ansible_item_label": "2",
            "_ansible_item_result": true,
            "_ansible_no_log": false,
            "_ansible_parsed": true,
            "changed": true,
            "cmd": "grep 'A temporary password is generated for root@localhost' /var/log/mysql-instance2/error.log | awk -F ' ' '{print $(NF)}'",
            "delta": "0:00:00.004983",
            "end": "2020-01-21 16:37:54.621576",
            "failed": false,
            "invocation": {
                "module_args": {
                    "_raw_params": "grep 'A temporary password is generated for root@localhost' /var/log/mysql-instance2/error.log | awk -F ' ' '{print $(NF)}'",
                    "_uses_shell": true,
                    "argv": null,
                    "chdir": null,
                    "creates": null,
                    "executable": null,
                    "removes": null,
                    "stdin": null,
                    "warn": true
                }
            },
            "item": "2",
            "rc": 0,
            "start": "2020-01-21 16:37:54.616593",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "mwY9h1y17r+D",
            "stdout_lines": [
                "mwY9h1y17r+D"
            ]
        },
        {
            "_ansible_ignore_errors": null,
            "_ansible_item_label": "3",
            "_ansible_item_result": true,
            "_ansible_no_log": false,
            "_ansible_parsed": true,
            "changed": true,
            "cmd": "grep 'A temporary password is generated for root@localhost' /var/log/mysql-instance3/error.log | awk -F ' ' '{print $(NF)}'",
            "delta": "0:00:00.004704",
            "end": "2020-01-21 16:37:55.073540",
            "failed": false,
            "invocation": {
                "module_args": {
                    "_raw_params": "grep 'A temporary password is generated for root@localhost' /var/log/mysql-instance3/error.log | awk -F ' ' '{print $(NF)}'",
                    "_uses_shell": true,
                    "argv": null,
                    "chdir": null,
                    "creates": null,
                    "executable": null,
                    "removes": null,
                    "stdin": null,
                    "warn": true
                  }
              },
              "item": "3",
              "rc": 0,
              "start": "2020-01-21 16:37:55.068836",
              "stderr": "",
              "stderr_lines": [],
              "stdout": "GZ!xq=ard9mz",
              "stdout_lines": [
                  "GZ!xq=ard9mz"
              ]
          }
      ]
    }


好的......所以 temppass.results 有我需要的所有信息,但我似乎无法得到它?

我想做的(在完美的世界中完全符合我的每一个心血来潮)是从 temppass.results 中获取“item”和“stdout”结果并将它们用作更新密码部分的输入。

   - name: Set root password using temp password to log in
     shell: 'mysql -e --protocol=TCP -P {{ item.port }}"ALTER USER ''root''@''localhost'' \
             IDENTIFIED WITH mysql_native_password AS ''{{ mysql_root_hash }}'';" \
             --connect-expired-password -uroot -p"{{ temppass_{{ item.instance }}.stdout }}"'
     with_items:
       - { instance: 1, port: 3306 }
       - { instance: 2, port: 3307 }
       - { instance: 3, port: 3308 }
     tags: hest888

或那种性质的东西。

我发现 double {{ 中的 double {{ 不起作用,但希望您了解我正在尝试做什么。

有任何想法吗 ?

标签: mysqlansiblenested-loopsansible-template

解决方案


下面是一个采用稍微不同的方法的答案,您不需要根据其索引在结果中选择元素。如果您仍想了解如何编写表达式以针对此类元素,您可以查看其他答案,其中有解释。


  1. 在你的剧本中创建一个 var 来保存你的 mysql 实例数据(而不是在你的最后一个任务循环中硬编码它,我们将重用它)
    mysql_instances:
      - instance: 1
        port: 3306
      - instance: 2
        port: 3307
      - instance: 3
        port: 3308
    
  2. 使用该 var 而不是 range 来遍历您的日志文件。请注意,当您调试结果时,item每个结果中的字段现在报告为正在循环的当前项(即 mysql 实例定义)

    - name: Parse temporary password from mysql log
      become: yes
      shell: "cat /var/log/mysql-instance{{ item.instance }}/error.log | sed -n 's/.*temporary password is generated for root@localhost: //p'"
      register: temppass
      loop: "{{ mysql_instances }}"
    
  3. 您现在拥有每个所需的所有信息temppass.results(捕获的密码、实例编号和端口)。你只需要循环它来设置你的密码。(注意:我保留了您的示例,但您可能想查看mysql_user模块而不是使用 shell)

    - name: Set root password using temp password to log in
      shell: 'mysql -e --protocol=TCP -P {{ item.item.port }}"ALTER USER ''root''@''localhost'' \
             IDENTIFIED WITH mysql_native_password AS ''{{ mysql_root_hash }}'';" \
             --connect-expired-password -uroot -p"{{ item.stdout }}"'
     loop: "{{ temppass.results }}"
    

推荐阅读