ansible经常使用的定义变量方式和变量注册facts缓存和template的使用

回顾

可使用自定义主机组的方式定义hosts,这样能够减小重复任务的代码(不推荐使用,由于自定义主机组的话,剧本中的all将没法使用)
ansible和saltstack都要使用yml语法,yml语法中最好使用2468空格
service和systemd启动服务,不支持列表的形式(只能用循环了)

[root@m01 ~]# hostname
m01
[root@m01 ~]# hostname -I
10.0.0.61 172.16.1.61 
[root@m01 ~]# hostnamectl set-hostname www.m01.com
[root@www ~]# 		#显示不完整主机名

"{{ ansible_fqdn }}" 不管是自定义变量仍是系统变量的调用,写到剧本中的路径里的话不要加引号,单独的调用须要加引号

变量自定义

1.经过命令行进行变量定义
2.在play文件中进行变量定义
3.经过Inventory主机信息文件中进行变量定义php

变量优先级:命令行 > playbook文件 > Inventory文件html

playbook中vars定义变量java

playbook变量能够经过多种方式进行定义,最简单的方式就是在playbook的开头经过vars进行定义。(以列表或者ad-hoc的方式定义变量)python

#方法一:
- hosts: web_group
  vars:
    packages:
      - httpd
      - mariadb-server
      - php
      - php-mysql
      - php-pdo
  tasks:       
  - name: Install httpd  mariadb php Server
    yum:
      name: "{{ packages }}"

#方法二:(#name不支持列表!!!)
- hosts: web_group
  vars:
    - web_server: httpd
    - db_server: mariadb-server
    - php_server:
      - php
      - php-mysql
      - php-pdo
   tasks:
   - name: Install httpd  mariadb php Server
     yum:
       name:
         - "{{ web_server }}"
         - "{{ db_server }}"
         - "{{ php_server }}"
 
# "{{ php_server }}" ,ansible中里面空格加不加都行,saltstack里面必须加空格,可是引号必需要加
#变量列表只能在支持列表的模块中使用

#file模块不能使用变量列表
[root@m01 ~]# vim ansible/cs.yml
- hosts: web01
  vars:
    dir: a
  tasks:
  - name: create dir
    file:
      path: /root/{{ dir }}
      state: directory

使用vars_file定义变量mysql

刚才咱们学到在playbook中使用vars定义变量,有一个缺陷,就是其余的play没法使用该变量。因此咱们能够采起第二种定义变量的方式,在vars_file中定义变量。nginx

#定义阶段
[root@m01 ~]# vim /vars/vars1.yml
web_server: httpd
[root@m01 ~]# vim /vars/vars2.yml
db_server: mariadb-server
#或者以列表形式定义
web_server:
  - tree
  - unzip

#调用阶段
- hosts: web_group
  vars_files: /root/vars1.yml
  tasks:
  - name: Install httpd  mariadb php Server
    yum:
      name: "{{ web_server }}"

#调用阶段(name尽可能不要使用列表项)
- hosts: web_group
  vars_file: 
    - /root/vars1.yml
    - /root/vars2.yml
  tasks:
  - name: Install httpd  mariadb php Server
    yum:
      name:
        - "{{ web_server }}"
        - "{{ db_server }}"

#获取Ansible内置变量(内外变量结合)
- hosts: web_group
  vars:
    - remote_ip: "{{ ansible_default_ipv4['address'] }}"
    - remote_hostname: "{{ ansible_fqdn }}"
  tasks:
    - name: Touch IP File
      file:
        path: /root/{{ remote_ip }}
        state: touch

    - name: Touch Hostname File
      file:
        path: /root/{{ remote_hostname }}
        state: touch

在Inventory中定义变量web

注意:在Inventory中定义变量,主机的变量要高于主机组的变量,因此该方法不推荐使用,容易将环境弄乱。(主机变量在动做中调用,主机组变量在hosts中调用)sql

#定义阶段
[root@m01 ~]# vim /etc/ansible/hosts
[web_group]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8

#主机的定义变量
[web_group:vars]
web_server=httpd
index_file=index.html

#主机组的定义变量
[rsync_server:children]
web_group
backup_group

#调用阶段
- hosts: web_group
  tasks:
  - name: Install httpd Server
    yum:
      name: "{{ web_server }}"
  - name: Create Index File
    file:
      path: /tmp/{{ index_file }}
      state: touch

官方推荐变量定义shell

以前的几种变量定义都不是很好用,比较好用的是在Ansible项目目录下建立两个变量目录:vim

host_vars :优先级高,目录名和目录位置是固定的(项目目录下)
group_vars :优先级低
切记,目录名字必定要一致,不能作任何修改。

执行的yml文件在哪,哪就是该yml文件的项目目录

1.主机组定义变量,对某组来讲能够调用

#定义阶段
[root@m01 ~]# mkdir group_vars

#切记定义变量所在的文件必须以组名为文件名(组名是主机组变量调用的令牌),包含主机变量
#组名必须是主机清单中的标签名
[root@m01 ~]# vim /root/group_vars/web_group
web_server: httpd   (#名值对)

#调用阶段
- hosts: web_group
  tasks:
  - name: Install httpd Server
    yum:
      name: "{{ web_server }}"

若是我想要全部组都能使用变量,该如何作?

2.主机定义变量,对某主机来讲,能够调用

#定义阶段
[root@m01 ~]# mkdir host_vars

#切记定义变量的文件必须以主机名为文件名
[root@m01 ~]# vim /root/host_vars/web01
web_server: nginx

#调用阶段
- hosts: web01
  tasks:
  - name: Install httpd Server
    yum:
      name: "{{ web_server }}"

命令行定义变量(优先级最高)

经过命令行覆盖变量,Inventory的变量会被playbook文件中覆盖,这两种方式的变量都会被命令行直接指定变量所覆盖,使用--extra-vars或者-e设置变量

#调用
[root@m01 ~]# vim test.yml
- hosts: web_group
  tasks:
  - name: Install httpd Server
    yum:
      name: "{{ web_server }}"

#定义阶段
[root@m01 ~]# ansible-playbook test.yml -e "web_server=vsftpd"
[root@m01 ~]# vim test.yml
- hosts: web_group
  tasks:
  - name: Install httpd Server
    yum:
      name:
        - "{{ web_server }}"
        - "{{ db_server }}"

#定义阶段
[root@m01 ~]# ansible-playbook test.yml -e "web_server=vsftpd" -e "db_server=mariadb-server"

变量优先级测试

[root@m01 ~]# vim touch_file.yml
- hosts: web_group
  vars:
    filename: vars			#2
  vars_files:
    - ./vars1.yml			#1
  tasks:
    - name: Touch vars File
      file:
        path: /root/{{ filename }}		#不能带引号
        state: directory

#定义vars_files
[root@m01 ~]# vim vars1.yml   
filename: vars_files

#定义group_vars中的web_group			#3
[root@m01 ~]# vim group_vars/web_group
filename: group_vars_web_group

#定义host_vars中的web01
[root@m01 ~]# vim host_vars/web01		#4
filename: host_vars

#定义group_vars中的all
[root@m01 ~]# vim group_vars/all		
filename: group_vars_all

#测试命令行
[root@m01 ~]# ansible-playbook touch_file.yml -e "filename=vars_command"

#测试全部(依次删除剧本中同一变量的指定)
[root@m01 ~]# ansible-playbook touch_file.yml

变量注册

为何要学变量注册?

absible的模块在运行以后,其实都会返回一些result结果,就像是执行脚本,咱们有的时候须要脚本给咱们一些return返回值,咱们才知道,上一步是否能够执行成功

可是...默认状况下,ansibleresult并不会显示出来,因此,咱们能够把这些返回值存储到变量中,这样咱们就能经过调用对应的变量名,从而获取到这些result

这种将模块的返回值,写入到变量中的方法被称为变量注册

那么咋样将返回值注册到变量,以下一个playbook示例:

#编辑剧本
[root@m01 ~]# vim register.yml
- hosts: web_group
  tasks:
    - name: Test Register Vars
      shell: "ls -l /"

#查看执行结果
[root@m01 ~]# ansible-playbook register.yml

如上执行结果可见,当咱们使用shell模块执行ls -l /时,ansible给咱们返回的只有changed咱们没法看到执行以后的结果,因此此时咱们须要使用到变量注册

playbook以下:

register:注册

#编辑playbook
[root@m01 ~]# vim register.yml
- hosts: web_group
  tasks:
    - name: Test Register Vars
      shell: "ls -l /"
      register: list_dir			#注册变量

    - name: Return Result
      debug:  var=result verbosity=0		#调试输出的结果
        msg: "{{ list_dir }}"			#输出

# debug 调试模块,用于在调试中输出信息 经常使用参数: msg:调试输出的消息 var:将某个任务执行的输出做为变量传递给debug模块,debug会直接将其打印输出 verbosity:debug的级别(默认是0级,所有显示)

#查看执行结果
[root@m01 ~]# ansible-playbook register.yml

#只输出本身想要的内容
[root@m01 ~]# vim register.yml
- hosts: web_group
  tasks:
    - name: Test Register Vars
      shell: "ls -l /"
      register: list_dir

    - name: Return Result
      debug:
        msg: "{{ list_dir.stdout_lines }}"
        #msg: "{{ list_dir['stdout_lines'] }}" 
        
#查看结果
[root@m01 ~]# ansible-playbook register.yml


#debug模块经常使用参数
msg:            #调试输出的消息
var:            #将某个任务执行的输出做为变量传递给debug模块,debug会直接将其打印输出
verbosity:      #debug的级别(默认是0级,所有显示)
debug 			#偶尔调试

变量注册,忽略错误的使用

[root@www ~]# vim cs.yml 
- hosts: web01
  tasks:
    - name: Test Register Vars
      shell: "ls -l /etc/nginx"
      #注册变量
      register: list_dir
      #忽略错误
      ignore_errors: yes

#输出shell指定的信息
    - name: return
      debug:
        msg: "{{ list_dir.stdout_lines }}"
    
    #解压
    - name: jieya nginx.pkg
      unarchive:
        src: /root/nginx_php.tar.gz
        dest: /root
      when: list_dir.rc != 0        #经过变量的注册,判断shell的执行结果(rc)

    #卸载
    - name: shanchu
      shell: yum remove -y php-common
      #忽略错误
      ignore_errors: yes
      
    #安装
    - name: install
      shell: "cd /root && yum localinstall -y *rpm"

ignore_errors的做用就是忽略错误步骤,继续执行下一步(错误输出仍是会输出)

层级定义变量

像是本身作字典,使用 [' '] 或者 . 调用下一级

#编辑变量文件
[root@m01 ~]# vim vars_file.yml
lamp:
  framework:
    web_package: httpd
    db_package: mariadb-server
    php_package: php

lnmp:
  framework:
    web_package: nginx
    db_package: mysql
    php_package: php

lnmt:
  framework:
    web_package: nginx
    db_package: mysql
    java_package: tomcat

#编辑playbook文件
[root@m01 ~]# vim test.yml
- hosts: web_group
  vars_files: ./vars_file.yml
  tasks:
    - name: Install LAMP httpd
      yum:
        name: "{{ lamp.framework.web_package }}"

    - name: Install LAMP mariadb-server
      yum:
        name: "{{ lamp.framework.db_package }}"

    - name: Install LAMP php
      yum:
        name: "{{ lamp.framework.php_package }}"
        
#官方推荐写法
[root@m01 ~]# vim test.yml
- hosts: web_group
  vars_files: ./vars_file.yml
  tasks:
    - name: Install LAMP httpd
      yum:
        name: "{{ lamp['framework']['web_package'] }}"

    - name: Install LAMP mariadb-server
      yum:
        name: "{{ lamp['framework']['db_package'] }}"

    - name: Install LAMP php
      yum:
        name: "{{ lamp['framework']['php_package'] }}"

#执行playbook
[root@m01 ~]# ansible-playbook test.yml

#层级调用变量也只能调用一次

ansible内置变量----facts缓存

Ansible facts是在被管理主机上经过Ansible自动采集发现的变量。facts包含每台特定的主机信息。好比:被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。


facts使用场景

1.经过facts缓存检查CPU,来生成对应的nginx配置文件
2.经过facts缓存检查主机名,生成不一样的zabbix配置文件
3.经过facts缓存检索物理机的内存大小来生成不通的mysql配置文件

综上所述的Ansible facts相似于saltstack中的grains对于作自动化的小伙伴是很是有用滴。


facts基本用法

#编辑
[root@m01 ~]# vim facts.yml
- hosts: web_group
  tasks:
    - name: Get Host Info
      debug:
        msg: >
          Hostname "{{ ansible_fqdn }}" and IP "{{ ansible_default_ipv4.address }}"

#执行
[root@m01 ~]# ansible-playbook facts.yml

#msg: > 能够识别中文,打印出变量

关闭facts

[root@m01 ~]# vim facts.yml
- hosts: web_group
  gather_facts: no			 #关闭信息采集
  tasks:
  
#通常在用不到变量的剧本中才会使用,提升生产效率

template的使用

facts生成zabbix配置文件,生成nginx的配置文件,生成saltstack配置文件

- hosts: web_group
  tasks:
    - name: copy zabbix agent conf
      template:
        src: ./zabbix_agentd.conf
        dest: /tmp/zabbix_agentd.conf
        
#template模块,能够将剧本中的主机信息被 脚本中的变量调用 ,语法和copy相似 
#该模块适用于作配置文件的修改

facts生成mysql配置文件

- hosts: db_group
  tasks:
    - name: Install mysql server
      yum:
        name: mariadb-server
        state: present

    - name: copy mysql  conf
      template:
        src: ./my.cnf
        dest: /etc/my.cnf


[root@m01 ~]# vim /etc/my.cnf
[mysqld]
basedir=/usr
datadir=/var/lib/mysql/
socket=/var/lib/mysql/mysql.sock
log_error=/var/log/mariadb/mariadb.log
innodb_buffer_pool_size={{ ansible_memtotal_mb * 0.8 }}		
#ansible变量支持计算

需求:使用ansible在web机器建立“/backup/web01_172.16.1.31_2020-6-11”目录

#剧本中支持显示子信息
[root@www ~]# vim bl.yml 
- hosts: web01
  tasks:
    - name: ip
      file:
        path: /backup/{{ ansible_fqdn }}_{{ ansible_default_ipv4['address'] }}_{{ ansible_date_time['date'] }}
        state: directory
        recurse: yes
[root@www ~]# ansible web01 -m setup -a 'filter=ansible_default_ipv4' 
web01 | SUCCESS => {
    "ansible_facts": {
        "ansible_default_ipv4": {
            "address": "10.0.0.7", 
            "alias": "eth0", 
            "broadcast": "10.0.0.255", 
            "gateway": "10.0.0.2", 
            "interface": "eth0", 
            "macaddress": "00:0c:29:6e:25:1b", 
            "mtu": 1500, 
            "netmask": "255.255.255.0", 
            "network": "10.0.0.0", 
            "type": "ether"
        }, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}

#命令行不支持显示子信息
[root@www ~]# ansible web01 -m setup -a 'filter=ansible_default_ipv4.address' 
web01 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
相关文章
相关标签/搜索