zoukankan      html  css  js  c++  java
  • 自动化运维工具——ansible模板与roles(四)

    一、 模板Templates

    • 文本文件,嵌套有脚本(使用模板编程语言编写)
    • Jinja2语言,使用字面量,有下面形式
      字符串:使用单引号或双引号
      数字:整数,浮点数
      列表:[item1, item2, ...]
      元组:(item1, item2, ...)
      字典:{key1:value1, key2:value2, ...}
      布尔型:true/false
    • 算术运算:+, -, *, /, //, %, **
    • 比较操作:==, !=, >, >=, <, <=
    • 逻辑运算:and, or, not
    • 流表达式:For If When

    1. templates功能

    根据模块文件动态生成相应的配置文件
    
    • templates文件必须存放于templates目录下,且命名为 .j2 结尾
    • ymal/yml 文件需要和templates目录平级,目录结构如下:
    ./
    ├── temnginx.yml
    └── templates
        └── nginx.conf.j2
    

    templates示例

    利用templates 同步nginx配置文件
    
        //准备templates/nginx.conf.j2文件,就是nginx配置文件  加后缀`.j2`
    vim temnginx.yml
    ---
        - hosts: webServer
          remote_user: root
    
          tasks:
            - name: template config to remote hosts
              template: src=nginx.conf.j2  dest=/etc/nginx/nginx.conf
    
    ansible-playbook  temnginx.yml
    
    
        //playbook中template变更替换
        //修改文件nginx.conf.j2 下列内容:
        worker_processes  {{  ansible_precessor_vcpus*2 }};
        
        //在配置文件模板里加变量 ,可以根据远程主机的属性不同,值也不同
    
       //再次执行temnginx.yml
    ansible-playbook  temnginx.yml
    
    

    2. Playbook中template算术运算

    vim nginx.conf.j2
    
        worker_processes  {{  ansible_precessor_vcpus*2 }};
        worker_processes  {{  ansible_precessor_vcpus+2 }};
    
    //最后的值会根据机器不同得到的变量不同,然后再进行计算
    

    3. Playbook中的when

    条件测试
    
    如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法格式在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法
    
    //当setup模块中ansible_os_family等于RedHat时执行关机
            tasks: 
            - name: shutdown redhat system
              command: /sbin/shutdown -h now
              when: ansible_os_family == 'RedHat'     
    		
    //根据系统版本来安装软件
            tasks: 
            - name: install nginx to centos7
              yum: name=nginx
              when: ansible_distribution_major_version == '7'
            - name: install httpd to centos6
              yum: name=httpd
              when: ansible_distribution_major_version == '6'
    

    1. 迭代:with——items

    迭代:当需要重复性执行任务时,可以使用迭代机制
    
    • 对迭代项的引用,固定变量名为" item "
    • 要在task中使用with_items给定要迭代的元素列表
    • 列表格式: 字符串,字典
    //示例:
        - name: add several users
          user: name={{ item }} state=present groups=wheel
          with_items:
                - testuser1
                - testuser2
    //上面语句的功能等同于下面的语句:
        - name: add user testuser1
          user: name=testuser1 state=present groups=wheel
        - name: add user testuser2
          user: name=testuser2 state=present groups=wheel
    
    //拷贝多个文件到被控端  
        - hosts: webServer
          remote_user: root
          tasks:
            - name: copy file
              copy: src={{ item }} dest=/tmp/{{ item }}
              with_items:
                    - file1
                    - file2
                    - file3
            - name: yum install httpd
              yum: name={{ item }} state=present
              with_items:
                    - apr
                    - apr-util
                    - httpd
    

    迭代嵌套子变量

        - hosts:webServer
          remote_user: root
          tasks:
            - name: add some groups
              group: name={{ item }} state=present
              with_items:
                  - group1
                  - group2
                  - group3
    	  - name: add some users
    	    user: name={{ item.name }} group={{ item.group }} state=present   //嵌套子变量,格式为:item.with_items的列表中的键名
                with_items:
                    - { name: 'user1', group: 'group1' }   //最外层{} 是键值对的语法,里面有2个键值对,用逗号,分隔。
                    - { name: 'user2', group: 'group2' }
                    - { name: 'user3', group: 'group3' }
    

    4. Playbook中 template 的 for循环

    //语法:
    {% for i in nginx_vhosts %}
        语句块
    {% endfor %}
    
    {% if vhost.root is defined %}
    root {{ vhost.root }};
    {% endif %}
    

    示例1

    // temnginx.yml
    ---
        - hosts: webServer
          remote_user: root
          vars:
            nginx_vhosts:
                - listen: 8080
    
    //templates/nginx.conf.j2
    {% for vhost in nginx_vhosts %}
    server{
        listen  {{  vhost.listen}}    
    }
    
    {% endfor%}
    
    //生成结果
    server {
        listen 8080
      }
    
    

    示例2

    // temnginx.yml
    ---
        - hosts: webServer
          remote_user: root
          vars:
            nginx_vhosts:
                - web1
                - web2
                - web3
          tasks:
            - name: template config
              template: src=nginx.conf.j2  dest=/etc/nginx/nginx.conf
    
    // templates/nginx.conf.j2
    {% for vhost in nginx_vhosts %}
    server {
        http{
            server_name {{ vhost }}
        }
    }
    {% endfor %}
    
    //生成的结果:
    server {
        http{
            server_name web1 
         }
    }
    server {
        http{
            server_nameweb2 
         }
    }
    server {
        http{
            server_name web3 
         }
    }
    
    

    示例3

    // temnginx.yml
    ---
        - hosts: webServer
          remote_user: root
          vars:
            nginx_vhosts:
                - web1:
                    listen: 8080
                    server_name: "web1.test.com"
                    root: "/var/www/nginx/web1/"
                - web2:
                    listen: 8080
                    server_name: "web2.test.com"
                    root: "/var/www/nginx/web2/"
                - web3:
                    listen: 8080
                    server_name: "web3.test.com"
                    root: "/var/www/nginx/web3/“
            tasks:
                - name: template config 
                  template: src=nginx.conf.j2   dest=/etc/nginx/nginx.conf
    
    // templates/nginx.conf.j2
    {% for vhost in nginx_vhosts %}
    server {
         listen {{ vhost.listen }}
         server_name {{ vhost.server_name }}
         root {{ vhost.root }} 
    }
    {% endfor %}
    生成结果:
    server {
         listen 8080
         server_name web1.test.com
         root /var/www/nginx/web1/ 
    }
    server {
         listen 8080
         server_name web2.test.com
         root /var/www/nginx/web2/ 
    }
    server {
         listen 8080
         server_name web3.test.com
         root /var/www/nginx/web3/     
    }
    
    

    5. Playbook中template的 if 判断

        增加一个if判断,排除一些特定的情况,然后输出不同配置
    
    //语法
    {% if i is defined %}
           //判断后执行的内容
    {% endif %}
    

    示例:

    // temnginx.yml
    ---
        - hosts: webServer
          remote_user: root
          vars:
            nginx_vhosts:
                - web1:
                  listen: 8080
                  root: "/var/www/nginx/web1/"
                - web2:
                  listen: 8080
                  server_name: "web2.test.com"
                  root: "/var/www/nginx/web2/"
                - web3:
                  listen: 8080
                  server_name: "web3.test.com"
                  root: "/var/www/nginx/web3/"
            
            tasks:
                
    // templates/nginx.conf.j2
    
    {% for vhost in nginx_vhosts %}
        server{
            listen {{ vhost.listen }}
    
            {% if vhosts.server_name is defined %}
    
            server_name  {{ vhost.server_name }}
    
            {% endif %}
    
            root  {{ vhost.root }}
    }
    {% endfor %}
    
    
    
    server{
            listen 8080
    
            root  /var/www/nginx/web1
    }
    
    server{
            listen 8080
    
            server_name  web2.test.com
    
            root  /var/www/nginx/web2
    }
    server{
            listen 8080
    
            server_name  web3.test.com
    
            root  /var/www/nginx/web3
    }
    

    二、 Roles

    1. roles简介

    ansible 自1.2版本引入的新特性,用于层次性,结构化地组织 playbook 。 roles 能够根据层次型结构不自动装载变量文件、 tasks 以及 handlers 等。要使用 roles 只需要在 playbook 中使用 include 指令即可。
    简单来讲, roles 就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷的 include 它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
    

    在复杂的场景中,建议使用roles,代码复用度高。

    2. roles创建步骤

    1、创建以 roles 命名的目录。
    2、在 roles 目录中分别创建以各角色名称命名的目录,如 webServer 等
    3、在每个角色命名的目录中分别创建 files,handlers、meta、tasks、templates 和 vars 目录
    4、在 playbook 文件中,调用各自角色

    3. Ansible Roles 目录编排结构

    ├── roles                                   // 必须是这个名字
    │   ├── git                                 // 具体项目名称
    │   │   ├── default                     // 设定默认变量时使用此目录中的main.yml文件
    │   │   │   └── main.yml            // 至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    │   │   ├── files                       // 存放有copy或script模块等调用的文件
    │   │   ├── handlers                 // 定义触发器
    │   │   │   └── main.yml           // 至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    │   │   ├── meta                        // 定义当前角色的特殊设定及其依赖关系
    │   │   │   └── main.yml            // 至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    │   │   ├── tasks                       // 定义task,role的基本元素
    │   │   │   └── main.yml            // 至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    │   │   ├── templates               // template模块查找所需要模板文件目录
    │   │   │   └── main.yml            // 至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    │   │   └── vars                        // 定义变量;;其他的文件需要在此文件中通过include进行包含
    │   │       └── main.yml            // 至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    
    

    roles示例:

    webServer.yml
    mysqlServer.yml
    roles/
            webservers/
                    files/
                    templates/
                    tasks/
                    handlers/
                    vars/
                    meta/
            mysqlservers/
                    files/
                    templates/
                    tasks/
                    handlers/
                    vars/
                    meta/
    

    4. Playbook调用角色的方法

    方法一:

        - hosts: webServer
          remote_user: root
          roles:
          - mysqlserver
          - webserver
    
    

    方法二:

    传递变量给角色
    
        - hosts:
          remote_user:
          roles:
            - mysqlserver
            - { role: nginx, username: nginx }
            //键role用于指定角色名称,后续key:value用于传递变量给角色
            //也可以基于条件测试实现角色调用
            roles:
             - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7'}
    

    5. 完整的roles架构

    //nginx-role.yml
    ---
    
        - host: testweb
          remote_user: root
    
          roles:
            - role: nginx  //  nginx为 roles目录下的任务角色目录的 名字
            - role: httpd   //可执行多个role
    
    // roles/nginx/tasks/main.yml
    ---
        
    - include:groupadd.yml
    - include:useradd.yml
    - include:install.yml
    - include:restart.yml
    - include:filecp.yml
    # 顺序不能颠倒,执行顺序是从上往下执行的。
    
    
    //roles/nginx/tasks/groupadd.yml  
    ---
        
    - name: add group nginx
      user: name=nginx state=present
    # 创建组
    
    // roles/nginx/tasks/filecp.yml
    ---
    
    - name:file copy
      copy: src=test.conf dest=/tmp/test.conf
    #复制配置文件
    
    //以下文件格式类似:
    useradd.yml、install.yml、restart.yml
    
    ls roles/nginx/files/
    test.conf
    
    

    6. roles playbook tags使用

    ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
    // nginx-role.yml
    ---
        - hosts: testweb
           remote_user: root
           roles:
                - { role: nginx ,tags: [ 'nginx', 'web' ] ,when:  ansible_distribution_major_version == "6“ }// 增加了判断
                - { role: httpd ,tags: [ 'httpd', 'web' ] }
                - { role: mysql ,tags: [ 'mysql', 'db' ] }
                - { role: marridb ,tags: [ 'mysql', 'db' ] }
                - { role: php }
    
    

    推荐资料
    http://galaxy.ansible.com
    http://github.com/
    http://ansible.com.cn/
    https://github.com/ansible/ansible
    https://github.com/ansible/ansible-examples

    只有今天
  • 相关阅读:
    .net开发环境的选择
    html头部的一些信息
    SQLHelper类
    C#实现文件下载
    js类
    Winform小知识点
    emacs 代码缩进
    自己喜欢的shell终端配置
    time_wait过多的优化
    Emacs 电子邮件组件RMAIL
  • 原文地址:https://www.cnblogs.com/arnoLixi/p/10396289.html
Copyright © 2011-2022 走看看