【自动化部署】Ansible Playbook 基础应用

文章目录

  • [Ansible Playbook](#Ansible Playbook)
    • 基础示例
      • [Playbook 结构](#Playbook 结构)
      • [运行 Playbook](#运行 Playbook)
    • 定义和引用变量
    • 指定远程主机sudo切换用户
    • when条件判断
    • [Ansible Playbook 迭代功能](#Ansible Playbook 迭代功能)
      • [`with_items` 循环结构](#with_items 循环结构)
      • [创建文件(Play 1)](#创建文件(Play 1))
      • [创建目录(Play 2)](#创建目录(Play 2))
      • [添加用户(Play 3)](#添加用户(Play 3))
      • [执行 Playbook](#执行 Playbook)
    • [Tags 与 Templates 模块](#Tags 与 Templates 模块)
      • [Tags 模块](#Tags 模块)
      • [Templates 模块](#Templates 模块)
    • [Ansible Roles 模块](#Ansible Roles 模块)
      • [Roles 简介](#Roles 简介)
      • [Roles 的目录结构](#Roles 的目录结构)
      • [在 Playbook 中使用 Roles](#在 Playbook 中使用 Roles)
      • 示例
      • [编写httpd、mysql、php模块的 roles](#编写httpd、mysql、php模块的 roles)
        • [1. 创建 httpd 模块](#1. 创建 httpd 模块)
        • [2. 创建 mysql 模块](#2. 创建 mysql 模块)
        • [3. 创建 php 模块](#3. 创建 php 模块)
        • [4. 编写 site.yml 以使用这些 roles](#4. 编写 site.yml 以使用这些 roles)
      • 注意

Ansible Playbook

Ansible Playbook 是 Ansible 的核心功能之一,它允许你以声明性的方式定义一系列的任务(tasks),这些任务将被应用到一组主机(hosts)上。Playbook 提供了强大的灵活性,可以组织复杂的自动化任务,包括配置管理、应用部署、服务编排等。

基础示例

bash 复制代码
vim test1.yaml
---     #yaml文件以---开头,以表明这是一个yaml文件,可省略
bash 复制代码
- name: first play     #定义一个play的名称,可省略
  gather_facts: false    #设置不进行facts信息收集,这可以加快执行速度,可省略
  hosts: webservers    #指定要执行任务的被管理主机组,如多个主机组用冒号分隔
  remote_user: root    #指定被管理主机上执行任务的用户
  tasks:     #定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行
   - name: test connection    #自定义任务名称
     ping:     #使用 module: [options] 格式来定义一个任务
   - name: disable selinux
     command: '/sbin/setenforce 0'    #command模块和shell模块无需使用key=value格式
     ignore_errors: True     #如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务
   - name: disable firewalld
     service: name=firewalld state=stopped    #使用 module: options 格式来定义任务,option使用key=value格式
   - name: install httpd
     yum: name=httpd state=latest
   - name: install configuration file for httpd
     copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf    #这里需要一个事先准备好的/opt/httpd.conf文件
     notify: "restart httpd"    #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
   - name: start httpd service
     service: enabled=true name=httpd state=started
  handlers:     #handlers中定义的就是任务,此处handlers中的任务使用的是service模块
   - name: restart httpd    #notify和handlers中任务的名称必须一致
     service: name=httpd state=restarted
##Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler,这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。

Playbook 结构

  1. Playbook 文件头

    • ---:YAML 文件的标准开头,表明这是一个 YAML 格式的文件。
  2. Play 定义

    • - name: first play:定义这个 play 的名称,便于日志记录和调试。
    • gather_facts: false:指定不收集目标主机的系统信息(facts),这可以加快执行速度。
    • hosts: webservers:指定这个 play 将要应用到的主机组。
    • remote_user: root:指定在目标主机上执行命令的用户。
  3. Tasks(任务)

    • 每个任务都包含一个 name 和一个或多个模块调用。
    • ping::使用 ping 模块检查主机的可达性。
    • command: '/sbin/setenforce 0':使用 command 模块执行命令,这里用于禁用 SELinux。
    • ignore_errors: True:忽略命令执行失败的情况,继续执行后续任务。
    • service: name=firewalld state=stopped:使用 service 模块停止 firewalld 服务。
    • yum: name=httpd state=latest:使用 yum 模块安装或更新 httpd 到最新版本。
    • copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf:使用 copy 模块复制配置文件到目标主机。
    • notify: "restart httpd":如果任务导致状态改变(changed),则触发名为 restart httpd 的 handler。
    • service: enabled=true name=httpd state=started:确保 httpd 服务启动并设置为开机自启。
  4. Handlers(处理器)

    • Handlers 类似于任务,但只在被 notify 触发时执行。
    • restart httpd:使用 service 模块重启 httpd 服务。

运行 Playbook

直接运行 Playbook

 ansible-playbook test1.yaml
  • -k--ask-pass:提示输入 SSH 密码。
  • -K--ask-become-pass:提示输入 sudo 密码。
  • -u:指定远程执行的用户。

附加参数和命令

ansible-playbook test1.yaml --syntax-check    #检查yaml文件的语法是否正确
ansible-playbook test1.yaml --list-task       #检查tasks任务
ansible-playbook test1.yaml --list-hosts      #检查生效的主机
ansible-playbook test1.yaml --start-at-task='install httpd'     #指定从某个task开始运行
  • --syntax-check:检查 Playbook 的语法是否正确。
  • --list-tasks:列出 Playbook 中的所有任务。
  • --list-hosts:列出 Playbook 将要应用到的主机。
  • --start-at-task='install httpd':从指定的任务开始执行 Playbook。

注意

  • 错误处理 :使用 ignore_errors 可以忽略任务失败,但应谨慎使用,因为它可能掩盖了重要的问题。
  • Handlers 的执行时机:Handlers 在当前 play 的所有任务执行完毕后统一执行,这有助于避免不必要的重复操作(如多次重启服务)。
  • 安全性 :在生产环境中,应避免使用 root 用户执行 Playbook,而是使用具有必要权限的最小权限用户。

定义和引用变量

在Ansible Playbook中,变量用于存储和管理在执行任务时需要用到的数据。变量的定义和引用如下:

  • 定义变量 :在vars部分,可以定义一系列的变量。每个变量都有一个键(key)和一个值(value)。

    yaml 复制代码
    vars:
      - groupname: mysql
      - username: nginx
  • 引用变量 :在任务(task)中,可以使用{``{key}}的格式来引用变量的值。

    yaml 复制代码
    tasks:
      - name: create group
        group: name={{groupname}} system=yes gid=306
      - name: create user
        user: name={{username}} uid=306 group={{groupname}}
  • 命令行定义变量 :在执行Playbook时,也可以通过命令行参数-e来定义变量。

    bash 复制代码
    ansible-playbook test1.yaml -e "username=nginx"

指定远程主机sudo切换用户

在Ansible Playbook中,可以使用becomebecome_user参数来指定在远程主机上执行命令时切换的用户。

  • become :启用sudo切换用户功能(Ansible 2.6版本以后的参数,之前使用的是sudo)。
  • become_user:指定要切换到的用户。

示例:

yaml 复制代码
---
- hosts: dbservers
  remote_user: zhangsan
  become: yes
  become_user: root

在执行Playbook时,需要输入远程用户zhangsan的密码和sudo用户的密码(如果使用-K参数)。

bash 复制代码
ansible-playbook test1.yml -k -K

when条件判断

Ansible中的when指令用于条件判断。当when指令的值为true时,该任务将被执行;否则,该任务将被跳过。

  • 常见应用场景:跳过某个主机不执行任务,或者只有满足条件的主机执行任务。

示例:

yaml 复制代码
---
- hosts: all
  remote_user: root
  tasks:
    - name: shutdown host
      command: /sbin/shutdown -r now
      when: ansible_default_ipv4.address == "192.168.80.12"
    # 或者
    # when: inventory_hostname == "<主机名>"

Ansible Playbook 迭代功能

with_items 循环结构

用于在任务中迭代一组项目。每个项目都可以是字符串、字典或其他数据结构。

创建文件(Play 1)

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

with_items 列表包含了四个路径。对于列表中的每个路径,file 模块都会被调用一次,以在该路径上创建一个空文件。

创建目录(Play 2)

yaml 复制代码
- 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}}"

定义了一个变量 test,它是一个包含四个目录路径的列表。然后,使用 with_items: "{``{test}}" 来迭代这个列表,并为每个路径创建一个目录。

添加用户(Play 3)

yaml 复制代码
- 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 列表包含了两个字典,每个字典都有 namegroups 键。对于列表中的每个字典,user 模块都会被调用一次,以添加具有指定名称和组的用户。这里使用 {``{item.name}}{``{item.groups}} 引用字典中的值。
state=present 参数指定了用户应该存在,如果不存在则创建。groups 参数指定了用户应该属于的组。

注意

  • 在 Ansible 2.5 及更高版本中,建议使用 loop 关键字代替 with_items,因为 loop 是更现代、更灵活的迭代机制。不过,with_items 仍然被广泛使用,并且在许多情况下都是有效的。
  • 在使用 with_itemsloop 时,请确保迭代的项目列表或字典是正确格式的,以避免运行时错误。
  • 在定义变量时,可以使用 YAML 的列表和字典语法来组织数据,这使得 Playbook 更加清晰和易于维护。

执行 Playbook

bash 复制代码
ansible-playbook test3.yaml

这将按顺序执行 play1play2play3,并在 dbservers 组中的每个主机上应用相应的任务。

Tags 与 Templates 模块

Tags 模块

在 Ansible Playbook 中,可以为任务(tasks)定义标签(tags),以便在执行 Playbook 时通过 --tags 选项仅运行指定的任务。

  • 定义标签 :在任务的 tags 字段下,可以定义一个或多个标签。例如:

    yaml 复制代码
    tasks:
      - name: Copy hosts file
        copy: src=/etc/hosts dest=/opt/hosts
        tags:
          - only
      - name: touch file
        file: path=/opt/testhost state=touch
        tags:
          - always
  • 执行带标签的任务 :使用 ansible-playbook 命令并添加 --tags 选项来仅执行带有指定标签的任务。例如:

    bash 复制代码
    ansible-playbook webhosts.yaml --tags="only"
  • 特殊标签 always :当使用 always 作为标签的任务时,无论执行哪一个标签,定义有 always 标签的任务都会执行。

Templates 模块

Jinja 是基于 Python 的模板引擎,用于在 Ansible 中生成目标文本。Template 类是 Jinja 的一个重要组件,可以看作是一个编译过的模板文件,用来将 Python 变量传递给模板,并替换模板中的标记。

  • 准备模板文件 :创建一个以 .j2 为后缀的模板文件,并在其中设置引用的变量。
  • 例如:
bash 复制代码
cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
bash 复制代码
vim /opt/httpd.conf.j2
apache 复制代码
Listen {{http_port}}				#42行,修改
ServerName {{server_name}}			#95行,修改
DocumentRoot "{{root_dir}}"          #119行,修改
  • 定义主机变量 :在 Ansible 的主机清单文件(/etc/ansible/hosts)中,为不同的主机定义相同名称但值不同的变量。例如:

    ini 复制代码
    [webservers]
    192.168.80.11 http_port=80 server_name=www.accp.com root_dir=/var/www/html
    
    [dbservers]
    192.168.80.12 http_port=8080 server_name=www.benet.com root_dir=/var/www/html_backup
  • 编写 Playbook :在 Playbook 中使用 template 模块将模板文件应用到远程主机上,并替换模板中的变量。例如:

    yaml 复制代码
    ---
    - hosts: all
      remote_user: root
      vars:
        - package: httpd
        - service: httpd
      tasks:
        - name: install httpd package
          yum: name={{package}} state=latest
        - name: install configure file
          template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
          notify:
            - restart httpd
        - name: create root dir
          file: path={{root_dir}} state=directory  # 注意这里使用了 {{root_dir}},但需要在每个主机的变量中定义
        - name: start httpd server
          service: name={{service}} enabled=true state=started
      handlers:
        - name: restart httpd
          service: name={{service}} state=restarted

    注意 :在上面的 Playbook 中,{``{root_dir}} 变量应该在每个主机的变量中定义,但上面的示例为了简化而直接放在了 file 任务的路径中。在实际应用中,可能需要在 Playbook 的 vars 部分或使用 host_vars 目录为每个主机定义不同的变量。

  • 执行 Playbook :使用 ansible-playbook 命令执行 Playbook。例如:

    bash 复制代码
    ansible-playbook apache.yaml

这将安装 httpd 包、复制模板配置文件(替换模板中的变量)、创建根目录(如果变量已定义),并启动 httpd 服务。如果配置文件发生变化,将触发 restart httpd 处理器来重启服务。

Ansible Roles 模块

Roles 简介

Roles 是 Ansible 中用于层次性、结构化地组织 Playbook 的一种机制。通过将变量、文件、任务、模板及处理器分别放置在单独的目录中,Roles 使得 Playbook 的编写更加模块化、清晰化,并提高了代码复用度。

Roles 的目录结构

在 Ansible 的配置目录中(默认为 /etc/ansible/),roles/ 目录用于存放所有的角色。每个角色都是一个子目录,其内部包含以下子目录和文件:

  • files/:用于存放由 copy 模块或 script 模块调用的文件。
  • templates/:用于存放 Jinja2 模板文件,template 模块会自动在此目录中查找模板。
  • tasks/:应包含一个 main.yml 文件,用于定义角色的任务列表。可以包含其他任务文件,并通过 include 指令引入。
  • handlers/:应包含一个 main.yml 文件,用于定义触发条件时执行的动作。
  • vars/:应包含一个 main.yml 文件,用于定义角色使用的变量。
  • defaults/:应包含一个 main.yml 文件,用于为角色设定默认变量。这些变量具有最低的优先级,可以被其他变量覆盖。
  • meta/:应包含一个 main.yml 文件,用于定义角色的元数据信息及其依赖关系。

在 Playbook 中使用 Roles

  1. 创建 Roles 目录 :确保 /etc/ansible/roles/ 目录存在。

  2. 创建角色目录 :为每个角色创建一个子目录,如 httpdmysql 等。

  3. 创建必要的子目录和文件 :在每个角色目录中创建 filestemplatestaskshandlersvarsdefaultsmeta 子目录,并创建相应的 main.yml 文件。

  4. 编写 Playbook :在 Playbook 中使用 roles 关键字来引用角色。例如:

    yaml 复制代码
    ---
    - hosts: webservers
      remote_user: root
      roles:
        - httpd
    - hosts: dbservers
      remote_user: root
      roles:
        - mysql
    - hosts: lampserver
      remote_user: root
      roles:
        - httpd
        - mysql
        - php
  5. 运行 Playbook :使用 ansible-playbook 命令运行 Playbook,如 ansible-playbook /etc/ansible/site.yml

示例

bash 复制代码
# 创建角色目录和文件
mkdir -p /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir -p /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir -p /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta}

# 创建 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
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml

# 编写 Playbook(site.yml)
vim /etc/ansible/site.yml
---
- hosts: webservers
  remote_user: root
  roles:
    - httpd
- hosts: dbservers
  remote_user: root
  roles:
    - mysql
- hosts: lampserver
  remote_user: root
  roles:
    - httpd
    - mysql
    - php

# 运行 Playbook
ansible-playbook /etc/ansible/site.yml

编写httpd、mysql、php模块的 roles

1. 创建 httpd 模块

步骤

  1. 创建 tasks 文件

    bash 复制代码
    vim /etc/ansible/roles/httpd/tasks/main.yml

    内容:

    yaml 复制代码
    - name: install apache
      yum: name={{pkg}} state=latest
    
    - name: start apache
      service: enabled=true name={{svc}} state=started
  2. 定义变量

    bash 复制代码
    vim /etc/ansible/roles/httpd/vars/main.yml

    内容:

    yaml 复制代码
    pkg: httpd
    svc: httpd
2. 创建 mysql 模块

步骤

  1. 创建 tasks 文件

    bash 复制代码
    vim /etc/ansible/roles/mysql/tasks/main.yml

    内容:

    yaml 复制代码
    - name: install mysql
      yum: name={{pkg}} state=latest
    
    - name: start mysql
      service: enabled=true name={{svc}} state=started
  2. 定义变量

    bash 复制代码
    vim /etc/ansible/roles/mysql/vars/main.yml

    内容:

    yaml 复制代码
    pkg:
      - mariadb
      - mariadb-server
    svc: mariadb
3. 创建 php 模块

步骤

  1. 创建 tasks 文件

    bash 复制代码
    vim /etc/ansible/roles/php/tasks/main.yml

    内容:

    yaml 复制代码
    - name: install php
      yum: name={{pkg}} state=latest
    
    - name: start php-fpm
      service: enabled=true name={{svc}} state=started
  2. 定义变量

    bash 复制代码
    vim /etc/ansible/roles/php/vars/main.yml

    内容:

    yaml 复制代码
    pkg:
      - php
      - php-fpm
    svc: php-fpm
4. 编写 site.yml 以使用这些 roles

步骤

  1. 创建 site.yml 文件

    bash 复制代码
    vim /etc/ansible/site.yml

    内容:

    yaml 复制代码
    ---
    - hosts: webservers
      remote_user: root
      roles:
        - httpd
        - mysql
        - php
  2. 运行 ansible-playbook

    bash 复制代码
    cd /etc/ansible
    ansible-playbook site.yml

注意

  • 定义变量:可以定义在全局变量中,也可以定义在roles角色变量中,一般定义在角色变量中。
  • 服务管理 :在 service 模块中,enabled=true 表示设置服务为开机自启,state=started 表示启动服务。
  • Ansible 版本 :确保你使用的 Ansible 版本支持以上语法。例如,yum 模块和 service 模块的参数可能会随着 Ansible 版本的更新而变化。
  • 权限:确保你有足够的权限在目标机器上安装软件和服务。
相关推荐
礁之28 分钟前
Fastdfs V6.12.1集群部署(arm/x86均可用)
docker·云原生·dfs
shelby_loo30 分钟前
在 Ubuntu 下通过 Docker 部署 MariaDB 服务器
服务器·ubuntu·docker
FBI780980459441 分钟前
利用API接口优化电商平台的用户体验
大数据·服务器·网络·数据库·人工智能·python
Onlooker-轩逸1 小时前
Docker安装与架构
docker·容器·架构
网络安全King1 小时前
网络安全的攻防战争
网络·安全·web安全
网络安全queen1 小时前
网络安全概论——TCP/IP协议族的安全性
网络·tcp/ip·web安全
GLAB-Mary2 小时前
华为HCIP认证培训多少天?
运维·服务器·华为
shen121382 小时前
【Graylog】索引别名deflector的异常处理和索引分片数限制解除
运维·elasticsearch·graylog
Spirit_NKlaus2 小时前
传统JavaWeb项目集成consul注册中心
运维·consul
RayLink远程控制电脑2 小时前
远程控制软件新趋势
网络·安全·电脑·生活