Ansible - Role介绍 和 使用playbook部署wordPress

1.roles角色

假设我们要写一个 playbook 来安装管理 lnmp 环境,那么这个 playbook 就会写很长。

所以我们希望把这个很大的文件分成多个功能拆分,分成:apache 管理、php 管理、mysql 管理,然后在需要使用的时候直接调用就可以了,以免重复写。

就类似编程里的模块化的概念,以达到代码复用的效果。

Roles 角色是 ansible 自1.2版本引入的新特性,用于层次性、结构化地组织 playbook。能够根据层次型结构自动装载变量文件、tasks 以及 handlers 等。

要使用 roles 只需要在 playbook 中使用include 指令即可。

简单来讲,roles 就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地 include 它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

roles 优点:

  • 模块中指令较少,方便编写

  • 重复调用方便

  • 排错方便

2.Roles目录编排

roles目录结构如下所示

每个角色,以特定的层级目录结构进行组织

roles 目录结构:

复制代码
roles/nginx/
├── defaults/           # 默认变量
│   └── main.yml        # 默认变量定义文件
├── files/              # 静态文件(如配置文件)
│   └── example.conf    # 示例配置文件
│   └── index.html      # 示例配置文件
├── handlers/           # 事件处理器
│   └── main.yml        # 处理器定义文件
├── meta/               # 角色依赖关系
│   └── main.yml        # 定义角色依赖关系
├── tasks/              # 任务列表
│   └── main.yml        # 主任务文件
├── templates/          # Jinja2 模板文件
│   └── example.conf.j2 # 示例模板文件
├── tests/              # 测试配置
│   ├── inventory       # 测试使用的主机清单文件
│   └── test.yml        # 测试 Playbook 文件
└── vars/               # 变量
    └── main.yml        # 变量定义文件

Roles 各目录作用:

  • roles/ :项目名称,有以下子目录

  • files/ :存放由 copyscript 模块等调用的文件

  • templates/template 模块查找所需要模板文件的目录

  • tasks/:定义 taskrole 的基本元素,至少应该包含一个名为 main.yml 的文件;其它的文件需要在此文件中通过 include 进行包含

  • handlers/:至少应该包含一个名为 main.yml 的文件;其它的文件需要在此文件中通过 include 进行包含

  • vars/:定义变量,至少应该包含一个名为 main.yml 的文件;其它的文件需要在此文件中通过 include 进行包含

  • meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为 main.yml 的文件,其它文件需在此文件中通过 include 进行包含

  • default/:设定默认变量时使用此目录中的 main.yml 文件,比 vars 的优先级低

3.创建 role

创建 role 的步骤:

  • 第一步: 创建以 roles 命名的目录

  • 第二步:roles 目录中分别创建以各角色名称命名的目录,如:mysqlnginx

  • 第三步: 在每个角色命名的目录中分别创建:fileshandlersmetataskstemplatesvars 目录;用不到的目录可以创建为空目录,也可以不创建。

  • 第四步:playbook 文件中,调用各角色,playbook 文件可以直接定义在 roles 目录下,也可以定义在不同角色的目录下。

roles 的目录结构:

复制代码
├── mysql
│   ├── files
│   ├── handlers
│   │   └── main.yml
│   ├── tasks
│   │   └── main.yml
│   ├── templates
│   └── vars
│       └── main.yml
└── nginx
    ├── files
    ├── handlers
    │   └── main.yml
    ├── nginx.yml
    ├── tasks
    │   ├── a1.yml
    │   ├── a2.yml
    │   └── main.yml
    ├── templates
    └── vars
        └── main.yml

请按照上述的目录结构来 roles ,在 roles 下分别有两个角色 mysqlnginx 。然后在 taskshandlersvars 等目录下创建 main.yml

切换到 nginx/tasks 目录分别创建 a1.ymla2.yml ,然后在 main.yml 中通过 include 命令分别引入不同的任务,如下:

复制代码
---
- name: install nginx
  tags: nginx
  include_tasks: a1.yml
- name: start nginx
  include_tasks: a2.yml

playbook 中调用角色。

  • 调用角色方法1:


    • hosts: websrvs
      remote_user: root
      roles:
      • mysql
      • nginx
  • 调用角色方法2:

键role用于指定角色名称,后续的k/v用于传递变量给角色

复制代码
---
- hosts: all
  remote_user: root
  roles:
    - mysql
    - { role: nginx, username: nginx }
    - role: nginx
      vars:
        username: nginx
        groupname: nginx
        service_state: started
  • 调用角色方法3:

还可基于条件测试实现角色调用

复制代码
---
- hosts: all
  remote_user: root
  roles:
    - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7'  }

rolestags 使用

复制代码
#nginx-role.yml
---
- hosts: websrvs
  remote_user: root
  roles:
    - { role: nginx ,tags: [ 'nginx', 'web' ] ,when: ansible_distribution_major_version == "6" }
    - { role: httpd ,tags: [ 'httpd', 'web' ]  }
    - { role: mysql ,tags: [ 'mysql', 'db' ] }
    - { role: mariadb ,tags: [ 'mariadb', 'db' ] }
​
ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml

4.实战案例

基于 Ansible 来实现 LNMP 的远程发布。

4.1.Nginx

  • 第一步:Ansible 目录及脚本文件定义

    定义变量

    roleName=nginx

    基于变量批量创建文件目录

    mkdir -p roles/${roleName}/{tasks,handlers,vars,files,templates}

    创建对应模块的主文件

    touch roles/${roleName}/{tasks,handlers,vars,files,templates}/main.yml

  • 第二步:切换到 files 目录下,创建 nginx.repo 文件,配置如下内容:

    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true

  • 第三步:切换至 tasks 目录,创建 nginx.yml 文件,逐一配置执行任务。

    安装 yum-utils 工具包

    • name: install utils
      yum:
      name: yum-utils
      state: present

    将files/nginx.repo文件复制到远程机器的/etc/yum.repos.d/目录下,并设置文件拥有者和所属组及权限

    • name: copy nginx.repo
      copy:
      src: nginx.repo
      dest: /etc/yum.repos.d/nginx.repo
      owner: root
      group: root
      mode: '0644'

    远程安装Nginx服务

    • name: install nginx
      yum:
      name: nginx
      state: present

      设置通知,也就是触发器,重启Nginx服务

      notify:
      • restart nginx

注意:这里不要在 tasks 目录下的主文件 main.yml 中定义执行任务,而是要在具体的配置文件中定义执行任务,最后通过 include_tasks 方式,在主文件 main.yml 中引入其他配置文件。

  • 第四步:切换至 handlers 目录下,编辑 main.yml ,来配置被通知时才执行的特殊任务。


    • name: restart nginx
      service:
      name: nginx
      state: restarted
  • 第五步:再次切换至 tasks/nginx.yml 文件,继续添加执行任务。

    执行lineinfile模块实现对nginx.conf配置文件的内容替换

    • name: configure nginx
      lineinfile:

      要被替换的配置文件位置

      path: /etc/nginx/nginx.conf

      使用正则表达式进行匹配

      regexp: '^user'

      设置要替换的文本行

      line: 'user root;'

      1.backrefs为no时,如果没有匹配,则添加一行line。如果匹配了,则把匹配内容替被换为line内容。

      2.backrefs为yes时,如果没有匹配,则文件保持不变。如果匹配了,把匹配内容替被换为line内容

      backrefs: yes

    备份nginx配置文件

    • name: backup default nginx config
      command: cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
      args:
      creates: /etc/nginx/conf.d/default.conf.bak

    创建blog.conf配置文件,默认80端口

    • name: create blog.conf
      command: mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/blog.conf
      args:
      creates: /etc/nginx/conf.d/blog.conf

    使用模板文件,创建nginx配置文件

    • name: config test.conf
      template:
      src: test.conf.j2
      dest: /etc/nginx/conf.d/test.conf

至此,部分配置结束,由于使用了模板文件,需要切换到 templates 目录下去定义模板文件内容。

  • 第六步:切换至 vars 目录下,编辑 main.yml 文件,定义配置所需变量。

    nginx_port: 8080
    nginx_root_dir: /var/www/html

  • 第七步:切换至 templates 目录,创建 test.conf.j2 模板文件,配置如下内容:

    server {
    listen {{nginx_port}};
    server_name localhost;

    location / {
    root {{ nginx_root_dir }};
    index index.php index.html index.htm;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root /usr/share/nginx/html;
    }
    }

  • 第八步:再次编辑 tasks/nginx.yml 文件,继续添加执行任务。

    • name: create directory
      file:
      path: "{{ nginx_root_dir }}"
      state: directory
      owner: nginx
      group: nginx
      mode: '0644'
    • name: copy index.html
      copy:
      src: index.html
      dest: "{{ nginx_root_dir }}/index.html"
      owner: nginx
      group: nginx
      mode: '0644'
      notify:
      • restart nginx
  • 第九步:切换至 files 目录下,创建 index.html 文件,配置内容:

    helle world

  • 第十步:将 tasks/nginx.yml 文件包含到 tasks/main.yml 主配置文件中。


    • name: install nginx
      include_tasks: nginx.yml
  • 第十一步:切换至 roles 目录外,创建 nginx_deploy.yml 文件,配置内容:


    • name: deploy nginx
      hosts: web
      user: root
      gather_facts: yes
      roles:
      • role: nginx

最后,使用命令 ansible-playbook nginx_deploy.yml 来执行任务。

4.2.MySQL

  • 第一步:定义 MySQLRoles 角色和相关脚本文件

    roleName=mysql
    mkdir -p roles/{roleName}/{tasks,handlers,vars,files,templates} ​ touch roles/{roleName}/tasks/main.yml
    touch roles/{roleName}/handlers/main.yml touch roles/{roleName}/vars/main.yml
    touch roles/${roleName}/templates/main.yml

  • 第二步:编辑 mysql/tasks/mysql.yml 文件

    下载 MySQL 源仓库配置文件并保存到/tmp目录中

    安装 MySQL 源仓库

    • name: Install MySQL repository
      yum:
      name: /tmp/mysql80-community-release-el7-8.noarch.rpm
      state: present

    安装 MySQL Server

    • name: Install MySQL server
      yum:
      name: mysql-community-server
      state: present
      disable_gpg_check: yes

    启动 MySQL 服务并设置自启动

    • name: Start MySQL service
      service:
      name: mysqld
      state: started
      enabled: yes

    使用模板文件,创建shell脚本,并设置0755权限

    • name: Generate secure script
      template:
      src: mysql_secure.j2
      dest: /tmp/mysql_secure.sh
      mode: '0755'

    执行 /tmp/mysql_secure.sh 文件

    • name: Execute secure script
      shell: bash /tmp/mysql_secure.sh
  • 第三步:切换至 templates 目录下,创建 mysql_secure.j2 模板文件。

    #!/bin/bash

    获取临时密码

    TEMP_PASS=(grep 'temporary password' /var/log/mysqld.log | awk '{print NF}')

    设置新密码

    NEW_PASS="{{ mysql_root_password }}"

    修改 root 用户密码

    mysql -u root -p"{TEMP_PASS}" --connect-expired-password -e \ "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '{NEW_PASS}';"

  • 第四步:编辑 vars/main.yml 文件,设置变量。

    mysql_root_password: 密码

注意:MySQL 密码有强度要求!!!

MySQL 有默认的密码策略:

  • 至少包含 1 位大小写

  • 至少包含 1 位数字

  • 包含 1 个特殊符号

  • 必须 8 位及以上

  • 第五步:将 tasks/mysql.yml 文件包含到 tasks/main.yml 主配置文件中。


    • name: install mysql
      include_tasks: mysql.yml
  • 第六步:切换至 roles 目录外,创建 mysql_deploy.yml 文件,配置内容:


    • name: deploy mysql
      hosts: web
      user: root
      gather_facts: yes
      roles:
      • role: mysql

最后,使用命令 ansible-playbook mysql-deploy.yml 来执行任务。

注意:如果在执行过程中提示了,MySQL 启动服务失败,可以通过命令:rm -rf /var/lib/mysql/* 来清除MySQL 所有的数据后,再重新执行 ansible-playbook mysql-deploy.yml 命令。

4.3.PHP

  • 第一步:定义 PhpRoles 角色和相关脚本文件

    roleName=php
    mkdir -p roles/{roleName}/{tasks,handlers,vars,files,templates} ​ touch roles/{roleName}/tasks/main.yml
    touch roles/{roleName}/handlers/main.yml touch roles/{roleName}/vars/main.yml
    touch roles/${roleName}/templates/main.yml

  • 第二步:编辑 php/tasks/php.yml 文件

    安装 EPEL 仓库

    • name: install epel-release
      yum:
      name: epel-release
      state: present

    安装 Remi 仓库提供了较新版本的 PHP 和其他软件包。

    启用 Remi PHP 7.4 仓库

    • name: enable remi php7.4
      command: yum-config-manager --enable remi-php74

    创建 php 用户和组

    • name: Create PHP-FPM user and group
      user:
      name: "{{ php_user }}"
      group: "{{ php_group }}"
      system: yes
      shell: /sbin/nologin
      create_home: no

    安装 php7.4

    • name: install php7.4
      yum:
      name:
      - php
      - php-fpm
      - php-cli
      - php-mysqlnd
      - php-zip
      - php-devel
      - php-gd
      - php-mcrypt
      - php-mbstring
      - php-curl
      - php-xml
      - php-pear
      - php-bcmath
      - php-redis
      - php-opcache
      state: present
      enablerepo: remi-php74

    配置 php-fpm 核心配置文件的用户,与nginx配置文件一致

    • name: configure php-fpm user
      lineinfile:
      path: /etc/php-fpm.d/www.conf
      regexp: '^user'
      line: 'user={{ php_user }}'
      backrefs: yes

    配置 php-fpm 核心配置文件的所属组,与nginx配置文件一致

    • name: configure php-fpm group
      lineinfile:
      path: /etc/php-fpm.d/www.conf
      regexp: '^group'
      line: 'group={{ php_group }}'
      backrefs: yes

    启动 php-fpm 并设置自启动

    • name: start php-fpm
      service:
      name: php-fpm
      state: started
      enabled: yes

    修改blog.conf,添加php访问支持

    • name: add PHP configure to blog.conf
      blockinfile:
      path: /etc/nginx/conf.d/blog.conf
      block: |
      location ~ .php { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/htmlfastcgi_script_name;
      include fastcgi_params;
      }
      insertafter: '^server {'
      validate: 'nginx -t -c %s'
      notify: reload nginx
  • 第三步:编辑 php/vars/main.yml 文件,配置变量。

    php_user: nginx
    php_group: nginx

  • 第四步:编辑 php/handlers/main.yml 文件,添加触发任务。


    • name: reload nginx
      service:
      name: nginx
      state: restarted
  • 第五步:将 tasks/php.yml 文件包含到 tasks/main.yml 主配置文件中。


    • name: install php
      include_tasks: php.yml
  • 第六步:切换至 roles 目录外,创建 php_deploy.yml 文件,配置内容:


    • name: deploy php
      hosts: web
      user: root
      gather_facts: yes
      roles:
      • role: php

最后,使用命令 ansible-playbook php-deploy.yml 来执行任务。

4.4.部署wordPress

  • 第一步:定义 wordpressRoles 角色和相关脚本文件

    roleName=wordpress
    mkdir -p roles/{roleName}/{tasks,handlers,vars,files,templates} ​ touch roles/{roleName}/tasks/main.yml
    touch roles/{roleName}/handlers/main.yml touch roles/{roleName}/vars/main.yml
    touch roles/${roleName}/templates/main.yml

  • 第二步:切换至 wordpress/tasks/wordpress.yml 文件

    下载 wordpress

    解压 wordpress

    • name: tar wordpress
      #command: tar xf /tmp/wordpress-6.0.1-zh_CN.tar.gz
      unarchive:
      src: /tmp/wordpress-6.0.1-zh_CN.tar.gz
      dest: /tmp/
      remote_src: yes
      creates: /tmp/unarchived_files/example_file.txt

    移动 wordpress

    • name: move wordpress
      shell: mv /tmp/wordpress/* /var/www/html/

    备份 wp-config-sample.php

    • name: backup config
      command: cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php

    更新 wp-config.php 配置文件,添加MySQL数据库连接配置

    • name: update config
      replace:
      path: "/var/www/html/wp-config.php"
      regexp: "define\( '{{ item.define }}', '{{ item.original }}' \);"
      replace: "define( '{{ item.define }}', '{{ item.new }}' );"
      with_items:
      • { define: 'DB_NAME', original: 'database_name_here', new: "{{ db_name }}" }
      • { define: 'DB_USER', original: 'username_here', new: "{{ db_user }}" }
      • { define: 'DB_PASSWORD', original: 'password_here', new: "{{ db_password }}" }
      • { define: 'DB_HOST', original: 'localhost', new: "{{ db_host }}" }
      • { define: 'DB_CHARSET', original: 'utf8', new: "{{ db_charset }}" }

    修改 /var/www/html 的用户和组

    • name: chmod
      command: chown -R nginx:nginx /var/www/html/

    修改 /var/www/html/ 的权限为755

    • name: chmod
      command: chmod -R 755 /var/www/html/

    清空 /usr/share/nginx/html 目录下的所有文件

    • name: clear
      shell: cd /usr/share/nginx/html && rm -rf *

    更新 /etc/nginx/conf.d/blog.conf 配置文件

    • name: update nginx config1
      replace:
      path: /etc/nginx/conf.d/blog.conf
      regexp: 'root /usr/share/nginx/html;'
      replace: 'root /var/www/html;'

    更新 /etc/nginx/conf.d/blog.conf 配置文件

    • name: update nginx config2
      replace:
      path: /etc/nginx/conf.d/blog.conf
      regexp: 'index index.html index.htm;'
      replace: 'index index.php index.html index.htm;'

    重启nginx

    • name: restart nginx
      service:
      name: nginx
      state: restarted
  • 第三步:编辑 php/handlers/main.yml 文件,添加触发任务。


    • name: restart nginx
      service:
      name: nginx
      state: restarted
  • 第四步:将 tasks/wordpress.yml 文件包含到 tasks/main.yml 主配置文件中。


    • name: install wordpress
      include_tasks: wordpress.yml
  • 第五步:切换至 roles 目录外,创建 wordpress_deploy.yml 文件,配置内容:


    • name: deploy wordpress
      hosts: web
      user: root
      gather_facts: yes
      roles:
      • role: wordpress

最后,使用命令 ansible-playbook wordpress-deploy.yml 来执行任务。

相关推荐
a_eastern2 小时前
linux electron-forge离线打包关键配置
android·linux·electron
城东米粉儿2 小时前
Dynamic Feature Modules 笔记
android
无言Echo2 小时前
Android 高斯模糊(1) 窗口模糊及java侧基本流程简述
android
无言Echo2 小时前
Android 高斯模糊(2)BackgroundBlurDrawable使用及相关Bug
android
清蒸鳜鱼3 小时前
【Open-AutoGLM】MacOS+Android配置、使用指南
android·macos
唐叔在学习3 小时前
buildozer打包详解:细说那些我踩过的坑
android·后端·python
2501_946233893 小时前
Flutter与OpenHarmony帖子详情页面开发
android·java·flutter
冬奇Lab3 小时前
稳定性性能系列之四——异常日志机制与进程冻结:问题排查的黑匣子
android·性能优化·车载系统·bug
秋邱3 小时前
Java匿名内部类的使用场景:从语法本质到实战优化全解析
android·java·开发语言·数据库·python