Variable和Register的使用

Ansible Variable

介绍

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

定义方式

在 Ansible 中定义变量分为如下三种方式:
1.通过命令行传递变量参数定义
2.在play文件中进行定义变量
    2.1 通过vars定义变量
    2.2 通过vars_files定义变量
3.通过inventory在主机组或单个主机中设置变量
  3.1 通过host_vars对主机进行定义
  3.2 通过group_vars对主机组进行定义

问题:如果定义的变量出现重复,造成冲突,如何解决?

在 playbook 中定义变量

vars 方式

# 在 playbook 的文件中开头通过 vars 关键字进行变量定义

- hosts: web
  gather_facts: false  # 不获取被控集机器的fact数据,速度会变快
  vars:
    - web_packages: httpd
    - ftp_packages: vsftpd

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

vars_file方式

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

cat vars.yml
web_packages:
  - httpd
  - nginx
ftp_packages: vsftpd

cat f2.yml
- hosts: web
  gather_facts: false
  vars_files: ./vars.yml
  tasks:
    - name: Output Vaiables
      debug:
        msg:
          - "{{ web_packages }}"
          - "{{ ftp_packages }}"

在 inventory 中定义变量

定义主机变量和组变量

cat /etc/ansible/hosts
[webserver]
172.16.1.7 myid=1 state=master    # 定义的主机变量
172.16.1.8 myid=2 state=backup

[webserver:vars]
port=80  # 定义组变量

# 模拟配置文件
cat ./files/test.conf.j2
hostrole: {{ state  }}
myid: {{ myid }}
port: {{ port }}

# 根据变量替换公共配置文件,使不同的主机有不同的配置
cat f3.yml
- hosts: webserver
  gather_facts: false
  tasks:
    - name: Output Vaiables
      template:
        src: ./files/test.conf.j2
        dest: /tmp/test.conf

# 执行
ansible-playbook f3.yml

# 登录每一台主机进行检查配置文件查看是否根据变换配置

host_vars 定义变量

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

# hosts文件改回去
cat /etc/ansible/hosts
[webserver]
172.16.1.7
172.16.1.8

# 在当前项目创建这个固定的目录
mkdir host_vars

# 创建对应的IP文件,写入变量内容
cat host_vars/172.16.1.7
state: MASTER
myid: 10

cat host_vars/172.16.1.8
state: BACKUP
myid: 20

# 执行上述 f3.yml
ansible-playbook f3.yml

group_vars定义变量

在项目目录中创建 group_vars 目录,然后在创建一 个文件,文件的文件名称要与 inventory 清单中的组名 称保持完全一致,但是系统提供了特殊的 all 组,也就说在 group_vars 目录下创建一个 all 文件,定义变量对所 有的主机组都生效

cat /etc/ansible/hosts
[webserver]
172.16.1.7
172.16.1.8

mkdir group_vars

cat group_vars/webserver
port: 8080

ansible-playbook f3.yml

Playbook传递变量

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

rm -f group_vars/webserver

# 传递单个变量
ansible-playbook f3.yml  -e "port=9090"

# 可以使用多个 -e 拼接或者在一个 "" 内,可以使用这个方法运行不同的组定义不同的变量
cat group_vars/all
port: 8080

cat f4.yml
- hosts: "{{ host }}"
  gather_facts: false
  tasks:
    - name: Output Vaiables
      template:
        src: ./files/test.conf.j2
        dest: /tmp/test.conf

ansible-playbook f4.yml  -e "host=lb port=9090 state=MasTer myid=23"

变量优先级

定义相同的变量不同的值,来测试变量的优先级。操作步骤如下:
1)在plabook中定义vars变量
2)在playbook中定义vars_files变量
3)在host_vars中定义变量
4)在group_vars中定义变量
5)通过执行命令传递变量

结果(从高到低):
命令行传参
playbook中的vars_files
playbook中的vars
host_vars
group_vars
group_vars/all

使用变量改写NFS

变量文件已经配置文件

cat exports.j2
{{ nfs_share_data }} (rw,all_squash,anonuid={{ nfs_uid }},anongid={{ nfs_gid }})

cat nfs_variables.yml
nfs_share_data: /fff
nfs_uid: 5655
nfs_gid: 5655
nfs_group: dddd
nfs_user: dddd

playbook 文件

- hosts: nfs-server
  gather_facts: false
  vars_files: ./nfs_variables.yml
  tasks:
    - name: 1.Install NFS Server
      yum:
        name: nfs-utils
        state: present

    - name: 2.Configure NFS Server
      template:
        src: ./exports.j2
        dest: /etc/exports
      notify: Restart NFS Server

    - name: 3.Created Group
      group:
        name: "{{ nfs_group }}"
        gid: "{{ nfs_gid }}"

    - name: 4.Created User
      user:
        name: "{{ nfs_user }}"
        uid: "{{ nfs_uid }}"
        group: "{{ nfs_group }}"
        shell: /sbin/nologin
        create_home: no

    - name: 5.Init Create  Directory
      file:
        path: "{{ nfs_share_data }}"
        state: directory
        owner: "{{ nfs_user }}"
        group: "{{ nfs_group }}"
        mode: "0755"

    - name: 6.Started NFS Server
      systemd:
        name: nfs
        state: started
        enabled: yes

  handlers:
    - name: Restart NFS Server
      systemd:
        name: nfs
        state: restarted

- hosts: localhost
  gather_facts: false
  vars_files: ./nfs_variables.yml
  tasks:
    - name: 7.Install NFS Cli
      yum:
        name: nfs-utils
        state: present

    - name: 8. Cli Mount
      mount:
        src: "192.168.100.7:{{ nfs_share_data }}"
        path: /mnt
        fstype: nfs
        opts: defaults
        state: mounted

Ansible Register

register 可以将 task 执行的任务结果存储至某个变 量中,便于后续的引用

输出命令的结果

- hosts: webservers
  gather_facts: false
  tasks:
    - name: Get Network Port
      shell: netstat -lntp
      register: System_Port

    - name: debug
      debug:
        msg:
          - "执行了 {{ System_Port.cmd }} 命令"
          - "{{ System_Port.stdout_lines  }}"

批量修改随机主机名称

- hosts: webservers
  gather_facts: false
  tasks:
    - name: String
      shell: echo $RANDOM |md5sum | cut -c 2-10
      register: systemd_sj

    - name: debug
      debug:
        msg: "{{ systemd_sj.stdout }}"

    - name: Chanage Hostname
      hostname:
        name: "web_{{ systemd_sj.stdout }}"

Facts Variables

简介

Ansible facts 变量主要用来自动采集,“被控端主机”自身的状态信息。 比如:被动端的,主机名、IP地址、系统版本、CPU数 量、内存状态、磁盘状态等等。

使用场景:
1.通过facts变量检查被控端硬件CPU信息,从而生成不同的Nginx配置文件
2.通过facts变量检查被控端内存状态信息,从而生成不同的memcached的配置文件
3.通过facts变量检查被控端主机名称信息,从而生成不同的Zabbix配置文件
4.通过facts变量检查被控端主机IP地址信息,从而生成不同的redis配置文件

使用

# 可以获取被控端的主机信息
ansible localhost -m setup

# 查看被控端的hostname IP 系统类型,注:gather_facts 此时就不能为 false 了
- hosts: web
  tasks:
    - name: Print msg
      debug:
        msg: "{{ ansible_nodename }} {{ ansible_default_ipv4.address }} {{ ansible_distribution }}"

根据主机地址 IP 生成配置

cat ./files/tes2t.conf.j2
IP_Server: {{ ansible_default_ipv4.address }}

cat facts2.yml
- hosts: web
  tasks:
    - name: Output Vaiables
      template:
        src: ./files/test2.conf.j2
        dest: /tmp/test2.conf

ansible-playbook facts2.yml

# 检查web组内的每个主机查看 /tmp/test2.conf 是否按照IP生成了对应内容

批量修改主机名

cat facts3.yml
- hosts: web
  tasks:
    - name: Get msg
      debug:
        msg: "{{ ansible_default_ipv4.address }}"

    - name: Change hostname
      hostname:
        name: "web_{{ ansible_default_ipv4.address.split('.')[-1] }}"

ansible-playbook facts3.yml

Redis缓存facts变量加速

当我们使用 gather_facts: no 关闭 facts,确实能加速 Ansible 执行,但是有时候又需要使用 facts 中的内容,还希望执行的速度快一点,这时候可以设置 facts 的缓存

[defaults]
# smart 表示默认收集 facts,但 facts 已有的情况下不会收集,即使用缓存 facts
# implicit 表示默认收集 facts,要禁止收集,必须使用 gather_facts: False;
# explicit 则表示默认不收集,要显式收集,必须使用gather_facts: Ture

#在使用 facts 缓存时设置为smart
gathering = smart
fact_caching_timeout = 86400
fact_caching = redis
fact_caching_connection = 172.16.1.41:6379:1

# 若 redis 设置了密码
# fact_caching_connection =172.16.1.41:6379:1:passwd  1 库
# 整体性能可以提升二到三倍以上