Ansible Playbook
Ansible Playbook 使用 yaml 格式,有严格的对其要求,一个 playbook 由多个 play 组成。
Palybook 例子
---
- name: init # 定义 Playbook 的名字
hosts: all # 定义被控主机范围
tasks: # 定义要执行的任务,下边一个 - 对应一个任务(一个 - 表示一个列表)
- name: set hostname # 第一个任务的名称
ansible.builtin.hostname: # 第一个任务使用的模块
name: "{{ inventory_hostname }}.{{ host_search_name }}" # 模块选项
- name: dnf install package # 第二个任务名称
ansible.builtin.dnf: # 第二个任务使用的模块
name: # 模块选项
- bash-completion
- vim
- gcc
- make
- git
- wget
- tar
- bzip2
- unzip
- python3
- sysstat
state: present
- name: set hosts
ansible.builtin.template:
src: ./templates/hosts.j2
dest: /etc/hosts
owner: root
group: root
mode: '0644'
---
:表示 yaml 文件的文档分隔符,多个 yaml 文档可以放在一个文件里,用 ---
来做分隔
- name
:用于定义 Playbook 和 Play 的名称,类似于注释
hosts
:定义 Playbook 作用的主机范围
tasks
:定义 Playbook 的多个自动化任务,下边包含多个任务
YAML 对缩进有严格要求,比方说 - name
和 hosts
是一个等级(在一个列表),所以缩进是对齐的,tasks
下的 - name
和 ansible.builtin.hostname
是它的子项(是 tasks
下的列表),所以会多缩进两个空格(缩进以第一个字母算,不考虑 -
)。
- name: set hosts
ansible.builtin.template:
src: ./templates/hosts.j2
dest: /etc/hosts
owner: root
group: root
mode: '0644'
这个表示一个 play,play 的名字为 set hosts,使用的模块为 ansible.builtin.template
,模块使用的参数有 src
、dest
、owner
、group
、mode
。
Ansible Playbook 命令常用选项
- 可以通过
ansible-playbook
命令来执行 Playbook,通过-v
可以查看更详细的信息。-v
: 提供任务和主机状态的详细信息,但不包括变量值和详细调试信息。-vv
: 提供更详细的任务执行信息,包括变量值。-vvv
: 显示包括变量展开和任务详细信息在内的更多调试信息。-vvvv
: 显示所有调试信息,包括 HTTP 请求和响应的详细内容。
- 可以通过
--syntax-check
选项来对 Playbook 的格式进行检查 - 可以通过
--check
来执行 Playbook,但并不做实际的改变
Ansible Playbook 队列错误处理机制
Ansible Playbook 的机制是如果某个主机的某个 Play 执行错误,那么这个主机就会被移除执行队列,该主机相关的后续所有 Play 都不会执行。
有时候我们可能希望任务报错后节点继续执行后边的任务,这个时候可以使用 ignore_errors: yes
来实现。
- name: dnf install package
ansible.builtin.dnf:
name: sysstat
state: present
ignore_errors: yes
Ansible Handlers
Ansible Handlers 表示一组特殊的任务,它只会在特定的情况下才会被执行,例如配置 sssd 服务,可以通过 Ansible Handlers 来实现只有 sssd 服务的配置文件发生改变后才执行 sssd 服务的重启。
Ansible Handlers 有两个常用选项,notify、handlers 和 listen。
handlers:定义一些特殊任务,这些特殊任务在某种条件下才会被执行,执行条件和 notify
有关
notify:在某个 play 下追加 notify
后,表示这个 play 执行成功后并且做出修改后触发 handlers
的某个特殊任务
Ansible Handlers 例子
---
- name: set sssd
hosts: all
gather_facts: false
vars:
sssd_packages:
- sssd
- sssd-tools
- oddjob
- oddjob-mkhomedir
- libsss_sudo
tasks:
- name: install packages
ansible.builtin.yum:
name: "{{ sssd_packages }}"
state: present
- name: set sssd.conf
ansible.builtin.template:
src: templates/sssd.conf.j2
dest: /etc/sssd/sssd.conf
mode: '0600'
owner: root
group: root
notify: set_pam_and_service
- name: set oddjob service
ansible.builtin.systemd:
name: oddjobd
state: started
enabled: true
handlers:
- name: set authselect
ansible.builtin.command: "authselect select sssd with-sudo with-mkhomedir --force"
listen: set_pam_and_service
- name: set sssd service
ansible.builtin.systemd:
name: sssd
state: restarted
listen: set_pam_and_service
在这个 Playbook 中,在名为 set sssd.conf 的 Play 下定义了一个 notify
,notify
的名字为 set_pam_and_service,然后在 handlers
中定义了两个 Play,分别是 set authselect 和 set sssd service,这两个 Play 都一个 listen
选项,listen
的内容均为 set_pam_and_service,这个实现的结果就是当 set sssd.conf 执行成功且做出改变之后就会触发 set authselect 和 set sssd service 这两个任务,当 set sssd.conf 没有做出改变时,set authselect 和 set sssd service 这两个任务会直接被跳过。
上述例子里是一个 Play 触发两个
handlers
的 Play,如果handlers
里被触发的 Play 只有一个,那么可以不用listen
,可以直接将handlers
里 Play 的name
设置为和notify
内容相同。(如果handlers
里多个 Play 的名字为 set_pam_and_service,那么只有第一个 Play 会被执行)--- - name: set sssd hosts: all gather_facts: false tasks: - name: set sssd.conf ansible.builtin.template: src: templates/sssd.conf.j2 dest: /etc/sssd/sssd.conf mode: '0600' owner: root group: root notify: set_pam_and_service handlers: - name: set_pam_and_service ansible.builtin.systemd: name: sssd state: restarted
强制执行 handlers
Ansible 的机制是如果某个主机的某个 Play 执行错误,那么这个主机就会被移除执行队列,该主机相关的后续所有 Play 都不会执行,所以为了保证 handlers
能够正常执行,可以添加 force_handlers: true
选项,这样无论是否有错误任务产生 handlers
都会正常执行。
---
- name: set sssd
hosts: all
gather_facts: false
force_handlers: true
tasks:
...