• 从入门到精通Ansible Playbook,一篇就够了


    一、Host Inventory(主机清单)

    在这里插入图片描述

    1.1 简介

    Inventory支持对主机进行分组每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。

    1.2 inventory 文件

    默认路径为/etc/ansible/hosts

    Ansible Inventory 文件是一个纯文本文件,用于定义 Ansible 执行命令的目标主机和组,以及这些主机和组的变量和属性

    Inventory 文件的构成包括:

    1)主机与组

    • 主机:一个主机就是目标机器,可以是 IP 地址、域名或在 SSH 配置中定义的别名,也可以使用 ansible_host 指定。

    • 组:可以将多个主机划分到同一个组中,并可以对组进行操作。

      示例:

    [WebServer]
    192.168.1.10
    192.168.1.11
    192.168.1.12
    
    [DatabaseServer]
    192.168.1.20
    192.168.1.21
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意:组名不能包含空格,并且主机和组名必须放在方括号中

    2)变量

    • 主机变量:为单个主机指定变量,使用主机名或 IP 地址作为标识符,变量可以设置为一个或多个值。

      示例:

    [ServerA]
    192.168.1.10 http_port=80 https_port=443
    
    [ServerB]
    serverb.example.com ansible_user=admin ansible_password=1234
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 组变量:在组名之后,使用 vars 关键字设置变量,可以在组间共享变量。示例:
    #所有主机指定 `ansible_ssh_user` 变量,这意味着每个主机都具有该变量。
    #为每个主机定义唯一的 `name` 变量。
    [WebServer]
    192.168.1.10 name=webserver1
    192.168.1.11 name=webserver2
    192.168.1.12 name=webserver3
    
    [DatabaseServer]
    192.168.1.20 name=dbserver1
    192.168.1.21 name=dbserver2
    
    [all:vars]
    ansible_ssh_user=centos
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3)组的嵌套
    将一个组嵌套到另一个组中,在 Inventory 文件中使用 :children 关键字。

    示例:

    #将 `WebServer` 和 `DatabaseServer` 组嵌套到 `Production` 组中。
    [WebServer]
    192.168.1.10
    192.168.1.11
    192.168.1.12
    
    [DatabaseServer]
    192.168.1.20
    
    [Production:children]
    WebServer
    DatabaseServer
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4)别名
    使用 Alias(别名)来引用 Inventory 中的主机。

    示例:

    #为 `WebServer` 和 `DatabaseServer` 组定义别名,并将它们作为两个分离的组 `Web` 和 `Db` 的成员
    #创建了一个名为 `Production` 的组,该组由这两个组的别名组成。
    [WebServer]
    192.168.1.10
    192.168.1.11
    192.168.1.12
    
    [DatabaseServer]
    192.168.1.20
    
    [Web:children]
    WebServer
    
    [Db:children]
    DatabaseServer
    
    [Production]
    @Web
    @Db
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1.2 inventory 中的变量

    hosts 文件中为主机或组定义变量,在 playbook 中可以直接调用变量。

    Inventory变量名含义
    ansible_hostansible连接节点时的IP地址
    ansible_port连接对方的端口号,ssh连接时默认为22
    ansible_user连接对方主机时使用的用户名。不指定时,将使用执行ansible或ansible-playbook命令的用户
    ansible_password连接时的用户的ssh密码,仅在未使用密钥对验证的情况下有效
    ansible_ssh_private_key_file指定密钥认证ssh连接时的私钥文件
    ansible_ssh_common_args提供给ssh、sftp、scp命令的额外参数
    ansible_become允许进行权限提升
    ansible_become_method指定提升权限的方式,例如可使用sudo/su/runas等方式
    ansible_become_user提升为哪个用户的权限,默认提升为root
    ansible_become_password提升为指定用户权限时的密码

    举个例子

    1)首先定义一个 my_port 变量,其值为 http_port 变量;

    2)然后使用 uri 模块检查 defined myserver 主机上特定端口的服务是否运行,并将结果存储在 result 变量中;

    3)最后使用 debug 模块输出该服务的响应内容。

    #编辑清单文件,定义变量
    vim /etc/ansible/hosts
    
    [webservers]
    192.168.2.102 ansible_host=192.168.2.102 http_port=8080
    
    • 1
    • 2
    • 3
    • 4
    • 5
    #在 playbook 中,用 `vars` 字段来使用变量:
    - name: Example playbook using inventory variable
      hosts: webservers
      tasks:
        - name: Ping the web server
          uri:
            url: "http://{{inventory_hostname}}:{{http_port}}"
            return_content: yes
          register: result
        - name: Show the response
          debug:
            var: result.content
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    二、Playbook 剧本

    在这里插入图片描述

    2.1 简介

    Playbook 剧本是由一个或多个play组成的列表。

    play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。

    Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作

    Playbook 文件是采用YAML语言编写的。

    2.2 Playbook的组成部分

    1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行;

    2)Variables:变量;

    3)Templates:模板;

    4)Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作;

    5)Roles:角色。

    2.3 如何编写Playbook?

    2.3.1 基本格式

    • 在单一文件第一行,用连续三个连字号“-” 开始,还有选择性的连续三个点号( … )用来表示文件的结尾;
    • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能;
    • 使用#号注释代码;
    • 缩进必须是统一的,不能空格和tab混用;
    • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的;
      YAML文件内容是区别大小写的,key/value的值均需大小写敏感;
    • 多个key/value可同行写也可换行写,同行使用,分隔;
    • v可是个字符串,也可是另一个列表;
    • 一个完整的代码块功能需最少元素需包括 name 和 task;
    • 一个name只能包括一个task;
    • YAML文件扩展名通常为yml或yaml
    xxx.yaml/xxx.yml
    --- #表示开始
    - name:  #指定play的名称
      hosts: #指定主机清单中定义的主机组名
      remote_user: #指定远程主机的执行用户
      grather_facts: ture|fales #指定是否要收集远程主机的facts信息
      vars:   #自定义变量,只能在当前play有效
        - 变量1: 值1  #格式为key: value
        - 变量2: 值2
      tasks: #定义任务列表,默认从上往下依次执行
        - name: #定义任务的名称
          模块名: 模块参数        
          ignore errors: true  #忽略任务的失败
        - name: #可以定义多个任务
          模块名: 模块参数  
          notify: 任务名  #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
          ##条件判断##
         - name:
           模块名: 模块参数
           when: #定义条件表达式(== != > < >= <=),条件成立时执行此task任务,否则不执行任务
           ##循环##
         - name:
           模块名: 模块参数={{item}}
           with_items: #定义循环列表
         ##tags模块,标签## 
         - name: 
           模块名: 模块参数 
           tags:
           - 标签1
           - 标签2
            
      handlers: 
        - name: 任务名  #和notify中的任务名相同
          模块名: 模块参数
    
    #无注释版
    ---
    - name: 
      hosts: 
      remote_user:
      grather_facts: ture|fales 
      vars:
        - 变量1: 值1
        - 变量2: 值2
      tasks:
        - name:
          模块名: 模块参数        
          ignore errors: true
        - name:
          模块名:
          notify: 任务名
         - name:
           模块名:
           when:
         - name:
           模块名: 模块参数={{item}}
           with_items:
      handlers: 
        - name: 任务名
          模块名: 模块参数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler。

    这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。

    2.3.2 语句的横向/纵向写法

    横向写法一般是数组类型

    纵向写法一般是列表类型

    task任务的模块语法格式
    横向格式:
    模块名: 参数1=值 参数2={{变量名}} ...
    
    纵向格式:
    模块名:
      参数1: 值
      参数2: "{{变量名}}"
      ...
      
    with_items 和 vars 的语法格式
    横向格式:
    with_items: ["值1", "值2", "值3", ...]
    
    值为对象(键值对字段)时:
    with_items:
    - {key1: "值1", key2: "值2"}
    - {key1: "值3", key2: "值4"}
    ...
    
    纵向格式:
    with_items:
    - 值1
    - 值2
    - 值3
    ...
    
    值为对象(键值对字段)时:
    with_items:
    - key1: "值1"
      key2: "值2"
    - key1: "值3"
      key2: "值4"
    ...
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    三、Playbook实例和知识点补充

    3.1 编写yum安装nginx的playbook

    1.先更新主机清单

    在这里插入图片描述

    2.编写剧本

    cd /etc/ansible
    
    • 1
    #编写yaml文件,安装nginx的剧本
    vim test.yaml
    
    ---
     - name: first play
       hosts: dbservers
       remote_user: root
       gather_facts: false
       tasks:
         - name: firewalld
           service: name=firewalld state=stopped enabled=no
         - name: selinux
           command: '/usr/sbin/setenforce 0 '
           ignore_errors: true
         - name: mount
           mount: src=/dev/sr0 path=/mnt state=mounted fstype=iso9660
         - name: local.repo
           copy: src=/etc/yum.repos.d/local.repo dest=/etc/yum.repos.d/
         - name: epel.repo
           copy: src=/etc/yum.repos.d/epel.repo dest=/etc/yum.repos.d/
         - name: nginx install
           yum: name=nginx state=latest
         - name: configuration file
           copy: src=/usr/local/nginx/conf/nginx.conf dest=/etc/nginx/nginx.conf
           notify: "reload nginx"
         - name: start nginx
           service: name=nginx state=started enabled=yes
       handlers:
         - name: reload nginx
           service: name=nginx state=reloaded
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

    3.运行剧本

    ansible-playbook test.yaml
    
    • 1

    在这里插入图片描述

    4.查看db服务器组的主机

    systemctl status firewalld
    getenforce
    
    systemctl status nginx
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3.2 参数补充

    #执行playbook
    ansible-playbook xx.yaml/yml [参数]
    
    • 1
    • 2
    常用参数描述
    --syntax-check检查yaml文件的语法是否正确
    --list-task检查tasks任务
    --list-hosts检查生效的主机
    --start-at-task=' name ' 指定从某个task开始运行一般用于剧本较长且不想从头重复执行的场景
    -k用来交互输入ssh密码-ask-pass
    -K用来交互输入sudo密码-ask-become-pass
    -u指定用户
    #检查yaml文件的语法是否正确
    ansible-playbook test.yaml --syntax-check    
    
    • 1
    • 2

    在这里插入图片描述

    #检查tasks任务
    ansible-playbook test.yaml --list-task      
    
    • 1
    • 2

    在这里插入图片描述

    #检查生效的主机
    ansible-playbook test.yaml --list-hosts      
    
    • 1
    • 2

    在这里插入图片描述

    #指定从 nginx install 开始运行
    ansible-playbook test.yaml --start-at-task='nginx install'
    
    • 1
    • 2

    在这里插入图片描述

    3.3 变量的定义和引用

      vars:   #自定义变量,只能在当前play有效
        - 变量1: 值1  #格式为key: value
        - 变量2: 值2
      tasks:  #在任务列表中引用变量
        -name:
         module: {{变量1}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方式一:在yaml文件中定义和引用

    vim test2.yml
    
    ---
     - name: second play
       hosts: dbservers
       remote_user: root
       gather_facts: true
       vars: 
         - groupname: mysql 
         - username: nginx
       tasks:
         - name: create group
           group: name={{groupname}} system=yes gid=306    #使用 {{key}} 引用变量的值
         - name: create user
           user: name={{username}} uid=306 group={{groupname}} 
         - name: copy file
           copy: content="{{ansible_default_ipv4.network}}" dest=/opt/vars.txt    #在setup模块中可以获取facts变量信息
           
    #ansible_default_ipv4为facts变量信息中的字段
    #ansible_default_ipv4.network中的 .network表示只提取信息中network部分
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    ansible-play test2.yml
    
    • 1

    在这里插入图片描述

    方式二:在命令行定义

    ansible-playbook test1.yaml -e "username=nginx"
    #通过 -e 参数传递一个额外的变量 "username=nginx" 给 playbook
    #playbook 将会使用变量 "username" 的值设置为 "nginx"
    
    • 1
    • 2
    • 3

    3.4 指定远程主机sudo切换用户

    使用-k-K 参数实现。

    1)先编写剧本

    vim test2.yaml
    
    ---
    - hosts: webservers
      remote_user: test2            
      become: yes	                 #2.6版本以后的参数,之前是sudo,意思为切换用户运行
      become_user: root              #指定sudo用户为root
      tasks: 
        - name: ts
          command: ls ./
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2)执行剧本

    #执行playbook,加上参数-k和-K
    ansible-playbook test2.yml -k -K 
    
    • 1
    • 2

    3.5 when条件判断

    3.5.1 用法

    在Ansible中,提供的唯一一个通用的条件判断when指令

    当when指令的值为true时,则该任务执行否则不执行该任务。

    When指令一个比较常见的应用场景是实现跳过某个主机不执行任务 或者 只有满足条件的主机执行任务。

    3.5.2 实例

    1.编写剧本,使用条件判断语句

    #如果条件判断成功,则对应主机关机
    vim test3.yaml
    
    ---
    - hosts: all
      remote_user: root
      tasks:
       - name: poweroff host 
         command: /usr/sbin/poweroff -r now
         when: ansible_default_ipv4.address == "192.168.2.102"      
         #when指令中的变量名不需要手动加上 {{}}when: inventory_hostname == "<主机名>"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.执行剧本

    #执行剧本
    ansible-playbook test3.yaml
    
    • 1
    • 2

    在这里插入图片描述

    3.6 迭代(循环结构)

    Ansible提供了很多种循环结构,一般都命名为with_items,作用等同于 loop 循环

    vim test4.yaml
    ---
    - name: play1
      hosts: dbservers
      gather_facts: false
      tasks: 
        - name: create file
          file:
            path: "{{item}}"
            state: touch
          with_items: [ /opt/a, /opt/b, /opt/c, /opt/d ]
    
    
    - name: play2
      hosts: dbservers
      gather_facts: false		
      vars:
        test:
        - /tmp/test1
        - /tmp/test2
        - /tmp/test3
        - /tmp/test4
      tasks: 
        - name: create directories
          file:
            path: "{{item}}"
            state: directory
          with_items: "{{test}}"
    		
    - name: play3
      hosts: dbservers
      gather_facts: false
      tasks:
        - name: add users
          user: name={{item.name}} state=present groups={{item.groups}}
          with_items:
            - name: test1
              groups: wheel
            - name: test2
              groups: root
    或
          with_items:
            - {name: 'test1', groups: 'wheel'}
            - {name: 'test2', goups: 'root'}
    
    
    ansible-playbook test3.yaml
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    四、Playbook的模块

    4.1 Template配置模板模块

    用于生成配置模板文件,配合hosts中定义的变量,或者剧本中定义的变量,为不同主机生成不同的配置参数。

    Jinja是基于Python的模板引擎。

    Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板去替换模板中的标记。

    4.1.1 怎么使用?

    1)先准备一个xxx.j2配置模板文件,在文件中使用{{变量名}} 引用主机变量或者vars字段自定义的变量 以及 facts信息字段做变量的值;

    2)在playbook剧本中的task任务定义template模块配置。

    template: src--xxx.j2 文件路径 dest-远程主机文件路径
    
    • 1

    4.1.2 实例

    1)先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变量

    mkdir /etc/ansible/playbook
    cp /usr/local/nginx/conf/nginx.conf /etc/ansible/playbook/nginx.conf.j2
    
    • 1
    • 2

    在这里插入图片描述

    vim /etc/ansible/playbook/nginx.conf.j2
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

    2)修改主机清单文件,使用主机变量定义一个变量名相同,而值不同的变量

    vim /etc/ansible/hosts
    
    [webservers]
    192.168.2.102 http_port=192.168.2.102:80 server_name=www.test1.com:80 root_dir=/var/www/html
    192.168.2.103 http_port=192.168.2.103:80 server_name=www.test2.com:80 root_dir=/var/www/html
    
    [dbservers]
    192.168.2.106 http_port=192.168.2.103:80 server_name=www.test3.com:80 root_dir=/var/www/html
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    3)编写 playbook并执行

    #编写剧本
    vim nginx1.yaml
    ---
    - name: new play
      hosts: webservers:dbservers
      remote_user: root
      gather_facts: yes
      tasks:
      - name: disable firewalld
        systemd:
          name: firewalld
          state: stopped
          enabled: no
      - name: disable selinux
        command: '/usr/sbin/setenforce 0'
        ignore_errors: true
      - name: copy local repo file
        copy:
          src: /etc/yum.repos.d/repo.bak/local.repo
          dest: /etc/yum.repos.d/
      - name: mount cdrom
        mount: src=/dev/sr0 path=/mnt state=mounted fstype=iso9660
      - name: install dependent packages
        with_items:
        - gcc
        - gcc-c++
        - make
        - pcre-devel
        - zlib-devel
        - openssl-devel
        yum: name={{item}} state=present
          #name: "gcc,gcc-c++,make,pcre-devel,zlib-devel,openssl-devel"
          #state: present
      - name: unarchive nginx package
        unarchive: copy=yes src=/opt/nginx-1.24.0.tar.gz dest=/opt/
      - name: install nginx
        shell: chdir=/opt/nginx-1.24.0/ ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module && make && make install
      - name: copy nginx config file
        template: src=/etc/ansible/playbook/nginx.conf.j2 dest=/usr/local/nginx/conf/nginx.conf
        notify: "reload nginx"
      - name: copy nginx systemd control script
        copy: src=/etc/ansible/playbook/nginx.service dest=/usr/lib/systemd/system/
      - name: create nginx user
        user: name=nginx shell=/sbin/nologin create_home=no
      - name: start nginx
        service: name=nginx state=started enabled=yes
      - name: create root dir
        file: path={{root_dir}} state=directory
      - name: create index.html for 2.102
        copy: content="this is test1" dest={{root_dir}}/index.html
        when: ansible_default_ipv4.address == "192.168.2.102"
      - name: create index.html for 2.103
        copy: content="this is test2" dest={{root_dir}}/index.html
        when: ansible_default_ipv4.address == "192.168.2.103"
      - name: create index.html for 2.106
        copy: content="this is test3" dest={{root_dir}}/index.html
        when: ansible_default_ipv4.address == "192.168.2.106"
      handlers:
      - name: reload nginx
        service: name=nginx state=reloaded
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    ``在这里插入图片描述

    #执行剧本
    ansible-playbook nginx1.yaml
    
    • 1
    • 2

    在这里插入图片描述

    4)切换到组内主机,查看是否配置了不同的参数

    grep -v -e '^$' -e '#' /usr/local/nginx/conf/nginx.conf
    #观察配置文件是否修改成功
    
    • 1
    • 2

    在这里插入图片描述

    4.2 tags模块

    可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用–tags选项能实现仅运行指定的tasks。

    playbook还提供了一个特殊的tags为always。

    作用就是当使用always作为tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。

    4.3 Roles模块

    Roles用于层次性、结构化地组织playbook,适用于代码复用度较高的场景。

    4.3.1 Roles模块的作用(重要)

    将playbook剧本中的各个play视作一个角色,将各个角色的tasks任务vars变量templates模板files文件等内容放置在指定角色的目录中统一管理。

    需要的时候可以在playbook中使用roles角色直接调用,即roles角色可以在playbook中实现代码的复用

    4.3.2 roles 的目录结构

    cd /etc/ansible/
    tree roles/
    roles/
    ├── web/    #相当于 playbook 中的 每一个 play 主题
    │   ├── files/
    │   ├── templates/
    │   ├── tasks/
    │   ├── handlers/
    │   ├── vars/
    │   ├── defaults/
    │   └── meta/
    └── db/
        ├── files/
        ├── templates/
        ├── tasks/
        ├── handlers/
        ├── vars/
        ├── defaults/
        └── meta/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4.3.3 roles 内各目录含义解释

    目录含义
    files用来存放由 copy 模块或 script 模块调用的文件
    templates用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件
    tasks此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件
    handlers此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作
    vars此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量
    defaults此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。 这些变量具有所有可用变量中最低的优先级,并且可以很容易地被任何其他变量覆盖。所以生产中我们一般不在这里定义变量
    meta此目录应当包含一个 main.yml 文件,用于定义此角色的元数据信息及其依赖关系

    4.3.3 在一个 playbook 中使用 roles 的步骤

    1)创建以 roles 命名的目录;

    #举个例子
    mkdir /etc/ansible/roles/ -p    #yum装完默认就有
    
    • 1
    • 2

    2)创建全局变量目录(可选);

    #举个例子
    mkdir /etc/ansible/group_vars/ -p
    touch /etc/ansible/group_vars/all     #文件名自己定义,引用的时候注意
    
    • 1
    • 2
    • 3

    3)在 roles 目录中分别创建以各角色名称命名的目录,如 httpd、mysql;

    #举个例子
    mkdir /etc/ansible/roles/httpd
    mkdir /etc/ansible/roles/mysql
    
    • 1
    • 2
    • 3

    4)在每个角色命名的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,也可以不创建;

    #举个例子
    mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
    mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}
    
    • 1
    • 2
    • 3

    5)在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 main.yml 文件,千万不能自定义文件名

    #举个例子
    touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
    touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
    
    • 1
    • 2
    • 3

    6)修改 site.yml 文件,针对不同主机去调用不同的角色;

    #举个例子
    vim /etc/ansible/site.yml
    ---
    - hosts: webservers
      remote_user: root
      roles:
         - httpd
    - hosts: dbservers
      remote_user: root
      roles:
         - mysql
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    7)ansible-playbook运行剧本。

    #举个例子
    cd /etc/ansible
    ansible-playbook site.yml
    
    • 1
    • 2
    • 3

    4.3.4 实例

    1) 创建各角色的目录和main.yaml文件

    mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p
    mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
    mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p
    
    touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
    touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
    touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    2)编写httpd模块

    #写一个简单的tasks/main.yml
    vim /etc/ansible/roles/httpd/tasks/main.yml
    - name: install apache
      yum: name={{pkg}} state=latest
    - name: start apache
      service: enabled=true name={{svc}} state=started
     
    
    #定义变量:可以定义在全局变量中,也可以定义在roles角色变量中,一般定义在角色变量中存档
    vim /etc/ansible/roles/httpd/vars/main.yml
    pkg: httpd
    svc: httpd
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3)编写mysql模块

    vim /etc/ansible/roles/mysql/tasks/main.yml
    - name: install mysql
      yum: name={{pkg}} state=latest
    - name: start mysql
      service: enabled=true name={{svc}} state=started
      
    vim /etc/ansible/roles/mysql/vars/main.yml
    pkg:
      - mariadb
      - mariadb-server
    svc: mariadb
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4)编写php模块

    vim /etc/ansible/roles/php/tasks/main.yml
    - name: install php
      yum: name={{pkg}} state=latest
    - name: start php-fpm
      service: enabled=true name={{svc}} state=started
    
    vim /etc/ansible/roles/php/vars/main.yml
    pkg:
      - php
      - php-fpm
    svc: php-fpm
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5)编写roles示例

    vim /etc/ansible/site.yml
    ---
    - hosts: webservers
      remote_user: root
      roles:
       - httpd
       - mysql
       - php
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    cd /etc/ansible
    ansible-playbook site.yml
    
    • 1
    • 2

    在这里插入图片描述

    6)效果测试

    切换到webservers组的主机
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    一个简单的查询学生信息的接口测试
    云计算-Hadoop-2.7.7 最小化集群的搭建(3台)
    【splishsplash】PBD探究
    centos7 Kafka安装
    跨境干货 | 如何搭建自己的独立站?
    PDE数值解中,为什么要引入弱解(weak solution)的概念?
    Java三大特性篇之——继承篇(超详解的好吧!)
    C++基础语法和概念
    阿里云验证SSL证书
    0033【Edabit ★☆☆☆☆☆】【字符串表达式计算器】Miserable Parody of a Calculator
  • 原文地址:https://blog.csdn.net/q2524607033/article/details/134089507