ansible变量注册多种方式

使用过ansible的同学都知道,注册变量并使用,是一个很常见的场景。今天就总结下常见的一些情况,了解ansible变量定义、引用及格式化相关内容。

目录

  • 1.使用register注册变量
    • 1.1 执行一条命令并把返回结果注册为变量
    • 1.2 列表遍历的结果注册为变量
  • 2.使用set_fact注册变量
    • 2.1 使用set_fact注册一个普通变量
    • 2.2 使用set_fact给list变量循环添加元素

1.使用register注册变量

当playbook运行的时候,经常需要中途收集一些数据,后面使用它。使用register注册变量是最简单、最常用的一种方式。

1.1 执行一条命令并把返回结果注册为变量

我们最常用的是,执行一条shell命令,并将返回结果注册为一个变量,例如:

 tasks:
    - name: define a var1
      shell: "whoami"
      register: whoami

    - debug:
        msg: "whoami: {{ whoami }}"
    
    - debug:
        msg: "whoami.stdout: {{whoami.stdout}}"

这里要注意,ansible执行结果一般都会返回一个字典类型的数据,你会看到很多你不关心的字段,可以通过指定字典的key,例如stdout或stdout_lines,只看到你关心的数据。

请看返回结果:

TASK [define a var1] ************************************************************************************************************************************************************************
changed: [vagrant1]

TASK [debug] ********************************************************************************************************************************************************************************
ok: [vagrant1] => {
    "msg": "whoami: {'stderr_lines': [], u'changed': True, u'end': u'2020-04-19 15:18:18.278098', 'failed': False, u'stdout': u'vagrant', u'cmd': u'whoami', u'rc': 0, u'start': u'2020-04-19 15:18:18.274052', u'stderr': u'', u'delta': u'0:00:00.004046', 'stdout_lines': [u'vagrant']}"
}

TASK [debug] ********************************************************************************************************************************************************************************
ok: [vagrant1] => {
    "msg": "whoami.stdout: vagrant"
}

1.2 列表遍历的结果注册为变量

这种场景,一般是列表中的元素逐个要参与运算,将运算后的结果存入一个变量,看一个示例:

---

- hosts: "{{ hosts_group }}"
  remote_user: vagrant
  vars:
    userss: []

  tasks:
    - name: define users in a loop
      shell: "grep {{ item }} /etc/passwd|cat"
      register: users
      with_items:
        - vagrant
        - root
        - nginx
    
    - name: show users
      debug:
        msg: "{{ users }}"

    - name: show users.results
      debug:
        msg: "{{ users.results }}"

    - name: define userss by set_fact
      set_fact: 
        userss: "{{userss +item.stdout_lines}}"
      with_list: "{{ users.results }}"

    - name: print userss
      debug:
        msg: "{{ userss }}"
    
    - name: print userss one by one
      debug:
        msg: "{{ item }}"
      with_list: "{{ userss}}"

    - name: print part of userss one by one
      debug:
        msg: "{{ item.split(':')[6] }}"
      with_list: "{{ userss}}"

该示例是通过关键字是查询系统的用户及shell信息,ansible会返回一个字典,查询的结果存储在字典名称为results的key对应的value中,这个value本身是一个list。因为我们都不知道到底会查到几个用户,所以再把结果list遍历一遍,存储到另外一个变量中。我们使用set_fact实现了循环给空list变量添加数据的效果。最后,我们分别获取每行的数据,并且进行拆分,获取到了第7个字段。

请看返回结果:

TASK [define users in a loop] ***************************************************************************************************************************************************************
changed: [vagrant1] => (item=vagrant)
changed: [vagrant1] => (item=root)
changed: [vagrant1] => (item=nginx)

TASK [show users] ***************************************************************************************************************************************************************************
ok: [vagrant1] => {
    "msg": {
        "changed": true, 
        "msg": "All items completed", 
        "results": [
            {
                "_ansible_ignore_errors": null, 
                "_ansible_item_label": "vagrant", 
                "_ansible_item_result": true, 
                "_ansible_no_log": false, 
                "_ansible_parsed": true, 
                "changed": true, 
                "cmd": "grep vagrant /etc/passwd|cat", 
                "delta": "0:00:00.004695", 
                "end": "2020-04-19 15:18:19.129083", 
                "failed": false, 
                "invocation": {
                    "module_args": {
                        "_raw_params": "grep vagrant /etc/passwd|cat", 
                        "_uses_shell": true, 
                        "argv": null, 
                        "chdir": null, 
                        "creates": null, 
                        "executable": null, 
                        "removes": null, 
                        "stdin": null, 
                        "warn": true
                    }
                }, 
                "item": "vagrant", 
                "rc": 0, 
                "start": "2020-04-19 15:18:19.124388", 
                "stderr": "", 
                "stderr_lines": [], 
                "stdout": "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash", 
                "stdout_lines": [
                    "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash"
                ]
            }, 
            {
                "_ansible_ignore_errors": null, 
                "_ansible_item_label": "root", 
                "_ansible_item_result": true, 
                "_ansible_no_log": false, 
                "_ansible_parsed": true, 
                "changed": true, 
                "cmd": "grep root /etc/passwd|cat", 
                "delta": "0:00:00.004695", 
                "end": "2020-04-19 15:18:19.421598", 
                "failed": false, 
                "invocation": {
                    "module_args": {
                        "_raw_params": "grep root /etc/passwd|cat", 
                        "_uses_shell": true, 
                        "argv": null, 
                        "chdir": null, 
                        "creates": null, 
                        "executable": null, 
                        "removes": null, 
                        "stdin": null, 
                        "warn": true
                    }
                }, 
                "item": "root", 
                "rc": 0, 
                "start": "2020-04-19 15:18:19.416903", 
                "stderr": "", 
                "stderr_lines": [], 
                "stdout": "root:x:0:0:root:/root:/bin/bash\noperator:x:11:0:operator:/root:/sbin/nologin", 
                "stdout_lines": [
                    "root:x:0:0:root:/root:/bin/bash", 
                    "operator:x:11:0:operator:/root:/sbin/nologin"
                ]
            }, 
            {
                "_ansible_ignore_errors": null, 
                "_ansible_item_label": "nginx", 
                "_ansible_item_result": true, 
                "_ansible_no_log": false, 
                "_ansible_parsed": true, 
                "changed": true, 
                "cmd": "grep nginx /etc/passwd|cat", 
                "delta": "0:00:00.004500", 
                "end": "2020-04-19 15:18:19.714496", 
                "failed": false, 
                "invocation": {
                    "module_args": {
                        "_raw_params": "grep nginx /etc/passwd|cat", 
                        "_uses_shell": true, 
                        "argv": null, 
                        "chdir": null, 
                        "creates": null, 
                        "executable": null, 
                        "removes": null, 
                        "stdin": null, 
                        "warn": true
                    }
                }, 
                "item": "nginx", 
                "rc": 0, 
                "start": "2020-04-19 15:18:19.709996", 
                "stderr": "", 
                "stderr_lines": [], 
                "stdout": "", 
                "stdout_lines": []
            }
        ]
    }
}

TASK [show users.results] *******************************************************************************************************************************************************************
ok: [vagrant1] => {
    "msg": [
        {
            "_ansible_ignore_errors": null, 
            "_ansible_item_label": "vagrant", 
            "_ansible_item_result": true, 
            "_ansible_no_log": false, 
            "_ansible_parsed": true, 
            "changed": true, 
            "cmd": "grep vagrant /etc/passwd|cat", 
            "delta": "0:00:00.004695", 
            "end": "2020-04-19 15:18:19.129083", 
            "failed": false, 
            "invocation": {
                "module_args": {
                    "_raw_params": "grep vagrant /etc/passwd|cat", 
                    "_uses_shell": true, 
                    "argv": null, 
                    "chdir": null, 
                    "creates": null, 
                    "executable": null, 
                    "removes": null, 
                    "stdin": null, 
                    "warn": true
                }
            }, 
            "item": "vagrant", 
            "rc": 0, 
            "start": "2020-04-19 15:18:19.124388", 
            "stderr": "", 
            "stderr_lines": [], 
            "stdout": "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash", 
            "stdout_lines": [
                "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash"
            ]
        }, 
        {
            "_ansible_ignore_errors": null, 
            "_ansible_item_label": "root", 
            "_ansible_item_result": true, 
            "_ansible_no_log": false, 
            "_ansible_parsed": true, 
            "changed": true, 
            "cmd": "grep root /etc/passwd|cat", 
            "delta": "0:00:00.004695", 
            "end": "2020-04-19 15:18:19.421598", 
            "failed": false, 
            "invocation": {
                "module_args": {
                    "_raw_params": "grep root /etc/passwd|cat", 
                    "_uses_shell": true, 
                    "argv": null, 
                    "chdir": null, 
                    "creates": null, 
                    "executable": null, 
                    "removes": null, 
                    "stdin": null, 
                    "warn": true
                }
            }, 
            "item": "root", 
            "rc": 0, 
            "start": "2020-04-19 15:18:19.416903", 
            "stderr": "", 
            "stderr_lines": [], 
            "stdout": "root:x:0:0:root:/root:/bin/bash\noperator:x:11:0:operator:/root:/sbin/nologin", 
            "stdout_lines": [
                "root:x:0:0:root:/root:/bin/bash", 
                "operator:x:11:0:operator:/root:/sbin/nologin"
            ]
        }, 
        {
            "_ansible_ignore_errors": null, 
            "_ansible_item_label": "nginx", 
            "_ansible_item_result": true, 
            "_ansible_no_log": false, 
            "_ansible_parsed": true, 
            "changed": true, 
            "cmd": "grep nginx /etc/passwd|cat", 
            "delta": "0:00:00.004500", 
            "end": "2020-04-19 15:18:19.714496", 
            "failed": false, 
            "invocation": {
                "module_args": {
                    "_raw_params": "grep nginx /etc/passwd|cat", 
                    "_uses_shell": true, 
                    "argv": null, 
                    "chdir": null, 
                    "creates": null, 
                    "executable": null, 
                    "removes": null, 
                    "stdin": null, 
                    "warn": true
                }
            }, 
            "item": "nginx", 
            "rc": 0, 
            "start": "2020-04-19 15:18:19.709996", 
            "stderr": "", 
            "stderr_lines": [], 
            "stdout": "", 
            "stdout_lines": []
        }
    ]
}

TASK [define userss by set_fact] ************************************************************************************************************************************************************
ok: [vagrant1] => (item={'_ansible_parsed': True, 'stderr_lines': [], '_ansible_item_result': True, u'end': u'2020-04-19 15:18:19.129083', '_ansible_no_log': False, u'stdout': u'vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash', u'cmd': u'grep vagrant /etc/passwd|cat', u'rc': 0, 'item': u'vagrant', u'delta': u'0:00:00.004695', '_ansible_item_label': u'vagrant', u'stderr': u'', u'changed': True, u'invocation': {u'module_args': {u'warn': True, u'executable': None, u'_uses_shell': True, u'_raw_params': u'grep vagrant /etc/passwd|cat', u'removes': None, u'argv': None, u'creates': None, u'chdir': None, u'stdin': None}}, 'stdout_lines': [u'vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash'], u'start': u'2020-04-19 15:18:19.124388', '_ansible_ignore_errors': None, 'failed': False})
ok: [vagrant1] => (item={'_ansible_parsed': True, 'stderr_lines': [], '_ansible_item_result': True, u'end': u'2020-04-19 15:18:19.421598', '_ansible_no_log': False, u'stdout': u'root:x:0:0:root:/root:/bin/bash\noperator:x:11:0:operator:/root:/sbin/nologin', u'cmd': u'grep root /etc/passwd|cat', u'rc': 0, 'item': u'root', u'delta': u'0:00:00.004695', '_ansible_item_label': u'root', u'stderr': u'', u'changed': True, u'invocation': {u'module_args': {u'warn': True, u'executable': None, u'_uses_shell': True, u'_raw_params': u'grep root /etc/passwd|cat', u'removes': None, u'argv': None, u'creates': None, u'chdir': None, u'stdin': None}}, 'stdout_lines': [u'root:x:0:0:root:/root:/bin/bash', u'operator:x:11:0:operator:/root:/sbin/nologin'], u'start': u'2020-04-19 15:18:19.416903', '_ansible_ignore_errors': None, 'failed': False})
ok: [vagrant1] => (item={'_ansible_parsed': True, 'stderr_lines': [], '_ansible_item_result': True, u'end': u'2020-04-19 15:18:19.714496', '_ansible_no_log': False, u'stdout': u'', u'cmd': u'grep nginx /etc/passwd|cat', u'rc': 0, 'item': u'nginx', u'delta': u'0:00:00.004500', '_ansible_item_label': u'nginx', u'stderr': u'', u'changed': True, u'invocation': {u'module_args': {u'warn': True, u'executable': None, u'_uses_shell': True, u'_raw_params': u'grep nginx /etc/passwd|cat', u'removes': None, u'argv': None, u'creates': None, u'chdir': None, u'stdin': None}}, 'stdout_lines': [], u'start': u'2020-04-19 15:18:19.709996', '_ansible_ignore_errors': None, 'failed': False})

TASK [print userss] *************************************************************************************************************************************************************************
ok: [vagrant1] => {
    "msg": [
        "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash", 
        "root:x:0:0:root:/root:/bin/bash", 
        "operator:x:11:0:operator:/root:/sbin/nologin"
    ]
}

TASK [print userss one by one] **************************************************************************************************************************************************************
ok: [vagrant1] => (item=vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash) => {
    "msg": "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash"
}
ok: [vagrant1] => (item=root:x:0:0:root:/root:/bin/bash) => {
    "msg": "root:x:0:0:root:/root:/bin/bash"
}
ok: [vagrant1] => (item=operator:x:11:0:operator:/root:/sbin/nologin) => {
    "msg": "operator:x:11:0:operator:/root:/sbin/nologin"
}

TASK [print part of userss one by one] ******************************************************************************************************************************************************
ok: [vagrant1] => (item=vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash) => {
    "msg": "/bin/bash"
}
ok: [vagrant1] => (item=root:x:0:0:root:/root:/bin/bash) => {
    "msg": "/bin/bash"
}
ok: [vagrant1] => (item=operator:x:11:0:operator:/root:/sbin/nologin) => {
    "msg": "/sbin/nologin"
}

2.使用set_fact注册变量

其实上个示例,已经提到了set_fact,因为set_fact配合register可以实现一些重要和灵活的功能。

2.1 使用set_fact注册一个普通变量

tasks:
    - name: define a var1
      shell: "whoami"
      register: whoami

    - debug:
        msg: "whoami: {{ whoami }}"
    
    - debug:
        msg: "whoami.stdout: {{whoami.stdout}}"
    
    - name: define a var by set_fact
      set_fact:
         whoami: "{{ whoami.stdout  }}"
     
    - name:  show a var after defined by set_fact
      debug:
         msg: "{{ whoami }}" 

使用这种方式,会简化变量的调用。

2.2 使用set_fact给list变量循环添加元素

这个功能只有通过set_fact可以显示,在好多场景都会用到,尤其是你不知道自己注册的变量有多少个元素,而且配合register可以大大简化变量的后续调用和重新格式化。其实示例1.2的示例代码已经用了这种方式:

  vars:
    userss: []

- name: define userss by set_fact
      set_fact: 
        userss: "{{userss +item.stdout_lines}}"
      with_list: "{{ users.results }}"

    - name: print userss
      debug:
        msg: "{{ userss }}"
    
    - name: print userss one by one
      debug:
        msg: "{{ item }}"
      with_list: "{{ userss}}"

    - name: print part of userss one by one
      debug:
        msg: "{{ item.split(':')[6] }}"
      with_list: "{{ userss}}"

尤其要注意,循环给list变量添加元素的时候,这个变量要已经定义过了,才可以循环添加元素。最后print part的时候,在ansible中调用了python的字符串拆分函数,对遍历到的每行元素进行拆分,获取我们最需要的字段。 先组合字符串,再拆分字符串,会简化整体playbook,避免使用难以理解容易出错的嵌套循环。

完整的示例,可以看这里: https://github.com/byygyy/ansible-best-practice/blob/master/test-vars-define.yml

你可能感兴趣的:(ansible)