Ansible Playbooks

文章目录
  1. 1. Playbooks简介
  2. 2. Playbooks Demo
  3. 3. 入门实例
  4. 4. 角色
  5. 5. 简单编程
    1. 5.1. 变量
    2. 5.2. 基本循环
    3. 5.3. 循环字典
    4. 5.4. 嵌套循环
    5. 5.5. 散列循环
    6. 5.6. 文件循环
    7. 5.7. 命令循环
    8. 5.8. 条件判断
  6. 6. 后记
  7. 7. 书签

Playbooks简介

与ad-hoc任务执行模式相比,Playbooks使用ansible是一种完全不同的方式,并且功能特别强大。

简而言之,playbooks是真正简单的配置管理和多机器部署系统的基础,与已有的系统不同,并且非常适合部署复杂的应用程序。

Playbooks可以声明配置,但它们也可以协调任何手动有序流程的步骤,即使不同的步骤必须按照特定顺序在机器组之间来回跳转。它们可以同步或异步启动任务。
更多playbooks的介绍参考官方文档

Playbooks以YAML格式表示(请参阅YAML语法),具有最少的语法,它不是编程语言或脚本,而是配置或进程的模型。

每个剧本由列表中的一个或多个“戏剧”组成。戏剧的目标是将一组主机映射到一些定义明确的角色,由ansible调用任务表示。在基本级别,任务只不过是对ansible模块的调用(请参阅使用模块)。

通过编写多个“戏剧”的剧本,可以编排多机部署,在Web服务器组中的所有计算机上运行某些步骤,然后在数据库服务器组上执行某些步骤,然后在Web服务器组上执行更多命令,等等。。

你可以有很多戏剧影响你的系统做不同的事情。这并不是说你只是定义了一个特定的状态或模型,而是可以在不同的时间运行不同的戏剧。

Playbooks Demo

以下是只包含一个戏剧的剧本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
- name: write the apache config file
template:
src: /srv/httpd.j2
dest: /etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running
service:
name: httpd
state: started
handlers:
- name: restart apache
service:
name: httpd
state: restarted

  • 文件开头三个横杠代表yaml文件。
  • hosts表示一个主机组。
  • tasks表示动作集合。
  • name是一个注释说明。
  • yum和下面两行,表示使用yum安装最新版的httpd。
  • template和下面两行,表示使用ansible的template模块传输/srv/httpd.j2作为客户机的/etc/httpd.conf。和copy相比,template支持jinja语法。
  • notify和下面一行,表示传输成功后触发重启apache命令。它需要和handlers组合使用。
  • handlers中的name和notify中的信息要完全相同。service和下面两行,表示重启httpd。

Playbooks可以包含多个戏剧。您可能有一个首先针对Web服务器,然后是数据库服务器的playbook。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
---
- hosts: webservers
remote_user: root

tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
- name: write the apache config file
template:
src: /srv/httpd.j2
dest: /etc/httpd.conf

- hosts: databases
remote_user: root

tasks:
- name: ensure postgresql is at the latest version
yum:
name: postgresql
state: latest
- name: ensure that postgresql is started
service:
name: postgresql
state: started

入门实例

目标:编写一个playbook,在客户机上安装chrony,然后检查启动情况。

1、新建chrony.yml,内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
---
- hosts: commonservers
tasks:
- name: install chrony
apt:
name: chrony
state: latest
notify:
- restart chrony
- name: ensure chrony is running
service:
name: chrony
state: started
handlers:
- name: restart chrony
service:
name: chrony
state: restarted

上面的playbook中用到了apt模块,如果有疑问可以查看帮助,ansible-doc apt。实际上,有一种更加简单的写法,就是把apt模块换成command模块,然后直接写命令。

2、检查playbook
ansible-playbook chrony.yml --syntax-check

3、以sudo权限执行playbook
ansible-playbook chrony.yml --user=voidking --private-key=/home/voidking/.ssh/id_rsa -s

4、在客户机测试
chronyc sources

角色

如果需要将一个大文件拆分为各个小文件,我们经常使用的就是include,这也是原先ansible拆分文件的做法。如今ansible使用roles来拆分文件,将nginx、mysql等分为各个角色,在各个角色内定义具体的小任务,方便管理。另一方面,类似于php类的自动加载,roles基于一个已知的文件结构,可以自动去加载某些vars_files、tasks、handlers等。

目标:使用角色的方式,编写配置playbook,在客户机上安装chrony,然后检查启动情况。

1、创建chrony角色目录
mkdir -p roles/chrony/tasks

mkdir -p roles/chrony/handlers

2、创建总的入口文件site.yml,内容为:

1
2
3
4
---
- hosts: commonservers
roles:
- chrony

3、创建安装剧本
vim roles/chrony/tasks/main.yml,内容为:

1
2
3
4
5
6
7
8
9
10
11
---
- name: install chrony
apt:
name: chrony
state: latest
notify:
- restart chrony
- name: ensure chrony is running
service:
name: chrony
state: started

vim roles/chrony/handlers/main.yml,内容为:

1
2
3
4
5
---
- name: restart chrony
service:
name: chrony
state: restarted

4、以sudo权限执行playbook
ansible-playbook site.yml --user=voidking --private-key=/home/voidking/.ssh/id_rsa -s

5、在客户机测试
chronyc sources

简单编程

变量

1
2
3
4
5
6
7
8
9
10
11
12
13
---
- hosts: commonservers
vars:
pre1: all info is
pre2: hostname is
tasks:
- name: register vars
shell: hostname
register: info
- name: display info
debug: msg="{{pre1}} {{info}}"
- name: display hostname
debug: msg="{{pre2}} {{info.stdout}}"

基本循环

1
2
3
4
5
6
7
8
9
---
- hosts: commonservers
tasks:
- name: loops demo
debug: msg="{{item}}"
with_items:
- one
- two
- three

循环字典

1
2
3
4
5
6
7
8
9
---
- hosts: commonservers
tasks:
- name: loops dict
debug: msg="key -> {{item.key}},value -> {{item.value}}"
with_items:
- {key: 1, value: "one"}
- {key: 2, value: "two"}
- {key: 3, value: "three"}

嵌套循环

1
2
3
4
5
6
7
8
---
- hosts: commonservers
tasks:
- name: loops2
debug: msg="item0 -> {{item[0]}},item1 -> {{item[1]}}"
with_nested:
- ['1','2']
- ['one','two','three']

散列循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
- hosts: commonservers
vars:
user:
voidking:
name: voidking
tel: 17600000000
haojin:
name: haojin
tel: 15100000000
tasks:
- name: loops3
debug: msg="key -> {{item.key}},value -> {{item.value}}"
with_dict:
- "{{user}}"

文件循环

1
2
3
4
5
6
7
---
- hosts: commonservers
tasks:
- name: loop file
debug: msg="{{item}}"
with_fileglob:
- /home/voidking/*.yml

命令循环

1
2
3
4
5
6
7
8
9
10
11
---
- hosts: commonservers
tasks:
- name: exec command
shell: "{{item}}"
with_items:
- hostname
- uname
register: ret
- name: display result
debug: msg="{% for i in ret.results %} {{i.stdout}} {% endfor %}"

条件判断

ansible的条件判断使用关键字when,有两种方式:

  • python语法支持的原生态格式 conditions > 1 or conditions == “ss”,in,not等等
  • ansible Jinja2 filters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---
- hosts: commonservers
vars:
pre: hostname is
tasks:
- name: register vars
shell: hostname
register: info
- name: display hostname
debug: msg="{{pre}} {{info.stdout}}"
- name: print true
debug: msg="result is ubuntu14"
when: info.stdout == "ubuntu14"
- name: print false
debug: msg="result is not ubuntu14"
when: info.stdout != "ubuntu14"
- name: print warning
debug: msg="client OS is ubuntu"
when: info['stdout'].startswith('u')

后记

至此,playbooks最基础的东西学习完毕。更高级的用法,在使用中再慢慢学习。

书签

Ansible Documentation

Ansible中文权威指南

Ansible精讲