Ansible自动化运维(三)playbook剧本详解

Ansible自动化运维这部分我将会分为五个部分来为大家讲解

(一)介绍、无密钥登录、安装部署、设置主机清单

(二)Ansible 中的 ad-hoc 模式 模块详解(15)个

(三)Playbook 模式详解

(四)jinja2 模板 Roles角色详解

(五)运维实战

相关文章大家在最后可以看到

目录

[一、Ansible 中的 Playbook 模式](#一、Ansible 中的 Playbook 模式)

[1.1 Playbook 的优势](#1.1 Playbook 的优势)

[1.2 Playbook 的组成](#1.2 Playbook 的组成)

[1.3 Playbook命令](#1.3 Playbook命令)

[1.4 Playbook的语法](#1.4 Playbook的语法)

1、权限

2、通知与触发

[1.5 Playbook中的变量](#1.5 Playbook中的变量)

[1.1 通过vars 定义变量](#1.1 通过vars 定义变量)

[1.2 通过vars_files定义变量](#1.2 通过vars_files定义变量)

1.3命令行定义变量

[1.4 官方推荐定义变量方法(推荐)](#1.4 官方推荐定义变量方法(推荐))

[1.6 debug](#1.6 debug)

[1.7 facts缓存](#1.7 facts缓存)

二、Playbook中的流程控制

Playbook条件

[1.1 条件判断](#1.1 条件判断)

[1.2 组合判断](#1.2 组合判断)

[1.3 操作实例](#1.3 操作实例)

Playbook的循环

[1.1 批量安装软件包](#1.1 批量安装软件包)

[1.2 批量创建用户](#1.2 批量创建用户)

[1.3 批量创建组](#1.3 批量创建组)

[1.4 批量删除用户和组](#1.4 批量删除用户和组)

[1.5 批量复制文件](#1.5 批量复制文件)

异常处理:

Tags标签

1、打标签的用法

[1.1 打标签的方式](#1.1 打标签的方式)

[1.2 标签的使用,](#1.2 标签的使用,)

[1.3 标签的作用](#1.3 标签的作用)


一、Ansible 中的 Playbook 模式

Playbook不同于使用单个模块操作远程服务器,Playbook的功能更加强大。如果说单个模块执行类似于Linux系统中的命令,那么Playbook就类似于shell脚本,将多个模块组合起来实现一组的操作。

Playbook还是会用到ad-hoc模式中的模块及参数,只不过Playbook与ad-hoc的写法不一样。

1.1 Playbook 的优势

功能比ad-hoc更全

能很好的控制先后执行顺序, 以及依赖关系

语法展现更加的直观

ad-hoc无法持久使用,playbook可以持久使用

1.2 Playbook 的组成

play:一个完整的部署任务,并且必须包含以下前两项:

hosts:定义对哪些主机进程操作

tasks:定义的是具体执行的任务

become:表示是否要以特权用户(通常是root)身份执行任务。如果设置为yes,则任务会以特权身份执行。

playbook: 由一个或多个play组成,一个play可以包含多个task任务

说明:Ansible 中的 Playbook 文件结尾为.yml 格式

示例:安装host1节点 httpd 服务并且在host3节点上重启nginx并且检查他们的服务状态

[root@server ~]# vi httpd.yml
[root@server ~]# cat httpd.yml
---
 - hosts: node1
   become: yes
   tasks:
   # 使用yum模块在node1主机上安装httpd服务  
     - name: Install httpd Server
       yum:
         name: httpd
         state: present

解析:

name:定义一个Playbook的名称,用于标识Playbook的用途;

hosts:指定要在哪个主机上执行,也是写主机或主机组名,

需要提前在/etc/ansible/hosts中配置好;

become:yes表示使用特权用户;

tasks:属于是一个任务列表,主要写具体执行什么的(可以有多个);

name:每个任务的名称,用于描述干什么的;上述yml中则是安装httpd服务;

yum:表示使用哪个模块来进行操作;

模块的参数可以看ad-hoc中的,用的都是一样的,写法不一样就是;

name:要安装的服务名称,我们这里是httpd:

state:要进行的操作,可以是安装、卸载、更新;

其实tasks就是Ansible的模块以YAML语法写入到playbook中。

生产环境中为了可读性与可维护性通常一个playbook中只编写一个play,如果某些主机需要执行多个play,那么可以使用include关键字在一个playbook中导入其他的playbook。

1.3 Playbook命令

格式:

ansible-playbook [选项] playbook.yml 

常用选项:

|-----------------|-----------------------------|
| 选项/参数 | 选项/参数/分析 |
| -T | 建立SSH连接的超时时间 |
| -i | 指定Inventory文件 |
| - -list-hosts | 匹配的服务器列表 |
| - -list-tasks | 列出任务列表 |
| - -step | 每执行一个任务后停止,等待用户确认 |
| - -syntax-check | 语法检测 |
| - -list-tags | 列出此yml文件中的所有tag标签 |
| - -skip-tags | 执行--skip-tags之外的标签任务 |
| -C | 检查当前这个Playbook是否会修改受控端,模拟执行 |
| -f | 并发执行的进程数,默认为5 |

1.4 Playbook的语法

1、权限

remote_user指定playbook运行时的用户身份,可以写在hosts下,也可以每个tasks做定义;

become 该选项为布尔值,当等于yes表示以管理员身份通常与become_method一起使用;

become_method:su或sudo

# 指定使用哪个用户执行此任务
remote_user: root
# 是否使用特权用户
become: yes

2、通知与触发

notify: 如果指定的操作执行了,会触发handlers的操作,指定的是handler的名称;
handlers和notify指定的名称必须相同,否则无法触发。
handlers 中需要- name指定名称 ,handlers只会在所有的tasks执行完后执行,
并且,即便一个handlers被触发多次,也只会执行一次。 handlers是一种特殊的tasks。

handlers(触发事件)

notify: 触发
handlers:触发的动作
# 两者的名称一定要相同,否则无法触发。

使用上场景:一般都是修改配置文件时

正常情况时handlers是不会执行的,除非触发任务,才会执行

任务导致系统状态发生变化(例如,配置文件被修改),则将触发名为restart的处理器。

bash 复制代码
- hosts: node1
  tasks:
  - name: installredis
    yum: name=redis
    
  - name: copyfile
    template: src=redis.conf dest=/etc/redis.conf
    tags: copyfile
    notify: restart   # 触发:触发名称
    
  - name: start
     service:
       name: redis
       state: started
       enabled: yes
    
  handlers:       # 触发动作
  - name: restart
    service:
      name: redis
      state: restarted

这是我又自己随便写的一个比较简单的

下载nginx并启动,启动成功后会自动执行关闭防火墙并且检查运行状态

bash 复制代码
[root@server ~]# cat nginx3.yml 
---
 - hosts: node3
   become: yes
   tasks:
     - name: install_nginx
       yum:
         name: nginx 
         state: present
      
     - name: Start_nginx
       service:
         name: nginx
         state: started
       notify: 
         - stop_firewalld
         - check_status_nginx  
         - display nginx status      
       changed_when: true  # 强制标记任务为已改变  
    
   handlers:
     - name: stop_firewalld
       service: 
         name: firewalld
         state: stopped
         enabled: no

     - name: check_status_nginx
       command: systemctl status nginx
       register: nginx_status
       changed_when: false
       
     - name: display nginx status
       debug:
         var: nginx_status.stdout_lines

在Ansible中,处理器(handlers)只有在任务状态发生变化时才会被触发。例如,如果Nginx服务之前已经是运行状态,那么Start_nginx任务不会被视为"改变"系统状态,因此不会触发处理器。

为了确保处理器能够被触发,你可以使用changed_when参数来强制标记任务为已改变,或者使用meta: flush_handlers来强制执行所有处理器。

1.5 Playbook中的变量

变量提供了便捷的方式来管理Ansible playbook的每一个项目中的动态值,比如nginx-1.6.3这个软件包的版本,在其它地方或许会反复使用,那么如果将此值设置为变量,然后再在其他的playbook中调用,会方便许多。如此一来还方便维护,减少维护的成本。

变量的定义方式

bash 复制代码
1.通过命令行进行变量定义
2.在play文件中进行变量定义
3.通过Inventory主机信息文件中进行变量定义

变量读取的优先级为: 命令行 > playbook文件 > Inventory文件

1.1 通过vars 定义变量

bash 复制代码
---
- name: LAMP
  hosts: node1
  vars:
    packages_name:
      - httpd
      - mariadb-server
      - php
      - php-mysql

  tasks:
    - name: install LAMP
      yum:
         name: "{{packages_name}}"
         state: present

执行此yml:

bash 复制代码
# 语法校验
ansible-playbook --syntax-check LAMP.yml
# 执行yml
ansible-playbook LAMP.yml(定义的yml文件名)

1.2 通过vars_files定义变量

当变量较少时,使用vars定义没有问题,当变量较多时,可以将变量保存到一个独立的文件中;

需要多个yml文件,一个主文件,需要调用其他yml独立文件,主要是最后运行的;其他是定义包名的yml文件。

bash 复制代码
[root@server ansible]# cat rzc.yml 
---
httpd_package: httpd
mariadb_package: mariadb-server
[root@server ansible]# vi nginx4.yml
[root@server ansible]# cat nginx4.yml 
---
 - name: nginx
   hosts: node3
   become: yes
   vars_files:
     - rzc.yml

   tasks:
     - name: Install httpd
       yum:
         name: "{{ httpd_package }}"
         state: present

     - name: Install mariadb-server
       yum:
         name: "{{ mariadb_package }}"
         state: present

执行此yml:

bash 复制代码
# 语法校验
ansible-playbook --syntax-check apache.yml
# 执行yml
ansible-playbook apache.yml(定义的yml文件名)

1.3命令行定义变量

ansible-playbook命令提供-e选项,用于在命令行定义变量,命令行定义变量的优先级最高

bash 复制代码
# 执行:命令行定义变量
[root@localhost yml]# vi test.yml
---
- name: apache 
  hosts: web
  become: yes
  vars: 
    httpd_package:
       - httpd

  tasks:
    - name: install httpd service
      yum:
        name: "{{ httpd_package }}"
        state: present
#定义阶段
[root@ansible ~]# ansible-playbook test.yml -e "httpd_package=httpd"

命令行指定多个变量。

bash 复制代码
ansible-playbook test.yml -e "file=command" -e "file2=command2"

1.4 官方推荐定义变量方法(推荐)

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

host_vars
group_vars

目录名字一定要一致,不能做任何修改。

理解如何设置和使用host_vars和group_vars可以使你的Ansible管理更加灵活和有组织。以下是更详细的步骤,从设置目录结构到创建Playbook的执行:

1.目录结构

your_ansible_project/

├── group_vars/

│ └── web-servers.yml

├── host_vars/

│ └── web-server.yml

├── playbook.yml

└── inventory.ini

bash 复制代码
group_vars目录用于存放组级别的变量定义。
host_vars目录用于存放主机级别的变量定义。
playbook.yml是你的Ansible Playbook。
inventory.ini是Ansible的主机清单文件,其中列出了你的主机和主机组。

2.清单文件(inventory.ini):

在这里添加你的主机和主机组

bash 复制代码
[root@server ~]# cat /etc/ansible/inventory.ini 
[node1]
host1
[node2]
host2
[node3]
host3
[node4]
host1
host3

3.组级别变量

group_vars/web-servers.yml

bash 复制代码
[root@server ~]# cd /etc/ansible/
[root@server ~]# mkdir -p /etc/ansible/group_vars
[root@server group_vars]# vi node4.yml
[root@server group_vars]# cat node4.yml 
---
httpd_package: httpd
mariadb_package: mariadb-server
nginx_package: nginx

4.主机级别变量

host_vars/web-server.yml

在host_vars目录下创建一个YAML文件,例如node1.yml,并在其中定义主机级别的变量,如:

bash 复制代码
[root@server ~]# cd /etc/ansible/
[root@server ~]# mkdir -p /etc/ansible/host_vars
[root@server ansible]# cd host_vars/
[root@server host_vars]# vi node3.yml
[root@server host_vars]# cat node3.yml 
---
nginx_package= nginx

5.Playbook(playbook.yml)

创建你的Ansible Playbook,例如:

bash 复制代码
[root@server ansible]# vi nginx4.yml 
[root@server ansible]# cat nginx4.yml 
---
 - name: nginx
   hosts: node3
   become: yes

   tasks:
     - name: Install nginx
       yum:
         name: "{{ nginx_package }}"
         state: present

6.运行playbook:

格式:

bash 复制代码
ansible-playbook -i inventory.ini playbook.yml

inventory.ini : 这里面表示你设置的主机分组

playbook.yml:你创造的脚本名称

此时,Ansible会自动加载group_vars和host_vars目录中的变量,你的Playbook将使用这些变量来配置主机。

通过这种方式,你可以更加有组织地管理变量,特别是对于多主机和多组的环境。你可以为不同的组或主机设置特定的变量,而不必在Playbook中硬编码这些值,提高了可维护性和可读性。

1.6 debug

将上一步任务执行的结果打印出来,不管成功还是失败都会返回;

bash 复制代码
- name: Check the status of httpd service 
  command: systemctl status httpd 
  register: httpd_status  # 存储到http_status变量中
  changed_when: false # 确保此任务不被标记为改变了系统状态 

- debug: # 输出httpd服务的状态信息 
    var: httpd_status.stdout_lines
    no_log: true  # 禁止记录此任务的输出

1.7 facts缓存

Ansible facts是在被管理主机上通过Ansible自动采集发现的变量。facts包含每台特定的主机信息。比如:被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。

facts变量的使用场景

bash 复制代码
通过facts缓存检查CPU,来生成对应的nginx配置文件
通过facts缓存检查主机名,生成不同的zabbix配置文件
通过facts缓存检索物理机的内存大小来生成不同的mysql配置文件

可以使用setup模块查看facts变量列表:

bash 复制代码
[root@server ~]# ansible node1 -m setup
host1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.232.101"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::cc52:8279:7d75:72a2", 
            "fe80::bfc3:2b7c:6878:575a", 
            "fe80::75a4:11da:7c98:fc74"
        ], 

下面省略,有好多;

显示 ipv4的所有地址:

bash 复制代码
[root@server ansible]# vi facts.yml
[root@server ansible]# cat facts.yml 
---
- hosts: node1
  become: yes
  tasks:
    - shell: echo {{ ansible_all_ipv4_addresses }}
      register: my_vars

    - debug:
        var: my_vars.stdout_lines
[root@server ansible]# ansible-playbook -i inventory.ini facts.yml 

在playbook中引用facts变量:

二、Playbook中的流程控制

Playbook条件

1.1 条件判断

when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行,并且跳过此步骤。

例:host3主机系统必须为 Centos系统

bash 复制代码
[root@server ansible]# cat when.yml 
---
- hosts: node3
  tasks: 
    - name: when
      shell: echo "hello world"
      when:
        - ansible_facts.distribution == 'CentOS'
      register: hhh

    - debug:
        var: hhh.stdout_lines

执行:

bash 复制代码
 ansible-playbook -i inventory.ini when.yml

执行成功

如果被控主机不是CentOS系统,条件不符,会出现什么状况呢?

这里我拿Ubuntu来为大家举例:

bash 复制代码
[root@server ansible]# cat when.yml 
---
- hosts: node3
  tasks: 
    - name: when
      shell: echo "hello world"
      when:
        - ansible_facts.distribution == 'Ubuntu'
      register: hhh

    - debug:
        var: hhh.stdout_lines

执行:

bash 复制代码
ansible-playbook -i inventory.ini when.yml

这里可以看到,when条件不符,所以并没有执行,而是跳过了这步。

1.2 组合判断

在Ansible中,when 语句可以用于组合多个条件判断,以实现更复杂的逻辑控制。以下是几种常用的 when 条件组合方式及其应用场景:

1、使用 and 组合条件

当所有条件都必须为真时才执行任务,可以使用 and 关键字。

bash 复制代码
cat lifeng1.yml
bash 复制代码
[root@server ansible]# cat lifeng1.yml
---
  - hosts: host1,host3
    become: yes
    tasks:
      - name: Print message for CentOS
        debug:
          msg: "恭喜你执行成功"
        when: >
          ansible_facts.distribution == 'CentOS' and 
          ansible_facts.distribution == 'CentOS'

执行:

bash 复制代码
ansible-playbook -i inventory.ini lifeng1.yml

2、使用 or 组合条件

当只要有一个条件为真时就执行任务,可以使用 or 关键字。
示例:检查操作系统是否为Ubuntu或CentOS

bash 复制代码
[root@server ansible]# cat rzc.yml 
---
- hosts: node1
  become: yes
  tasks:
    - name: Print message for Ubuntu or CentOS
      debug:
        msg: "This is either Ubuntu or CentOS"
      when: >
        ansible_facts.distribution == 'Ubuntu' or 
        ansible_facts.distribution == 'CentOS'

执行:

bash 复制代码
ansible-playbook -i inventory.ini rzc.yml 

3、使用not进行否定条件

not可以用来否定一个条件,当条件不满足时执行任务。

举例:我的系统是 CentOS

我的条件判断是当系统不是Ubuntu时,输出"hello world"

bash 复制代码
[root@server ansible]# cat when.yml
bash 复制代码
[root@server ansible]# cat when.yml 
---
- hosts: node3
  tasks: 
    - name: when
      shell: echo "hello world"
      when:
        - not (ansible_facts.distribution == 'Ubuntu')
      register: hhh

    - debug:
        var: hhh.stdout_lines

去执行:

bash 复制代码
ansible-playbook -i inventory.ini when.yml

4、混合使用and、or和not

你可以混合使用这些运算符来创建更复杂的条件表达式。

bash 复制代码
[root@server ansible]# cat when.yml
bash 复制代码
[root@server ansible]# cat when.yml 
---
- hosts: node3
  tasks: 
    - name: when
      shell: echo "hello world"
      when: >
        ansible_facts.distribution == 'CentOS' and
        ansible_facts.distribution == 'CentOS' or
        ansible_facts.distribution != 'Ubuntu'
      register: hhh

    - debug:
        var: hhh.stdout_lines

这实际上对于CentOS总是成立,所以这个例子有点多余,但为了演示目的):

and前后必须都要满足条件才能执行,and后面由于添加了or所以它前后其中一个成立即可

1.3 操作实例

我们给host1主机创建hhhhh1的用户,host3主机不做任何动作。然后我们写一个同时删除这两个主机中的hhhhh1用户的脚本,执行之后看一看是什么效果吧。

我们给host1主机创建hhhhh1用户:

bash 复制代码
ansible node1 -i inventory.ini -m user -a "name=hhhhh1 state=present"

检查:

bash 复制代码
ansible node1 -i inventory.ini -m command -a "tail -3 /etc/passwd"

接下来我们写一个脚本

bash 复制代码
[root@server ansible]# cat hhhhh.yml
bash 复制代码
---
- hosts: node4
  become: yes
  tasks:
    - name: delete user hhhhh1
      user: 
        name: hhhhh1
        state: absent
      register: abest_user
      ignore_errors: yes # 执行错误,play继续。
    - debug:
        msg: "命令执行成功"
      when:
        abest_user.changed == True

    - debug:
        msg: "命令执行失败"
      when:
        abest_user.changed != True

执行:

bash 复制代码
ansible-playbook -i inventory.ini hhhhh.yml 

从这张图片就可以看出,因为我们之前就只在host1主机下创建名为hhhhh1的用户,而host3主机并没有创建。所以执行脚本后,由图可知,host1主机执行成功并且成功删除了hhhhh1的用户。但是host3主机我们之前并没有创建用户,所以并未做出删除的步骤,就直接跳过

Playbook的循环

1.1 批量安装软件包

bash 复制代码
[root@server ansible]# cat with_item.yml 
bash 复制代码
[root@server ansible]# cat with_item.yml 
---
- hosts: node3
  become: yes
  tasks:
    - name: Installed packages
      yum: 
       name: "{{ item }}"
       state: present
      
      loop:
        - wget
        - tree
        - lrzsz

执行:

bash 复制代码
ansible-playbook -i inventory.ini  with_item.yml

但是并不建议使用循环方式使用yum模块来安装软件包,这里只是为了展示效果

1.2 批量创建用户

标准循环使用场景------批量创建用户

bash 复制代码
[root@server ansible]# cat user2.yml 
bash 复制代码
[root@server ansible]# cat user2.yml 
---
- hosts: node4
  become: yes
  tasks: 
    - name: 批量创建用户
      user:
        name: "{{ item }}"
        state: present
      
      loop:
        - lifeng1
        - lifeng2
        - lifeng3

执行:

bash 复制代码
ansible-playbook -i inventory.ini user2.yml

1.3 批量创建组

bash 复制代码
[root@server ansible]# cat user3.yml
bash 复制代码
[root@server ansible]# cat user3.yml 
---
- hosts: node4 
  become: yes
  tasks: 
    - name: 批量创建组
      group:
        name: "{{ item }}"
        state: present

      loop:
        - mygroup1
        - mygroup2
        - mygroup3

执行:

bash 复制代码
ansible-playbook -i inventory.ini user3.yml

1.4 批量删除用户和组

删除lifeng用户和删除mugroup组

bash 复制代码
[root@server ansible]# cat drop.yml 
bash 复制代码
[root@server ansible]# cat drop.yml 
---
- hosts: node4
  become: yes
  tasks:
    - name: 删除用户
      user: 
        name: "{{ item }}"
        state: absent
      loop:
        - lifeng1
        - lifeng2
        - lifeng3

    - name: 删除组
      group:
        name: "{{ item }}"
        state: absent         
      loop:
        - mygroup1
        - mygroup2
        - mygroup3

执行:

bash 复制代码
ansible-playbook -i inventory.ini drop.yml drop.yml

1.5 批量复制文件

标准循环使用场景 - 批量拷贝多个文件

bash 复制代码
[root@server ansible]# cat copy.yml
bash 复制代码
[root@server ansible]# cat copy.yml 
---
- hosts: node1
  become: yes
  tasks: 
    - name: 复制文件
      copy:
        src: "{{ item.src }}" 
        dest: "{{ item.dest }}"
        mode: "{{ item.mode }}"
      loop:
        - {src: "/opt/a.sh", dest: "/root/a.sh", mode: "0777"}
        - {src: "/opt/b.sh", dest: "/root/b.sh", mode: "0777"}

执行:

bash 复制代码
ansible-playbook -i inventory.ini copy.yml 

异常处理:

默认Playbook会检查命令和模块的返回状态,如遇到错误就中断playbook的执行

加入参数: ignore_errors: yes # 忽略错误

bash 复制代码
[root@server ansible]# cat expect.yml
bash 复制代码
[root@server ansible]# cat expect.yml 
---
- hosts: node3
  become: yes
  tasks:
    - name: 忽略错误,play继续
      command: ps -aux | grep nginx
     #ignore_errors: yes

    - name: 开启nginx服务
      service:
        name: nginx
        state: started

正常command模块是不可以使用管道命令的,

我们先把 ignore_errors: yes 注释,来一起看一看执行的效果:

大家可以看到,正常执行之后,play遇到错误会立马报错,后面的tasks任务自然也不会继续执行。

bash 复制代码
[root@server ansible]# cat expect.yml
bash 复制代码
[root@server ansible]# cat expect.yml 
---
- hosts: node3
  become: yes
  tasks:
    - name: 忽略错误,play继续
      command: ps -aux | grep nginx
      ignore_errors: yes

    - name: 开启nginx服务
      service:
        name: nginx
        state: started

将注释符去掉后

执行:

bash 复制代码
ansible-playbook -i inventory.ini expect.yml 

执行后我们会发现,即使报错了,但是接下来的tasks任务也会继续执行
所以 ignore_errors: yes 这个命令意思就是:忽略/跳过play错误,继续执行下面的内容

Tags标签

默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务;Ansible playbook中的tag标签是一种用于选择性运行特定任务或任务集的机制。通过为每个任务指定标签,您可以在运行playbook时选择只运行带有特定标签的任务,而不运行其他任务。这对于控制和管理Ansible playbook的执行非常有用,特别是当您的playbook包含许多任务时。

1、打标签的用法

1.1 打标签的方式

bash 复制代码
a.对一个对象打一个标签
b.对一个对象打多个标签
c.对多个对象打一个标签

1.2 标签的使用,

通过tags和任务对象进行捆绑,控制部分或者指定的task执行

bash 复制代码
-t:执行指定的tag标签任务
--list-tags:列出此yml文件中的所有tag标签
--skip-tags:执行--skip-tags之外的标签任务

1.3 标签的作用

以下是tag标签的作用:

1、选择性运行任务:可以使用--tags参数在运行ansible-playbook命令时指定一个或多个标签,只有带有指定标签的任务会运行。这对于在大型playbook中只运行特定任务非常有用,而不是运行整个playbook。

2、排除任务:您可以使用--skip-tags参数来排除具有特定标签的任务,从而运行除带有指定标签的任务之外的所有其他任务。这对于在大型playbook中排除不需要运行的任务非常有用。

3、组织任务:标签可以帮助您组织和分类任务。例如,您可以为配置任务添加一个config标签,为安装任务添加一个install标签,以便更容易了解每个任务的用途。

4、文档和注释:标签还可以作为任务的文档和注释。您可以将标签用作描述任务的方式,以便其他人更容易理解每个任务的目的。

下面是一些示例,演示如何在运行ansible-playbook时使用标签:

仅运行带有install标签的任务:

bash 复制代码
ansible-playbook your_playbook.yml --tags install

排除带有test标签的任务:

bash 复制代码
ansible-playbook your_playbook.yml --skip-tags test

运行带有多个标签的任务:

bash 复制代码
ansible-playbook your_playbook.yml --tags "install,config"

列出yml文件中所有的标签:

bash 复制代码
ansible-playbook your_playbook.yml --list-tags

标签功能有助于增加Ansible playbook的可维护性,使您能够更精细地控制任务的执行。

这里举一个非常简单的例子

bash 复制代码
[root@server ansible]# cat anzhuang.yml
bash 复制代码
[root@server ansible]# cat anzhuang.yml 
---
- name: 安装nginx、httpd,愿意安装哪个就安哪个
  hosts: node3
  become: yes
  tasks:
    - name: 安装nginx
      yum:
        name: nginx
        state: present
      tags:
        - install_nginx

    - name: 安装httpd
      yum:
        name: httpd
        state: present
      tags: 
        - install_httpd

正常执行:

bash 复制代码
ansible-playbook anzhuang.yml

只安装nginx服务:

bash 复制代码
ansible-playbook anzhuang.yml --tags="install_nginx"

这里再举一个例子:

bash 复制代码
[root@server ansible]# cat tags.yml
bash 复制代码
[root@localhost yml]# cat tags.yml
---
- name: 部署apache服务
  hosts: web
  remote_user: root
  vars:
    - http_port: 8080

  tasks:
    - name: Install Http Server
      yum:
        name: httpd
        state: present
      tags: 
        - install_httpd
        - httpd_server

    - name: configure httpd server
      copy:
        src: ./httpd.conf
        dest: /etc/httpd/conf/httpd.conf
        mode: 0777
      notify: Restart Httpd Server
      tags: 
        - config_httpd
        - httpd_server

    - name: start httpd server
      service:
        name: httpd
        state: started
        enabled: yes
      tags: start_httpd
   
    - name: stop httpd server
      service:
        name: httpd
        state: stopped
      tags: stop_httpd

    - name: uninstall httpd server
      yum:
        name: httpd
        state: absent
      tags: uninstall_httpd

  handlers:
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted

执行:

bash 复制代码
# 查看此yml文件中的所有tags标签
[root@localhost http]# ansible-playbook tags.yml --list-tags

playbook: tags.yml

  play #1 (web): 部署apache服务 TAGS: []
      TASK TAGS: [config_httpd, httpd_server, install_httpd, start_httpd, stop_httpd, uninstall_httpd]

# 执行 install_httpd,config_httpd(安装、移动配置文件)标签;执行移动配置文件会触发处理程序,所以会自动启动服务;
[root@localhost http]# ansible-playbook tags.yml -t install_httpd,config_httpd

# 执行 uninstall_httpd(卸载httpd服务) 标签
[root@localhost http]# ansible-playbook tags.yml -t uninstall_httpd

# 执行 httpd_server 标签
[root@localhost http]# ansible-playbook tags.yml -t httpd_server
# httpd_server标签包含(Install Http Server、configure httpd server、Restart Httpd Server)
# 所以会直接执行这三个任务,也就是安装、移动配置文件(因为使用移动文件触发了处理程序notify,所以就会执行Restart Httpd Server重启服务)
# 总结就是:执行httpd_server标签,会安装服务并启动服务。
# 跳过 httpd_server,start_httpd(安装加启动,启动)标签

[root@localhost http]# ansible-playbook tags.yml --skip-tags httpd_server,start_httpd

# 执行结果为,关闭httpd服务并卸载httpd服务;因为已经跳过 httpd_server ,所以不会执行安装和启动;

三、相关文章

相关文章标题以及链接
Ansible自动化运维(一)介绍、无密钥登录、安装部署_ansible自动化运维免费版本-CSDN博客
Ansible自动化运维(二) ad-hoc 模式 模块详解_ansible adhoc-CSDN博客
Ansible自动化运维(三)playbook剧本详解-CSDN博客
相关推荐
黑蛋同志1 小时前
CentOS 上下载特定的安装包及其所有依赖包
linux·运维·centos
是程序喵呀2 小时前
部署GitLab服务器
运维·服务器·gitlab
●VON2 小时前
go语言的成神之路-标准库篇-os标准库
linux·运维·服务器·开发语言·后端·学习·golang
TracyGC2 小时前
ubuntu 新建脚本shell并增加图标 双击应用实现python运行
linux·运维·ubuntu
清风 0012 小时前
一、使用 mdadm 工具在 Ubuntu 上创建 RAID 1(镜像)
运维·服务器·数据库
白白白白白kkk2 小时前
【Ubuntu】脚本自动化控制终端填充
linux·ubuntu·自动化
LCL_182 小时前
ansible 自动化运维工具(三)playbook剧本
linux·运维·自动化·ansible
无所不在的物质2 小时前
ansible运维实战
运维·ansible
Suckerbin2 小时前
linux部署ansible自动化运维
linux·运维·ansible