Ansible Roles 一、Ansible Roles基本概述 案例 二、template 模板

1.Ansible Roles介绍

roles不管是Ansible还是saltstack,我在写一键部署的时候,都不可能把所有的步骤全部写入到一个'剧本'文件当中,我们肯定需要把不同的工作模块,拆分开来,解耦,那么说到解耦,我们就需要用到roles官方推荐,因为roles的目录结构层次更加清晰。

例如:我们之前推荐大家写一个lnmp.yml里面写所有基础优化的项目,其实把所有东西摞进去也是很鸡肋的,不如我们把这些功能全部拆分开,谁需要使用,就调用即可。
作用:就是继续规范剧本的代码,使其更加精简、完善
     层层细化拆分,层次调用,灵活方便!

建议:每个roles最好只使用一个tasks这样方便我们去调用,能够很好的做到解耦。(SOA)
# 运维复杂的场景:建议使用 roles,代码复用度高

roles:多个角色的集合目录, 可以将多个的role,分别放至roles目录下的独立子目录中,如下示例

 roles/
 mysql/
 nginx/
 tomcat/
 redis/

默认roles存放路径

/root/.ansible/roles
/usr/share/ansible/roles
/etc/ansible/roles

目录结构

├── nginx -------------role1名称
│   ├── defaults  ---------必须存在的目录,存放默认的变量,模板文件中的变量就是引用自这里。defaults中的变量优先级最低,通常我们可以临时指定变量来进行覆盖
│   │   └── main.yml
│   ├── files -------------ansible中unarchive、copy等模块会自动来这里找文件,从而我们不必写绝对路径,只需写文件名
│   │   ├── mysql.tar.gz
│   │   └── nginx.tar.gz
│   ├── handlers -----------存放tasks中的notify指定的内容
│   │   └── main.yml
│   ├── meta
│   ├── tasks --------------存放playbook的目录,其中main.yml是主入口文件,在main.yml中导入其他yml文件,要采用import_tasks关键字,include要弃用了
│   │   ├── install.yml
│   │   └── main.yml -------主入口文件
│   ├── templates ----------存放模板文件。template模块会将模板文件中的变量替换为实际值,然后覆盖到客户机指定路径上
│   │   └── nginx.conf.j2
│   └── vars

Roles各目录作用

- files/ :存放由copy或script模块等调用的文件
- templates/:template模块查找所需要模板文件的目录
- tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
- handlers/:至少应该包含一个名为main.yml的文件;此目录下的其它的文件需要在此文件中通过
- include进行包含
- vars/:定义变量,至少应该包含一个名为main.yml的文件;此目录下的其它的变量文件需要在此文件中通过include进行包含
- meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
- default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低

2.创建role目录

创建role的步骤

1. 创建以roles命名的目录
2. 在roles目录中分别创建以各角色名称命名的目录,如mysql等
3. 在每个角色命名的目录中分别创建files、handlers、tasks、templates和vars等目录;用不到的目录可以创建为空目录,也可以不创建
4. 在每个角色相关的子目录中创建相应的文件,如 tasks/main.yml,templates/nginx.conf.j2
5. 在playbook文件中,调用需要的角色

[root@m01 package]# mkdir -p /root/package/roles/nginx/{files,handlers,tasks,templates,vars,meta}
[root@m01 package]# tree
.
└── roles
    └── nginx
        ├── files
        ├── handlers
        ├── meta
        ├── tasks
        ├── templates
        └── vars

1).手动创建 (不推荐)

[root@m01 ~]# mkdir /project
[root@m01 ~]# cd /project/
[root@m01 project]# mkdir roles
[root@m01 project]# touch site.yml
[root@m01 project]# ll
total 0
drwxr-xr-x 2 root root 6 May  9 16:47 roles
-rw-r--r-- 1 root root 0 May  9 16:47 site.yml
[root@m01 roles]# mkdir {mariadb,php,nfs-client,nfs-server,nginx}
[root@m01 roles]# mkdir nginx/{tasks,files,templates,vars,handlers,meta} -p
[root@m01 roles]# tree nginx
nginx/              
├── defaults        #低优先级变量
├── files           #存放文件
├── handlers        #触发器文件
├── meta            #依赖关系文件
├── tasks           #工作任务文件
├── templates       #jinja2模板文件
├── tests           #测试文件
└── vars            #变量文件  

2)命令创建

[root@m01 roles]# ansible-galaxy init nginx
- Role nginx was created successfully

[root@m01 roles]# tree nginx
nginx				    #项目目录名称
├── defaults			#默认的变量(优先级很低)
│   └── main.yml
├── files				#存放文件,使用copy模块时自动获取
├── handlers			#存放触发器的配置
│   └── main.yml
├── meta				#依赖的服务,执行该项目时先执行其他的项目
│   └── main.yml
├── README.md
├── tasks				#默认执行的playbook
│   └── main.yml
├── templates			#存放jinja2模板,使用template模块时自动获取
├── tests
│   ├── inventory
│   └── test.yml
└── vars				#存放变量
    └── main.yml

3.Ansible Roles依赖关系

`roles`允许你再使用roles时自动引入其他的roles。role依赖关系存储在roles目录中meta/main.yml文件中。

例如:推送wordpress并解压,前提条件,必须要安装nginx和php,把服务跑起来,才能运行wordpress的页面,此时我们就可以在wordpress的roles中定义依赖nginx和php的roles

[root@m01 roles]# vim /etc/ansible/roles/wordpress/meta/main.yml
dependencies:
  - { role: nginx }
  - { role: php }
  
如果编写了meta目录下的main.yml文件,那么Ansible会自动先执行meta目录中main.yml文件中的dependencies文件,如上所示,就会先执行nginx和php的安装。

案例

http角色
#创建角色相关的目录
[root@m01 ~]# mkdir -pv /data/ansible/roles/httpd/{tasks,handlers,files}
  
#创建角色相关的文件
[root@m01 ~]# cd /data/ansible/roles/httpd/

#main.yml 是task的入口文件
[root@m01 httpd]# vim tasks/main.yml
- include: group.yml
- include: user.yml
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml

[root@m01 httpd]# vim tasks/group.yml
- name: create apache group
  group: name=apache system=yes gid=80
  
[root@m01 httpd]# vim tasks/user.yml
- name: create apache user
  user: name=apache system=yes shell=/sbin/nologin home=/var/www/ uid=80 group=apache
  
[root@m01 httpd]# vim tasks/install.yml
- name: install httpd package
  yum: name=httpd state=present 
  
[root@m01 httpd]# vim tasks/config.yml
- name: config file
  copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes
  notify: restart
  
[root@m01 httpd]# vim tasks/index.yml
- name: index.html
  copy: src=index.html dest=/var/www/html/
  
[root@m01 httpd]# vim tasks/service.yml
- name: start service
  service: name=httpd state=started enabled=yes
  
[root@m01 httpd]# vim handlers/main.yml
- name: restart
  service: name=httpd state=restarted
  
#在files目录下准备两个文件
[root@m01 httpd]# ls files/
httpd.conf index.html
[root@m01 ~]# tree /data/ansible/roles/httpd/
/data/ansible/roles/httpd/
├── files
│   ├── httpd.conf
│   └── index.html
├── handlers
│   └── main.yml
└── tasks
   ├── config.yml
   ├── group.yml
   ├── index.yml
   ├── install.yml
   ├── main.yml
   ├── service.yml
   └── user.yml
3 directories, 10 files
#在playbook中调用角色
[root@m01 ~]# vim /data/ansible/role_httpd.yml
---
# httpd role
- hosts: websrvs
  remote_user: root
  roles:
    - httpd
    
#运行playbook
[root@m01 ~]# ansible-playbook /data/ansible/role_httpd.yml

NGINX角色

[root@m01 ~]# mkdir -pv /data/ansible/roles/nginx/{tasks,handlers,templates,vars}

#创建task文件
[root@m01 ~]# cd /data/ansible/roles/nginx/
[root@m01 nginx]# vim tasks/main.yml 
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml

[root@m01 nginx]# vim tasks/install.yml 
- name: install
  yum: name=nginx 
 
[root@m01 nginx]# vim tasks/config.yml 
- name: config file for centos7
  template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf
  when: ansible_distribution_major_version=="7"
  notify: restart
- name: config file for centos8
  template: src=nginx8.conf.j2 dest=/etc/nginx/nginx.conf
  when: ansible_distribution_major_version=="8"
  notify: restart
  
#跨角色调用文件
[root@m01 nginx]# vim tasks/index.yml 
- name: index.html
  copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/
  
[root@m01 nginx]# vim tasks/service.yml 
- name: start service
  service: name=nginx state=started enabled=yes
  
#创建handler文件
[root@m01 nginx]# vim handlers/main.yml 
- name: restart
  service: name=nginx state=restarted
  
#创建两个template文件
[root@m01 nginx]# cat templates/nginx7.conf.j2
...省略...
user {{user}};
worker_processes {{ansible_processor_vcpus+3}};   #修改此行
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
...省略...
[root@ansible nginx]#cat templates/nginx8.conf.j2
...省略...
user nginx;
worker_processes {{ansible_processor_vcpus**3}};  #修改此行
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
...省略...
#创建变量文件
[root@ansible nginx]#vim vars/main.yml 
user: daemon
#目录结构如下
[root@ansible ~]#tree /data/ansible/roles/nginx/
/data/ansible/roles/nginx/
├── handlers
│   └── main.yml
├── tasks
│   ├── config.yml
│   ├── file.yml
│   ├── install.yml
│   ├── main.yml
│   └── service.yml
├── templates
│   ├── nginx7.conf.j2
│   └── nginx8.conf.j2
└── vars
   └── main.yml
4 directories, 9 files
#在playbook中调用角色
[root@ansible ~]#vim /data/ansible/role_nginx.yml 
---
#nginx role 
- hosts: web
 roles:
    - role: nginx
    
#运行playbook
[root@ansible ~]#ansible-playbook /data/ansible/role_nginx.yml
Copy to clipboardErrorCopied

二、template 模板

template 模板是一个文本文件,可以做为生成文件的模版,并且模板文件中还可嵌套jinja语法

jinja2语言

官方网站:

http://jinja.pocoo.org/

https://jinja.palletsprojects.com/en/2.11.x/

数据类型

jinja2 语言支持多种数据类型和操作:

  • 字符串:使用单引号或双引号,
  • 数字:整数,浮点数
  • 列表:[item1, item2, ...]
  • 元组:(item1, item2, ...)
  • 字典:{key1:value1, key2:value2, ...}
  • 布尔型:true/false
  • 算术运算:+, -, *, /, //, %, **
  • 比较操作:==, !=, >, >=, <, <=
  • 逻辑运算:and,or,not
  • 流表达式:For,If,When

template

template功能:可以根据和参考模块文件,动态生成相类似的配置文件,template文件必须存放于templates目录下,且命名为 .j2 结尾,yaml/yml 文件需和templates目录平级,目录结构如下示例:

 ./
├── temnginx.yml
└── templates
    └── nginx.conf.j2 

范例:利用template 同步nginx配置文件

#准备templates/nginx.conf.j2文件
[root@m01 ~]# vim temnginx.yml
---
- hosts: web_group
  remote_user: root 
  tasks:
    - name: template config to remote hosts
     template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
[root@m01 ~]# ansible-playbook temnginx.yml

template变更替换

#修改文件nginx.conf.j2 
[root@m01 ~]# mkdir templates
[root@m01 ~]# vim templates/nginx.conf.j2
......
worker_processes {{ ansible_processor_vcpus }};  #只修改此处{{ }}
......
[root@m01 ~]# vim temnginx.yml
---
- hosts: web_group
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 
    - name: start service
      service: name=nginx state=started enabled=yes
       
[root@m01 ~]# ansible-playbook temnginx.yml 

template算术运算

[root@m01 ansible]# vim templates/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus**3 }};
[root@m01 ansible]# vim templnginx.yml
---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart nginx
    - name: start service
      service: name=nginx state=started enabled=yes
 handlers:
    - name: restart nginx
      service: name=nginx state=restarted
[root@am01 ~]# ansible -playbook templnginx.yml --limit 10.0.0.8

template中使用流程控制for和if

不管是shell还是各大编程语言中,流程控制,条件判断这些都是必不可少的,在我们使用Ansible的过程中,条件判断的使用频率极其高。
例如:
1.我们使用不同的系统的时候,可以通过判断系统来对软件包进行安装。
2.在nfs和rsync安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play,会影响效率。

3.我们在源码安装nginx的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。

template中也可以使用流程控制 for 循环和 if 条件判断,实现动态生成文件功能

# 需求:在web机器中搭建三个项目,分别使用80、81、82三个端口
#temlnginx2.yml
---
- hosts: websrvs
 remote_user: root
 vars:
   nginx_vhosts:
     - 81
     - 82
     - 83
 tasks:
   - name: template config
     template: src=nginx.conf2.j2 dest=/data/nginx.conf
#templates/nginx.conf2.j2
{% for vhost in nginx_vhosts %}
server {
   listen {{ vhost }}
}
{% endfor %}
ansible-playbook -C templnginx2.yml --limit 192.168.15.8
#生成的结果:
server {
   listen 81   
}
server {
   listen 82   
}
server {
   listen 83   
}

# 需求:部署www.abck8s.com、blog.abck8s.com、linux.abck8s.com
#templnginx4.yml
- hosts: websrvs
 remote_user: root
 vars:
   nginx_vhosts:
     - listen: 8080
       server_name: "web1.oldboy.com"
       root: "/var/www/nginx/web1/"
     - listen: 8081
       server_name: "web2.oldboy.com"
       root: "/var/www/nginx/web2/"
     - {listen: 8082, server_name: "web3.oldboy.com", root: 
"/var/www/nginx/web3/"}
 tasks:
   - name: template config 
     template: src=nginx.conf4.j2 dest=/data/nginx4.conf
        
# templates/nginx.conf4.j2
{% for vhost in nginx_vhosts %}
server {
   listen {{ vhost.listen }}
   server_name {{ vhost.server_name }}
   root {{ vhost.root }}  
}{% endfor %} 

[root@ansible ~]#ansible-playbook templnginx4.yml --limit 10.0.0.8
#生成结果:
server {
   listen 8080
   server_name web1.oldboy.com
   root /var/www/nginx/web1/  
}
server {
   listen 8081
   server_name web2.oldboy.com
   root /var/www/nginx/web2/  
}
server {
   listen 8082
   server_name web3.oldboy.com
   root /var/www/nginx/web3/  
}Copy to clipboardErrorCopied

playbook使用when

when语句,可以实现条件测试。如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过在task后添加when子句即可使用条件测试,jinja2的语法格式。

1.在剧本中设置判断信息(when)

[root@m01 ansible-playbook]# cp rsync_server.yaml rsync_server_判断信息.yaml
[root@m01 project]# vim xitong.yml
- hosts: web_group
  tasks:
    - name: Install Centos httpd
      shell: "yum install -y httpd"
      when: ansible_distribution == "CentOS"

    - name: Install Ubuntu httpd
      shell: "apt-get apache2"
      when: ansible_distribution == "Ubuntu"

2.判断主机

[root@m01 project]# cat base.yml
    - name: Create www Group
      group:
        name: www
        gid: 666
        state: present
      when: ansible_fqdn != "db01"

    - name: Create www User
      user:
        name: www
        uid: 666
        group: www
        shell: /sbin/nologin
        create_home: false
        state: present
      when: ansible_fqdn != "db01"

3.判断服务是否安装

[root@m01 project]# cat php.yml
- hosts: web_group
  tasks:
    - name: Tar php Package
      unarchive:
        src: /project/package/php.tar.gz
        dest: /tmp/
    
    #使用shell模块,检查php是否安装,将结果赋值给注册的变量
    - name: Check php Install Status
      shell: "rpm -qa | grep php | wc -l"
      register: get_php_instll_status

    #调用注册的变量,当变量中stdout_lines为0的时候,才会安装php
    - name: Install php Server
      shell: "yum localinstall -y /tmp/*.rpm"
      when: get_php_instll_status.stdout_lines == 0

4.判断系统版本启动服务

1)写法一:使用列表的形式

[root@m01 project]# vim startserver.yml
- hosts: web_group
  tasks:
    - name: Start CentOS 6 Server
      shell: "/etc/init.d/httpd start"
      when:
        - ansible_distribution == "CentOS"
        - ansible_distribution_major_version == "6"

    - name: Start CentOS 7 Server
      shell: "systemctl start httpd"
      when:
        - ansible_distribution == "CentOS"
        - ansible_distribution_major_version == "7"

2)写法二:多条件and连接

[root@m01 project]# vim startserver.yml
- hosts: web_group
  tasks:
    - name: Start CentOS 6 Server
      shell: "/etc/init.d/httpd start"
      when: (ansible_distribution == "CentOS") and (ansible_distribution_major_version == "6")

    - name: Start CentOS 7 Server
      shell: "systemctl start httpd"
      when: (ansible_distribution == "CentOS") and (ansible_distribution_major_version == "7")

5.判断服务是否启动

- hosts: web_group
  tasks:
    - name: Check Httpd Server
      command: systemctl is-active httpd
      ignore_errors: yes
      register: check_httpd

    - name: debug outprint
      debug: var=check_httpd

    - name: Httpd Restart
      service:
        name: httpd
        state: restarted
      when: check_httpd.rc == 0

playbook使用迭代with_items(loop)

迭代:当有需要重复性执行的任务时,可以使用迭代机制对迭代项的引用,固定内置变量名为"item",要在task中使用with_items给定要迭代的元素列表

注意: ansible2.5版本后,可以用loop代替with_items

# 单一定义
[root@m01 project]# vim systemd.yml
---
- hosts: web_server
  remote_user: root 
  tasks:
    - name: add several users
      systemd: name={{ item }} state=present 
      with_items:
        - nginx
        - mariadb

迭代嵌套子变量:在迭代中,还可以嵌套子变量,关联多个变量在一起使用

# 字典定义变量
[root@m01 project]# vim systemd.yml
---
- hosts: webgroup
  remote_user: root
  tasks:
    - name: add some groups
      group: name={{ item }} state=present
      with_items:
        - nginx
        - mysql
        - apache
    - name: add some users
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: 'nginx', group: 'nginx' }
        - { name: 'mysql', group: 'mysql' }
        - { name: 'apache', group: 'apache' }

管理节点过多导致的超时问题解决方法

默认情况下,Ansible将尝试并行管理playbook中所有的机器。对于滚动更新用例,可以使用serial关键字定义Ansible一次应管理多少主机,还可以将serial关键字指定为百分比,表示每次并行执行的主机数占总数的比例

#vim test_serial.yml
---
- hosts: all
  serial: 2  #每次只同时处理2个主机,将所有task执行完成后,再选下2个主机再执行所有task,直至所有主机
  gather_facts: False
  tasks:
    - name: task one
  comand: hostname
    - name: task two
      command: hostname

# 案例2:
- name: test serail
  hosts: all
  serial: "20%"   #每次只同时处理20%的主机Copy to clipboardErrorCopied

二、重构playbook

1.配置主机清单

[root@m01 roles]# cat /etc/ansible/hosts 
[web_group] 
web01 ansible_ssh_pass='123'
web02 ansible_ssh_pass='123'

[nfs_group]
nfs ansible_ssh_pass='123'

[slb]
lb01 ansible_ssh_pass='123 '
lb02 ansible_ssh_pass='123 '

[db_group]
db01 ansible_ssh_pass='123'

[backup_group]
backup ansible_ssh_pass='123'

[nginx_group:children]
web_group
slb

[nfs_server:children]
web_group
nfs_group 

[nginx_group:vars]
web=host_vars

2.配置hosts

[root@m01 roles]# vim /etc/hosts
172.16.1.107 web01

172.16.1.108 web02

172.16.1.131 nfs

172.16.1.141 backup

172.16.1.151 db01

172.16.1.105 lb01

172.16.1.106 lb02

3.优化部分

1.创建优化部分的roses结构
[root@m01 ~]# mkdir /project
[root@m01 ~]# cd /project/
[root@m01 project]# mkdir roles
[root@m01 project]# cd roles
[root@m01 roles]# ansible-galaxy init base
- Role base was created successfully
[root@m01 roles]# tree
.
└── base
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── README.md
    ├── tasks
    │   └── main.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml
3.编写优化playbook剧本
[root@m01 ~]# cd /project/roles/base/tasks/
[root@m01 tasks]# ll
-rw-r--r-- 1 root root 25 May  9 17:18 main.yml
[root@m01 tasks]# vim main.yml 
- name: Stop Selinux
  selinux: state=disabled   
  
- name: stop firewalld
  systemd: name=firewalld state=stopped
  
- name: create www group
  group: name:=www gid=666

- name: create www user
  user: name=www group=www uid=666 shell=/sbin/nologin create_home=no

- name: install unzip server 
  yum: name=unzip state=present

4.nginx部分

1、创建roles结构
[root@m01 roles]# ansible-galaxy init nginx
- Role base was created successfully  #代表创建成功
2.准备文件
[root@m01 roles]# cd /project/roles/nginx/files/
[root@m01 files]# cp /etc/nginx/nginx.conf ./
[root@m01 files]# ll
total 4
-rw-r--r-- 1 root root 671 May  9 18:08 nginx.conf
[root@m01 files]# cp /etc/yum.repos.d/nginx.repo ./
[root@m01 files]# ll
total 8
-rw-r--r-- 1 root root 671 May  9 18:08 nginx.conf 
-rw-r--r-- 1 root root 183 May  9 18:08 nginx.repo
# nginx官方源安装
3、编写nginx的playbook剧本
[root@m01 tasks]# vim main.yml 
- name: copy nginx repo
  copy: src=/etc/yum.repos.d/nginx.repo dest=/etc/yum.repos.d/
    
- name: install nginx server
  yum: name=nginx state=present

- name: config nginx server
  copy: src=nginx.conf dest=/etc/nginx/
  notify: restart_nginx 

- name: start nginx server
  systemd: name=nginx state=started
4、单独执行测试
[root@m01 project]# cat /project/site.yml 
- hosts: all
  roles:
    - base
- hosts: web_group
  roles:
    - nginx
 #第二种方式
 [root@m01 project]# cat /project/site.yml 
- hosts: all
  roles:
    - role: base
    - role: nginx
      when: ansible_fqdn is match "web*"   
# 检查语法并测试      
[root@m01 project]# ansible-playbook --syntax-check site.yml 

playbook: site.yml
[root@m01 project]# ansible-playbook site.yml 

5.php部分

1、创建roles结构
[root@m01 roles]# ansible-galaxy init php
- Role base was created successfully  #代表创建成功
2.准备文件
[root@m01 roles]# cd php/files/
[root@m01 files]# cp /package/php.tar.gz ./
[root@m01 files]# cp /etc/php.ini ./
[root@m01 files]# cp /etc/php-fpm.d/www.conf ./
[root@m01 files]# ll
total 19508
-rw-r--r-- 1 root root    62645 May  9 19:15 php.ini
-rw-r--r-- 1 root root 19889622 May  9 19:14 php.tar.gz
-rw-r--r-- 1 root root    17962 May  9 19:16 www.conf
3、编写php的playbook剧本
[root@m01 php]# vim tasks/main.yml 
- name: tar php.tar.gz
  unarchive:  src=php.tar.gz dest=/opt/

- name: install php server
  shell: "yum localinstall -y /opt/*.rpm"

- name: config php server
  copy: src=php.ini  dest=/etc/
   
- name: config php server
  copy: src=www.conf  dest: /etc/php-fpm.d/  
  notify: restart_php

- name: start php server
  systemd:  name-php-fpm state: started
3、配置触发器
[root@m01 roles]# vim php/handlers/main.yml 
- name: restart_php
  systemd:
    name: php-fpm
    state: restarted
4.单独执行测试
[root@m01 project]# cat site.yml 
- hosts: all
  roles:
    - role: base
    - role: nginx
      when: ansible_fqdn is match "web*"
    - role: php
      when: ansible_fqdn is match "web*"
# 检查语法并测试      
[root@m01 project]# ansible-playbook --syntax-check site.yml 

playbook: site.yml
[root@m01 project]# ansible-playbook site.yml 

6.数据库部分

1、创建roles结构
[root@m01 roles]# ansible-galaxy init mariadb
- Role base was created successfully  #代表创建成功
2.编写数据库playbook剧本
[root@m01 roles]# cd mariadb/tasks/
[root@m01 tasks]# ll
total 4
-rw-r--r-- 1 root root 28 May  9 19:36 main.yml 

[root@m01 project]# cat roles/mariadb/tasks/main.yml 
- name: install mariadb sever
  yum:
    name: "{{ item.name }}"
    state: present
  with_items:
    - { name: "mariadb-server" }
    - { name: "MySQL-python" }

- name: start mariadb server
  systemd:
    name: mariadb
    state: started
    enabled: yes

7.博客部分

1、创建roles结构
[root@m01 roles]# ansible-galaxy init wordpress
- Role base was created successfully  #代表创建成功 
2、准备文件
[root@m01 roles]# cd wordpress/files/
[root@m01 files]# cp /etc/nginx/conf.d/discuz.conf ./
[root@m01 files]# cp /code/discuz/upload/config/cfg.php ./
[root@m01 files]# rz
[root@m01 files]# ll
[root@m01 files]# ll
total 12272
-rw-r--r-- 1 root root    10091 Jun  3 17:56 cfg.php
-rw-r--r-- 1 root root      254 Jun  3 17:16 discuz.conf
-rw-r--r-- 1 root root 12546097 May  7 18:45 Discuz-DiscuzX-master.zip
3、编写博客playbook剧本
# 安装discuz部分
[root@m01 tasks]# vim /project/roles/discuz/tasks/main.yml
- name: mkdir code
  file:path=/code state=directory owner=www group=www

- name: tar bao
  unarchive: src=Discuz-DiscuzX-master.zip dest=/code/ owner=www group=www

- name: config discuz conf
  copy: src=discuz.conf dest=/etc/nginx/conf.d/
  notify: restart_discuz_nginx
4、配置触发器
[root@m01 handlers]# vim main.yml 
- name: restart_discuz_nginx
  systemd:
    name: nginx
    state: restarted
5 .编写建库playbook剧本
# 1、建库的目录结构
[root@m01 roles]# ansible-galaxy init database
- Role base was created successfully  #代表创建成功 

# 2 、编写建库playbook剧本
[root@m01 project]# vim roles/database/tasks/main.yml 
- name: create discuze database
  mysql_db: name=discuz state=present

- name: create discuz database user
  mysql_user: name="discuz" host="172.16.1.%" password=123 priv='*.*:ALL' state: present
6.配置站点依赖 (无需配置)
[root@m01 wordpress]# cat /project/roles/wordpress/meta/main.yml 
dependencies:
  - { role: database }
  
# 可以不配置,直接为空
[root@m01 project]# echo >roles/wordpress/meta/main.yml 
7.访问测试
[root@m01 project]# cat site.yml 
- hosts: all
  roles:
    - role: base
    - role: nginx
      when: ansible_fqdn is match "web*"
    - role: php
      when: ansible_fqdn is match "web*"

    - role: mariadb
      when: ansible_fqdn == "db01"
    - role: database
      when: ansible_fqdn == "db01"
    - role: wordpress
      when: ansible_fqdn is match "web*"
      
# 1.检查语法并测试      
[root@m01 project]# ansible-playbook --syntax-check site.yml 

playbook: site.yml
[root@m01 project]# ansible-playbook site.yml 

# 2.本地hosts访问测试 
192.168.15.107 linux12.wp.com
192.168.15.108 linux12.wp.com

8.负载均衡部分

1、创建roles结构
[root@m01 roles]# ansible-galaxy init slb
- Role base was created successfully  #代表创建成功 
2、准备文件
[root@m01 files]# cd /project/roles/slb/files/
[root@m01 files]# cp /root/mm/proxy.conf ./
[root@m01 files]# cp /root/mm/proxy_params ./
[root@m01 files]# ll
total 8
-rw-r--r-- 1 root root 203 May  9 23:47 proxy.conf
-rw-r--r-- 1 root root 334 May  9 23:47 proxy_params
3、编写slb的playbook剧本
[root@m01 tasks]# cat /project/roles/slb/tasks/main.yml 
- name: config slb server
  copy:
    src: /root/mm/proxy.conf
    dest: /etc/nginx/conf.d
  notify: restart_slb
   
- name: copy proxy_params
  copy:
    src: /root/mm/proxy_params
    dest: /etc/nginx/

- name: start web nginx server
  systemd:
    name: nginx
    state: started
    enabled: yes
3、配置触发器
[root@m01 slb]# cat handlers/main.yml 
- name: restart_slb
  systemd:
    name: nginx
    state: restarted
4.配置依赖
[root@m01 wordpress]# cat /project/roles/wordpress/meta/main.yml 
[root@m01 slb]# cat /project/roles/slb/meta/main.yml 
dependencies:
  - { role: nginx }
5.负载均衡访问测试
[root@m01 project]# cat site.yml 
- hosts: all
  roles:
   # - role: base
   # - role: nginx
   #   when: ansible_fqdn is match "web*"
   # - role: php
   #   when: ansible_fqdn is match "web*"

   # - role: mariadb
   #   when: ansible_fqdn == "db01"
   # - role: database
   #   when: ansible_fqdn == "db01"
   # - role: wordpress
   #   when: ansible_fqdn is match "web*"
    - role: slb
      when: ansible_fqdn is match "lb*"
      
#注释: 因为前面都测试完成正确,所有不需要测试了
# 1.检查语法并测试      
[root@m01 project]# ansible-playbook --syntax-check site.yml 

playbook: site.yml
[root@m01 project]# ansible-playbook site.yml 

# 2.本地hosts访问测试 
192.168.15.107 linux12.wp.com
192.168.15.108 linux12.wp.com

9.配置keepalived高可用

1、创建roles结构
[root@m01 roles]# ansible-galaxy init keepalived
- Role base was created successfully  #代表创建成功 
2、准备文件
[root@m01 files]# cd /project/roles/keepalived/files/
[root@m01 templates]# cp /root/mm/keepalived.j2 ./
[root@m01 templates]# ll
total 4
-rw-r--r-- 1 root root 381 Dec 24 16:38 keepalived.j2
2、编写keepalived的playbookl剧本
[root@m01 roles]# vim keepalived/tasks/main.yml 
- name: Install keepalived Server
  yum:
    name: keepalived
    state: present

- name: Config keepalived Server
  template:
    src: /root/mm/keepalived.j2
    dest: /etc/keepalived/keepalived.conf

- name: Start keepalived Server
  systemd:
    name: keepalived
    state: started
3.keepalived 访问测试
[root@m01 project]# cat site.yml 
- hosts: all
  roles:
   # - role: base
   # - role: nginx
   #   when: ansible_fqdn is match "web*"
   # - role: php
   #   when: ansible_fqdn is match "web*"

   # - role: mariadb
   #   when: ansible_fqdn == "db01"
   # - role: database
   #   when: ansible_fqdn == "db01"
   # - role: wordpress
   #   when: ansible_fqdn is match "web*"
    - role: slb
      when: ansible_fqdn is match "lb*"
    - role: keepalived
      when: ansible_fqdn is match "lb*" 
# 2.本地hosts访问测试,实现vip飘逸
192.168.15.107 linux12.wp.com
192.168.15.108 linux12.wp.com
# vip: 192.168.15.102

10.整合剧本

[root@m01 project]# cat site.yml 
- hosts: all
  roles:
    - role: base
    - role: nginx
      when: ansible_fqdn is match "web*"
    - role: php
      when: ansible_fqdn is match "web*"

    - role: mariadb
      when: ansible_fqdn == "db01"
    - role: database
      when: ansible_fqdn == "db01"
    - role: wordpress
      when: ansible_fqdn is match "web*"
    - role: slb
      when: ansible_fqdn is match "lb*"
   - role: keepalived
      when: ansible_fqdn is match "lb*"