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: value1key2: value2
- key1: value3key2: 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 selinuxcommand: '/sbin/setenforce 0'    #command模块和shell模块无需使用key=value格式ignore_errors: True     #如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务。#这里需要忽略是因为如果selinux已经关闭再次关闭会返回1- name: disable selinux foreverreplace: path=/etc/selinux/config  regexp="enforcing"  replace="disabled"- name: disable firewalldservice: name=firewalld state=stopped enabled=no    #使用 module: options 格式来定义任务,option使用key=value格式
#======================================================================================================================
# 若想要挂载光盘使用本地yum源安装(需要在控制服务器存在/etc/yum.repos.d/repo.bak/local.repo配置文件)可以省略- name: mount cdrommount: src=/dev/sr0 path=/mnt fstype=iso9660 state=mounted- name: copy local yum configuration filecopy: src=/etc/yum.repos.d/repo.bak/local.repo  dest=/etc/yum.repos.d/local.repo
#======================================================================================================================- name: install httpdyum: name=httpd state=latest- name: prepare httpd configuration filecopy: src=/etc/ansible/playbook/httpd.conf dest=/etc/httpd/conf/httpd.conf #这里需要一个事先准备好的/opt/httpd.conf文件notify: "restart httpd" ##如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作- name: start apache httpdservice: name=httpd state=started enabled=yeshandlers:     #handlers中定义由notify触发的任务- name: restart httpd    #notify和handlers中任务的名称必须一致。注意reload不能让httpd重新加载配置文件中端口等配置,只能restartservice: 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 playhosts: dbserversremote_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.txtgather_facts: true #可以不写 默认开启tasks:- name: create groupgroup: name={{groupname}} system=yes gid=2800    #使用 {{key}} 引用变量的值 system为默认项可以省略不写不影>响- name: create useruser: 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 filefile: 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: dbserversremote_user: zhangsan            become: yes                    #2.6版本以后的参数,之前是sudo,意思为切换用户运行become_user: root              #指定sudo用户为root

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

adduser zhangsan
passwd zhangsanvim /etc/sudoerszhangsan 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 playhosts: allremote_user: roottasks:- name: touch filefile: 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 playhosts: dbserversremote_user: root
##############################################################################vars:myfile:- /opt/a- /opt/b- /opt/c- /opt/dtasks:- name: touch directory #✨方法1 预先编写var变量,随后赋值给with_itemswith_items: "{{myfile}}"file: path={{item}} state=directory #🧯模组 横向写法
##############################################################################- name: touch file 1    #✨方法2 直接在with_items中定义file:                               #🧯模组 纵向写法path: "{{item}}"state: touchwith_items:                                        #🔥with_items纵向写法- /root/a- /root/b- /root/c- /root/d- name: touch file 2file:                               #🧯模组 纵向写法path: "{{item}}"state: touchwith_items: [ /opt/aa, /opt/bb, /opt/cc, /opt/dd ] #🔥with_items横向写法

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

vim /etc/ansible/playbook/test5.yaml#😊with_items——值为对象(键值对字段)
---
- name: fifth playhosts: dbserversremote_user: roottasks:- name: touch filewith_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 dirwith_items: #✨with_items(键值对字段对象)纵向写法- filename: /opt/cfileusername: xuegroupname: xue- filename: /opt/dfileusername: zhangsangroupname: zhangsanfile: #模块 纵向写法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.j2Listen {{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 playhosts: webserversremote_user: rootvars:- pkgname: httpdtasks:- name: install apacheyum: name=httpd state=latest#创建webserver1 webserver2文件夹(此处直接在每个主机上都创建这两个文件夹,可以指定when不同ip做更细分优化)- name: create root dirfile: state=directory path={{item}}with_items:- /var/www/html/webserver1- /var/www/html/webserver2#根据不同ip生成不同页面- name: create index.html in www.ws1.comcopy: content="<h1>this is web1</h1>" dest=/var/www/html/webserver1/index.htmlwhen: ansible_default_ipv4.address == "192.168.80.102"- name: create index.html in www.ws2.comcopy: content="<h1>this is web2</h1>" dest=/var/www/html/webserver2/index.htmlwhen: inventory_hostname == "192.168.80.103"#引用template模板,生成配置后触发restart - name: prepare configuration filetemplate: src=/etc/ansible/playbook/httpd.conf.j2 dest=/etc/httpd/conf/httpd.confnotify: "restart apache" #本处可以为reload也可以为restart。虽然触发项最后才执行,会在start后reload。#但是实测可能是由于start需要时间,reload第一次运行会报错,第二次运行httpd完全启动后才正常。#所以直接使用restart,即使未启动restart也会直接执行start不报错。#后续补充:restart 似乎也需要执行两次,应该也与触发项或是启动时间有关- name: start apacheservice: name={{pkgname}} state=started enabled=yeshandlers:- name: reload apacheservice: 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 playhosts: dbserversremote_user: roottasks:- name: create together-do.txtfile: path=/opt/together-do.txt state=touchtags:- xiaoming_do_it- xiaohong_do_it- name: create always-do.txtfile: path=/opt/always—do.txt state=touchtags:- always- name: create xiaohong-do.txtcopy: content="0721" dest=/opt/xiaohong—do.txttags:- 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: webserversremote_user: rootroles:- httpd
- hosts: dbserversremote_user: rootroles:- 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} -ptouch /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 playhosts: webserversremote_user: rootroles:- nginx- name: php playhosts: phpserversremote_user: rootroles:- php- name: mysql playhosts: mysqlserversremote_user: rootroles:- mysql

 

role:nginx

vars (变量)

vim /etc/ansible/roles/nginx/vars/main.yamlhttp_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 firewalldservice: name=firewalld  state=stopped  enabled=no- name: disable selinuxshell: "/usr/sbin/setenforce 0"ignore_errors: true
vim /etc/ansible/roles/nginx/tasks/main.yaml- include: "init.yaml"- name: copy nginx yum repo filecopy: src=nginx.repo  dest=/etc/yum.repos.d/- name: install nginxyum: name={{pkg}}  state=latest- name: copy index.phpunarchive: src=/etc/ansible/roles/nginx/files/wordpress-4.9.4-zh_CN.tar.gz dest={{root_dir}} copy=yes- name: copy nginx template configuration filetemplate: src=default.conf.j2  dest=/etc/nginx/conf.d/default.confnotify: reload nginx- name: start nginxservice: name={{service}} state=started enabled=yes

handles (task中触发器)

vim /etc/ansible/roles/nginx/handlers/main.yaml- name: reload nginxservice: name={{service}}  state=reloaded

files (文件)

vim /etc/ansible/roles/nginx/files/nginx.reponginx.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.j2server {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.yamlhttp_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 firewalldservice: name=firewalld  state=stopped  enabled=no- name: disable selinuxshell: "/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 mysqlshell: wget -i -c http://repo.mysql.com/mysql57-community-release-el7-11.noarch.rpm -P /etc/yum.repos.d- name: rpm mysql57-community-releaseshell: rpm -ivh /etc/yum.repos.d/mysql57-community-release-el7-11.noarch.rpmignore_errors: True- name: turn off yum gpgcheckreplace: path=/etc/yum.repos.d/mysql-community.repo regexp='gpgcheck=1' replace='gpgcheck=0'- name: yum install mysqlyum: name=mysql-server- name: start and enable mysqlservice: enabled=true name=mysqld.service state=started- name: get passwd from logshell: grep "password" /var/log/mysqld.log | awk 'NR==1{print $NF}'register: mysql_password   #将获取的密码导入到mysql_password的变量中
- name: echo passwddebug:    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 locationshell:  mysql --connect-expired-password -uroot -p"{{ mysql_password['stdout'] }}" -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'Admin@123';"ignore_errors: True
#授予root用户所有权限 
- name: grant optionshell: 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 databaseshell: mysql --connect-expired-password -uroot -pAdmin@123 -e "create database wordpress;"ignore_errors: True
#赋予mywordpress用户访问wordpress的权限(本地权限与远程权限)
- name: grantshell: mysql --connect-expired-password -uroot -pAdmin@123 -e "grant all on wordpress.* to 'admin'@'%' identified by 'mywordpress@123456';"ignore_errors: True
- name: grantshell: mysql --connect-expired-password -uroot -pAdmin@123 -e "grant all on wordpress.* to 'admin'@'localhost' identified by 'mywordpress@123456';"ignore_errors: True
#刷新权限
- name: flush privilegesshell: 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.yamltimezone: 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 firewalldservice: name=firewalld  state=stopped  enabled=no- name: disable selinuxshell: "/usr/sbin/setenforce 0"ignore_errors: true
vim /etc/ansible/roles/php/tasks/main.yaml- include: "init.yaml"- name: install yum reposhell: "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 phpwith_items:- php72w- php72w-cli- php72w-common- php72w-devel- php72w-embedded- php72w-gd- php72w-mbstring- php72w-pdo- php72w-xml- php72w-fpm- php72w-mysqlnd- php72w-opcacheyum: name={{item}}- name: create php useruser: name={{user_name}}- name: crate web root dirfile: name={{root_dir}} state=directory- name: copy index.phpunarchive: src=/etc/ansible/roles/nginx/files/wordpress-4.9.4-zh_CN.tar.gz dest={{root_dir}} copy=yes- name: modify php configuration filereplace: path=/etc/php.ini  regexp=";date.timezone ="  replace="date.timezone = Asia/Shanghai"notify: reload php- name: modify username and groupname in www.confreplace: path=/etc/php-fpm.d/www.conf  regexp="apache"  replace="{{user_name}}"notify: reload php- name: modify listen addr in www.confreplace: 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.confreplace: path=/etc/php-fpm.d/www.conf  regexp="127.0.0.1"  replace="{{nginx_addr}}"notify: reload php- name: start phpservice: name={{service}} state=started enabled=yes

handles (task中触发器)

vim /etc/ansible/roles/php/handlers/main.yaml- name: reload phpservice: name={{service}} state=reloaded

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

ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsayum 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服务器的文件夹,导致出错


 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JVM】(一)深入理解JVM运行时数据区

文章目录 一、JVM 运行流程二、虚拟机栈&#xff08;线程私有&#xff09;三、本地方法栈 &#xff08;线程私有&#xff09;四、方法区&#xff08;元数据区&#xff09;五、堆&#xff08;线程共享&#xff09;六、程序计数器&#xff08;线程私有&#xff09; 一、JVM 运行流…

华为华三思科 交换机基础配置一览

console密码修改 华为 user-interface console 0 authentication-mode password set authentication password cipher XXXXXXXXX华三 line aux 0 authentication-mode password set auth pass simple XXX思科 en configure terminal line console 0 password 123 login忘记…

TypeScript基础学习

目录 一、安装 1、下载国内镜像 2、安装 3、查看安装情况 4、使用例子 二、变量声明 1、规则 2、声明的四种方式 3、注意 4、类型断言 5、类型推断 6、变量作用域 三、基础类型&#xff08;共11种&#xff09; 1、Any 类型 2、Null 和 Undefined 3、never 类型…

【备战csp-j】 csp常考题型详解(2)

二.计算机网络。 1. TCP/IP 协议共有( )层协议 。 A.3 B.4 C.5 D.6 答案&#xff1a;B 解析&#xff1a; 2.Ipv4 地址是由( ) 位二进制数码表示的。 A.16 B.32 C.24 D.8 答案&#xff1a;B 解析&#xff1a;IP地址是IP协议提供的一种统一的地址格式。在目前使用的IPv…

Linux - 进程控制(进程替换)

0.引入 创建子进程的目的是什么&#xff1f; 就是为了让子进程帮我执行特定的任务 让子进程执行父进程的一部分代码 如果子进程想执行一个全新的程序代码呢&#xff1f; 那么就要使用 进程的程序替换 为什么要有程序替换&#xff1f; 也就是说子进程想执行一个全新的程序代码&a…

HCIP OSPF+BGP综合实验

题目 1、该拓扑为公司网络&#xff0c;其中包括公司总部、公司分部以及公司骨干网&#xff0c;不包含运营商公网部分。 2、设备名称均使用拓扑上名称改名&#xff0c;并且区分大小写。 3、整张拓扑均使用私网地址进行配置。 4、整张网络中&#xff0c;运行OSPF协议或者BGP协议…

python森林生物量(蓄积量)数据处理到随机森林估算全流程

python森林生物量&#xff08;蓄积量&#xff09;估算全流程 一.哨兵2号获取/处理/提取数据1.1 影像处理与下载采用云概率影像去云采用6S模型对1C级产品进行大气校正geemap下载数据到本地NDVI 1.2 各种参数计算&#xff08;生物物理变量、植被指数等&#xff09;LAI&#xff1a…

抖音引流推广的几个方法,抖音全自动引流脚本软件详细使用教学

大家好我是你们的小编一辞脚本&#xff0c;今天给大家分享新的知识&#xff0c;很开心可以在CSDN平台分享知识给大家,很多伙伴看不到代码我先录制一下视频 在给大家做代码&#xff0c;给大家分享一下抖音引流脚本的知识和视频演示 不懂的小伙伴可以认真看一下&#xff0c;我们…

【C++】总结9

文章目录 C从源代码到可执行程序经过什么步骤静态链接和动态链接类的对象存储空间C的内存分区内存池在成员函数中调用delete this会出现什么问题&#xff1f;如果在类的析构函数中调用delete this&#xff0c;会发生什么&#xff1f; C从源代码到可执行程序经过什么步骤 预处理…

java学习路程之篇六、进阶知识、常用API、Arrays工具类、冒泡排序、选择排序、二分查找、正则表达式

文章目录 1、Arrays工具类2、冒泡排序3、选择排序4、二分查找5、正则表达式 1、Arrays工具类 2、冒泡排序 3、选择排序 4、二分查找 5、正则表达式

【Maven】Nexus3上传maven依赖jar

后端依赖 上次说到前端的批量tgz文件上传私服&#xff0c;其实服务端也有类似情况&#xff0c;我们有个私服也需要进行上传到私服&#xff0c;这里做个记录。因为上次有个小细节没注意白白传错了一遍&#xff0c;这里重新记录总结一下。 # 查看一下结构 $ tree -L 2 . |-- re…

【vue】 Tinymce 富文本编辑器 不想让上传的图片转换成base64,而是链接

前言&#xff1a;最近项目上需要使用富文本编辑器&#xff0c;觉得tinymce很不错就用了&#xff0c;具体怎么在项目中使用参考 【vue】 vue2 中使用 Tinymce 富文本编辑器 【vue】 Tinymce 数据 回显问题 | 第一次正常回显后面&#xff0c;显示空白bug不能编辑 这两天又遇到了…

Windows下RocketMQ的启动

下载地址&#xff1a;下载 | RocketMQ 解压后 一、修改runbroker.cmd 修改 bin目录下的runbroker.cmd set "JAVA_OPT%JAVA_OPT% -server -Xms2g -Xmx2g" set "JAVA_OPT%JAVA_OPT% -XX:MaxDirectMemorySize15g" set "JAVA_OPT%JAVA_OPT% -cp %CLASSP…

八大排序算法--希尔排序(动图理解)

目录 希尔排序 概念 算法思路 动画演示 代码如下 复杂度分析 时间复杂度测试 运行结果 完整代码 创作不易&#xff0c;如果本篇博客对您有一定的帮助&#xff0c;大家记得留言点赞哦。 希尔排序 概念 希尔排序是插入排序的一种&#xff0c;是对直接插入排序的优化。其…

ChinaJoy 2023微星雷鸟17游戏本震撼发布:搭载AMD锐龙9 7945HX首发8499元

ChinaJoy 2023展会中微星笔记本再次给大家带来惊喜&#xff0c;发布了搭载AMD移动端16大核的旗舰游戏本&#xff1a;雷鸟17&#xff0c;更重要的这样一款旗舰性能的游戏本&#xff0c;首发价8499元堪称当今游戏本市场中的“性价比爆款”&#xff01; 本着和玩家一同制霸游戏战场…

k8s概念-StatefulSet

StatefulSet 是用来管理有状态应用的控制器 StatefulSet 用来管理某Pod集合的部署和扩缩&#xff0c; 并为这些 Pod 提供持久存储和持久标识符StatefulSet | KubernetesStatefulSet 运行一组 Pod&#xff0c;并为每个 Pod 保留一个稳定的标识。 这可用于管理需要持久化存储或稳…

【设计模式——学习笔记】23种设计模式——代理模式Proxy(原理讲解+应用场景介绍+案例介绍+Java代码实现)

介绍 基础介绍 代理模式为一个对象提供一个代理对象&#xff0c;以控制对这个对象的访问。即通过代理对象访问目标对象&#xff0c;这样做的好处是&#xff1a;可以在不修改目标对象代码的基础上&#xff0c;增强额外的功能操作&#xff0c;即扩展目标对象的功能被代理的对象…

牛客网Verilog刷题——VL52

牛客网Verilog刷题——VL52 题目答案 题目 请编写一个十进制计数器模块&#xff0c;当mode信号为1&#xff0c;计数器输出信号递增&#xff0c;当mode信号为0&#xff0c;计数器输出信号递减。每次到达0&#xff0c;给出指示信号zero。模块的接口信号图如下&#xff1a; 模块的…

Flask学习笔记_异步论坛(四)

Flask学习笔记_异步论坛&#xff08;四&#xff09; 1.配置和数据库链接1.exts.py里面实例化sqlalchemy数据库2.config.py配置app和数据库信息3.app.py导入exts和config并初始化到app上 2.创建用户模型并映射到数据库1.models/auth.py创建用户模型2.app.py导入模型并用flask-mi…

教师工作量管理系统Springmvc+Spring+Mybatis课程工作量教室java源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 教师工作量管理系统SpringmvcSpringMybatis 系统有1权…