自动化运维工具Ansible之Playbooks的roles和include

当需要对多个远程节点,做很多操作的时候,如果将所有的内容都书写到一个playbooks中,这就会产生一个很大的文件,而且里面的某些内容也很难复用。此时不得不考虑怎么样分隔及组织相关的文件。

最基本的,可以将任务列表单独分隔到一个小文件里,然后在tasks中包含该文件即可。同样的handlers其实也是一个任务列表(里面指定的任务都需要有一个全局唯一的名称),所以也可以在handlers中包含单独定义好的handlers任务文件。

playbooks也可以包含其他playbooks文件。

playbooks中的文件包含使得你在大多数情况下并不需要考虑具体功能的实现细节,只需要复用某些已有的文件即可,类似于编程中的封装概念一样,当某个功能封装并测试OK以后,在需要的地方调用即可,如,一个人会开车,但他并不需要了解发动机的原理是什么。

Ansible中的“角色”就是利用文件包含这个功能来使得文件组织的更加清晰明了,并具有很高的复用性。

任务文件包含和重用

如果想在多个playbooks之间服用任务列表,那么include将会是个很好的方法。

官方示例的一个很小的任务列表文件:

    ---
    # possibly saved as tasks/foo.yml
    
    - name: placeholder foo
      command: /bin/foo
    
    - name: placeholder bar
      command: /bin/bar

在playbooks中包含该文件:

tasks:
    
      - include: tasks/foo.yml

同时也可以向包含文件内传递参数,称为“参数化包含”。

例如,想要部署多个wordpress,可以将部署操作写到一个文件中,保存为wordpress.yml,然后以下边这样包含文件并传递参数:

    tasks:
      - include: wordpress.yml wp_user=timmy
      - include: wordpress.yml wp_user=alice
      - include: wordpress.yml wp_user=bob

在wordpress.yml可以{{ wp_user }}的方式使用变量。

还可以传递一个参数列表:

    tasks:
     - { include: wordpress.yml, wp_user: timmy, ssh_keys: [ ‘keys/one.txt‘, ‘keys/two.txt‘ ] }

以上两种传递参数都称为显式传参,在vars中定义的变量特可以在被包含文件中使用。

也可以在handlers中包含文件。如,想要定义一个重启apache的handler,这时候只需要为所有的playbooks定义一个handler即可,保存为handlers.yml:

     ---
    # this might be in a file like handlers/handlers.yml
    - name: restart apache
      service: name=httpd state=restarted

在playbooks中包含该文件:

    handlers:
      - include: handlers/handlers.yml

还可以将一个playbooks文件导入到另外一个playbooks中,这样的话,只需要定义一个顶级的且内容为一些较为通用的操作的playbooks文件,然后再文件中包含其他的playbooks即可。

     - name: this is a play at the top level of a file
      hosts: all
      remote_user: root
    
      tasks:
    
      - name: say hi
        tags: foo
        shell: echo "hi..."
    
    - include: load_balancers.yml
    - include: webservers.yml
    - include: dbservers.yml

示例:

[[email protected] ansible]# tree /etc/ansible/
    /etc/ansible/
    ├── handlers
    │   └── restart.yml
    ├── hosts
    ├── main.yml
    ├── tasks
    │   └── apache.yml
    └── templates
        └── httpd.j2
    [[email protected] ansible]# cat tasks/apache.yml 
    ---
    - name: config httpd.file
      template: src=templates/httpd.j2 dest=/etc/httpd.conf
    [[email protected] ansible]# cat handlers/restart.yml 
    ---
    - name: restart apache
      service: name=httpd state=restarted
    [[email protected] ansible]# cat main.yml 
    ---
    - hosts: webservers
      remote_user: root
      vars:
        http_port: 8085
        max_clients: 123
      
      tasks:
        - include: tasks/apache.yml
        
      handlers:
        - include: handlers/restart.yml
    [[email protected] ansible]# ansible-playbook /etc/ansible/main.yml 
    
    PLAY [webservers] ************************************************************* 
    
    GATHERING FACTS *************************************************************** 
    ok: [192.168.1.65]
    
    TASK: [config httpd.file] ***************************************************** 
    changed: [192.168.1.65]
    
    PLAY RECAP ******************************************************************** 
    192.168.1.65               : ok=2    changed=1    unreachable=0    failed=0

注:上边文件虽然定义并包含了重启apache的handler,但并没有任务一个任务来触发该handler。所以并没有执行重启操作,即使配置文件发生了改变。

角色


“文件包含”本身只是很简单且很单纯的包含各个子文件,当文件较多的时候,其组织方式也并是好,且需要人为的来指定包含哪些文件。Ansible中的“角色”会基于已知的文件结构来自动加载特定的变量文件、任务文件一级handlers文件,使用角色来组织内容可以更好的实现共享。

官方的一个使用角色组织内容的文件结构:

    site.yml
    webservers.yml
    fooservers.yml #playbooks文件,最后ansible执行的就是这些文件
    roles/
       common/
         files/
         templates/ #保存操作中所需要的模板文件
         tasks/ #保存任务列表文件
         handlers/ #保存handler文件
         vars/ #保存定义变量的文件
         defaults/ #默认变量文件
         meta/ #角色的依赖关系
       webservers/
         files/
         templates/
         tasks/
         handlers/
         vars/
         defaults/
         meta/

在playbooks中这样书写内容,如上边的webservers.yml文件:

     ---
     - hosts: webservers
      roles:
         - common
         - webservers

每个角色都会遵循以下原则:

  1. - 如果`roles/x/tasks/main.yml`存在,里面的任务列表会被添加到`play`中。
  2. - 如果`roles/x/handlers/main.yml`存在,里面的`handlers`会被添加到`play`中。
  3. - 如果`roles/x/vars/main.yml`存在,里面的变量会被添加到`play`中。
  4. - 如果`roles/x/meta/main.yml`存在,里面的角色依赖会被添加到角色列表中。
  5. - 在`roles/x/files`任务所需要被复制的文件,无需绝对路径或者相对路径都可以引用该文件。
  6. - 在`roles/x/files`中的任务脚本都可以直接使用该文件,无需指定绝对路径或者是相对路径。
  7. - 在`roles/x/templates`中的模板,无需指定绝对路径或者相对路径,都可以直接使用文件名引用该文件。
  8. - 需要包含在`roles/x/tasks`中的任务文件时,无需指定绝对路径或者相对路径,可以直接使用文件名包含。

tasks,handlers,vars,meta目录下main.yml中的内容都会被自动调用。

如果某些文件不存在的话,将会自动跳过,所以`vars/`之类的子目录如果用不到的话也可以不创建。

也可以给角色传递参数,在playbooks文件定义:

    ---
    
    - hosts: webservers
      roles:
        - common
        - { role: foo_app_instance, dir: ‘/opt/a‘,  port: 5000 }
        - { role: foo_app_instance, dir: ‘/opt/b‘,  port: 5001 }

有时候也可以给角色添加执行条件:

    ---
    
    - hosts: webservers
      roles:
        - { role: some_role, when: "ansible_os_family == ‘RedHat‘" }

当远程节点的操作系统为RedHat的时候才会执行"some_role"中的操作。

如果在某个play中定义了一个tasks任务块,它将会在橘色执行完成后再执行。

定义在角色执行之前或者执行后需要执行的任务:

    ---
    
    - hosts: webservers
    
      pre_tasks:
        - shell: echo ‘hello‘
    
      roles:
        - { role: some_role }
    
      tasks:
        - shell: echo ‘still busy‘
    
      post_tasks:
        - shell: echo ‘goodbye‘

示例:

[[email protected] ~]# tree /etc/ansible/
    /etc/ansible/
    ├── hosts
    ├── roles
    │   └── webservers
    │       ├── defaults
    │       ├── files
    │       ├── handlers
    │       │   ├── main.yml
    │       │   └── restart.yml
    │       ├── meta
    │       ├── tasks
    │       │   ├── apache.yml
    │       │   └── main.yml
    │       ├── templates
    │       │   └── httpd.j2
    │       └── vars
    │           └── main.yml
    └── webservers.yml
    
    [[email protected] ~]# cat /etc/ansible/roles/webservers/tasks/main.yml 
    ---
    - include: apache.yml
    [[email protected] ~]# cat /etc/ansible/roles/webservers/tasks/apache.yml 
    ---
    - name: config httpd.file
      template: src=httpd.j2 dest=/etc/httpd.conf
      notify:
        - restart apache
    [[email protected] ~]# cat /etc/ansible/roles/webservers/handlers/main.yml 
    ---
    - include: restart.yml
    [[email protected] ~]# cat /etc/ansible/roles/webservers/handlers/restart.yml 
    ---
    - name: restart apache
      service: name=httpd state=restarted
    [[email protected] ~]# cat /etc/ansible/roles/webservers/vars/main.yml 
    ---
    http_port: 8099
    max_clients: 321

    [[email protected] ansible]# ansible-playbook /etc/ansible/webservers.yml
    
    PLAY [webservers] ************************************************************* 
    
    GATHERING FACTS *************************************************************** 
    ok: [192.168.1.65]
    
    TASK: [webservers | config httpd.file] **************************************** 
    changed: [192.168.1.65]
    
    NOTIFIED: [webservers | restart apache] *************************************** 
    changed: [192.168.1.65]
    
    PLAY RECAP ******************************************************************** 
    192.168.1.65               : ok=3    changed=2    unreachable=0    failed=0

有些子目录并没有使用到,如meta目录,就可以不用创建。

角色依赖


角色依赖使得当使用某个角色的时候自动将其他角色导入。角色依赖保存在角色目录下的`meta/main.yml`文件中,该文件包含一个角色和参数的列表,这些内容会在某个特定的角色之前插入。即在某个特定的角色执行之前会先执行其依赖。

     ---
    dependencies:
      - { role: common, some_parameter: 3 }
      - { role: apache, port: 80 }
      - { role: postgres, dbname: blarg, other_parameter: 12 }

也可以以绝对路径的方式定义:

     ---
    dependencies:
       - { role: ‘/path/to/common/roles/foo‘, x: 1 }

角色依赖总在包含它们的角色执行之前而执行,而且是递归执行。默认情况下,角色也只能作为一个依赖关系添加一次,如果另一个角色也将它列为一个依赖关系,它将不再运行。但是在`meta/main.yml`设置`allow_duplicates: yes`,可以突破这个限制。如一个称为`car`的角色需要添加一个名为`wheel`的角色作为它的依赖:

    ---
    dependencies:
    - { role: wheel, n: 1 }
    - { role: wheel, n: 2 }
    - { role: wheel, n: 3 }
    - { role: wheel, n: 4 }

meta/main.yml内容:

    ---
    allow_duplicates: yes
    dependencies:
    - { role: tire }
    - { role: brake }

执行的结果会是类似下边这样:

    tire(n=1)
    brake(n=1)
    wheel(n=1)
    tire(n=2)
    brake(n=2)
    wheel(n=2)
    ...
    car

总结:

角色和文件包含,在平时的运维工作中会经常使用到,而且使得文件组织更加清晰,复用性较高。可以对远程节点主机进行大量且复杂有序的操作。

时间: 2024-08-14 06:03:34

自动化运维工具Ansible之Playbooks的roles和include的相关文章

自动化运维工具Ansible之Playbooks循环语句

在使用ansible做自动化运维的时候,免不了的要重复执行某些操作,如:添加几个用户,创建几个MySQL用户并为之赋予权限,操作某个目录下所有文件等等.好在playbooks支持循环语句,可以使得某些需求很容易而且很规范的实现. with_items是playbooks中最基本也是最常用的循环语句. - name: add several users   user: name={{ item }} state=present groups=wheel   with_items:      - t

自动化运维工具Ansible之Playbooks变量的使用

在平时运维工作中有时候需要根据不同的远程节点或者针对不同的IP的系统做不同的配置部署.如,Ansible可以根据不同的IP地址来对各个节点上的配置文件做不同的处理,这里就需要用到变量. 可以在playbooks文件中直接定义变量: - hosts: webservers   vars:     http_port: 80 定义了一个变量名为http_port的变量,值为80. 通过文件包含和角色定义变量 [[email protected] ~]# cat /etc/ansible/roles/

自动化运维工具——ansible详解案例分享

自动化运维工具--ansible详解案例分享(一)目录ansible 简介ansible 是什么?ansible 特点ansible 架构图ansible 任务执行ansible 任务执行模式ansible 执行流程ansible 命令执行过程ansible 配置详解ansible 安装方式使用 pip(python的包管理模块)安装使用 yum 安装ansible 程序结构ansible配置文件查找顺序ansible配置文件ansuble主机清单ansible 常用命令ansible 命令集a

3.1 自动化运维工具ansible

自动化运维工具ansible 运维自动化发展历程及技术应用 Iaas 基础设施即服务Pass 平台服务SaaS 软件即服务 云计算工程师核心职能 Linux运维工程师职能划分 自动化动维应用场景 文件传输命令执行 应用部署配置管理任务流编排 企业实际应用场景分析 1 Dev开发环境 使用者:程序员功能:程序员开发软件,测试BUG的环境管理者:程序员123 2 测试环境 使用者:QA测试工程师功能:测试经过Dev环境测试通过的软件的功能管理者:运维说明:测试环境往往有多套,测试环境满足测试功能即可

自动化运维工具-Ansible基础

目录 自动化运维工具-Ansible基础 自动化运维的含义 Ansible 基础及安装 Ansible的架构 Ansible的执行流程 ansible配置文件 ansible Inventory(主机清单文件) Ansible ad-hoc ansible常用模块 实战 自动化运维工具-Ansible基础 自动化运维的含义 1.手动运维时代 2.自动化运维时代 3.自动化运维工具给运维带来的好处 Ansible 基础及安装 1.什么是Ansible Ansible是一个自动化统一配置管理工具 2

自动化运维工具Ansible详细部署 (转载)

自动化运维工具Ansible详细部署 标签:ansible 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog.51cto.com/353572/1579894 ========================================================================================== 一.基础介绍 ===========================

自动化运维工具Ansible架构部署应用及playbooks简单应用

在日常服务器运维中,我们经常要配置相同的服务器配置,前期我们都是一台一台的去配置,这种方法操作主要应对于服务器数量不多且配置简单的情况还可以继续这样操作,如果我们后期维护几百服务器或者几万服务器呢? 我应该怎样去快速配置服务器呢?如果需要手动的每台服务器进行安装配置将会给运维人员带来许多繁琐而又重复的工作同时也增加服务器配置的异常,至此自动化运维工具解决我们的瓶颈---Ansible工具. Ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfeng

自动化运维工具ansible的基本应用

在很多场景中我们都需要在多个主机上执行相同的命令或者是做相同的配置工作,此时,为了简化操作,我们可以借助一些自动化的工具来完成我们的需求,这种工具我们称之为自动化运维工具.ansible就是其中之一,下面我们就来用ansible来实现一些简单操作. 下面是ansible可以实现很多工具的功能,框架图如下所示:ansible不能实现操作系统的安装 ansible作者就是早期puppet和func的维护者之一,因为ansible充分吸取了puppet和func的优势,又力图避免他们的劣势. OS P

自动化运维工具ansible详解

 ll  本文导航    · ansible的基础介绍   · ansible的安装与配置   · ansible的简单应用   · YAML介绍及语法   · ansible-playbooks(剧本)  ll  要求  掌握ansible基本应用与playbooks. 1.ansible介绍 ansible是一款基于python开发的自动化运维工具,它结合了puppet.cfengine.func.chef.fabric等工具的优点,实现了批量系统配置.批量部署应用程序及批量部署命令   a