1.playbook练习
安装Apache并修改监听端口为8080
修改ServerName配置,执行apachectl -t命令不报错
设置默认主页hello world
启动服务并设开机自启
***********
json数据格式:
{} 集合,里面存放多组键值对
[ ] 数组,存放多个值,可以是集合
两者可以互相嵌套
{ "all":[
{ "a1": "A1","a2": "A2" },
{ "b1": "B1","b2": "B2" },
{ "c1": "C1","c2": "C2" }
]
}
************
YAML数据格式:
--- ,表示一个文件的开始
数组:-空格
键值对::空格
#表示注释
不要用tab键,分隔必须是英文符号
"all":
-
"a1": "A1"
"a2": "A2"
-
"b1": "B1"
"b2": "B2"
-
"c1": "C1"
"c2": "C2"
************
Jinja2语法规则
{ { 表达式 }}
{% 控制语句 %}
{# 注释 #}
调用变量 { {var}}
计算 { {2+3}}
判断 { { 1 in [1,2,3]}}
{% if "name" == "aa" %}
"aa"
{% elif "name" == "bb" %}
"bb"
{% for "BB" in [AA,BB,CC] %}
{ { do method }}
{% endfor %}
{% else %}
"cc"
{% endif %}
对abc哈希加密
{ { "abc" | hash('md5') }}
把一个列表用逗号连接起来
{ { list | join(',') }}
************
playbook构成
Target 远程主机组
Variable 定义playbook运行时需要使用的变量
Tasks 定义将要在远程主机上执行的任务列表(命令的集合)
Handler 定义Task执行任务完成以后需要调用的任务
红色表示失败,绿色表示成功
主机与主机之间运行命令是并发的
命令是按顺序执行的
---
- hosts: all
remote_user: root
tasks:(此处有空格)
- ping:(此处有空格)
ansible ~]# ansible-playbook ping.yml -f 5
-空格ping:空格参数
-f 并发进程数量,默认是5
hosts 一个或多个组或主机的patterns,以逗号为分隔符
remote_user 账户名
每个task命令批量执行于hosts里所有主机,所有task依次执行
************
1.1 playbook的ping脚本检测
ansible]# vim ping.yml
---
- hosts: all
remote_user: root
tasks:
- ping:
ansible]# ansible-playbook ping.yml //输出结果
注意:如果检测的时候出错,会在当前的目录生成一个新的文件(以.retry结尾),可以去这个文件里面看是哪个主机的错
1.2 用playbook安装Apache,修改端口,配置ServerName,修改主页,设置开机自启
[root@ansible ansible]# vim http.yml
---
- hosts: cache
remote_user: root
tasks:
- name: install one specific version of Apache
yum:
name: httpd //安装Apache
state: installed
- lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^Listen '
line: 'Listen 8080' //修改端口为8080
- replace:
path: /etc/httpd/conf/httpd.conf
regexp: '^#(ServerName).*' //配置ServerName
replace: '\1 localhost'
- service:
name: httpd
enabled: yes //开机自启
state: restarted
- copy:
src: /root/index.html //修改主页,可以自己写个页面
dest: /var/www/html/index.html
ansible]# ansible-playbook http.yml
ansible]# curl 192.168.1.56:8080
hello world
ansible]# ssh cache
cache ~]# apachectl -t
Syntax OK
2. 变量练习
练习使用user模块添加用户
练习使用变量简化task,让play通用性更强
练习使用过滤器
2.1 用user模块添加用户,并修改密码
ansible]# vim user.yml
---
- hosts: cache
remote_user: root
vars:
username: lisi
tasks:
- name: create user "{ {username}}"
user: group=wheel uid=1000 name={ {username}}
- shell: echo 123456 | passwd --stdin { {username}}
- shell: chage -d 0 { {username}}
ansible]# ansible-playbook user.yml //执行结果
2.2 变量过滤器,创建一个用户,设置密码
ansible模块添加用户,如果用户不存在,则自动创建用户,如果用户存在,则执行下一步。
ansible]# vim user1.yml
---
- hosts: cache
remote_user: root
tasks:
- user:
name: zhangsan
group: root
password: "{ {'123456' | password_hash('sha512')}}"
- shell: chage -d 0 zhangsan
password_hash 过滤器 { {调用变量|过滤器}}
变量在vars:下面定义
变量名:变量值
ansible]# ansible-playbook user1.yml
2.3 定义一个变量创建用户,设置密码
ansible]# vim user2.yml
---
- hosts: cache
remote_user: root
vars:
user: wangwu
tasks:
- user:
name: "{ {user}}"
group: root
password: "{ {'123456' | password_hash('sha512')}}"
- shell: chage -d 0 "{ {user}}"
ansible]# ansible-playbook user2.yml
3. handlers练习(定义触发脚本)
安装Apache软件
配置文件,重新载入配置文件让服务生效
使用handlers来实现
3.1 error
playbook从上往下顺序执行,若报错,后面的命令不会在执行,若想解决有两种方法:
1)当返回值为假时,显示true: - shell: setenforce 0 || true
ansible]# vim user4.yml
---
- hosts: cache
remote_user: root
vars:
user: bb
tasks:
- shell: setenforce 0 || true
- user:
name: "{ {user}}"
group: root
password: "{ {'123456' | password_hash('sha512')}}"
- shell: chage -d 0 "{ {user}}"
作用:报错不提示
ansible]# ansible-playbook user4.yml
2) 忽略:ignoring_errors: True
(推荐使用这个,会有报错信息,告诉你错误忽略,继续执行下面的命令)
ansible]# vim user5.yml
---
- hosts: cache
remote_user: root
vars:
user: bb
tasks:
- shell: setenforce 0
ignore_errors: True
- user:
name: "{ {user}}"
group: root
password: "{ {'123456' | password_hash('sha512')}}"
- shell: chage -d 0 "{ {user}}"
ansible]# ansible-playbook user5.yml
...ignoring...
3.2 handlers
关注的资源发生变化时采取的操作(有所变化,就执行handlsers的操作)
1) 使用handlers来配置文件,重新载入配置文件让服务生效
ansible]# vim adhttp.yml
---
- hosts: cache
remote_user: root
tasks:
- copy:
src: /root/httpd.conf
dest: /etc/httpd/conf/httpd.conf
owner: root
group: root
mode: 0644
notify:
- restart httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
ansible]# ansible-playbook adhttp.yml
ansible]# ssh cache apachectl -t
Syntax OK
ansible]# curl 192.168.1.56:8080
hello world
2)使用脚本调用变量更改服务
ansible]# vim adhttp2.yml
---
- hosts: cache
remote_user: root
vars:
server: httpd
tasks:
- copy:
src: /root/httpd.conf
dest: /etc/httpd/conf/httpd.conf
owner: root
group: root
mode: 0644
notify:
- restart "{ {server}}"
handlers:
- name: restart "{ {server}}"
service: name=httpd state=restarted
ansible]# ansible-playbook adhttp2.yml
4.编写playbook
把所有监听端口是8080的Apache服务全部停止
4.1 把监听端口是8080的Apache服务全部停止
]# vim ad.yml
---
- hosts: cache
remote_user: root
tasks:
- shell: netstat -atunlp | awk '{print $4}'| awk '-F:' '{print $2}'
register: result
- service:
name: httpd
state: stopped
ansible]# ansible-playbook ad.yml
4.2 when条件判断
1)当系统负载超过0.7时,则关掉httpd
ansible]# vim when.yml
---
- hosts: cache
remote_user: root
tasks:
- shell: uptime | awk '{printf("%.2f",$(NF-2))}'
register: result
- service:
name: httpd
state: stopped
when: result.stdout|float < 0.7
(此处写<,方便查看效果)
ansible]# ansible-playbook when.yml
4.3 with_items标准循环
1)为不同用户定义不同组
(批量创建用户,分别设置用户组)
ansible]# vim add.yml
---
- hosts: web2
remote_user: root
tasks:
- user:
name: "{ {item.name}}"
group: "{ {item.group}}"
password: "{ {'123456'|password_hash('sha512')}}"
with_items:
- {name: "aa", group: "users"}
- {name: "bb", group: "mail" }
- {name: "cc", group: "wheel"}
- {name: "dd", group: "root" }
ansible]# ansible-playbook add.yml
2) 嵌套循环,循环添加多用户
ansible]# vim add1.yml
---
- hosts: web2
remote_user: root
vars:
un: [a, b, c]
id: [1, 2, 3]
tasks:
- name: add users
shell: echo { {item}}
with_nested:
- "{ {un}}"
- "{ {id}}"
ansible]# ansible-playbook add1.yml
*
changed: [web2] => (item=[u'a', 1])
changed: [web2] => (item=[u'a', 2])
changed: [web2] => (item=[u'a', 3])
changed: [web2] => (item=[u'b', 1])
changed: [web2] => (item=[u'b', 2])
changed: [web2] => (item=[u'b', 3])
changed: [web2] => (item=[u'c', 1])
changed: [web2] => (item=[u'c', 2])
changed: [web2] => (item=[u'c', 3])
4.4 tags给指定的任务定义一个调用标识
以后不用重复整个过程,只需要执行tags标签的部分
1)tags 样例
ansible]# vim adhttp.yml
---
- hosts: cache
remote_user: root
tasks:
- copy:
src: /root/httpd.conf
dest: /etc/httpd/conf/httpd.conf
owner: root
group: root
mode: 0644
tags: config_httpd
notify:
- restart httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
2)调用方式
ansible]# ansible-playbook adhttp.yml --tags=config_httpd
3)include and roles
在编写playbook的时候随着项目越来越大,playbook越来越复杂。可以把一些play、task 或 handler放到其他文件中,通过包含进来是一个不错的选择
roles像是加强版的include,它可以引入一个项目的文件和目录
一般所需的目录层级有
vars:变量层
tasks:任务层
handlers:触发条件
files:文件
template:模板
default:默认,优先级最低
...
tasks:
- include: tasks/setup.yml
- include: tasks/users.yml user=plj
//users.yml 中可以通过{ { user }}来使用这些变量
handlers:
- include: handlers/handlers.yml
4.5 debug检测
ansible]# ansible-playbook --syntax-check http.yml //检测语法
playbook: http.yml
ansible]# ansible-playbook -C http.yml //测试运行
ansible]# ansible-playbook http.yml --list-tasks
ansible]# vim debug.yml
---
- hosts: cache
remote_user: root
tasks:
- shell: uptime |awk '{printf("%f\n",$(NF-2))}'
register: result
- shell: touch /tmp/isreboot
when: result.stdout|float > 0.5
- name: Show debug info
debug: var=result
ansible]# ansible-playbook debug.yml //运行
...
"result": {
"changed": true,
"cmd": "uptime |awk '{printf(\"%f\\n\",$(NF-2))}'",
"delta": "0:00:00.004577",
"end": "2019-02-27 16:58:50.151040",
"failed": false,
"rc": 0,
"start": "2019-02-27 16:58:50.146463",
"stderr": "",
"stderr_lines": [],
"stdout": "0.080000",
"stdout_lines": [
"0.080000"
########################
知识点整理:
01:ansible的七种武器:
a:ansble 执行临时性工作b:ansible-doc 文档c:ansible-console 用户交互式工具(类似shell)d:ansible-galaxy 从github上下载管理Roles的工具(类似Python的pip,下载别人的项目,回来自己修改)e:ansible-playbook 任务集(命令集合)f:ansible-vault 配置文件加密g:ansible-pull/push 大批量机器配置02:json YAML Jinja2 playbook
json数据格式:{} 集合,里面存放多组键值对[ ] 数组,存放多个值,可以是集合两者可以互相嵌套{ "all":[ { "a1": "A1","a2": "A2" }, { "b1": "B1","b2": "B2" }, { "c1": "C1","c2": "C2" } ]}YAML数据格式:--- ,表示一个文件的开始数组:-空格键值对::空格#表示注释不要用tab键,分隔必须是英文符号"all": - "a1": "A1" "a2": "A2" - "b1": "B1" "b2": "B2" - "c1": "C1" "c2": "C2"Jinja2语法规则基于Python的模板引擎,包含变量和表达是两部分,两者在模板求值时会被替换为值,模板中还有标签,控制模板的逻辑。Playbook的模板使用Python的Jinjia2模块来处理。{ { 表达式 }}{% 控制语句 %}{# 注释 #}调用变量 { {var}}计算 { {2+3}}判断 { { 1 in [1,2,3]}}{% if "name" == "aa" %} "aa"{% elif "name" == "bb" %} "bb" {% for "BB" in [AA,BB,CC] %} { { do method }} {% endfor %}{% else %} "cc"{% endif %}对abc哈希加密{ { "abc" | hash('md5') }}把一个列表用逗号连接起来{ { list | join(',') }}playbook构成由YAML语言编写,支持YAML脚本Target 远程主机组Variable 定义playbook运行时需要使用的变量Tasks 定义将要在远程主机上执行的任务列表(命令的集合)Handler 定义Task执行任务完成以后需要调用的任务红色表示失败,绿色表示成功主机与主机之间运行命令是并发的命令是按顺序执行的---- hosts: all remote_user: root tasks:(此处有空格) - ping:(此处有空格)ansible ~]# ansible-playbook ping.yml -f 5 -空格ping:空格参数-f 并发进程数量,默认是5hosts 一个或多个组或主机的patterns,以逗号为分隔符remote_user 账户名每个task命令批量执行于hosts里所有主机,所有task依次执行
触发器:跟tasks平齐 如过变标签里执行了某个task,则执行某个handler,notify调用此handler的name为触发。
########################