Ansible使用Roles编排服务

  1. 概述
  2. Ansible Roles简介
  3. 一个简单的示例

概述

在使用Ansible执行自动化任务时,有如下几种场景:
1.如果只是临时执行一些操作,直接使用Ansible的模块即可,通过命令行执行
2.如果需要对一个服务进行编排,比如:安装nginx,配置nginx,启动nginx,此时使用Playbook将多个模块编排到一个yaml文件中执行
3.如果需要对多个服务进行编排,比如:初始化一台应用服务器环境时安装并配置nginx,java运行时,MySQL数据库等等,此时涉及多个服务的编排操作,需要使用Roles

Ansible Roles简介

Ansible自1.2版本之后,引入了Roles的新特性,以便层次性和结构化的组织Playbook。相比于Ansible Playbook,Roles能够层次型结构自动装载变量、任务以及handlers。在本质上,Ansible Roles就是将变量、任务、模板以及处理器分别的放在不同的目录中,并通过include的方式进行调用,并组合成一个整体。

使用Roles的完整目录结构如下:

roles/              # Ansible的Roles配置全部存放在roles目录下,在该目录下有着很多子文件夹,每个子文件夹就是一个“role”
  -mysql/           # 表示一个“role”,通常是需要编排的服务名称,如:mysql
   -tasks/          # 用于存放一系列任务文件,在该目录下,必须存在一个main.yml文件,该文件会通过include调用其他的文件
    -main.yml
   -handlers/       # 存放Role中触发条件后执行的动作,在该目录下也必须存在一个main.yml文件
    -main.yml
   -templates/      # 存放此Role需要使用的jinjia2模板文件
    -ntp.conf.j2
   -files/
    -file1.txt      # 用来存放copy模块的文件,或者是script模块的脚本文件
    -file2.sh
   -vars/
    -main.yml       # 该目录下存放一系列的变量,在该目录下,必须存在一个main.yml文件,该文件会通过include调用其他的文件
   -defaults/
    -main.yml       # 存放此Role的设定默认变量,该目录下必须存在一个main.yml文件
   -meta/
    -main.yml       # “role”的依赖配置
   -library/        # “role”可以包含的自定义模块
   -module_utils/   # “role”可以包含的自定义模块工具
   -lookup_plugins/ # 其他插件
playbook.yml        # 调用Roles的编排文件

tasks目录下除了必须存在main.yml文件,还可以包含其他文件,这些文件可以在main.yml文件中引用,如下:

# 在main.yml中使用条件判断,引入其他任务配置文件
# tasks/main.yml
---
- name: Install the correct web server for RHEL
  import_tasks: redhat.yml
  when: ansible_facts['os_family']|lower == 'redhat'

- name: Install the correct web server for Debian
  import_tasks: debian.yml
  when: ansible_facts['os_family']|lower == 'debian'

# tasks/redhat.yml
---
- name: Install web server
  yum:
    name: httpd
    state: installed

# tasks/debian.yml
---
- name: Install web server
  yum:
    name: apache2
    state: installed

如上示例中使用“ansible_facts”信息,那么如何采集被管理设备的系统信息呢?答案是使用setup模块获取:

$ ansible all -m setup

在上如示例使用了被管理主机的os_family信息进行条件判断。

一个简单的示例

在如下示例中使用Roles在目标主机上安装Web服务器和MySQL服务器,文件目录结构如下:

# tree .
.
├── roles # 在roles目录下分别包含了2个子目录:mysql和webserver,表示要在目标主机安装的服务
│   ├── mysql
│   │   ├── files
│   │   │   └── mysql80-community-release-el7-11.noarch.rpm # MySQL仓库包文件
│   │   └── tasks
│   │       └── main.yml # 安装MySQL服务的Ansible任务
│   └── webserver
│       └── tasks
│           ├── debian.yml
│           ├── main.yml
│           └── redhat.yml
├── role-sample.yaml

主Playbook文件role-sample.yaml内容如下:

---
- hosts: web
  roles: 
    - webserver
    - mysql

角色webserver的主编排文件main.yml内容如下:

---
- name: Install the correct web server for RHEL
  import_tasks: redhat.yml
  when: ansible_facts['os_family']|lower == 'redhat' # 使用条件判断,动态选择其他task文件,在条件判断中使用了“ansible_facts”信息

- name: Install the correct web server for Debian
  import_tasks: debian.yml
  when: ansible_facts['os_family']|lower == 'debian'

roles/webserver/tasks/debian.yml内容如下:

---
- name: Install apache2
  yum:
    name: apache2
    state: installed

roles/webserver/tasks/redhat.yml内容如下:

---
- name: Install httpd
  yum:
    name: httpd
    state: installed

角色mysql只有一个主编排文件main.yml,其内容如下:

---
- name: Check mysqld installed
  shell: "if which mysqld; then ehco true; else echo false;fi"
  ignore_errors: yes
  register: mysqld_installed # 定义自定义条件:检查MySQL服务是否已经安装

- name: Check mysqld package file installed
  shell: "if rpm -qa|grep mysql80-community-release-el7-11.noarc; then echo true; else ehco false;fi"
  ignore_errors: yes
  register: mysqld_package_file_installed # 定义自定义条件:检查MySQL源仓库是否已经安装

- name: Copy mysql package name file
  copy:
    src: mysql80-community-release-el7-11.noarch.rpm
    dest: ~/mysql80-community-release-el7-11.noarch.rpm
  when: mysqld_installed.stdout == "false" # 使用自定义条件进行判断

- name: Install mysql package name file
  shell:
    cmd: rpm -Uvh mysql80-community-release-el7-11.noarch.rpm
    chdir: ~
  when: mysqld_package_file_installed.stdout == "false"
  
- name: Install MySQL server
  yum:
    name: mysql-community-server
    state: installed
  when: mysqld_installed.stdout == "false"

最后执行安装:

# ansible-playbook role-sample.yaml 

PLAY [web] *****************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************
ok: [192.168.3.141]

TASK [Check mysqld installed] **********************************************************************************************************************************
changed: [192.168.3.141]

TASK [Check mysqld package file installed] *********************************************************************************************************************
changed: [192.168.3.141]

TASK [Copy mysql package name file] ****************************************************************************************************************************
ok: [192.168.3.141]

TASK [Install mysql package name file] *************************************************************************************************************************
skipping: [192.168.3.141]

TASK [mysql : Install MySQL server] ****************************************************************************************************************************
changed: [192.168.3.141]

PLAY RECAP *****************************************************************************************************************************************************
192.168.3.141              : ok=5    changed=3    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

【参考】
ansible的setup模块和Facts变量及magic变量
Ansible facts详解
Roles


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,在下面评论区告诉我^_^^_^