一、基本结构
用于安装或升级 apache 服务的 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
vars:
http_port: 80
max_clients: 200
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
target
target 部分用于指定执行 playbook 任务时面向的目标主机和远程用户。1
2
3
- hosts: webservers
remote_user: root
远程用户也可以在特定的 task
中额外进行定义:1
2
3
4
5
6
7
- hosts: webservers
remote_user: root
tasks:
- name: test connection
ping:
remote_user: yourname
执行任务时允许远程用户通过 sudo
提升权限:1
2
3
4
5
- hosts: webservers
remote_user: yourname
become: yes
become_method: sudo
执行任务时切换到其他用户身份:1
2
3
4
5
- hosts: webservers
remote_user: yourname
become: yes
become_user: postgres
variable
variable 部分用于定义变量,作用域为当前 play。1
2
3vars:
http_port: 80
max_clients: 200
通过 vars_files
定义变量:1
2
3
4vars_files:
conf/country-AU.yml
conf/datacenter-SYD.yml
conf/cluster-mysql.yml
交互式地从用户输入中获取变量的值。如将用户输入赋值给变量 https_passphrase
:1
2
3
4vars_prompt:
- name: https_passphrase
prompt: Key Passphrase
private: yes
task
task 部分包含了一系列我们希望在目标机器上执行的动作。1
2
3
4
5tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
handler
handler 与 task 有着相同的语法和类似的功能。但是 handler 只可以在特定的条件下由 task 调用后执行。
如配置文件替换成功后触发重启服务的动作:1
2
3
4
5
6
7
8
9
10
11
12tasks:
- name: copy the DHCP config
copy:
src: dhcp/dhcpd.conf
dest: /etc/dhcp/dhcpd.conf
notify: restart dhcp
handlers:
- name: restart dhcp
service:
name: dhcpd
state: restarted
可以在单个 task 中同时调用多个 handler: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
27
- hosts: qroud
tasks:
- name: checkout Qroud
git:
repo:git@github.com:smarthall/Qroud.git
dest: /opt/apps/Qroud force=no
notify:
- migrate db
- generate static
- restart httpd
handlers:
- name: migrate db
command: ./manage.py migrate –all
args:
chdir: /opt/apps/Qroud
- name: generate static
command: ./manage.py collectstatic -c –noinput
args:
chdir: /opt/apps/Qroud
- name: restart httpd
service:
name: httpd
state: restarted
二、playbook 模块
template
template
模块一般用于定义配置文件的主体框架,并为 Ansible 中的变量预留好位置以便在需要时渲染。类似于 Flask 应用依据模板文件动态地生成 HTML 文档。
其模板功能由 Jinja2 提供,支持条件语句、for 循环和宏等高级语法。1
2
3{% for ip in ansible_all_ipv4_addresses %}
{{ ip }};
{% endfor %}
1 | tasks: |
pause
pause
模块会将执行中的 playbook 暂停一段时间。比如部署了一个新版本的 web 应用,需要用户手动确认一切正常才能继续执行后面的任务。1
2
3
4
5
6
7
8
9
- hosts: localhost
tasks:
- name: wait on user input
pause:
prompt: "Warning! Press ENTER to continue or CTRL-C to quit."
- name: timed wait
pause:
seconds: 30
wait_for
等待某个特定的 TCP 端口可以被远程主机访问连通。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- hosts: webapps
tasks:
- name: Install Tomcat
yum:
name: tomcat7
state: latest
- name: Start Tomcat
service:
name: tomcat7
state: started
- name: Wait for Tomcat to start
wait_for:
port: 8080
state: started
group_by
group_by
模块可以在 task 中基于收集到的 facts 信息动态地对 hosts 进行分组。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- name: Create operating system group
hosts: all
tasks:
- group_by: key=os_{{ ansible_distribution }}
- name: Run on CentOS hosts only
hosts: os_CentOS
tasks:
- name: Install Apache
yum: name=httpd state=latest
- name: Run on Ubuntu hosts only
hosts: os_Ubuntu
tasks:
- name: Install Apache
apt: pkg=apache2 state=latest
三、Playbooks 进阶
Looping
1 | tasks: |
条件语句
1 |
|
1 | # Copy a file to the remote server if the hosts file doesn't exist |
1 | # Downgrade PHP version if the current version contains '7.0'. |
注册变量
1 | - name: Using register |
debug
查看变量的值:1
2
3
4- name: capture output of id command
command: id -un
register: login
- debug: msg="Logged in as user {{ login.stdout }}"
filter
Jinja2 模板提供的 filter 功能可以将原始数据转换为用户需要的格式1
2
3
4
5
6
7
8
9
10
11
12
- name: Create user accounts
hosts: all
vars:
users:
tasks:
- name: Create accounts
user: name={{ item|lower }} state=present
with_items:
- Fred
- John
- DanielH
常用 filter:
min
:参数为列表,返回列表中最小的项目max
:参数为列表,返回列表中最大的项目random
:参数为列表,随机返回列表中的某个值default(x)
:指定变量不存在时,以 x 为该变量的默认值unique
:参数为列表,返回该列表去除重复项后的版本replace(x, y)
:将字符串中出现的所有 x 替换为 yjoin(x)
:参数为列表,返回由 x 拼接所有列表项后形成的字符串
针对文件路径的常用 filter:
basename
:返回路径中包含的文件名dirname
:返回文件所在的目录expanduser
:将路径中包含的~
替换为 home 目录realpath
:文件的真实路径
1 | vars: |
Lookup
lookups 允许 Ansible 从多种类型的源头(如文本文档、CSV 文件等)读取配置数据。
file:读取文本文件内容作为参数1
2- name: Add my public key as an EC2 key
ec2_key: name=mykey key_material="{{ lookup('file', '/Users/lorin/.ssh/id_rsa.pub') }}"
pipe:在远程机器上执行某个外部程序并关联其标准输出1
2- name: get SHA of most recent commit
debug: msg="{{ lookup('pipe', 'git rev-parse HEAD') }}"
env:获取远程机器上的某个环境变量1
2- name: get the current shell
debug: msg="{{ lookup('env', 'SHELL') }}"
password:生成随机密码,并将该密码写入指定文件1
2
3
4- name: create deploy postgres user
postgresql_user:
name: deploy
password: "{{ lookup('password', 'deploy-password.txt') }}"
redis-kv:获取 redis 服务器上某个 key 的值(需要在远程机器上安装 redis
Python 库)1
2- name: look up value in Redis
debug: msg="{{ lookup('redis_kv', 'redis://localhost:6379,weather') }}"
复杂循环
名称 | 输入 | 循环规则 |
---|---|---|
with_items | 列表 | 遍历所有列表项 |
with_lines | 命令 | 遍历命令输出的所有行 |
with_fileglob | Glob | 遍历文件(文件名可使用通配符) |
with_first_found | 路径列表 | 路径中检索到的第一个文件目标 |
with_dict | 字典 | 遍历字典中的数据项 |
with_flattened | 多层列表 | 遍历展开后的多层列表 |
with_inventory | Host 模式 | 遍历匹配的主机 |
with_lines:1
2
3
4
5# files/turing.txt
Leslie Lamport
Silvio Micali
Shafi Goldwasser
Judea Pearl
1 | - name: Send out a slack message |
with_fileglob:1
2
3
4
5- name: add public keys to account
authorized_key: user=deploy key="{{ lookup('file', item) }}"
with_fileglob:
- /var/keys/*.pub
- keys/*.pub
with_dict:1
2
3- name: iterate over ansible_eth0
debug: msg={{ item.key }}={{ item.value }}
with_dict: "{{ ansible_eth0.ipv4 }}"