关于循环
1.简单循环
loop: ##赋值列表
- value1
- value2
- ...
-
{{item}} ##迭代变量名称
例如:创建文件
---
- name: create file
hosts: 172.25.0.254
tasks:
- name: file module
file:
name: /mnt/{{item}}
state: touch
loop:
- westos_file1
- westos_file2
测试如下:
执行如下:
创建成功!在受控机查看如下:
2.循环散列或字典列表
好处在于:可以赋予不同的服务不同的状态!
---
- name: create file
hosts: all
tasks:
- name: file
service:
name: "{{ item.name}}"
state: "{{ item.state }}"
loop:
- name: httpd
state: started
- name: firewalld
state: stopped
操作如下:
执行:
执行成功之后:在受控机查看服务状态!
火墙已经关闭!
httpd服务开启成功!
脚本练习:
在系统中完成以下用户操作
1.建立用户组shengchan,caiwu,jishu并满足以下要
- shengchan组id为8000
- caiwu组id为8001
- jishu组id为8002
2.建立westosuser,linux,lee,westosadmin等用户完成以下要求
- westosuser用户的附加组为shengchan和jishu
- lee的主组为caiwu附加组为技术,lee的uid和gid必须一致
- linux为系统账号不能直接被操作者使用
- westosamdin用户不属于以上三个部门,但是可以在系统中*的管理用户
- 以上用户密码均为westos,并要求用户首次登陆时强制修改密码
- 设定以上用户密码必须在30天内进行休改,并在过期前2天发出警告求
---
- name: create file
hosts: list1
tasks:
- name: create group
group:
name: "{{item.name}}"
gid: "{{item.gid}}"
state: present
loop:
- name: shengchan
gid: 8000
- name: caiwu
gid: 8001
- name: jishu
gid: 8002
- name: westosuser
gid: 8003
- name: linux
gid: 8004
- name: westosadmin
gid: 8005
- name: create user
user:
name: "{{item.name}}"
groups: "{{item.groups}}"
group: "{{item.group}}"
shell: "{{item.shell}}"
uid: "{{item.uid}}"
password: '$6$4RBSjfuYIt694mEi$KetzruRtGRzZIPA4B/hDCimIWCalsOkzCH2GEoHvRTZpDXWL1xf.0.SYDg.SQ6KwtMUDKsNIcH0MAd3AHBRET0'
loop:
- name: westosuser
groups: shengchan, jishu
group: 8003
shell: /bin/bash
uid: 8003
- name: lee
groups: jishu
group: caiwu
shell: /bin/bash
uid: 8001
- name: linux
groups: linux
group: linux
shell: /sbin/nologin
uid: 8004
- name: westosadmin
groups: westosadmin
group: westosadmin
shell: /bin/bash
uid: 8005
- name: westosadmin
lineinfile:
path: /etc/sudoers
regexp: "^root"
insertafter: "^root"
line: "westosadmin {{ansible_facts['fqdn']}}=(root) NOPASSWD: /sbin/useradd, /sbin/userdel, /sbin/usermod"
- name: configure password messages
shell: chage -d 0 -M 30 -W 2 "{{item}}"
loop:
- westosuser
- lee
- westosadmin
条件
when:
- 条件1
- 条件2
#条件判断#
= value == "字符串",value == 数字
< value < 数字
> value > 数字
<= value <= 数字
>= value >= 数字
!= value != 数字
is defined value value is defined 变量存在
is not defined value is not defined 变量不存在
bool变量 为true value value的值为true
bool变量 false not value value的值为false
value in value2 value的值在value2列表中
#多条条件组合#
when:
条件1 and 条件2
- 条件1
- 条件2
when:
条件1 or 条件2
when: >
条件1
or
条件2
测试题:
*建立大小为1500M名为exam_lvm的 lvm在westos组中
*如果westos不存在请输入:
vg westos is not exist
*如果westos大小不足1500M清输出:
vg westos is less then 1500M
并建立800M大小的lvm!!
vim lvm.yml
---
- name: create lvm
hosts: all
tasks:
- name: check vg westos
debug:
msg: vg westos is not exist
when: ansible_facts['lvm']['vgs']['westos'] is not defined
- name: create 1500M exam_lvm
lvol:
vg: westos
lv: exam_lvm
size: 1500m
when: ansible_facts['lvm']['vgs']['westos'] is defined
ignore_errors: yes
register: LVSTATE
- name: create 800M exam_lvm
lvol:
vg: westos
lv: exam_lvm
size: 800m
when:
- ansible_facts['lvm']['vgs']['westos'] is defined
- LVSTATE['rc'] != 0
执行如下:
因为没有创建所以会输出不存在!
触发器
notify: 触发器当遇到更改是触发handlers
handlers: 触发器触发后执行的动作
例如:
---
- name: create virtualhost for web server
hosts: all
vars_files:
./vhost_list.yml
tasks:
- name: create document
file:
path: "{{web2.document}}"
state: directory
- name: create vhost.conf
copy:
dest: /etc/httpd/conf.d/vhost.conf
content:
"<VirtualHost *:{{web1.port}}>\n\tServerName {{web1.name}}\n\tDocumentRoot {{web1.document}}\n\tCustomLog logs/{{web1.name}}.log combined\n</VirtualHost>\n\n<VirtualHost *:{{web2.port}}>\n\tServerName {{web2.name}}\n\tDocumentRoot {{web2.document}}\n\tCustomLog logs/{{web2.name}}.log combined\n</VirtualHost>"
notify:
restart apache
handlers:
- name: restart apache
service:
name: httpd
state: restarted
处理失败任务
1.ignore_errors#
#作用:
当play遇到任务失败是会终止
ignore_errors: yes 将会忽略任务失败使下面的任务继续运行
例如:
---
- name: test
hosts: all
tasks:
- name: test
dnf:
name: qweqwe
state: present
ignore_errors: yes
- name: create file
file:
path: /mnt/filess
state: touch
测试如下:
因为qweqwe根本没有,所以不可能下载成功,但是失败不会影响下一步创建文件!
执行如下:
在受控机查看文件创建成功!
2.force_handlers#
#作用:
#当任务失败后play被终止也会调用触发器进程
例如:
例如:
---
- name: apache change port
hosts: all
force_handlers: yes
vars:
http_port: 8080
tasks:
- name: configure apache conf file
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: "^Listen"
line: "Listen {{ http_port }}"
notify: restart apache
- name: install error
dnf:
name: westos
state: latest
handlers:
- name: restart apache
service:
name: httpd
state: restarted
enabled: yes
下载服务westos肯定不会成功!
但是后面的触发器重启服务还是会触发!
因为 force_handlers: yes
所以中间任务失败后,也会调用触发器!
执行如下:
3.changed_when#
#作用:
#控制任务在何时报告它已进行更改
上个实验修改如下:
执行如下:
4.failed_when#
#当符合条件时强制任务失败
比如:
---
- name: test
hosts: all
tasks:
- name: test
dnf:
name: lftp
state: present
register: lftp_out
failed_when: "'0' in lft_out.rc"
- name: create file
file:
path: /mnt/sun
state: touch
测试如下:
在执行的时候:遇到任务test,服务lftp下载之后,把下载结果输入lftp_out
当lftp_out结果为0时。强制任务失败!
5.block
当有始终要运行的部分的时候,就可以使用block!
block: 定义要运行的任务
rescue: 定义当block句子中出现失败任务后运行的任务
always: 定义最终独立运行的任务
练习:
建立playbook ~/vbd1.yml要求如下:
建立大小为1500M名为/dev/vdb1的设备
如果/dev/vdb不存在请输入:
/dev/vdb is not exist
如果/dev/vdb大小不足1.5G请输出:
/dev/vdb is less then 1.5G
并建立800M大小的/dev/vdb1
此设备挂载到/vbd1上
---
- name: create /dev/vdb1
hosts: all
tasks:
- block:
- parted:
device: /dev/vdb
number: 1
state: present
part_end: 1500MiB
when: ansible_facts['devices']['vdb'] is defined
rescue:
- debug:
msg: /dev/vdb is less then 1.5G
- parted:
device: /dev/vdb
number: 1
state: present
part_end: 800MiB
always:
- filesystem:
fstype: xfs
dev: /dev/vdb1
force: yes
- mount:
path: /vdb1
src: /dev/vdb1
fstype: xfs
state: mounted
- name: check /dev/vdb
debug:
msg: "vdb is not exist"
when: ansible_facts['devices']['vdb'] is not defined
测试:
执行如下:
因为129上没有硬盘分区,229上有/dev/vdb
所以129会显示不存在,229会直接分区成功!