ansible系列(20)--ansible的变量详解



1. Ansible Variables

变量提供了便捷的方式来管理 ansible 项目中的动态值。 比如 nginx-1.12 ,可能后期会反复的使用到这个版本的值,那么如果将此值设置为变量,后续使用和修改都将变得非常方便。这样可以简化项目的创建和维护。

变量名:仅能由字母、数字和下划线组成,且只能以字母开头。

1.1 变量定义的方式

Ansible 中定义变量分为如下三种方式:

    1. 通过ansible-playbook命令行传递变量参数定义;
    1. play文件中进行定义变量;
    • 2.1) 通过vars定义变量;
    • 2.2) 通过vars_files定义变量;
    1. 通过inventory在主机组或单个主机中设置变量;
    • 3.1) 通过host_vars对主机进行定义;
    • 3.2) 通过group_vars对主机组进行定义;
    • 3.3) 通过inventory-hosts主机清单文件中定义变量;

1.2 在playbook中定义变量

1.2.1 使用vars方式定义变量

playbook 的文件中开头通过 vars 关键字进行变量定义,格式如下:

vars:
  - var1: value1
  - var2: value2

使用示例如下,定义变量,使用debug模块打印变量:

[root@xuzhichao ansible_var]# cat test1.yml
---
- hosts: 192.168.20.23
  remote_user: root

  vars:
    - web_packages: httpd
    - ftp_packages: vsftpd

  tasks:
    - name: Print Vaiables
      debug:
        msg:
          - "{{ web_packages }}"
          - "{{ ftp_packages }}"

执行结果,打印变量的值:

[root@xuzhichao ansible_var]# ansible-playbook test1.yml 

PLAY [192.168.20.23] *****************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************
ok: [192.168.20.23]

TASK [Print Vaiables] ****************************************************************************************************************************************
ok: [192.168.20.23] => {
    "msg": [
        "httpd",       <==变量的内容
        "vsftpd"       <==变量的内容
    ]
}

PLAY RECAP ***************************************************************************************************************************************************
192.168.20.23              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

1.2.2 使用vars_file方式定义变量

playbook 中使用 vars_files 指定文件作为变量文件,好处就是其他的playbook 也可以调用。

使用示例如下:

  • 编写一个vars_files文件,专门用于存放变量:

    [root@xuzhichao ansible_var]# cat vars.yml 
    web_packages: httpd
    ftp_packages: vsftpd
    
  • 编写playbook文件,调用变量文件:

    [root@xuzhichao ansible_var]# cat test2.yml 
    ---
    - hosts: 192.168.20.23
      remote_user: root
      vars_files: ./vars.yml
    
      tasks:
        - name: Print Vaiables
          debug:
            msg:
              - "{{ web_packages }}"
              - "{{ ftp_packages }}"
    
  • 执行结果,打印变量的值:

    [root@xuzhichao ansible_var]# ansible-playbook test2.yml 
    
    PLAY [192.168.20.23] *****************************************************************************************************************************************
    
    TASK [Gathering Facts] ***************************************************************************************************************************************
    ok: [192.168.20.23]
    
    TASK [Print Vaiables] ****************************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "httpd", 
            "vsftpd"
        ]
    }
    
    PLAY RECAP ***************************************************************************************************************************************************
    192.168.20.23              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    

1.3 针对每个主机定义变量

1.3.1 Inventory文件中定义变量

示例一:分别为每个主机设置不同的主机名:

  • Inventory文件中为每个主机定义变量:

    [root@xuzhichao ansible_var]# cat /etc/ansible/hosts
    [NginxWebs]
    192.168.20.22 hostname=nginx02
    192.168.20.23 hostname=nginx03
    
  • 编写playbook,修改主机名:

    [root@xuzhichao ansible_var]# cat test3.yml 
    ---
    - hosts: NginxWebs
      remote_user: root
    
      tasks:
        - name: Set Hostname
          hostname:
            name: "{{ hostname }}"
            
    [root@xuzhichao ansible_var]# ansible-playbook test3.yml        
    

示例二:设置组公共变量:

  • 编写hosts文件中的变量:

    [root@xuzhichao ansible_var]# cat /etc/ansible/hosts
    [NginxWebs]
    192.168.20.22 myid=1 state=master
    192.168.20.23 myid=2 state=slave
    
    [NginxWebs:vars]
    port=80
    
  • 编写playbook文件:

    [root@xuzhichao ansible_var]# cat test4.yml 
    ---
    - hosts: NginxWebs
      remote_user: root
    
      tasks:
        - name: Print Vaiables
          debug:
            msg: 
              - "{{ myid }}-{{ state }}-{{ port }}"
    
  • 运行playbook文件:

    [root@xuzhichao ansible_var]# ansible-playbook test4.yml
    
    PLAY [NginxWebs] *********************************************************************************************************************************************
    
    TASK [Gathering Facts] ***************************************************************************************************************************************
    ok: [192.168.20.22]
    ok: [192.168.20.23]
    
    TASK [Print Vaiables] ****************************************************************************************************************************************
    ok: [192.168.20.22] => {
        "msg": [
            "1-master-80"   <==显示的内容
        ]
    }
    ok: [192.168.20.23] => {
        "msg": [
            "2-slave-80"    <==显示的内容
        ]
    }
    
    PLAY RECAP ***************************************************************************************************************************************************
    192.168.20.22              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    192.168.20.23              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

1.3.2 使用host_vars定义变量

注意:在host_vars目录中定义的变量,只能给对应的主机使用,没有定义变量的主机不能使用此处的变量。

  • 在项目目录中创建 host_vars 目录,然后在创建一个文件,文件的文件名称要与inventory 清单中的主机名称要保持完全一致,如果是ip地址,则创建相同ip地址的文件即可:

    [root@xuzhichao ansible_var]# cat /etc/ansible/hosts
    [NginxWebs]
    192.168.20.22
    192.168.20.23
    
    [root@xuzhichao ansible_var]# mkdir host_vars
    [root@xuzhichao ansible_var]# cd host_vars/
    
    [root@xuzhichao host_vars]# cat 192.168.20.22 
    web_packages: httpd
    ftp_packages: vsftpd
    
    [root@xuzhichao host_vars]# cat 192.168.20.23
    web_packages: nginx
    ftp_packages: tftp
    
  • 编写palybook文件:

    [root@xuzhichao host_vars]# cat ../test5.yml 
    ---
    - hosts: NginxWebs
      remote_user: root
    
      tasks:
        - name: Print Vaiables
          debug:
            msg:
              - "{{ web_packages }}"
              - "{{ ftp_packages }}"
    
  • 运行playbook文件:

    [root@xuzhichao ansible_var]# ansible-playbook test5.yml 
    
    PLAY [NginxWebs] *********************************************************************************************************************************************
    
    TASK [Gathering Facts] ***************************************************************************************************************************************
    ok: [192.168.20.23]
    ok: [192.168.20.22]
    
    TASK [Print Vaiables] ****************************************************************************************************************************************
    ok: [192.168.20.22] => {
        "msg": [
            "httpd", 
            "vsftpd"
        ]
    }
    ok: [192.168.20.23] => {
        "msg": [
            "nginx", 
            "tftp"
        ]
    }
    
    PLAY RECAP ***************************************************************************************************************************************************
    192.168.20.22              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    192.168.20.23              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

1.3.3 使用group_vars定义变量

  • 在项目目录中创建 group_vars 目录,然后在创建一个文件,文件的文件名称要与inventory 清单中的组名称保持完全一致;

    [root@xuzhichao ansible_var]# cat /etc/ansible/hosts
    [NginxWebs]
    192.168.20.22
    192.168.20.23
    
    [root@xuzhichao ansible_var]# mkdir group_vars
    [root@xuzhichao ansible_var]# cd group_vars
    
    [root@xuzhichao group_vars]# cat NginxWebs
    port: 80
    
  • 编写palybook文件:

    [root@xuzhichao ansible_var]# cat test6.yml 
    ---
    - hosts: NginxWebs
      remote_user: root
    
      tasks:
        - name: Print Vaiables
          debug:
            msg:
              - "{{ port }}"
    
  • 运行playbook文件:

    [root@xuzhichao ansible_var]# ansible-playbook test6.yml 
    
    PLAY [NginxWebs] *********************************************************************************************************************************************
    
    TASK [Gathering Facts] ***************************************************************************************************************************************
    ok: [192.168.20.23]
    ok: [192.168.20.22]
    
    TASK [Print Vaiables] ****************************************************************************************************************************************
    ok: [192.168.20.22] => {
        "msg": [
            80
        ]
    }
    ok: [192.168.20.23] => {
        "msg": [
            80
        ]
    }
    
    PLAY RECAP ***************************************************************************************************************************************************
    192.168.20.22              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    192.168.20.23              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

注意:在group_vars目录中定义的组文件,只能改组中的主机使用,不是该组的主机无法使用此处定义的变量。

在系统中提供了一个特殊的 all 组,也就说在 group_vars 目录下创建一个 all 文件,定义变量对所有的主机组都生效;

[root@xuzhichao ansible_var]# cd group_vars/
[root@xuzhichao group_vars]# cat all
port: 80

1.4 通过执行Playbook传递变量

在执行Playbook时,可以通过命令行 --extra-vars-e 外置传参设定变量;

  • playbook文件如下:

    [root@xuzhichao ansible_var]# cat test5.yml 
    ---
    - hosts: NginxWebs
      remote_user: root
    
      tasks:
        - name: Print Vaiables
          debug:
            msg:
              - "{{ web_packages }}"
              - "{{ ftp_packages }}"
    
  • 执行 playbook 时进行变量的传递:

    [root@xuzhichao ansible_var]# ansible-playbook -e "web_packages=tomcat" -e "ftp_packages=sftp" test5.yml
    
    PLAY [NginxWebs] *********************************************************************************************************************************************
    
    TASK [Gathering Facts] ***************************************************************************************************************************************
    ok: [192.168.20.23]
    ok: [192.168.20.22]
    
    TASK [Print Vaiables] ****************************************************************************************************************************************
    ok: [192.168.20.22] => {
        "msg": [
            "tomcat", 
            "sftp"
        ]
    }
    ok: [192.168.20.23] => {
        "msg": [
            "tomcat", 
            "sftp"
        ]
    }
    
    PLAY RECAP ***************************************************************************************************************************************************
    192.168.20.22              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    192.168.20.23              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

1.5 变量定义的优先级

1.5.1 编写测试环境

定义相同的变量不同的值,来测试变量的优先级。操作步骤如下:

  • plabook中定义vars变量:

    [root@xuzhichao ansible_var]# cat test.yml 
    ---
    - hosts: 192.168.20.23
      remote_user: root
      
      vars:
        - test_var: "playbook var"
    
      vars_files: ./vars.yml
    
      tasks:
        - name: Print Vaiables
          debug:
            msg:
              - "{{ test_var }}"
    
  • playbook中定义vars_files变量:

    [root@xuzhichao ansible_var]# cat vars.yml
    test_var: vars_files
    
  • host_vars中定义变量:

    [root@xuzhichao ansible_var]# cat host_vars/192.168.20.23
    test_var: host_vars
    
  • group_vars中定义变量:

    [root@xuzhichao ansible_var]# cat group_vars/NginxWebs 
    test_var: groups_vars
    
  • group_vars目录中的all文件中定义变量:

    [root@xuzhichao ansible_var]# cat group_vars/all
    test_var: all_file_var
    
  • inventory中定义主机变量和主机组变量:

    [root@xuzhichao ansible_var]# cat /etc/ansible/hosts
    [NginxWebs]
    192.168.20.22 test_var=inventory_host_var  
    192.168.20.23 test_var=inventory_host_var
    
    [NginxWebs:vars]
    test_var=inventory_group_var
    
  • 通过执行命令传递变量:

    ansible-playbook -e "test_var=ansible-playbook_var" test.yml
    

1.5.2 测试变量的优先级

测试思路:运行playbook文件,当前显示的就是优先级最高的,然后把优先级最高的变量删除,再依次向下测试。

  1. 最优先的为命令行传递的参数:

    [root@xuzhichao ansible_var]# ansible-playbook -e "test_var=ansible-playbook_var" test.yml 
    
    TASK [Print Vaiables] **************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "ansible-playbook_var"
        ]
    }
    
  2. 然后是在playbook中定义的vars_files变量:

    [root@xuzhichao ansible_var]# ansible-playbook test.yml 
    
    TASK [Print Vaiables] **************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "vars_files"
        ]
    }
    
  3. 然后是在plabook中定义的vars变量:

    #删除playbook中的vars_files: ./vars.yml行再进行测试:
    [root@xuzhichao ansible_var]# ansible-playbook test.yml 
    
    TASK [Print Vaiables] **************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "playbook var"
        ]
    }
    
  4. 然后是在host_vars中定义的变量

    #删除playbook中的vars:行再进行测试:
    [root@xuzhichao ansible_var]# ansible-playbook test.yml 
    
    TASK [Print Vaiables] *************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "host_vars"
        ]
    }
    
  5. 然后是在inventory中定义的主机变量:

    #删除host_vars/192.168.20.23文件,再进行测试:
    root@xuzhichao ansible_var]# ansible-playbook test.yml 
    
    TASK [Print Vaiables] *************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "inventory_host_var"
        ]
    }
    
  6. 然后是在group_vars中定义的组变量:

    #删除/etc/ansible/hosts中192.168.20.23的主机变量,再进行测试:
    [root@xuzhichao ansible_var]# ansible-playbook test.yml 
    
    TASK [Print Vaiables] *************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "groups_vars"
        ]
    }
    
  7. 然后是在group_vars中定义的all文件中的变量:

    #删除group_vars/NginxWebs文件,再进行测试:
    [root@xuzhichao ansible_var]# ansible-playbook test.yml 
    
    TASK [Print Vaiables] *************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "all_file_var"
        ]
    }
    
  8. 然后是在inventory中定义的主机组变量:

    #删除group_vars/all文件,再进行测试:
    [root@xuzhichao ansible_var]# ansible-playbook test.yml 
    
    TASK [Print Vaiables] *************************************************************************************************************************
    ok: [192.168.20.23] => {
        "msg": [
            "inventory_group_var"
        ]
    }
    

1.5.3 变量优先级总结

变量的优先级从高到低依次为:

  1. 命令行传递的变量;
  2. playbook中定义的vars_files
  3. playbook中定义的vars
  4. host_vars中定义的变量;
  5. inventory中定义的主机变量;
  6. group_vars中定义的组变量:group_vars/group_name
  7. group_vars中定义的all文件中的变量:group_vars/all
  8. inventory中定义的主机组变量;
posted @ 2021-08-18 17:18  向往自由的独行者  阅读(394)  评论(0编辑  收藏  举报