zoukankan      html  css  js  c++  java
  • 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主机信息文件中进行变量定义

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

    playbook中vars定义变量

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

    #方法一:
    - 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定义变量

    刚才我们学到在playbook中使用vars定义变量,有一个缺陷,就是其他的play无法使用该变量。所以我们可以采取第二种定义变量的方式,在vars_file中定义变量。

    
    #定义阶段
    [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中定义变量

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

    #定义阶段
    [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 
    

    官方推荐变量定义

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

    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
    }
    
  • 相关阅读:
    poj 1654(利用叉积求面积)
    poj 3230(初始化。。动态规划)
    hdu 1392(凸包)
    hdu 1348(凸包)
    hdu 1147(线段相交)
    hdu 1115(多边形重心问题)
    POJ 2373 Yogurt factory
    GCJ 2008 APAC local onsites C Millionaire
    FZU 1397 保送
    FZU 1064 教授的测试
  • 原文地址:https://www.cnblogs.com/syy1757528181/p/13122236.html
Copyright © 2011-2022 走看看