Day04-Ansible变量与Task控制
1. ansible变量
- 用户自定义变量(剧本中,存放在指定的文件中) ※※※※※
- register(寄存器)变量 类似于 $? $() ※※※
- facts变量(ansible内置变量) 收集每个服务器的信息 ※
1.1 用户自定义变量(剧本中,存放在指定的文件中)
#01 创建变量 并放在剧本中 ※※※※※
oldboy=666
echo $oldboy
key: value 变量名: 值 (键值)
[root@m01 playbook]# cat 04-show-vars.yml
- hosts: all
vars:
- name1: nc
- name2: nmap
tasks:
- name: install soft
yum:
name:
- "{{ name1 }}"
- "{{ name2 }}"
state: installed
#02 创建变量存放在文件中
[root@m01 playbook]# cat vars.yml
name1: nc
name2: nmap
[root@m01 playbook]# cat 04-show-vars.yml
- hosts: all
vars_files: vars.yml
tasks:
- name: install soft
yum:
name:
- "{{ name1 }}"
- "{{ name2 }}"
state: installed
#03 根据主机组变量 ※※※※※
group_vars/
db/vars.yml
backup/vars.yml
web/vars.yml
data/vars.yml
all/vars.yml
组的名字
[root@m01 playbook]# tree -F group_vars/
group_vars/
├── all/
│ └── vars.yml
├── backup/
│ └── vars.yml.gz
├── data/
├── db/
└── web/
└── vars.yml.gz
5 directories, 3 files
[root@m01 playbook]# cat 05-group-vars-show.yml
- hosts: all
tasks:
- name: touch file
file:
path: /tmp/{{ name }}
state: touch
#面试题: ansible中使用变量何时使用双引号,如果变量开头的内容,变量两边加上双引号
[root@m01 playbook]# cat 05-group-vars-show.yml
- hosts: all
vars:
- dir: /tmp/
tasks:
- name: touch file
file:
path: "{{dir}}/lidao.txt"
state: touch
自定义变量小结
- 剧本中变量 play vars ※※※※※
- 剧本中的变量 指定变量文件 vars_files ※※
- 指定主机组共享的变量文件 group_vars ※※※※※
group_vars/
web/
vars.yml --->root: /data
1.2 register注册变量 类似于 $? $() ※※※
# register关键字可以将某个task任务结果存储至变量中,最后使用debug输出变量内容,可以用于后**续排障
# 目的,排错
## 01 应用案例 显示ip地址
[root@m01 playbook]# cat 06-reg-var-ip.yml
- hosts: all
tasks:
- name: print ip addr
shell: hostname -I |awk '{print $NF}'
register: ip_addr
- name: debug
debug:
msg: this is you ip addr {{ ip_addr }}
# 注册变量默认输出的是json格式的数据
key: value
{
'stderr_lines': [],
u'changed': True,
u'end': u'2021-08-19 09:56:21.545851',
'failed': False,
u'stdout': u'172.16.1.31', #注册变量中的 stdout 部分 standard output 标准输出
u'cmd': u\"hostname -I |awk '{print $NF}'\",
u'rc': 0,
u'start': u'2021-08-19 09:56:21.514319',
u'stderr': u'', #strerr 标准错误输出
u'delta': u'0:00:00.031532',
'stdout_lines': [u'172.16.1.31'] # stdout_lines 标准输出
}
#变量叫做ip_addr
ip_addr.stdout_lines #取出ip 常用
ip_addr.rc #返回值 return code $? 常用
ip_addr.stdout #标准输出, 屏幕上面的输出 常用
ip_addr.stderr #标准错误输出,错误信息.
[root@m01 playbook]# vim 06-reg-var-ip.yml
- hosts: all
tasks:
- name: print ip addr
shell: hostname -I |awk '{print $NF}'
register: ip_addr
- name: debug
debug:
msg: this is you ip addr {{ ip_addr.stdout }} {{ ip_addr.rc }} {{ ip_addr.stderr }}
注册变量小结
register应用场景小结
- **用于调试 配合debug 模块 msg 输出与打印中间过程**
- 用于与when一起使用实现判断功能.
1.3 facts变量(ansible内置变量)
Ansible facts是在被管理主机上通过ansible自动采集发现的变量。
facts包含每台特定的主机信息。比如:被控端主机的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。
facts使用场景(利用fact获取指标进行配置)
1.通过facts检查CPU,来生成对应的Nginx配置文件 (收集每台机器的cpu核心数)
2.通过facts检查主机名信息,来生成不同的Zabbix配置文件(收集每台机器的主机名)
3.通过fact检索的内存情况来自定义mysql的配置文件 (收集每台机器的内存)
4.通过facts收集内存大小,设置tomcat最多可以用多少内存 (收集每台机器的内存)
ansible backup -m setup #显示所有的facts
#常用必备的facts
ansible_default_ipv4.address ※※※※※ #默认的网卡ip eth0
ansible_distribution #系统发行版本名字 CentOS Ubuntu Debian ...
ansible_memtotal_mb ※※※※※ #内存大小
ansible_processor_vcpus ※※※※※ #cpu数量
ansible_processor_cores ※※※※※ #cpu 核心数
ansible_date_time.date
[root@m01 playbook]# cat 07-reg-facts-nginx-conf.yml
- hosts: web
tasks:
- name: copy conf file
template: # template 传输中变量可以解析,copy 传输变量无法解析
src: nginx-conf-muban.j2
dest: /etc/nginx/nginx.conf
backup: yes
- name: restart nginx
systemd:
name: nginx
state: restarted
[root@m01 playbook]# cat nginx-conf-muban.j2
user www;
worker_processes "{{ ansible_processor_cores*2 }}"; # 变量计算在变量里面
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format access '-$proxy_protocol_addr-,--$remote_addr--,---$http_x_forwarded_for---,----$proxy_add_x_forwarded_for----,$remote_user,$time_local,$host,$request,$status,$http_referer,$HTTP_X_UP_CALLING_LINE_ID,$request_time,$http_user_agent $upstream_addr $upstream_response_time $upstream_cache_status';
access_log /var/log/nginx/access.log access;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
facts 变量小结:
- 通过facts取出,服务器相关信息,ip,时间,磁盘分区…
- setup+filter进行过滤出
1.4 ansible变量总结
- 用户自定义变量:
通过剧本paly部分中vars定义变量, ※※※※※
剧本中play部分vars_files指定变量文件
通过group_vars指定主机组共享变量文件 ※※※※※ - 注册变量:
实现echo $?. $() `` 把模块执行结果存放在变量中。 register模块下面加上register
一般应用:配合debug模块调试,配合when条件进行判断
把模块输出存放在一个变量中. 通过debug msg输出变量内容 变量.rc 变量.stdout 变量.stderr - ansible内置变量
facts变量
比较容易的快速的取出被管理端,ip,主机名,发行版本,系统版本,内存,网卡,磁盘…
链接: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html
2. Task控制 判断与循环 触发器
- when 条件 不同主机做不同的事情
- 循环
批量启动或重启服务
批量添加用户www nfs … - 触发器
只想在nginx配置文件发生变化的时候重启nginx
2.1 when条件
- when条件一般是与变量一起使用(facts,注册变量)
##案例01 根据不同的系统安装不同软件
- hosts: centubt
tasks:
- name: CentOS install cowsay
yum:
name:
- cowsay
state: present
when: ( ansible_distribution == "CentOS" ) #只有centos系统才安装 cowsay
- name: Ubuntu install cmatrix
apt:
name:
- cmatrix
state: present
when: ( ansible_distribution == "Ubuntu" ) #只有ubuntu系统 才安装 cmatrix
#02 根据不同的服务器配置不同的源
# yum源 base epel nginx php
# lb √ √ √ x
# web √ √ √ √
# db √ √ x x
# nfs √ √ x x
m01 playbook]# cat 08-when-config-repo.yml
- hosts: all
tasks:
- name: add nginx repo
yum_repository:
file: nginx
name: nginx
description: "ngx repo"
baseurl: "http://nginx.org/packages/centos/$releasever/$basearch/"
enabled: yes
gpgcheck: no
state: present
when: ( ansible_hostname is match("lb|web") )
- name: add php repo
yum_repository:
file: php
name: php
description: "php repo"
baseurl: "http://us-east.repo.webtatic.com/yum/el7/x86_64/"
enabled: no
gpgcheck: no
state: present
when: ( ansible_hostname is match("web") )
##ansible when格式
when: 结合ansible内置变量或注册变量 实现判断
== 完全匹配
is match() 模糊匹配,支持正则
# 如果想表达多个条件 and 或or进行链接
when: ( ansible_hostname is match("web|bc") )
when: ( ansible_hostname is match("web") ) or ( ansible_hostname is match("lb") )
[root@m01 playbook]# cat when_service.yml
- hosts: web
tasks:
- name: Check Httpd Server
command: systemctl is-active httpd
ignore_errors: yes
register: check_httpd
- name: debug outprint
debug: var=check_httpd #通过debug的var输出该变量的所有内容
#msg=" :{{check_httpd}}"
- name: Httpd Restart #如果check_httpd执行命令结果等于0,则执行重启httpd,否则跳过
service: name=httpd state=restarted
when: check_httpd.rc == 0
when 小结
- when条件语句小结
- 配合ansible facts变量 实现判断(ip,主机名,系统)
- 配合register变量,实现判断(if $? == 0 执行xxxx服务/模块 )
- 加入或使用debug 显示执行过程
- 匹配规则:
==
!=
is match()
when中可以使用的表达式传送门:https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#playbooks-tests
2.2 循环语句 loop
- 表示批量重启、开启服务
## 案例01 一个变量的循环
[root@m01 playbook]# cat 09-loop.yml
- hosts: web
tasks:
- name: start nginx php
systemd: name={{ item }} state=started enabled=yes
with_items:
- nginx
- php-fpm
## 案例02 多个变量
useradd -u 999 -g root -s /sbin/nologin -M lidao996
useradd -u 1000 -g oldboy -s /sbin/nologin -M lidao007
[root@m01 playbook]# cat 10-loop-two-vars.yml
- hosts: web
tasks:
- name: useradd
user: name={{ item.name }} uid={{ item.id }} state=present
with_items:
- { name: "lidao996", id: 666 }
- { name: "lidao007", id: 12306 }
小结循环
- with_items 实现单个变量循环 *****
- with_tiems 实现多个变量循环(字典)**
参考资料: https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
2.3 handlers
- trigger 扳机,触发器
- 实现,只有配置文件发生变化,然后重启服务
[root@m01 playbook]# cat 11-handers-nginx-conf.yml
- hosts: web
tasks:
- name: copy conf file
template:
src: nginx-conf-muban.j2
dest: /etc/nginx/nginx.conf
backup: yes
notify:
- Restart nginx
handlers :
- name: Restart nginx
systemd:
name: nginx
state: restarted
[root@m01 playbook]# ansible-playbook -i hosts 11-handers-nginx-conf.yml
____________
< PLAY [web] >
------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
________________________
< TASK [Gathering Facts] >
------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
ok: [172.16.1.7]
_______________________
< TASK [copy conf file] >
-----------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
changed: [172.16.1.7]
_________________________________
< RUNNING HANDLER [Restart nginx] >
---------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
changed: [172.16.1.7]
____________
< PLAY RECAP >
------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
172.16.1.7 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
handlers 小结
- handlers注意事项
1.无论多少个task通知了相同的handlers,handlers仅会在所有tasks结束后运行一次。
2.只有task发生改变了才会通知handlers,没有改变则不会触发handlers
3.不能使用handlers替代tasks* - 核心应用场景: 使用notify+handlers实现文件/配置文件,更新并重启/重新挂载/重新…
handlers传送门:https://docs.ansible.com/ansible/latest/user_guide/playbooks_handlers.html
2.4 标签 tags
- tags
方便我们进行调整,执行某个、某些模块
忽略或跳过某些模块。
[root@m01 playbook]# cat 12-nfs-tags.yml
- hosts: backup
tasks:
- name: install nfs rpcbind
yum: name=nfs-utils state=installed
tags:
- install_nfs
- name: configure nfs exports file
copy: dest=/etc/exports content="/playbook-backup/ 172.16.1.0/24(rw,sync,all_squash)"
tags:
- config_nfs
- config_nfs_file
- name: mkdir chown
file: path=/playbook-backup state=directory owner=nfsnobody group=nfsnobody
tags:
- config_nfs
- config_nfs_dir
- name: start && enable rpc
systemd: name={{ item }} enabled=yes state=started
with_items:
- rpcbind
- nfs
tags:
- start_srv
- name: mount test
mount: fstype=nfs src=172.16.1.41:/playbook-backup path=/mnt state=mounted
tags:
- nfs_mount
ansible-playbook -i hosts -C 12-nfs-tags.yml
ansible-playbook -i hosts -C 12-nfs-tags.yml --tags install_nfs # 执行某个标签
ansible-playbook -i hosts -C 12-nfs-tags.yml --skip-tags install_nfs # 排除某个标签
ansible-playbook -i hosts -C 12-nfs-tags.yml --tags config_nfs # 检查配置两部分
2.5 ansible 剧本复用
- 部署lnmp环境
主剧本 | 子剧本 |
---|---|
main.yml | |
01-nginx.yml | 01-nginx.yml ----> 详细nginx流程 |
02-php.yml | |
03-mysql.yml | |
04-redis.yml | |
05-nfs.yml |
cat main.yml
- hosts: all
tasks:
- include_tasks: 01-nginx.yml
- include_tasks: 02-php.yml
- include_tasks: 03-mysql.yml
- include_tasks: 04-redis.yml
- include_tasks: 05-nfs.yml
2.6 忽略错误ignore_errors
[root@manager ~]# cat 13-ignore-errors.yml
---
- hosts: all
remote_user: root
tasks:
- name: Ignore False
command: /bin/false
#ignore_errors: yes
- name: touch new file
file: path=/tmp/oldboy_ignore state=touch
小结
- tags标签:调试debug
- include_tasks 引用或复用剧本
- ignore_errors 忽略故障