文章目录
1、when语句
-
判断的结果一致的话,就执行任务,否则跳过任务
-
ansible中判断语句是when判断,默认when判断,就识别变量,所以的话,不需要使用"{{}}"来引用变量when inventory_hostname == 'node1
-
还有一个点就是如果不使用变量的话,就只使用这个值的话,那么的话就要带上这个双引号,并且里面还要有单引号即可
-
层级和模块的层级一样
1、判断表达式
1、比较运算符
符号 | 作用 |
---|---|
== | 比较2边是否相等 |
!= | 比较2边 |
>= | 左边大于右边 |
2、逻辑运算符
符号 | 作用 |
---|---|
and | 逻辑与,2边都为真,则返回 |
or | 逻辑或,有一个为真,则返回真 |
not | 逻辑否,对表达式进行取反,真为假,假为真 |
3、根据rc的返回值判断task任务是否执行成功
[root@controller mnt]# cat f8.yml
- hosts: node1
tasks:
- shell: ls /etc/passsssss
register: get_status
ignore_errors: yes
- debug:
msg: rc is 0
when: get_status.rc == 0
- debug:
msg: rc is error
when: get_status.rc != 0
5、通过条件判断路径是否存在
名称 | 作用 |
---|---|
file | 判断指定路径是否为一个文件 |
directory | 判断指定路径是否是一个目录 |
link | 判断指定路径是否为一个软链接 |
mount | 判断路径是否为挂载点 |
exists | 判断指定路径是否存在 |
# /etc/passwd存在的话,就执行任务
# when直接使用值的话需要使用双引号里面的值在加上单引号即可
[root@controller mnt]# cat f9.yaml
- hosts: all
tasks:
- debug:
msg: exist
when: "'/etc/passwd is exists'"
6、in
- 判断值是不是在列表中
[root@controller mnt]# cat f3.yml
- hosts: node1
tasks:
- debug:
msg: ens160 exists
when: "'ens160' in ansible_interfaces"
2、when和其他关键字
1、block关键字
- 判断一个部分的任务是否成功执行
[devops@controller ansible]$ cat when/2.yaml
- hosts: all
tasks:
- block:
- file:
path: /mnt/111.txt
state: touch
- file:
path: /mnt/1.dir
state: directory
when: inventory_hostname == "node1"
2、rescue关键字
- block中任务失败的话,就会执行rescue下的任务,否则,不执行
- name: rescue
hosts: all
tasks:
- block:
- shell: ls /etc/p11111
- file:
path: /etc/passwd
state: file
rescue:
- debug:
msg: rescue
when: inventory_hostname == 'node1'
3、always关键字
- 无论block任务执行成功还是失败都会执行的
- name: rescue
hosts: all
tasks:
- block:
- shell: ls /etc/p11111
- file:
path: /etc/passwd
state: file
rescue:
- debug:
msg: rescue
always:
- debug:
msg: always
when: inventory_hostname == 'node1'
3、ansible循环语句
1、基于列表循环(whith_items)
- hosts: all
vars:
users:
- zhangsan
- lisi
- wangwu
tasks:
- debug:
msg: "{{ item }}"
with_items: "{{users}}"
2、基于字典循环(with_dict)
[devops@controller ansible]$ cat dict.yaml
- hosts: all
vars:
users:
q1:
uid: 2022
name: zhangsan
q2:
uid: 2023
name: lisi
tasks:
- debug:
msg: "{{ item.value.name }}"
with_dict: "{{ users }}"
# vaule就是uid和name
3、loop循环
- 天生用来便利列表,也可以过滤字典
[devops@controller ansible]$ cat loop.yml
- hosts: all
vars:
users:
- zhangsan
- lisi
- wangwu
tasks:
- debug:
msg: "{{ item }}"
loop: "{{ users }}" # 循环里面
4、jinja2模块管理
1、为什么需要这个
-
很多个主机都要搭建httpd服务,将一个httpd的配置文件拷贝到其余的主机上面,上面的ip地址都是一样的,所以的话,这个jinjia2模版文件会根据不同主机更改需要的内容
-
将带有变量的模版,拷贝到其他节点上面,变量会自动的识别出来的值
[devops@controller ansible]$ cat j1.yml
- hosts: all
tasks:
- template:
src: /mnt/http.conf.j2
dest: /mnt/httpd.conf
[devops@controller ansible]$ cat /mnt/http.conf.j2
Listen {{ ansible_ens160.ipv4.address }}:80
# 会根据不同的主机来获取到不同的信息
2、jinjia条件语句
-
跟when语句是一样的
-
主要就是利用了setup收集事实变量,从而实现内容的更替
# 格式
{% if 表达式 %}
执行语句
{% elif 表达式 %}
执行语句
{% else %}
执行语句
{% endif %}
# 需求如果是node1主机就显示node1 is ok ,node2主机就显示node2 is ok
[devops@controller ansible]$ cat /mnt/1.j2
{% if ansible_hostname == 'node1' %}
"node1 is ok"
{% elif ansible_hostname == 'node2' %}
"node2 is ok"
{% else %}
error
{% endif %}
[devops@controller ansible]$ cat j2.yml
- hosts: all
tasks:
- template:
src: /mnt/1.j2
dest: /mnt/1
3、jinjiafor语句
{% for 变量 in 循环体 %}
执行语句
{% endof %}
-
groups.all 获取所有主机
-
hostvars 获取指定主机的信息,比如获取node1的fqdn hostvars[node1].ansible_fqdn
[devops@controller ansible]$ cat j3.yml
- hosts: all
tasks:
- template:
src: /mnt/3.j2
dest: /etc/hosts
[devops@controller ansible]$ cat /mnt/3.j2
{% for i in groups.all %}
{{ hostvars[i].ansible_ens160.ipv4.address }} {{ hostvars[i].ansible_fqdn}} {{ hostvars[i].ansible_hostname}}
{% endfor %}
4、jinjia2过滤器
1、default过滤器
- default 就是没有值的就使用定义的默认值
[devops@controller ansible]$ cat p1.yml
- hosts: node
vars:
users:
- name: qq
uid: 3333
- name: ww
- name: rr
tasks:
- debug:
msg: "{{ item.uid|default('9999') }}"
loop: "{{ users }}"
2、password_hash
[devops@controller ansible]$ cat p2.yml
- hosts: node
tasks:
- user:
name: j11
password: "{{'123'|password_hash('sha512')}}"
5、角色
1、为什么需要角色
-
解决了这个剧本之间的移植的关系,使用了角色的话,就可以直接移植到其他主机上面也能进行运行,就变得非常的高效了
-
角色的组成部分
-
files:用于存放一些非模版文件的文件,就是一些普通的文件,会被复制到被控节点上面的
-
templates:用于存放角色相关的jinja2模版文件,当使用角色相关的模版时,如果没有明确指定模版的路径,则默认使用此目录中的模版
-
tasks:角色所需要执行的所有任务文件都存放于此,包含一个主文件main.yml,可以通过include的方式引入其他任务文件,就是可以创建多个tasks任务,然后在main,yml里面进行引用
-
handlers:用于定义角色中需要调用的handlers,包含一个主配置文件main.yml,也可以通过include引入其他的handlers文件
-
vars:定义此角色要用到的变量,包含一个主文件main.yml
-
meta:用于存储角色的元数据信息,这个写元数据用于描述角色的相关属性,作者等
-
defaults:除了vars目录,也可以定义角色用到的变量,定义的变量的优先级是最低的
-
2、创建角色
[devops@controller ansible]$ ansible-galaxy init apache
- Role apache was created successfully
[devops@controller apache]$ ls
defaults files handlers meta README.md tasks templates tests vars
# 编写一个httpd
[devops@controller tasks]$ cat main.yml
---
# tasks file for apache
- name: mount
mount:
src: /dev/sr0
path: /media
fstype: iso9660
state: mounted
- name: use yum
yum:
name: httpd
state: present
- name: use template
template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
- name: index.html
copy:
src: index.html
dest: /var/www/html/
- name: service
service:
name: "{{item}}"
state: started
enabled: yes
loop:
- firewalld
- httpd
- name: firewalld
firewalld:
service: http
permanent: yes
state: enabled
immediate: yes
# {{}} 输出变量,for和if可以一起使用
{% if inventory_hostname == 'node1' %}
Listen {{hostvars['node1'].ansible_ens160.ipv4.address}}:80
{% elif inventory_hostname == 'node2' %}
Listen {{hostvars['node2'].ansible_ens160.ipv4.address}}:80
{% endif %}