一、管理变量和事实
练习:使用基本身份认证httpd
[root@workstation ~]# mkdir westos
[root@workstation westos]# ls
ansible.cfg inventory
[root@workstation westos]# cat ansible.cfg
[defaults]
inventory = ./inventory
[root@workstation westos]# cat inventory
[webservers]
servera.lab.example.com
[root@workstation westos]# vim playbook.yml
[root@workstation westos]# cat playbook.yml
---
- name: Webservers vars
hosts: webservers
vars: 定义变量
firewall_pkg: firewalld 火墙安装包
firewall_srv: firewalld 火墙服务
web_pkg: httpd
web_srv: httpd
ssl_pkg: mod_ssl
httpdconf_src: files/httpd.conf
httpdconf_dest: /etc/httpd/conf/httpd.conf
secrets_dir: /etc/httpd/secrets
secrets_src: files/htpasswd
secrets_dest: "{{ secrets_dir }}/htpasswd"
web_root: /var/www/html/
tasks:
- name: Install packages 安装软件包
yum:
name:
- "{{ firewall_pkg }}"
- "{{ web_pkg }}"
- "{{ ssl_pkg }}"
state: latest 最新版本
- name: Configure service 设定服务
copy:
src: "{{ httpdconf_src }}"
dest: "{{ httpdconf_dest }}"
owner: root 所有人
group: root 所有组
mode: 0644 文件权限
- name: Create secrets directory 创建secrets目录
file:
path: "{{ secrets_dir }}" 指定创建路径
state: directory
owner: apache
group: apache
mode: 0500
- name: Create htpasswd
copy:
src: "{{ secrets_src }}"
dest: "{{ secrets_dest }}"
owner: apache
group: apache
mode: 0400
- name: Create index.html 创建默认发布页面
copy:
content: "{{ ansible_facts['fqdn']}} ({{ ansible_facts['all_ipv4_addresses'] }})\n"
dest: "{{ web_root }}/index.html"
- name: Configure firewalld service 设置 火墙服务
service:
name: "{{ firewall_srv }}"
state: started
enabled: true
- name: Configure httpd service 设置http服务
service:
name: "{{ web_srv }}"
state: started
enabled: true
- name: Firewalld permits https 火墙中允许https通过
firewalld:
service: https
state: enabled
immediate: true 立即添加
permanent: true 永久添加
- name: The apache 访问Apache
hosts: localhost 本地用户访问
become: no 身份不需要提升
vars:
- web_user: admin
vars_files:
- vars/secret.yml
tasks:
- name: Connect to apache with auth 连接Apache需要认证
uri:
url: https://servera.lab.example.com
validate_certs: no
force_basic_auth: yes
user: "{{ web_user }}"
password: "{{ web_pass }}"
return_content: yes
status_code: 200
register: auth_test
- debug:
var: auth_test.content
...
[root@workstation westos]# mkdir files
[root@workstation westos]# mkdir vars
[root@workstation westos]# ansible-vault create vars/secret.yml 密码lee
[root@workstation westos]# ansible-vault view vars/secret.yml
Vault password:
web_pass: redhat
[root@servera ~]# htpasswd -cm htpasswd admin
New password:
Re-type new password:
Adding password for user admin
[root@servera ~]# scp htpasswd root@172.25.254.21:/root/westos/files
root@172.25.254.21's password:
htpasswd 100% 44 38.3KB/s 00:00
[root@servera ~]# scp /etc/httpd/conf/httpd.conf root@172.25.254.21:/root/westos/files
[root@workstation files]# ls
htpasswd httpd.conf
[root@workstation files]# cat htpasswd
admin:$apr1$AJm03d79$Kj78AfLcrAqFmxpnV1LQI.
[root@workstation files]# vim httpd.conf
............................................
# Further relax access to the default document root:
<Directory "/var/www/html">
AuthUserFile /etc/httpd/secrets/htpasswd
AuthType basic
AuthName "Please input your name and password!!"
Require user admin
Require valid-user
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
............................................................
交互式输入密码/语法检测/playbook运行
[root@workstation westos]# ansible-playbook --syntax-check --vault-id @prompt playbook.yml
Vault password (default): lee
playbook: playbook.yml
[root@workstation westos]# ansible-playbook --vault-id @prompt playbook.yml
受管主机上检查
[root@servera httpd]# ls
conf conf.d conf.modules.d logs modules run secrets(文件已创建) state
[root@servera secrets]# cat htpasswd
admin:$apr1$AJm03d79$Kj78AfLcrAqFmxpnV1LQI.
[root@servera httpd]# cat conf/httpd.conf
总结
1.变量能够让playbook复用
2.可以给清单中的主机和主机组定义变量
3.可以使用事实和外部文件定义变量,也可以在命令行中
4.register关键字何以用于捕获命令输出
5.ansiblevault
6.ansible事实是从受管主机自动检测到的变量
二、实施任务控制
1.编写循环和条件任务
1.1不用循环
2.循环散列或字典列表
3.register和loop一起使用
执行后结果
迭代上面的playbook的结果(即使用上面的item的结果)
---
- name: loop register test
gather_facts: no
hosts: localhost
tasks:
- name: loop task
shell: "echo This is my item: {{ item }}"
loop:
- one
- two
register: echo_results
- name: Show results
debug:
msg: "STDOUT from previous task: {{ item.stdout }}"
loop: "{{ echo_results['results'] }}"
三、条件任务语法
3.1关键字:when
使用布尔值测试
测试my_service变量是否有值,有值则安装
[root@workstation loop]# cat when.yml
---
- name: Boolean test
hosts: all
vars:
my_service: httpd
tasks:
- name: "{{ my_service }} is installed"
yum:
name: "{{ my_service }}"
when: my_service is defined 判定http是否存在
3.2 条件
等于(字符串) A== "B"
等于(数字) A==100
小于 <
大于 >
小于等于<=
大于等于>=
不等于 !=
变量存在xxxisdefined
变量不存在 xxxisnotdefined
布尔值true 1、true、yes
布尔值false 0、false、no
第一个变量的值存在,且在第二个变量的列表中 A in B
测试多个条件
or 两个条件一个为真即可
and 两个条件必须都为真
3.3when支持使用列表描述条件
when:
-ansible_distribution_version=="8.0"
-ansible_kernel=="4.18.0-80.1.2.el8_0.x86_64"
再如:
when:
(ansible_distribution=="RedHat"and
ansible_distribution_major_version=="8")
or
(ansible_distribution=="CentOS"and
ansible_distribution_major_version=="7")
3.4组合循环和有条件任务
示列1:
ansible_mounts:
item.mount
item.size_available
[root@workstation loop]# cat keyword.yml
---
- name : keyword
hosts: all
tasks:
- name: mariadb-server
yum:
name: mariadb-server
state: latest
loop: "{{ ansible_mounts }}"
when: item.mount == "/" and item.size_available > 300000000
示列2:在vsftpd服务开启的状态下重启httpd服务
[root@workstation loop]# cat vsftpd.yml
---
- name: Restart httpd if vsftpd is running vsftpd服务运行重启http服务
hosts: all 所有主机
tasks:
- name: Get vsftpd status 检测vsftpd服务是的开启
command: /usr/bin/systemctl is-active vsftpd 启动vsftpd服务
ignore_errors: yes 若vsftpd服务失败,则继续运行,不中断
register: result 定义变量保存结果
- name: Restart httpd 重启http
service:
name: httpd
state: restarted
when: result.rc == 0 退出码为0.则重启httpd服务
...
四、编写循环和条件任务:
练习
[root@workstation loop]# cat inventory
[westos1]
servera.lab.example.com
[westos2]
serverb.lab.example.com
[root@workstation loop]# cat ansible.cfg
[defaults]
inventory = ./inventory
[root@workstation loop]#
[root@workstation loop]# cat db.yml
---
- name: Mariadb is running
hosts: westos1
vars:
mariadb_pkgs: 指定变量
- mariadb-server
- python3-PyMySQL
tasks:
- name: Mariadb is installed
yum:
name: "{{ item }}"
state: present
loop: "{{ mariadb_pkgs }}" 循环安装变量指定的软件包
- name: Start Mariadb
service:
name: mariadb
state: started
enabled: true
4.1修改playbook,条件变为受管主机使用Redhat操作系统才可执行
查看受管主机组当中主机的系统名称
[root@workstation loop]# ansible westos2 -m command -a 'cat /etc/redhat-release' -u student --become
serverb.lab.example.com | CHANGED | rc=0 >>
Red Hat Enterprise Linux release 8.0 (Ootpa)
---
- name: Mariadb is running
hosts: westos2
vars:
mariadb_pkgs:
- mariadb-server
- python3-PyMySQL
tasks:
- name: Mariadb is installed
yum:
name: "{{ item }}"
state: present
loop: "{{ mariadb_pkgs }}"
when: ansible_distribution == "RedHat" when条件可以判断是否是Redhat操作系统
五、实时处理程序
处理程序是响应由其他任务触发的通知的任务
实时处理程序又称"实时操作系统",是一类特殊的多道程序系统,主要应用于需要对外部事件进行及时响应并处理的领域。
所谓的实时就是立即或及时,具体含义是指计算机系统能够及时响应随机发生的外部事件的请求,在规定的时间内完成对事件的处理,并能控制所有实时设备和实时任务协调运行。
[root@workstation loop]# cat inventory 受管主机
[webservers]
servera.lab.example.com
serverb.lab.example.com
[root@workstation loop]# cat ansible.cfg ansible配置文件
[defaults]
inventory = ./inventory
[root@workstation loop]# mkdir files
[root@workstation loop]# cd files
[root@workstation files]# vim example.conf
[root@workstation files]# cat example.conf
<VirtualHost *:80>
DocumentRoot /www
ServerName www.westos.com
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /dds
ServerName dds.westos.com
</VirtualHost>
[root@workstation loop]# ansible-playbook --syntax-check notify.yml
[root@workstation loop]# ansible-playbook notify.yml
编写playbook
只有在template任务通知已发生更改时才会触发
[root@workstation loop]# vim notify.yml
---
- name: test
hosts: webservers 受管主机组
tasks:
- name: Copy File
template:
src: files/example.conf
dest: /etc/httpd/conf.d/example.conf
notify: notify语句支出该任务需要触发一个处理程序
- restart httpd 程序名称可以多个写入
- restart mysql
handlers: 表示处理程序任务列表的开头
- name: restart apache 被任务调用的处理程序名称
service: 程序模块
name: httpd 服务
state: restarted 重启服务
- name: restart mysql
service:
name: mariadb
state: restarted
...
[root@workstation loop]# ansible-playbook --syntax-check notify.yml 语法检测正常
playbook: notify.yml
使用处理程序注意:
1.处理程序始终按照play的handlers部分指定的顺序运行,不按notify里的服务名称排序
2.处理程序通常在相关play中所有其他任务运行完后运行
3.处理程序名称存在于个play命名空间中(如果两个处理程序同名,只会运行一个)
4.如果多个任务通知处理程序,处理程序也只会运行一次
5.如果包含notify的语句任务没有报告changed结果,则处理程序不会获得通知