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

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

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

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

(三)Playbook 模式详解

(四)jinja2 模板 Roles角色详解

(五)运维实战

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

目录

一、Ansible 中的 Playbook 模式

1.1 Playbook 的优势

1.2 Playbook 的组成

1.3 Playbook命令

1.4 Playbook的语法

1、权限

2、通知与触发

1.5 Playbook中的变量

1.1 通过vars 定义变量

1.2 通过vars_files定义变量

1.3命令行定义变量

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

1.6 debug

1.7 facts缓存

二、Playbook中的流程控制

Playbook条件

1.1 条件判断

1.2 组合判断

1.3 操作实例

Playbook的循环

1.1 批量安装软件包

1.2 批量创建用户

1.3 批量创建组

1.4 批量删除用户和组

1.5 批量复制文件

异常处理:

Tags标签

1、打标签的用法

1.1 打标签的方式

1.2 标签的使用,

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的处理器。

- 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并启动,启动成功后会自动执行关闭防火墙并且检查运行状态

[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中调用,会方便许多。如此一来还方便维护,减少维护的成本。

变量的定义方式

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

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

1.1 通过vars 定义变量

---
- name: LAMP
  hosts: node1
  vars:
    packages_name:
      - httpd
      - mariadb-server
      - php
      - php-mysql

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

执行此yml:

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

1.2 通过vars_files定义变量

当变量较少时,使用vars定义没有问题,当变量较多时,可以将变量保存到一个独立的文件中;
需要多个yml文件,一个主文件,需要调用其他yml独立文件,主要是最后运行的;其他是定义包名的yml文件。

[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:

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

1.3命令行定义变量

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

# 执行:命令行定义变量
[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"

命令行指定多个变量。

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

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

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

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

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

3.组级别变量

group_vars/web-servers.yml

[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,并在其中定义主机级别的变量,如:  

[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,例如:

[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:

格式:

ansible-playbook -i inventory.ini playbook.yml

inventory.ini : 这里面表示你设置的主机分组
playbook.yml:你创造的脚本名称

此时,Ansible会自动加载group_vars和host_vars目录中的变量,你的Playbook将使用这些变量来配置主机。
通过这种方式,你可以更加有组织地管理变量,特别是对于多主机和多组的环境。你可以为不同的组或主机设置特定的变量,而不必在Playbook中硬编码这些值,提高了可维护性和可读性。

1.6 debug

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

- 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变量的使用场景

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

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

[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的所有地址:

[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系统

[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

执行:

 ansible-playbook -i inventory.ini when.yml

执行成功

如果被控主机不是CentOS系统,条件不符,会出现什么状况呢?
这里我拿Ubuntu来为大家举例:

[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

执行:

ansible-playbook -i inventory.ini when.yml

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

1.2 组合判断

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

1、使用 and 组合条件

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

cat lifeng1.yml
[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'

执行:

ansible-playbook -i inventory.ini lifeng1.yml

2、使用 or 组合条件

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

[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'

执行:

ansible-playbook -i inventory.ini rzc.yml 

3、使用not进行否定条件

not可以用来否定一个条件,当条件不满足时执行任务。
举例:我的系统是 CentOS
我的条件判断是当系统不是Ubuntu时,输出“hello world”

[root@server ansible]# cat when.yml
[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

去执行:

ansible-playbook -i inventory.ini when.yml

4、混合使用and、or和not

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

[root@server ansible]# cat when.yml
[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用户:

ansible node1 -i inventory.ini -m user -a "name=hhhhh1 state=present"

检查:

ansible node1 -i inventory.ini -m command -a "tail -3 /etc/passwd"

接下来我们写一个脚本

[root@server ansible]# cat hhhhh.yml
---
- 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

执行:

ansible-playbook -i inventory.ini hhhhh.yml 

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

Playbook的循环

1.1 批量安装软件包

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

执行:

ansible-playbook -i inventory.ini  with_item.yml

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

1.2 批量创建用户

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

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

执行:

ansible-playbook -i inventory.ini user2.yml

1.3 批量创建组

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

      loop:
        - mygroup1
        - mygroup2
        - mygroup3

执行:

ansible-playbook -i inventory.ini user3.yml

1.4 批量删除用户和组

删除lifeng用户和删除mugroup组

[root@server ansible]# cat drop.yml 
[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

执行:

ansible-playbook -i inventory.ini drop.yml drop.yml

1.5 批量复制文件

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

[root@server ansible]# cat copy.yml
[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"}

执行:

ansible-playbook -i inventory.ini copy.yml 

异常处理:

默认Playbook会检查命令和模块的返回状态,如遇到错误就中断playbook的执行
加入参数: ignore_errors: yes # 忽略错误

[root@server ansible]# cat expect.yml
[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任务自然也不会继续执行。

[root@server ansible]# cat expect.yml
[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

将注释符去掉后
执行:

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 打标签的方式

a.对一个对象打一个标签
b.对一个对象打多个标签
c.对多个对象打一个标签

1.2 标签的使用,

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

-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标签的任务:

ansible-playbook your_playbook.yml --tags install

排除带有test标签的任务:

ansible-playbook your_playbook.yml --skip-tags test

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

ansible-playbook your_playbook.yml --tags "install,config"

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

ansible-playbook your_playbook.yml --list-tags

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

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

[root@server ansible]# cat anzhuang.yml
[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

正常执行:

ansible-playbook anzhuang.yml

只安装nginx服务:

ansible-playbook anzhuang.yml --tags="install_nginx"

这里再举一个例子:

[root@server ansible]# cat tags.yml
[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

执行:

# 查看此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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/934996.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【汽车】-- 燃油发动机3缸和4缸

3缸和4缸燃油发动机是小轿车常见的发动机配置。以下从结构特点、性能、经济性等方面对两者进行对比,并分析优缺点及使用注意事项: 1. 结构与运行原理 3缸发动机 特点:少一个气缸,内部零部件更少,整体结构更紧凑。优点…

如何在x86模拟器和鸿蒙API9如何使用MQTT模块ohos_mqtt

目录 引言 安装失败的原因 如何编译so文件的x86_64版本 下载源代码 安装NDK 代码编译 安装MQTT软件包 避免MQTT软件包自动升级 设置libs 客户端程序的编写 运行测试 结语 参考文献 引言 在上周的博客(如何在鸿蒙API9和x86模拟器中使用MQTT-CSDN博客&am…

若依集成更好用的easyexcel

背景 若依使用的是apach poi并在此基础上进行封装apach poi的原生的api是很复杂的,若依简化了了此操作apach poi的上传速率和下载速率都是没有优化的,依赖于文件大小的限制在此前提下,如果没法满足客户的需求(超大型文件的上传&am…

我们来学mysql -- 探讨win安装方式(安装篇)

题记 书接上回,在我们来学mysql – 闲聊(安装篇)中,拿到安装包,当宝贝一样揣在怀里 然而,还没捂热乎,得粉丝秘报,U哥,上篇文章用了滞后的官方文档,哈哈哈…内心的小倔强&#xff0c…

[WiFi] WiFi安全加密WEP Vs WPA Vs WPA2 Vs WPA3整理

WiFi安全标准时间线 WEP(Wired Equivalent Privacy) WEP最早于1997年推出,是为了保护无线网络上的数据通信而设计的。当时,Wi-Fi技术还处于起步阶段,人们开始意识到需要一种安全协议来防止未经授权的访问和窃听。WEP被…

05 在 Linux 使用 AXI DMA

DMA简介 DMA 是一种采用硬件实现存储器与存储器之间或存储器与外设之间直接进行高速数据传输的技术,传输过程无需 CPU 参与(但是CPU需要提前配置传输规则),可以大大减轻 CPU 的负担。 DMA 存储传输的过程如下: CPU 向…

深入解析下oracle的number底层存储格式

oracle数据库中,number数据类型用来存储数值数据,它既可以存储负数数值,也可以存储正数数值。相对于其他类型数据,number格式的数据底层存储格式要复杂得多。今天我们就详细探究下oracle的number底层存储格式。 一、环境搭建 1.…

多速率信号处理

介绍 简单来说, 多速率信号处理,是指对同时存在两个以上数据速率的系统进行信号处理。多速率信号处理原理就是通过改变信号速率,以适应系统内部各个节点对信号速率的要求。这里的速率其实就是指采样率。 多速率技术已广泛应用于数字音频处理…

golang实现简单的redis服务

golang 手搓redis服务器仓库地址:实现思路: golang 手搓redis服务器 仓库地址: 仓库: https://github.com/dengjiayue/my-redis.git 实现思路: ● 协议: tcp通信 ● 数据包: 长度(4byte)方法(1byte)数据json ● 数据处理: 单线程map读写 ○ 依次处理待处理队列的请求(chan)…

ssd202d-badblock-坏块检测

这边文章讲述的是坏快检测功能 思路: 1.第一次烧录固件会实现跳坏块,但是后续使用会导致坏块的产生; 于是我在uboot环境变量添加了两个变量来控制坏快 lb_badnum = //坏块个数 lb_badoff = //坏块所在位置 2.第一次开机会根据lb_badnum是否存在判断,如果不存在则保存上…

Y3编辑器文档2:场景编辑

文章目录 一、操作区二、地图设置2.1 地图大小2.2 其它选项三、地形编辑3.1 地势3.2 地形3.3 通行(碰撞、通行和视野规则)3.4 植被四、物件放置4.1 单位4.1.1 单位的摆放与调整4.1.2 状态栏属性编辑4.2 装饰物摆放4.3 物品4.4 镜头4.4.1 镜头的基本参数4.4.2 镜头时间轴动画4…

windows将文件推给Android真机/实机

记录一下 因为以前只试过从真机实机中将文件推给windows 但是从windows只简单复制粘贴的话会一直报错。 1.电脑安装adb 2.手机开启开发者模式 usb调试 3.usb连接选择文件传输 4.推送命令adb push 文件路径 /sdcard/download 步骤1和2和3不作赘述,可以搜相关配置教程…

[机器学习] 监督学习之线性回归与逻辑回归

这里写目录标题 一、监督学习概述二、线性回归(一)模型表示(二)损失函数(三)梯度下降算法导入所需库生成模拟数据(可替换为真实数据)初始化参数并进行训练可视化损失函数随迭代次数的…

精准预测美国失业率和贫困率,谷歌人口动态基础模型PDFM已开源,可增强现有地理空间模型

疾病、经济危机、失业、灾害……人类世界长期以来被各种各样的问题「侵扰」,了解人口动态对于解决这类复杂的社会问题至关重要。 政府相关人员可以通过人口动态数据来模拟疾病的传播,预测房价和失业率,甚至预测经济危机。然而,在过…

E172 ASP.NET+SQL+C#+LW+图书管理系统的设计与实现 配置 源码 文档 全套资料

图书管理系统 1.项目摘要2. 系统的概述3.项目功能4.界面展示5.源码获取 1.项目摘要 摘 要 书籍是供人们获取并增长知识的主要途径,由于图书的种类较多,阅读者也较多,借阅量较大,且易出错,传统的图书借阅若还停留在手工…

aippt:AI 智能生成 PPT 的开源项目

aippt:AI 智能生成 PPT 的开源项目 在现代办公和学习中,PPT(PowerPoint Presentation)是一种非常重要的展示工具。然而,制作一份高质量的PPT往往需要花费大量的时间和精力。为了解决这一问题,aippt项目应运…

轮转数组

轮转数组 1、题目描述2、解答思路2.1、辅助数组2.2、原地反转 1、题目描述 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 2、解答思路 2.1、辅助数组 如果我们在原数组上通过覆盖元素会导致部分元素的丢失&#xff0c…

selenium学习:等待方式

隐式等待 1.针对查找元素设置最大的超时时间 2.可以全局性的设置 3.不满足时,提示no such element driver.implicitly_wait(5) #对查找元素最大的超时时间,如果超过最大等待时间后,没有找到元素,则会报错:no such #e…

一文说清flink从编码到部署上线

引言:目前flink的文章比较多,但一般都关注某一特定方面,很少有一个文章,从一个简单的例子入手,说清楚从编码、构建、部署全流程是怎么样的。所以编写本文,自己做个记录备查同时跟大家分享一下。本文以简单的…

ZUC256 Go Go Go!!!

文章目录 背景运行效果代码 背景 因业务需要使用ZUC算法,GitHub上又没有对ZUC256相对应的Go语言的实现。 吃水不忘挖井人,在这里感谢GmSSL及BouncyCastle两个强大的密码学库! 本ZUC256的编写,参考了这两个库及中科院软件院发布的…