Ansible自动化运维工具 —— Playbook 剧本

playbooks 本身由以下各部分组成
(1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行
(2)Variables:变量
(3)Templates:模板
(4)Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作
(5)Roles:角色

playbook 剧本 总结

vim  XXX.yaml

- name:                      #指定play名称
  hosts:                     #指定主机组
  remote_user:               #执行用户 
  gather_facts: true|false   #是否收集远程主机facts信息
  vars:                      #定义变量
  tasks:                     #定义task任务列表
  - name:                 #定义task任务名称
    模块:                 #定义任务使用的模块和参数
    with_items:           #定义循环列表
    when:                 #定义判断条件(== != >= > <= <),true则执行任务,否则不执行任务
    ignore_errors: true   #忽略任务失败
    notify:               #定义task任务changed状态时触发的任务名
    tags:                 #指定标签,ansible-playbook --tags 仅执行拥有指定 tags 标签的任务(always标签总会执行)
  handlers:                  #定义notify触发的任务列表

task任务 模块语法格式

模块名: 参数选项1=值  参数选项2={{变量名}}  ...

模块名:
  参数选项1: 值
  参数选项2: "{{变量名}}"
  ...

with_items 和 变量 的语法格式

with_items: ["值1", "值2", "值3"]

with_items:
- 值1
- 值2
- 值3

值为对象(键值对字段)时:

with_items:
- {key1: value1, key2: value2, ...}
- {key1: value3, key2: value4, ...}


with_items:
- key1: value1
  key2: value2
- key1: value3
  key2: value4

template模板模块
1)先要准备一个 xxx.j2 模板文件,在文件中使用 {{变量名}} 引用主机变量 或者 vars 自定义的变量 及 facts 字段的值
2)在 playbook 中的 tasks 中定义 template 模板配置  template: src=xxx.j2  dest=xxx

roles 角色 的作用?【重中之重】

把playbook剧本里的各个play看作为角色,将各个角色的tasks任务、vars变量、templates模板、files文件等内容放置到角色的目录中统一管理,需要的时候可在playbook中直接使用roles调用,所以roles可以实现playbook代码的复用。

实验

架构

192.168.80.101 ansible

192.168.80.102 被控服务器

192.168.80.103 被控服务器

/etc/ansible/hosts配置如下

cat /etc/ansible/hosts

示例1 安装httpd服务

mkdir -p /etc/ansible/playbook/
cp /etc/httpd/conf/httpd.conf /etc/ansible/playbook/httpd.conf
#本机的httpd配置复制到ansible目录。可以自定义位置,在下面yaml更改对应位置即可。
vim /etc/ansible/playbook/test1.yaml

---     #yaml文件以---开头,以表明这是一个yaml文件,可省略。
        #若文件中存在多个--- 则代表有多个yaml配置文件存在于同一个文件中
- name: the first play for install apache     #定义一个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忽略失败的任务。
			     #这里需要忽略是因为如果selinux已经关闭再次关闭会返回1
   - name: disable selinux forever
     replace: path=/etc/selinux/config  regexp="enforcing"  replace="disabled"
   - name: disable firewalld
     service: name=firewalld state=stopped enabled=no    #使用 module: options 格式来定义任务,option使用key=value格式
#======================================================================================================================
# 若想要挂载光盘使用本地yum源安装(需要在控制服务器存在/etc/yum.repos.d/repo.bak/local.repo配置文件)可以省略
   - name: mount cdrom
     mount: src=/dev/sr0 path=/mnt fstype=iso9660 state=mounted
   - name: copy local yum configuration file
     copy: src=/etc/yum.repos.d/repo.bak/local.repo  dest=/etc/yum.repos.d/local.repo
#======================================================================================================================
   - name: install httpd
     yum: name=httpd state=latest
   - name: prepare httpd configuration file
     copy: src=/etc/ansible/playbook/httpd.conf dest=/etc/httpd/conf/httpd.conf #这里需要一个事先准备好的/opt/httpd.conf文件
     notify: "restart httpd" ##如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
   - name: start apache httpd
     service: name=httpd state=started enabled=yes
  handlers:     #handlers中定义由notify触发的任务
   - name: restart httpd    #notify和handlers中任务的名称必须一致。注意reload不能让httpd重新加载配置文件中端口等配置,只能restart
     service: name=httpd state=restarted

##Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler
##这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。


//运行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开始运行

 

定义、引用变量

vim /etc/ansible/playbook/test2.yaml

- name: second play
  hosts: dbservers
  remote_user: root
  #remote_user: zhangsan
  #become: yes #这三行代表 远程控制时 使用的普通用户zhangsan提升权限使用root用户
  #become_user: root #需要先修改sudo配置/etc/sudoers使zhangsan用户可以使用sudo提权
  vars:                 #定义变量
   - groupname: mysql   #格式为 key: value
   - username: nginx
   - filename: /opt/123.txt
  gather_facts: true #可以不写 默认开启
  tasks:
   - name: create group
     group: name={{groupname}} system=yes gid=2800    #使用 {{key}} 引用变量的值 system为默认项可以省略不写不影>响
   - name: create user
     user: name={{username}} uid={{uid}} group={{groupname}} #uid并未写在var中,由外部命令执行时传参
   - name: copy file
     #copy: content="{{ansible_default_ipv4}}" dest={{filename}}     #在setup模块中可以获取facts变量信息 这里获>取ipv4块所有信息
     copy: content="{{ansible_default_ipv4.address}}" dest={{filename}}     #在setup模块中可以获取facts变量信息 这里获取ipv4块中address一项信息
   - name: modify username and groupname of file
     file: path={{filename}} owner={{username}}  group={{groupname}}
ansible-playbook test2.yaml -e "username=nginx2" -e "uid=1234"
#在命令行里定义变量 命令行内指定的参数优先级更高可以覆盖playbook var内写的变量

可看到命令行的传参username覆盖了playbook中定义的变量,并且uid也传参进去,其余参数都从playbook中已经定义的var变量中取 



指定远程主机sudo切换用户

在上面的脚本做修改

额外注意在 /etc/ansible/hosts 组变量中是否已经指定了 用户等参数!优先级:命令行传参>host组定义>playbook中定义变量

若host组中已经规定了用户,playbook中的用户设置,become提权等可能被覆盖不会生效!

---
- hosts: dbservers
  remote_user: zhangsan            
  become: yes                    #2.6版本以后的参数,之前是sudo,意思为切换用户运行
  become_user: root              #指定sudo用户为root

运行前需要先在被控制的远程主机上创建zhangsan用户,并修改sudo配置使zhangsan用户可以使用sudo提权,才能在playbook中使用become 使用root用户

adduser zhangsan
passwd zhangsan

vim /etc/sudoers
    zhangsan ALL=ALL

执行playbook,原先命令上附加上 -k -K参数

ansible-playbook test2.yaml  -e "username=nginx3" -e "uid=1357" -k -K
 -k -K
-k(–ask-pass):用来交互输入ssh密码
-K(-ask-become-pass):用来交互输入sudo密码 都输入zhangsan密码即可
-u:指定用户

 

when条件判断

在Ansible中,提供的唯一一个通用的条件判断是when指令,当when指令的值为true时,则该任务执行,否则不执行该任务。

when一个比较常见的应用场景是实现跳过某个主机不执行任务或者只有满足条件的主机执行任务

vim /etc/ansible/playbook/test3.yaml

---
- name: third play
  hosts: all
  remote_user: root
  tasks:
   - name: touch file
     file: path=/opt/1.txt state=touch #创建文件
     #command: /sbin/shutdown/ -r now  #重启指令
     when: inventory_hostname == "192.168.80.102"
       #写法1 inventory_hostname为主机清单 /etc/ansible/hosts的主机名
     #when: ansible_default_ipv4.address != "192.168.80.103" 
       #写法2 ansible_default_ipv4.address为gather_facts获取的主机信息    != 含义为除了103主机
     #when指令中的变量名不需要手动加上 {{}} 
ansible-playbook test3.yaml

迭代(循环) with_items

Ansible提供了很多种循环结构,一般都命名为with_items,作用等同于 loop 循环。

with_items普通取值  写法演示

vim /etc/ansible/playbook/test4.yaml

#😊with_items普通取值
---
- name: fouth play
  hosts: dbservers
  remote_user: root
##############################################################################
  vars:
    myfile:
    - /opt/a
    - /opt/b
    - /opt/c
    - /opt/d
  tasks:
  - name: touch directory #✨方法1 预先编写var变量,随后赋值给with_items
    with_items: "{{myfile}}"
    file: path={{item}} state=directory #🧯模组 横向写法
##############################################################################
  - name: touch file 1    #✨方法2 直接在with_items中定义
    file:                               #🧯模组 纵向写法
      path: "{{item}}"
      state: touch
    with_items:                                        #🔥with_items纵向写法
    - /root/a
    - /root/b
    - /root/c
    - /root/d

  - name: touch file 2
    file:                               #🧯模组 纵向写法
      path: "{{item}}"
      state: touch
    with_items: [ /opt/aa, /opt/bb, /opt/cc, /opt/dd ] #🔥with_items横向写法

with_items——值为对象(键值对字段) 写法演示

vim /etc/ansible/playbook/test5.yaml

#😊with_items——值为对象(键值对字段)
---
- name: fifth play
  hosts: dbservers
  remote_user: root
  tasks:
  - name: touch file
    with_items: #✨with_items(键值对字段对象)横向写法
    - {filename: /opt/afile, username: xue, groupname: xue}
    - {filename: /opt/bfile, username: zhangsan, groupname: zhangsan}
        #当值为对象(键值对字段)引用值需要像item.filename指定对象中的某个字段
    file: path={{item.filename}}  owner={{item.username}} group={{item.groupname}} state=touch #模块 横向写法

  - name: create dir
    with_items: #✨with_items(键值对字段对象)纵向写法
    - filename: /opt/cfile
      username: xue
      groupname: xue
    - filename: /opt/dfile
      username: zhangsan
      groupname: zhangsan
    file: #模块 纵向写法
      path: "{{item.filename}}"
      owner: "{{item.username}}"
      group: "{{item.groupname}}"
      state: directory

  


执行playbook test4

ansible-playbook test4.yaml


 执行playbook test5

由于playbook中指定了用户与组,需要在被控制的远程主机创建
adduser xue
adduser zhangsan

 查看用户 与 组 信息(playbook中指定的{filename: /opt/afile, username: xue, groupname: xue}一定要与系统中的用户—组对应关系相匹配!不然报错)

 

在ansible服务器运行
ansible-playbook test5.yaml

Templates 模块

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

1)先要准备一个 xxx.j2 模板文件,在文件中使用 {{变量名}} 引用主机变量 或者 vars 自定义的变量 及 facts 字段的值
2)在 playbook 中的 tasks 中定义 template 模板配置  template: src=xxx.j2  dest=xxx

1.先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变量

cp /etc/httpd/conf/httpd.conf /etc/ansible/playbook/httpd.conf.j2
vim /etc/ansible/playbook/httpd.conf.j2

Listen {{http_port}}                 #42行
ServerName {{server_name}}           #95行
DocumentRoot "{{root_dir}}"          #119行

2.修改主机清单文件,定义变量,用于传参给模版

vim /etc/ansible/hosts

[webservers]
192.168.80.102 http_port=192.168.80.102:80 server_name=www.ws1.com:80 root_dir=/var/www/html/webserver1
192.168.80.103 http_port=192.168.80.103:80 server_name=www.ws2.com:80 root_dir=/var/www/html/webserver2

3.编写 playbook,在其中引用第一步定义的template模版。运行时host文件变量会传给playbook yaml配置文件再传参给模版。

根据不同host ip为不同的服务器生成指定的配置文件。

vim /etc/ansible/playbook/test6.yaml

- name: sixth play
  hosts: webservers
  remote_user: root
  vars:
  - pkgname: httpd

  tasks:
  - name: install apache
    yum: name=httpd state=latest

    #创建webserver1 webserver2文件夹(此处直接在每个主机上都创建这两个文件夹,可以指定when不同ip做更细分优化)
  - name: create root dir
    file: state=directory path={{item}}
    with_items:
    - /var/www/html/webserver1
    - /var/www/html/webserver2

    #根据不同ip生成不同页面
  - name: create index.html in www.ws1.com
    copy: content="<h1>this is web1</h1>" dest=/var/www/html/webserver1/index.html
    when: ansible_default_ipv4.address == "192.168.80.102"
  - name: create index.html in www.ws2.com
    copy: content="<h1>this is web2</h1>" dest=/var/www/html/webserver2/index.html
    when: inventory_hostname == "192.168.80.103"

    #引用template模板,生成配置后触发restart 
  - name: prepare configuration file
    template: src=/etc/ansible/playbook/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    notify: "restart apache" 
    #本处可以为reload也可以为restart。虽然触发项最后才执行,会在start后reload。
    #但是实测可能是由于start需要时间,reload第一次运行会报错,第二次运行httpd完全启动后才正常。
    #所以直接使用restart,即使未启动restart也会直接执行start不报错。
         #后续补充:restart 似乎也需要执行两次,应该也与触发项或是启动时间有关

  - name: start apache
    service: name={{pkgname}} state=started enabled=yes

  handlers:
  - name: reload apache
    service: name={{pkgname}} state=reloaded
ansible-playbook test6.yaml

 

tags 模块

可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。
playbook还提供了一个特殊的tags为always。作用就是当使用always作为tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。

vim /etc/ansible/playbook/test7.yaml

- name: seventh play
  hosts: dbservers
  remote_user: root
  tasks:
  - name: create together-do.txt
    file: path=/opt/together-do.txt state=touch
    tags:
    - xiaoming_do_it
    - xiaohong_do_it

  - name: create always-do.txt
    file: path=/opt/always—do.txt state=touch
    tags:
    - always

  - name: create xiaohong-do.txt
    copy: content="0721" dest=/opt/xiaohong—do.txt
    tags:
    - xiaohong_do_it
ansible-playbook test7.yaml --tags="xiaoming_do_it"
#执行 tag:xiaoming与always

 

ansible-playbook test7.yaml --tags="xiaohong_do_it"
#执行 tag:xiaohong与always

Roles 模块

roles用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令引入即可。
简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷的include它们的一种机制。roles一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。主要使用场景代码复用度较高的情况下。

roles 角色 的作用?

把playbook剧本里的各个play看作为角色,将各个角色的tasks任务、vars变量、templates模板、files文件等内容放置到角色的目录中统一管理,需要的时候可在playbook中直接使用roles调用,所以roles可以实现playbook代码的复用。

roles 的目录结构

cd /etc/ansible/
tree roles/

roles/
├── httpd/                 #相当于 playbook 中的 每一个 play 主题,目录名即为角色名
│   ├── files/                  #存放copy 模块或 script 模块调用的文件
│   ├── templates/              #存放template 模块调用的jinjia2 模板文件
│   ├── tasks/main.yml          #定义此角色的任务列表
│   ├── handlers/main.yml       #定义此角色通过notity触发条件时执行的任务列表
│   ├── vars/main.yml           #定义此角色用到的自定义变量
│   ├── defaults/main.yml       #定义此角色用到的设定默认变量(一般不用)
│   └── meta/main.yml           #定义此角色的元数据信息
└── mysql/
    ├── files/
    ├── templates/
    ├── tasks/
    ├── handlers/
    ├── vars/
    ├── defaults/
    └── meta/

●files
用来存放由 copy 模块或 script 模块调用的文件。

●templates
用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件。

●tasks
此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件。

●handlers
此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作。

●vars
此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量。

●defaults
此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。 这些变量具有所有可用变量中最低的优先级,并且可以很容易地被任何其他变量覆盖。所以生产中我们一般不在这里定义变量

●meta
此目录应当包含一个 main.yml 文件,用于定义此角色的元数据信息及其依赖关系。

在一个 playbook 中使用 roles的步骤

(1)创建以 roles 命名的目录

mkdir /etc/ansible/roles/ -p
#yum装完默认就有

(2)创建全局变量目录(可选)

mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all
#文件名自己定义,引用的时候注意

(3)在 roles 目录中分别创建以各角色名称命名的目录,如 httpd、mysql

mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql

(4)在每个角色命名的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,也可以不创建

mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}

(5)在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 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

(6)修改 site.yml 文件,针对不同主机去调用不同的角色

vim /etc/ansible/site.yml
---
- hosts: webservers
  remote_user: root
  roles:
     - httpd
- hosts: dbservers
  remote_user: root
  roles:
     - mysql

(7)运行 ansible-playbook

cd /etc/ansible
ansible-playbook site.yml

示例:安装分布式LNMP架构web服务器

创建工作目录
mkdir /etc/ansible/roles/nginx/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p

touch /etc/ansible/roles/nginx/{defaults,vars,tasks,meta,handlers}/main.yaml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yaml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yaml
编辑主机列表
vim /etc/ansible/hosts

[webservers]
192.168.80.101

[mysqlservers]
192.168.80.102

[phpservers]
192.168.80.103
创建playbook,包含roles
vim /etc/ansible/playbook/lnmp.yaml

- name: nginx play
  hosts: webservers
  remote_user: root
  roles:
    - nginx

- name: php play
  hosts: phpservers
  remote_user: root
  roles:
    - php

- name: mysql play
  hosts: mysqlservers
  remote_user: root
  roles:
    - mysql

 

role:nginx

vars (变量)

vim /etc/ansible/roles/nginx/vars/main.yaml

http_port: 192.168.80.101:80
http_hostname: www.xue.com
root_dir: /usr/share/nginx/html
php_remote: 192.168.80.103:9000
pkg: nginx
service: nginx

tasks (任务)

vim /etc/ansible/roles/nginx/tasks/init.yaml

- name: disable firewalld
  service: name=firewalld  state=stopped  enabled=no

- name: disable selinux
  shell: "/usr/sbin/setenforce 0"
  ignore_errors: true
vim /etc/ansible/roles/nginx/tasks/main.yaml

- include: "init.yaml"

- name: copy nginx yum repo file
  copy: src=nginx.repo  dest=/etc/yum.repos.d/

- name: install nginx
  yum: name={{pkg}}  state=latest

- name: copy index.php
  unarchive: src=/etc/ansible/roles/nginx/files/wordpress-4.9.4-zh_CN.tar.gz dest={{root_dir}} copy=yes

- name: copy nginx template configuration file
  template: src=default.conf.j2  dest=/etc/nginx/conf.d/default.conf
  notify: reload nginx

- name: start nginx
  service: name={{service}} state=started enabled=yes

handles (task中触发器)

vim /etc/ansible/roles/nginx/handlers/main.yaml

- name: reload nginx
  service: name={{service}}  state=reloaded

files (文件)

vim /etc/ansible/roles/nginx/files/nginx.repo

nginx.repo 用于yum下载nginx。
也可以不使用这个方法用不着准备这个文件,直接yum install epel 更新epel源

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
准备 WordPress论坛安装包 
(不一定要藏这么深的文件夹,只要脚本中对应上路径即可。为了显示file文件夹的作用,就放在这里)

/etc/ansible/roles/nginx/files/wordpress-4.9.4-zh_CN.tar.gz

templates(模版 用于给nginx服务器生成配置)

vim /etc/ansible/roles/nginx/templates/default.conf.j2

server {
    listen       {{http_port}};
    server_name  {{http_hostname}};

    #access_log  /var/log/nginx/host.access.log  main;

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

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root           {{root_dir}};
        fastcgi_pass   {{php_remote}};
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  {{root_dir}}$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
role:mysql

 vars (变量)

vim /etc/ansible/roles/mysql/vars/main.yaml

http_port: 192.168.80.101:80
http_hostname: www.xue.com
root_dir: /usr/share/nginx/html
php_remote: 192.168.80.103:9000
pkg: nginx
service: nginx

tasks (任务)

vim /etc/ansible/roles/mysql/tasks/init.yaml

- name: disable firewalld
  service: name=firewalld  state=stopped  enabled=no

- name: disable selinux
  shell: "/usr/sbin/setenforce 0"
  ignore_errors: true
vim /etc/ansible/roles/mysql/tasks/main.yaml

- name: yum uninstall mariadb*
  yum: name=mariadb* state=absent

- name: wget mysql
  shell: wget -i -c http://repo.mysql.com/mysql57-community-release-el7-11.noarch.rpm -P /etc/yum.repos.d

- name: rpm mysql57-community-release
  shell: rpm -ivh /etc/yum.repos.d/mysql57-community-release-el7-11.noarch.rpm
  ignore_errors: True

- name: turn off yum gpgcheck
  replace: path=/etc/yum.repos.d/mysql-community.repo regexp='gpgcheck=1' replace='gpgcheck=0'

- name: yum install mysql
  yum: name=mysql-server

- name: start and enable mysql
  service: enabled=true name=mysqld.service state=started

- name: get passwd from log
  shell: grep "password" /var/log/mysqld.log | awk 'NR==1{print $NF}'
  register: mysql_password   #将获取的密码导入到mysql_password的变量中
- name: echo passwd
  debug:    
   msg: "{{ mysql_password }}"           #输出变量mysql_password的值
#grep "password" /var/log/mysqld.log     #在日志文件中找出root用户的初始密码
#2021-07-31T07:55:00.366359Z 1 [Note] A temporary password is generated for root@localhost: ga7%<d<0*jD&
#grep "password" /var/log/mysqld.log | awk '{print $NF}'

#临时密码修改
- name: grant location
  shell:  mysql --connect-expired-password -uroot -p"{{ mysql_password['stdout'] }}" -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'Admin@123';"
  ignore_errors: True
#授予root用户所有权限 
- name: grant option
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e "grant all privileges on *.* to 'root'@'%' identified by 'Admin@123456' with grant option;"
  ignore_errors: True
#创建wordpress数据库
- name: create database
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e "create database wordpress;"
  ignore_errors: True
#赋予mywordpress用户访问wordpress的权限(本地权限与远程权限)
- name: grant
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e "grant all on wordpress.* to 'admin'@'%' identified by 'mywordpress@123456';"
  ignore_errors: True
- name: grant
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e "grant all on wordpress.* to 'admin'@'localhost' identified by 'mywordpress@123456';"
  ignore_errors: True
#刷新权限
- name: flush privileges
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e 'flush privileges;'
  ignore_errors: True

- name: yum uninstall mariadb*
  yum: name=mysql57-community-release-el7-11.noarch.rpm state=absent
  #为了防止每次yum操作都会自动更新,卸载这个软件

role:php

vars (变量)

vim /etc/ansible/roles/php/vars/main.yaml

timezone: Asia/Shanghai
user_name: php
http_port: 192.168.80.103:9000
nginx_addr: 192.168.80.101
root_dir: /usr/share/nginx/html
service: php-fpm

tasks (任务)

vim /etc/ansible/roles/php/tasks/init.yaml

- name: disable firewalld
  service: name=firewalld  state=stopped  enabled=no

- name: disable selinux
  shell: "/usr/sbin/setenforce 0"
  ignore_errors: true
vim /etc/ansible/roles/php/tasks/main.yaml

- include: "init.yaml"

- name: install yum repo
  shell: "rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm && rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm"
  ignore_errors: True

- name: install php
  with_items:
  - php72w
  - php72w-cli
  - php72w-common
  - php72w-devel
  - php72w-embedded
  - php72w-gd
  - php72w-mbstring
  - php72w-pdo
  - php72w-xml
  - php72w-fpm
  - php72w-mysqlnd
  - php72w-opcache
  yum: name={{item}}

- name: create php user
  user: name={{user_name}}

- name: crate web root dir
  file: name={{root_dir}} state=directory

- name: copy index.php
  unarchive: src=/etc/ansible/roles/nginx/files/wordpress-4.9.4-zh_CN.tar.gz dest={{root_dir}} copy=yes

- name: modify php configuration file
  replace: path=/etc/php.ini  regexp=";date.timezone ="  replace="date.timezone = Asia/Shanghai"
  notify: reload php

- name: modify username and groupname in www.conf
  replace: path=/etc/php-fpm.d/www.conf  regexp="apache"  replace="{{user_name}}"
  notify: reload php

- name: modify listen addr in www.conf
  replace: path=/etc/php-fpm.d/www.conf  regexp="127.0.0.1:9000"  replace="{{http_port}}"
  notify: reload php

- name: modify allowed client in www.conf
  replace: path=/etc/php-fpm.d/www.conf  regexp="127.0.0.1"  replace="{{nginx_addr}}"
  notify: reload php

- name: start php
  service: name={{service}} state=started enabled=yes

handles (task中触发器)

vim /etc/ansible/roles/php/handlers/main.yaml

- name: reload php
  service: name={{service}} state=reloaded

配置密钥对验证 免交互登录

ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

yum install -y sshpass
sshpass -p '密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.80.102
sshpass -p '密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.80.102
sshpass -p '密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.80.103

执行 

ansible-playbook /etc/ansible/playbook/lnmp.yaml

 访问http://192.168.80.101/wordpress/index.php

故障处理

出现这种情况,由于是分布式部署lnmp,与单机不同,分布式部署必须在php服务器和nginx服务器上都存在相同的html目录以及其中的内容。

本次只在NGINX的html存放了WordPress论坛文件,而没有创建php服务器的文件夹,导致出错


 

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

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

相关文章

iOS——Block one

块类似于匿名函数或闭包&#xff0c;在许多其他编程语言中也存在类似的概念。 可以访问上下文&#xff0c;运行效率高 Block 以下是块的一些基本知识&#xff1a; 块的定义&#xff1a;块是由一对花括号 {} 包围的代码片段&#xff0c;可以包含一段可执行的代码。块的定义使…

Stable Diffusion - Stable Diffusion WebUI 支持 SDXL 1.0 模型的环境配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132056980 SDXL 1.0 版本 是 Stable Diffusion 的最新版本&#xff0c;是基于潜在扩散模型的文本到图像生成技术&#xff0c;能够根据输入的任何文…

机器学习知识经验分享之六:决策树

python语言用于深度学习较为广泛&#xff0c;R语言用于机器学习领域中的数据预测和数据处理算法较多&#xff0c;后续将更多分享机器学习数据预测相关知识的分享&#xff0c;有需要的朋友可持续关注&#xff0c;有疑问可以关注后私信留言。 目录 一、R语言介绍 二、R语言安装…

ansible的脚本——playbook剧本

目录 一、playbook的组成 二、 playbook安装httpd服务 1.编写playbook剧本 2.运行playbook 三、定义、引用变量 四、 指定远程主机sudo切换用户 五、when条件判断 六、迭代 七、Templates 模块 1.先准备一个以 .j2 为后缀的 template 模板文件&#xff0c;设置引用的变…

数据库:MYSQL参数max_allowed_packet 介绍

1、参数作用 max_allowed_packet参数是指mysql服务器端和客户端在一次传送数据包的过程当中最大允许的数据包大小。如果超过了设置的最大长度,则会数据库保持数据失败。 2、问题场景 ● 有时候业务的需要,可能会存在某些字段数据长度非常大(比如富文本编辑器里面的内容),…

docker 哨兵模式和集群模式安装Redis7.0.12

docker 哨兵模式和集群模式安装Redis7.0.12 1.下载镜像 1.1 配置阿里云加速源 墙外能访问https://hub.docker.com/_/redis 的可跳过 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 登录后选择左侧的镜像工具>镜像加速器&#xff0c;获取加速器地址&#…

Vue3和typeScript路由传参

1 params传的参数&#xff0c;页面刷新就消失,而query传的参数&#xff0c;页面刷新还会存在&#xff0c;所以通常用query。 query传参 跳转页面&#xff1a;拿到router对象,调用push方法做跳转. import { useRoute,useRouter} from "vue-router"; export default…

GPIO简介

一、GPIO GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出&#xff0c;GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连&#xff0c;从而实现与外部硬件设备的通讯、控制及信号采集等功能 LED实验步骤 实验步骤 以L…

图文演示:如何三分钟极速搭建一个元宇宙3D虚拟展厅

引言&#xff1a; 元宇宙3D虚拟展厅时代已经来临。元宇宙是一个虚拟的、立体的数字空间&#xff0c;可以让用户沉浸在其中进行交互操作&#xff0c;并体验无限可能。如何快速搭建一个属于自己的虚拟展厅则受到越来越多人的关注。 一&#xff0e;虚拟展厅类型 1.党建展馆 实现…

小研究 - 微服务系统服务依赖发现技术综述(一)

微服务架构得到了广泛的部署与应用, 提升了软件系统开发的效率, 降低了系统更新与维护的成本, 提高了系统的可扩展性. 但微服务变更频繁、异构融合等特点使得微服务故障频发、其故障传播快且影响大, 同时微服务间复杂的调用依赖关系或逻辑依赖关系又使得其故障难以被及时、准确…

mysql月统计数据,没有的填充为0

要按时间戳字段按月份分组查询记录表&#xff0c;可以使用DATE_FORMAT函数将时间戳字段格式化为年月格式&#xff0c;然后将结果按照该字段进行分组。 SELECT a.month month,ifnull(b.count, 0) count FROM (SELECT 1 month UNION ALL SELECT 2 month UNION ALL SELECT 3 mont…

Vue实现leafletMap自定义绘制线段 并且删除指定的已绘制的点位

效果&#xff1a;点击表格可实现选中地图点位&#xff0c;删除按钮点击可删除对应点位并且重新绘制线段&#xff0c;点击确定按钮 保存已经绘制的点位信息传给父组件 并且该组件已实现回显 完整的组件代码如下 文件名称为&#xff1a; leafletMakePointYt <!--* Descripti…

小红书APP出现闪退问题,电商erp系统接口测试怎么做?(一)

7月27日凌晨&#xff0c;部分网友反馈小红书APP出现闪退问题。对此&#xff0c;小红书客服微博发文称&#xff0c;如遇到小红书APP无法启动的情况&#xff0c;用户可前往AppStore下载最新版本。 大家在讨论崩溃原因时&#xff0c;提到大概是接口出现了问题&#xff0c;对于软件…

05-向量的意义_n维欧式空间

线性代数 什么是向量&#xff1f;究竟为什么引入向量&#xff1f; 为什么线性代数这么重要&#xff1f;从研究一个数拓展到研究一组数 一组数的基本表示方法——向量&#xff08;Vector&#xff09; 向量是线性代数研究的基本元素 e.g. 一个数&#xff1a; 666&#xff0c;…

企业大数据可视化案例专题分享-入门

一、什么是数据可视化&#xff1f; 基本概念&#xff1a;数据可视化是以图示或图形格式表示的数据。让决策者可以看到以直观方式呈现的分析&#xff0c;以便他们可以掌握困难的概念或识别新的模式。借助交互式可视化&#xff0c;可以使用技术深入挖掘图表和图形以获取更多详细…

Pytorch基础

文章目录 一、Pytorch简介二、安装2.1 安装GPU环境2.2 安装Pytorch2.3 测试 三、Tensor3.1 Tensor创建3.1.1 torch.tensor() && torch.tensor([])3.1.2 torch.randn && torch.randperm3.1.3 torch.range(begin,end,step)3.1.4 指定numpy 3.2 Tensor运算3.2.1 A…

开源Blazor UI组件库精选:让你的Blazor项目焕然一新!

今天给大家推荐一些开源、美观的Blazor UI组件库&#xff0c;这些优秀的开源框架和项目不仅能够帮助开发者们提高开发效率&#xff0c;还能够为他们的项目带来更加丰富的用户体验。 注&#xff1a;排名不分先后&#xff0c;都是十分优秀的开源框架和项目 ​Ant Design Blazor…

深度学习(34)—— StarGAN(1)

深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;1&#xff09; 文章目录 深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;1&#xff09;1. 背景2. 基本思路3. 整体流程4. StarGAN v2(1) 网络结构(2) mapping network(3) style encoder(4)Loss 和之前…

【机器学习】西瓜书习题3.5Python编程实现线性判别分析,并给出西瓜数据集 3.0α上的结果

参考代码 结合自己的理解&#xff0c;添加注释。 代码 导入相关的库 import numpy as np import pandas as pd import matplotlib from matplotlib import pyplot as plt导入数据&#xff0c;进行数据处理和特征工程 得到数据集 D { ( x i , y i ) } i 1 m , y i ∈ { 0 ,…

安装企业级高负载web服务器tomcat,并部署应用

web服务器Tocamt 1.Tocmat简介2.Tocmat安装1.安装jdk2.部署Tomcat1.配置环境变量2.启动tocmat3.Tomcat web管理功能 3.部署jpress应用 1.Tocmat简介 Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个核心项目&#xff0c;由…