今日内容Ansible Playbook变量解析

# 1.变量概述

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

定义变量分为如下的三种方式

(1)通过命令行进行定义变量

(2)在play文件中进行定义变量

(3)通过inventory在主机组或单个主机中设置变量

如果定义的变量出现重复,且造成冲突,优先级如下:

1.命令行定义的变量高于->play文件定义的变量->高于->inventory文件定义的变量

# 2.变量的定义

2.1playbook 变量可以通过多种方式进行定义,最简单的方式就是在playbook的开头通过vars进行定义变量

```HTML
#安装两个软件包使用变量方式

[root@manager ansible_lianxi-5.18]# cat var1.yml 
- hosts: webservers
  vars:
    - web_packages: httpd
    - ftp_packages: vsftpd
  tasks: 
    - name: installed rpm packages "{{web_packages}}" "{{ftp_packages}}"
      yum:
        name: 
          - "{{web_packages}}"
          - "{{ftp_packages}}"
        state: present```

2.2也可以在playbook中使用vars_file指定的文件作为变量文件,好处其他的playbook也可以调用变量

```HTML
[root@manager ansible_lianxi-5.18]# cat test.yml 
web_packages: httpd
ftp_packages: vsftpd
[root@manager ansible_lianxi-5.18]# cat var2.yml 
- hosts: webservers
  vars_files: test.yml  tasks:
    - name: install rpm packages "{{web_packages}}" "{{ftp_packages}}"
      yum:
        name:
          - "{{web_packages}}"
          - "{{ftp_packages}}"
        state: present
```

2.3在inventory中定义变量,主机变量优先级高于主机组变量(不推荐使用)

```HTML
[root@manager ansible_lianxi-5.18]# cat hosts 
[webservers]172.16.1.7
172.16.1.8
[webservers:vars]
filename=group_vars
[db]
172.16.1.51
[lb]
172.16.1.5
[root@manager ansible_lianxi-5.18]# cat p3.yml 
- hosts: webservers
  tasks:
    - name: create file "{{filename}}"
      file:
        path: /tmp/{{filename}}
        state: touch
```

2.4.更好的方式是在ansible的项目目录中创建额外的两个变量目录,分别是host_vars和group_vars

```HTML
[root@manager ansible_lianxi-5.18]# mkdir host_vars
[root@manager ansible_lianxi-5.18]# mkdir group_vars
[root@manager ansible_lianxi-5.18]# cat group_vars/webservers 
web_packages: wget
ftp_packages: tree
[root@manager ansible_lianxi-5.18]# cat var4.yml 
- hosts: webservers
  tasks:
    - name: install rpm packages "{{web_packages}}" "{{ftp_packages}}" 
      yum: 
        name: 
          - "{{web_packages}}"
          - "{{ftp_packages}}"
        state: present


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

[root@manager ansible_lianxi-5.18]# cat group_vars/all 
web_packages: nfs-utils
ftp_packages: rsync
[root@manager ansible_lianxi-5.18]# cat var5.yml 
- hosts: db
  tasks:
    - name: install rpm packages "{{web_packages}}" "{{ftp_packages}}"
      yum:
        name:
          - "{{web_packages}}"
          - "{{ftp_packages}}"
        state: present```

2.5通过命令的方式进行定义变量

```HTML
[root@manager ansible_variables]# cat var6.yml
- hosts: webservers
  tasks:
    - name: Install Rpm Packages "{{ test_packages }}"
      yum:
        name:
          - "{{ test_packages }}"
        state: present[root@manager ansible_variables]# ansible-playbook var6.yml -e "test_packages=sl"
```

2.6变量优先级测试

命令行变量--play中的vars_files---play中的vars变量---host_vars中定义的变量--group_vars/组名---group_vars/all

```HTML
设定同一个变量,不同的值,去测试,看谁优先被使用。
1)在plabook中定义vars变量
2)在playbook中定义vars_files变量
3)在host_vars中定义变量
4)在group_vars中定义变量
5)通过执行命令传递变量
变量的查找优先级:
1.外置传参 -e
2.playbook
vars_files
vars
3.host_vars
4.group_vars/组名
4.group_vars/all
```

2.7 案例演示nfs服务端和nfs客户端

```HTML
[root@manager ansible_lianxi-5.18]# cat group_vars/all 
share_dir: /data4
[root@manager ansible_lianxi-5.18]# cat exports.j2 
{{share_dir}} 172.16.1.0/24(rw,all_squash,anonuid=666,anongid=666)
[root@manager ansible_lianxi-5.18]# cat var8.yml 
- hosts: webservers
  tasks:
    - name: installed nfs server
      yum:
        name: nfs-utils
    - name: configure nfs server
      template:
        src: ./exports.j2
        dest: /etc/exports
      notify: restart nfs server
    - name: create share directory
      file:
        path: "{{share_dir}}"
        state: directory
        owner: www
        group: www
        mode: 755
    - name: started nfs server
      systemd:
        name: nfs
        state: started
        enabled: yes
  handlers:
    - name: restart nfs server
      systemd:
        name: nfs
        state: restarted
- hosts: db
  tasks:
    - name: client mount nfs server
      mount:
        src: 172.16.1.7:{{share_dir}}
        path: /ansible_mont
        fstype: nfs
        state: mounted[root@db01 ~]#


文件系统 容量 已用 可用 已用% 挂载点

/dev/mapper/centos-root   17G  2.3G   15G   14% /
devtmpfs                 475M     0  475M    0% /dev
tmpfs                    487M     0  487M    0% /dev/shm
tmpfs                    487M  7.7M  479M    2% /run
tmpfs                    487M     0  487M    0% /sys/fs/cgroup
/dev/sda1               1014M  133M  882M   14% /boot
tmpfs                     98M     0   98M    0% /run/user/0
172.16.1.7:/data4         17G  2.8G   15G   17% /ansible_mont
```

2.8register变量注册,将执行的结果存储至变量中,后期可以通过结果进行判断的操作。

```HTML
[root@manager ansible_lianxi-5.18]# cat var9.yml 
- hosts: webservers
  tasks:
    - name: Get Network Status
      shell: netstat -lntp
      register: System_Net
      #将shell命令的执行输出结果,存储至System_Net变量中
    - name: Print Variables
      debug:
        msg: "{{ System_Net.stdout_lines }}"
```

2.9 facts变量

Ansible facts是在被管理主机上通过ansible自动采集发现的变量。facts包含每台特定的主机信息。比如:被控端主机的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。
facts使用场景
1.通过facts检查CPU,来生成对应的Nginx配置文件
2.通过facts检查主机名信息,来生成不同的Zabbix配置文件
3.通过fact检索的内存情况来自定义mysql的配置文件

1.facts基本用法,比如获取被控端的主机名与IP地址

```HTML
[root@manager ansible_lianxi-5.18]# cat var10.yml
- hosts: webservers
  tasks:
    - name: Output variables ansible facts
      debug:
        msg: >
          this default IPv4 address "{{ ansible_fqdn}}" is "{{ ansible_default_ipv4.address}}"
```

2.10 实战一、根据IP地址生成不同的Redis配置

```HTML
[root@manager ansible_lianxi-5.18]# cat redis.yml 
- hosts: webservers
  tasks:    - name: Installed Redis Server
      yum:
        name: redis
        state: present    - name: Configure Redis Server
      template:
        src: ./redis.conf.j2
        dest: /etc/redis.conf
      notify: Restart Redis Server    - name: Started Redis Server
      systemd:
        name: redis
        state: started
        enabled: yes  handlers:
    - name: Restart Redis Server
      systemd:
        name: redis
        state: restarted
[root@manager ansible_lianxi-5.18]# cat redis.conf.j2 
bind 127.0.0.1 {{ ansible_eth1.ipv4.address }}[root@manager ansible_lianxi-5.18]# ansible webservers -m shell -a "netstat -lntp|grep redis"
```

实战二、根据CPU核心生成不同的Nginx配置

```HTML
[root@manager ansible_lianxi-5.18]# cat ngix.yml 
- hosts: webservers
  tasks:
    - name: Configure  Nginx.conf
      template:
        src: ./nginx.conf.j2
        dest: /tmp/nginx.conf
[root@manager ansible_lianxi-5.18]# cat nginx.conf.j2 
worker {{ ansible_processor_vcpus * 2 }};
[root@manager ansible_lianxi-5.18]# ansible webservers -m shell -a "cat /tmp/nginx.conf"
172.16.1.8 | CHANGED | rc=0 >>
worker 2;
172.16.1.7 | CHANGED | rc=0 >>
worker 2;```

实战三、根据主机内存生成不同的Memcached配置 ( 使用物理内存的一半 )

```HTML
[root@manager ansible_lianxi-5.18]# cat memcached.yml 
- hosts: webservers
  tasks:
    - name: Installed Memcached Server
      yum:
        name: memcached
        state: present    - name: Configure Memcached Server
      template:
        src: memcached.j2
        dest: /etc/sysconfig/memcached
      notify: Restart Memcached Server    - name: Started Memcached Server
      systemd:
        name: memcached
        state: started
        enabled: yes  handlers:
    - name: Restart Memcached Server
      systemd:
        name: memcached
        state: restarted
[root@manager ansible_lianxi-5.18]# cat memcached.j2 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ ansible_memtotal_mb //2 }}"
OPTIONS=""
[root@manager ansible_lianxi-5.18]# ansible webservers -m shell -a "cat /etc/sysconfig/memcached"
172.16.1.8 | CHANGED | rc=0 >>
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="486"
OPTIONS=""
172.16.1.7 | CHANGED | rc=0 >>
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="486"
OPTIONS=""
```

实战四、根据主机名称生成不同的zabbix配置

```HTML
[root@manager ansible_lianxi-5.18]#wget https://mirror.tuna.tsinghua.edu.cn/zabbix/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.0-2.el7.x86_64.rpm
[root@manager ansible_lianxi-5.18]# yum install zabbix-agent-4.0.0-2.el7.x86_64.rpm -y
[root@manager ansible_lianxi-5.18]# cp /etc/zabbix/zabbix_agentd.conf ansible_lianxi-5.18/zabbix_agentd.conf.j2
Hostname={{ansible_hostname}}
[root@manager ansible_lianxi-5.18]# cat zabbix_agent.yml 
- hosts: all
  tasks:
    - name: Installed ZabbixAgent
      yum:
        name: https://mirror.tuna.tsinghua.edu.cn/zabbix/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.0-2.el7.x86_64.rpm
        state: present    - name: Configure ZabbixAgent
      template:
        src: ./zabbix_agentd.conf.j2
        dest: /etc/zabbix/zabbix_agentd.conf
      notify: Restart ZabbixAgent    - name: Started ZabbixAgent
      systemd:
        name: zabbix-agent
        state: started
        enabled: yes  handlers:
    - name: Restart ZabbixAgent
      systemd:
        name: zabbix-agent
        state: restarted```

facts优化:
facts变量开启会影响playbook运行的效率? 但是关闭又会造成无法提取被控端的状态。 最佳的方案使用缓存来解决。

```HTML
[root@manager ansible_lianxi-5.18]# cat ansible.cfg 
[defaults]
inventory = ./hostsgathering = smart
fact_caching_timeout = 86400
fact_caching = redis
fact_caching_connection = 172.16.1.7:6379
[root@manager ansible_lianxi-5.18]#yum install python-pip
[root@manager ansible_lianxi-5.18]#pip install redis
[root@web01 ~]# redis-cli 
127.0.0.1:6379> keys *
1) "ansible_cache_keys"
2) "ansible_facts172.16.1.5"
3) "ansible_facts172.16.1.51"
4) "ansible_facts172.16.1.8"
5) "ansible_facts172.16.1.7"```