第11章 Ansible剧本
第1章 Ansible剧本介绍
1.什么是剧本
剧本 --> playbook
电影 --> 剧本 --> 场景 角色 剧情
Ansible --> 剧本 --> 功能丰富 控制执行流程
2.playbook剧本的优势
命令行缺点:
1)重复冗余太多
2)不能控制/选择流程
3)不支持高级功能/循环/判断/变量
playbook剧本优点:
1)减少重复的书写的指令: ansible backup -m file -a
2)看起来简洁清晰
3)功能强大,可以控制流程,比如:判断,循环,变量,标签
4)其他剧本可以复用
5)提供语法检查以及模拟执行
第2章 Ansible剧本的格式书写要求
1.YAML格式特点
变态的缩进要求,通过缩进表示层级关系
: 和 - 后面必须接空格
不要使用tab缩进
文件后缀名需要改为yaml或yml,vim可以智能高亮提示
2.剧本的组成
hosts: 需要执行的主机组
tasks: 只要执行的任务
- name: 任务名称
yum: 模块名称
name: 软件名称
state: 状态
第3章 实战-编写Nginx剧本
1.命令行写法
ansible web -m yum -a "name=nginx state=installed"
ansible web -m service -a "name=nginx state=started"
2.剧本写法
- name: install nginx server
hosts: web
tasks:
- name: 01-install
yum:
name: nginx
state: installed
- name: 02-started
service:
name: nginx
state: started
第4章 实战-编写NFS剧本
1.命令行模式
ansible nfs_server -m yum -a "name=nfs-utils state=present"
ansible nfs_server -m group -a "name=www gid=1000 state=present"
ansible nfs_server -m user -a "name=www uid=1000 group=www create_home=false shell=/sbin/nologin state=present"
ansible nfs_server -m file -a "path=/data state=directory owner=www group=www"
ansible nfs_server -m copy -a "src=/opt/nfs_server/conf/exports dest=/etc/"
ansible nfs_server -m systemd -a "name=nfs state=started enabled=true"
2.剧本模式
- name: install nfs server
hosts: nfs_server
tasks:
- name: 01-yum
yum:
name: nfs-utils
state: present
- name: 02-groupadd
group:
name: www
gid: 1000
state: present
- name: 03-useradd
user:
name: www
uid: 1000
group: www
create_home: false
shell: /sbin/nologin
state: present
- name: 04-data
file:
path: /data
state: directory
owner: www
group: www
- name: 05-config
copy:
src: /opt/nfs_server/conf/exports
dest: /etc/
- name: 06-start
systemd:
name: nfs
state: started
enabled: true
3.模拟执行
ansible-playbook -C nfs_server.yaml
4.真正执行
ansible-playbook nfs_server.yaml
第5章 Ansible剧本高级特性-循环
1.官方地址
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html
2.使用场景
创建多个目录
复制多个目录
复制多个文件到不同的目录
不同的文件权限不一样
3.不使用循环复制多个文件
- name: create_data
file:
path: /data
state: directory
owner: www
group: www
- name: create_backup
file:
path: /backup
state: directory
owner: www
group: www
4.循环特性语法-单循环
第一步:找出需要替换的地方
第二步:将需要循环的地方替换成固定格式"{{ item }}"
第三步:和模块对其添加循环体loop
第四步:填写需要循环的内容
举例:
- name: 01-create
file:
path: "{{ item }}"
state: directory
owner: www
group: www
loop:
- /data
- /backup
5.循环特性语法-双循环
举例:
- name: Add several users
user:
name: "{{ item.姓名 }}"
groups: "{{ item.性别 }}"
loop:
- { 姓名: '李xx', 性别: '男' }
- { 姓名: '王xx', 性别: '男' }
练习:
命令行写法
ansible backup -m copy -a "src=rsyncd.conf dest=/etc/"
ansible backup -m copy -a "src=rsync.passwd dest=/etc/ mode=0600"
多循环写法
- name: 01-copy
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
loop:
- { src: 'rsyncd.conf', dest: '/etc/', mode: '0644' }
- { src: 'rsync.passwd', dest: '/etc/', mode: '0600' }
第6章 Ansible剧本高级特性-变量
1.应用场景
自定义某个变量,在任务中被多次引用
从主机收集到系统信息里提取某个变量,比如IP地址,主机名
2.自定义变量并引用---局部变量
命令行写法:
ansible backup -m copy -a "src=/root/rsync/conf/rsyncd.conf dest=/etc/"
ansible backup -m copy -a "src=/root/rsync/conf/rsync.passwd dest=/etc/ mode=0600"
剧本写法:
- name: test
hosts: web
vars:
data_path: "/data"
backup_path: "/backup"
tasks:
- name: 01-data
file:
path: "{{ data_path }}"
state: directory
- name: 02-backup
file:
path: "{{ backup_path }}"
state: directory
- name: 03-file
file:
path: "{{ data_path }}/file1.txt"
state: touch
- name: 04-file
file:
path: "{{ backup_path }}/file2.txt"
state: touch
3.全局变量--所有yaml都能直接用
第一步:在/etc/ansible/hosts里定义变量
[web]
10.0.0.[7:8] data_path="/mnt/data" backup_path="/mnt/backup"
第二步:在yaml剧本里直接使用变量
- name: test
hosts: web
tasks:
- name: 01-data
file:
path: "{{ data_path }}"
state: directory
- name: 02-backup
file:
path: "{{ backup_path }}"
state: directory
- name: 03-file
file:
path: "{{ data_path }}/file1.txt"
state: touch
- name: 04-file
file:
path: "{{ backup_path }}/file2.txt"
state: touch
第三步:在loop循环里引用变量
- name: test
hosts: web
tasks:
- name: 01-loop
file:
path: "{{ item.path }}"
mode: "{{ item.mode }}"
state: touch
loop:
- { path: "{{ data_path }}/file1.txt", mode: '0600' }
- { path: "{{ backup_path }}/file2.txt", mode: '0644' }
4.内置变量--直接可以用
查看内置变量
ansible 10.0.0.31 -m setup
使用变量获取主机的eth1地址和主机名
- hosts: web
tasks:
- name: get IP
shell: "echo {{ ansible_default_ipv4.address }} >> /tmp/ip.txt"
- name: get hostname
shell: "echo {{ ansible_hostname }} >> /tmp/hostname.txt"
第7章 剧本高级特性-注册变量
1.应用场景
调试,回显命令执行的内容
把状态保存成变量,其他任务可以进行判断或引用
2.使用内置变量将IP地址保存到文本里,并将文本内容显示出来
- hosts: all
tasks:
- name: echo IP
shell: "echo {{ ansible_default_ipv4.address }} >> /tmp/ip.txt"
- name: cat IP
shell: "cat /tmp/ip.txt"
register: ip_txt
- debug:
msg: "{{ ip_txt.stdout_lines }}"
3.如果配置文件发生了变化,就重启服务,否则不重启
- hosts: backup
tasks:
- name: 01-copy_conf
copy:
src: /opt/rsyncd.conf
dest: /etc/
register: conf_status # 注册变量
- name: 02-start
systemd:
name: rsyncd
state: started
enabled: yes
- name: 03-restart
systemd:
name: rsyncd
state: restarted
when: conf_status.changed # 判断变量状态是否发生改变
4.注册变量和判断场景
官方地址:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html
使用场景:
场景:
判断所有机器/tmp/下有没有ip.txt的文件
如果有,打印出来内容并且格式为:
例如:
web01 has ip.txt
内容为:
如果不存在:
输出内容:nfs is nofile
参考实现:
- name: Check for ip.txt and print content
hosts: all
tasks:
- name: Check if ip.txt exists
stat:
path: /tmp/ip.txt
register: ip_txt_stat
- name: Print content of ip.txt if it exists
shell: cat /tmp/ip.txt
register: ip_txt_content
when: ip_txt_stat.stat.exists
- name: Display the content of ip.txt
debug:
msg: "{{ inventory_hostname }} has ip.txt\n内容为:\n{{ ip_txt_content.stdout }}"
when: ip_txt_stat.stat.exists
- name: Output message if ip.txt does not exist
debug:
msg: "nfs is nofile"
when: not ip_txt_stat.stat.exists
第8章 Ansible剧本高级特性-服务状态管理
1.官方文档
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html
2.现在存在的问题
如果只有start,那么配置文件发生变化了并不会重启
如果只有restart,那么配置文件不管变没变化都会重启
3.我们期望的效果
第一次安装的时候 --> start
配置文件发生变化 --> restart
配置文件没发生变化 --> 不做任何操作
4.nfs剧本改写
- name: install nfs server
hosts: nfs_server
vars:
conf_path: "/root/yaml/nfs_server/conf/"
data_path: "/data"
backup_path: "/backup"
tasks:
- name: 01-yum
yum:
name: nfs-utils
state: present
- name: 02-groupadd
group:
name: www
gid: 1000
state: present
- name: 03-useradd
user:
name: www
uid: 1000
group: www
create_home: false
shell: /sbin/nologin
state: present
- name: 04-data
file:
path: "{{ item }}"
state: directory
owner: www
group: www
loop:
- "{{ data_path }}"
- "{{ backup_path }}"
- name: 05-config
copy:
src: "{{ conf_path }}/exports"
dest: /etc/
notify:
- Restart nfs
- name: 06-start
systemd:
name: nfs
state: started
enabled: true
handlers:
- name: Restart nfs
systemd:
name: nfs
state: restarted
5.注意
notify里写的任务名称一定要和handlers里的任务名称一模一样
handlers一定是在原本所有任务都执行完,最后才会执行handlers动作
第9章 Ansible剧本高级特性-选择tasks
1.应用场景
调试的时候
从某个任务开始往下依次执行
2.查看所有task列表
[root@m-61 ~/yaml/nfs_server]# ansible-playbook --list-tasks nfs_server.yaml
playbook: nfs_server.yaml
play #1 (nfs_server): install nfs server TAGS: []
tasks:
01-yum TAGS: []
02-groupadd TAGS: []
03-useradd TAGS: []
04-data TAGS: []
05-config TAGS: []
06-start TAGS: []
3.从某个指定的task开始执行
[root@m-61 ~/yaml/nfs_server]# ansible-playbook --start-at-task '05-config' nfs_server.yaml
PLAY [install nfs server] *************************************************************************************
TASK [Gathering Facts] ****************************************************************************************
ok: [10.0.0.31]
TASK [05-config] **********************************************************************************************
ok: [10.0.0.31]
TASK [06-start] ***********************************************************************************************
ok: [10.0.0.31]
PLAY RECAP ****************************************************************************************************
10.0.0.31 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
第10章 Ansible剧本高级特性-选择tag
1.查看tag标签
ansible-playbook --list-tasks nfs_server.yaml
2.选择指定的任务
ansible-playbook -t '05-config' nfs_server.yaml
ansible-playbook -t '01-yum,05-config,06-start' nfs_server.yaml
3.完整剧本
- name: install nfs server
hosts: nfs_server
vars:
conf_path: "/root/yaml/nfs_server/conf/"
tasks:
- name: 01-yum
yum:
name: nfs-utils
state: present
tags: 01-yum
- name: 02-groupadd
group:
name: www
gid: 1000
state: present
tags: 02-groupadd
- name: 03-useradd
user:
name: www
uid: 1000
group: www
create_home: false
shell: /sbin/nologin
state: present
tags: 03-useradd
- name: 04-data
file:
path: "{{ item }}"
state: directory
owner: www
group: www
loop:
- /data
- /backup
tags: 04-data
- name: 05-config
copy:
src: "{{ conf_path }}/exports"
dest: /etc/
notify:
- Restart nfs
tags: 05-config
- name: 06-start
systemd:
name: nfs
state: started
enabled: true
tags: 06-start
handlers:
- name: Restart nfs
systemd:
name: nfs
state: restarted
第x章 Ansible剧本-语法模板
- name: 剧本名称
hosts: 要执行的主机组
tasks:
- name: 第一个任务名称
模块1:
参数1: 参数的值
参数2: 参数的值
- name: 第二个任务名称
模块2:
参数1: 参数的值
参数2: 参数的值
第x章 总结
1.yaml语法格式
- 缩进表示层级关系
- :和-后面要有空格
2.循环
- 单个循环
- 多个循环
3.变量
- 局部变量
- 全局变量
4.服务状态管理
- notify
- handlers
5.选择任务
- task
- tags
6.检查
- 模拟执行
- 列出tasks
更新: 2024-11-25 16:31:12