|
task
- name : 可选配置, 用于提示task 的功能. 另, ansible-playbook --start-at-task 可以调用 name, 从 task 的中间开始执行.
- 模块(功能) : 必选配置, 有模块的名称组成的 key 和 模块参数组成的 value.
从 Ansible 前段所使用的 YAML 解析器角度看, 参数将被按照字符串处理, 而不是字典
apt: name=nginx update_cache=yes
- 复杂参数:
ansible 提供一个将模块调用分隔成多行的选择, 可以传递 key 为变量名的字典, 而不是传递字符串参数. 这种方式, 在调用拥有复杂参数的模块时, 十分有用. 如 ec2 模块.
- name: install pip pkgs pip:
name: "{{ item.name }}"
version: "{{ item.version }}"
virtualenv: "{{ venv_path }}"
with_items:
- {name: mazzanine, version: 3.1.10}
- {name: gunicorn, version: 19.1.1}
- environment : 设置环境变量
传入包含变量名与值的字典, 来设置环境变量.
- name: set the site>script: scripts/setsite.py environment:
PATH: "{{ venv_path }}/bin"
PROJECT_DIR: "{{ proj_path }}"
ADMIN_PASS: "{{ admin_pass }}"
- sudo, sudo_user
- notify
触发 handler 任务.
- when
当 when 表达式返回 True 时, 执行该 task , 否则不执行.
- local_action : 运行本地任务
在控制主机本机上(而目标主机)执行命令.
如果目标主机为多台, 那么, local_action 执行的task 将执行多次, 可以指定 run_once , 来限制 local_action 的执行次数.
# 调用 wait_for 模块 : 注: inventory_hostname 的值仍然是远程主机, 因为这些变量的范围仍然是远程主机, 即使 task 在本机执行.
- name: wait for ssh server to be running
local_action: wait_for port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH
# 调用 command 模块
- name: run local cmd
hosts: all
gather_facts: False
tasks:
- name: run local shell cmd
local_action: command touch /tmp/new.txtxt
- delegate_to: 在涉及主机之外的主机上运行 task
使用场景:
- 在报警主机中, 启用基于主机的报警, 如 Nagios
- 向负载均衡器中, 添加一台主机, 如 HAProxy
# 配置 Nagios 示例, inventory_hostname 仍然指 web 主机, 而非 nagios_server.example.com .
- name: enable alerts for web servers
hosts: web
tasks:
- name: enable alerts
nagios: action=enanle_alerts service=web host={{ inventory_hostname }}
delegate_to: nagios_server.example.com
---
# This playbook does a rolling update for all webservers serially (one at a time).
# Change the value of serial: to adjust the number of server to be updated.
#
# The three roles that apply to the webserver hosts will be applied: common,
# base-apache, and web. So any changes to configuration, package updates, etc,
# will be applied as part of the rolling update process.
#
# gather facts from monitoring nodes for iptables rules
- hosts: monitoring
tasks: []
- hosts: webservers
serial: 1
# These are the tasks to run before applying updates:
pre_tasks:
- name: disable nagios alerts for this host webserver service
nagios: 'action=disable_alerts host={{ inventory_hostname }} services=webserver'
delegate_to: "{{ item }}"
with_items: groups.monitoring
- name: disable the server in haproxy
haproxy: 'state=disabled backend=myapplb host={{ inventory_hostname }} socket=/var/lib/haproxy/stats'
delegate_to: "{{ item }}"
with_items: groups.lbservers
roles:
- common
- base-apache
- web
# These tasks run after the roles:
post_tasks:
- name: wait for webserver to come up
wait_for: 'host={{ inventory_hostname }} port=80 state=started timeout=80'
- name: enable the server in haproxy
haproxy: 'state=enabled backend=myapplb host={{ inventory_hostname }} socket=/var/lib/haproxy/stats'
delegate_to: "{{ item }}"
with_items: groups.lbservers
- name: re-enable nagios alerts
nagios: 'action=enable_alerts host={{ inventory_hostname }} services=webserver'
delegate_to: "{{ item }}"
with_items: groups.monitoring
- run_once : 值为 True/False
该 task 是否只运行一次, 与 local_action 配合十分好用.
- changed_when & failed_when
使用 changed_when 和 failed_when 语句改变 Ansible 对 task 是 chenged 状态还是 failed 状态的认定.
需要了解命令的输出结果
- name: initialize the database django_manage:
command: createdb --noinput --nodata
app_path: "{{ proj_path }}"
virtualenv: "{{ venv_path }}"
register: result
changed_when: not result.failed and "Creating tables" in result.out
failed_when: result.failed and "Database already created" not in result.msg
- 循环
playbook 执行后, 跟踪主机状态.
play
play 可以想象为连接到主机(host)上执行任务(task)的事务.
选项:
- host : 必选配置, 需要配置的一组主机
- task : 必选配置, 需要在主机上执行的任务
- name : 可选配置, 一段注释, 用来描述 play 的功能, ansible 在 play 开始执行的时候, 会把 name 打印出来.
- sudo : 可选配置, 如果为真, ansible 会在运行每个 task 的时候, 都是用 sudo 命令切换为 (默认) root.
- vars : 可选配置, 变量与其值组成的列表. 任何合法的 YAML 对象都可以作为变量的值. 变量不仅可以在 tasks 中使用, 还可以在 模板文件 中使用.
- vars_files : 可选, 把变量放到一个或者多个文件中.
- gather_facts : 是否收集 fact.
- handlers : 可选, ansible 提供的 条件机制, 和 task 类似, 但只有在被 task 通知的时候才会运行. 如果 ansible 识别到 task 改变了系统的状态, task 就会触发通知机制. task 将 handler 的名字作为参数传递, 依此来通知 handler.
handler 只会在所有任务执行完成之后执行, 而且即使被通知了多次, 也只会执行一次. handler 按照play 中定义的顺序执行, 而不是被通知的顺序.
handler 常见的用途就是重启服务和重启服务器.
- serial, max_fail_percentage
默认情况下, Ansible 会并行的在所有相关联主机上执行每一个 task.
可以使用 serial 限制并行执行 play 的主机数量.
一般来说, 当 task 失败时, Ansible 会停止执行失败的那台主机上的任务, 但是继续对其他主机执行. 在负载均衡场景中, 可能希望 Ansible 在所有主机都发生失败前让整个 play 停止执行, 否则将会导致, 所有主机都从 负载均衡器上移除, 并且全部执行失败, 最终负载均衡器上没有任何主机的局面. 此时, 可以使用 serial 和 max_fail_percentage 语句来指定, 最大失败主机比例达超过 max_fail_percentage 时, 让整个 play 失败.
如果希望 Ansible 在任何主机出现 task 执行失败的时候, 都放弃执行, 则需要设置max_fail_percentage=0.
- name: upgrade packages on servers behind load balancer hosts: myhosts
serial: 1
max_fail_percentage: 25
tasks:
- name: get the ec2 instance> ec2_facts:
- name: task the out of the elastic load balancer
local_action: ec2_elb
args:
instance_id: "{{ ansible_ec2_instance_id }}"
state: absent
- name: upgrade packages
apt: update_cache=yes upgrade=yes
- name: put the host back in the elastic load balancer
local_action: ec2_elb
args:
instance_id: "{{ ansible_ec2_instance_id }}"
state: present
ec2_elbs: "{{ item }}"
with_items: ec2_elbs
- roles
- pre-task
- post-task
role
role 是将 playbook 分隔为多个文件的主要机制, 他大大简化了复杂 playbook 的编写, 同时使得 role 更加易于复用.
role 的基本构成.
每个 role 都会用一个名字, 如 'database', 与该 role 相关的文件都放在 roles/database 目录下. 其结构如下: 每个单独文件都是可选的
- task:
task 定义
roles/database/tasks/main.yml
- files
需要上传到目标主机的文件:
roles/database/files/
- templates
Jinja2 模板文件
roles/database/templates
- handlers
handler
roles/database/handler/main.yml
- vars
不应被覆盖的变量
roles/database/vars/main.yml
- defaults
可以被覆盖的默认变量
roles/database/default/main.yml
- meta
role 的依赖信息
roles/database/meta/main.yml
default 变量与 vars 变量:
- default : 希望在 role 中变更变量的值.
- vars : 不希望变量的值变更.
role 中变量命名的一个良好实践: 变量建议以 role 的名称开头, 因为在 Ansible 中不同的 role 之间没有命名空间概念, 这意味着在其他 role 中定义的变量, 或者再 playbook 中其他地方定义的变量, 可以在任何地方被访问到. 如果在两个不同的 role 中使用了同名的变量, 可能导致意外的行为.
role 的存放位置
- playbook 并列的 roles 目录下;
- /etc/ansible/roles/ 下
- ansible.cfg 中 default 段 roles_path 指向的位置
- 环境变量 ANSIBLE_ROLES_PATH 指向的位置
在 playbook 中使用 role
# mezzaning-single-host.yml
- name: deploy mezzanine on vagrant
hosts: web
vars_file:
- secrets.yml
roles:
- role: database
database_name: "{{ mezzanine_proj_name }}" # 定义覆盖变量
database_pass: "{{ mezzanine_proj_name }}" # 定义覆盖变量
- role: mezzanine
live_hostname: 192.168.33.10.xip.io
domains:
- 192.168.33.10.xip.io
- www.192.168.33.10.xip.io
# mezzaning-across-host.yml
- name: deploy postgres vagrant
hosts: db
vars_files:
- secrets.yml
roles:
- role: database
database_name: "{{ mezzanine_proj_name }}" # 定义覆盖变量
database_pass: "{{ mezzanine_proj_name }}" # 定义覆盖变量
- name: deploy mezzanine on vagrant
hosts: web
vars_files:
- secrets.yml
roles:
- role: mezzanine
database_host: "{{ hostvars.db.ansible_eth1.ipv4.address }}"
live_hostname: 192.168.33.10.xip.io
domains:
- 192.168.33.10.xip.io
- www.192.168.33.10.xip.io
pre-task & post-task
pre-task : 定义在 role 执行之前, 执行的 task
post-task : 定义在 role 执行之后, 执行的 task.
- name: deploy mezzanine on vagrant hosts: web
vars_files:
- secrets.yml
pre_tasks:
- name: update the apt cache
apt: update_cache=yes
roles:
- role: mezzanine
database_host: "{{ hostvars.db.ansible_eth1.ipv4.address }}"
live_hostname: 192.168.33.10.xip.io
domains:
- 192.168.33.10.xip.io
- www.192.168.33.10.xip.io
post_tasks:
- name: notify Slack that the servers have been updated
local_action:>
slack
domain=acme.slack.com
token={{ slack_token }}
msg="web server {{ inventory_hostname }} configured"
inclued
用于调用位于同一目录下的其他 定义文件, 可用于 Tasks,Playbook, Vars, Handler, Files 等.
# task example
---
- name: install apt packages
apt: pkg={{ item }} update_cache=yes cache_valid_time=3600
sudo: True
with_items:
- git
- libjpeg-dev
- libpq-dev
- memcached
- nginx
- include: django.yml
- include: nginx.yml
# example 2
---
- name: check host environment
include: check_environment.yml
- name: include OS family/distribution specific variables
include_vars: "{{ item }}"
with_first_found:
- "../defaults/{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml"
- "../defaults/{{ ansible_distribution | lower }}.yml"
- "../defaults/{{ ansible_os_family | lower }}.yml"
- name: debug variables
include: debug.yml
tags:
- debug
ansible-galaxy : 创建 role 初始文件和目录
- 创建初始 role 文件和目录
$ ansible-galaxy init -p playbook/roles web -p /path/to/roles : 指定 roles 的目录, 未指定则为当前目录.
- 从 role 仓库中检索, 安装,删除 role.
ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options]
- 检索
$ ansible-galaxy search ntp
- 安装
$ ansible-galaxy install -p ./roles bennojoy.ntp
- 列出
$ ansible-galaxy list
- 删除
$ ansible-galaxy remove bennojoy.ntp
- 在线网站 https://galaxy.ansible.com
dependent role:
dependent role 用于指定 role 依赖的其他一个或多个 role, Ansible 会确保被指定依赖的role 一定会优先被执行.
Ansible 允许向 dependent role 传递参数
dependent role 一般在 myrole/meta/main.yml 中指定.
# roles/web/meta/main.yml
dependencies:
- { role: ntp, ntp_server=ntp.ubuntu.com }
- { role: common }
- { role: memcached }
playbook : 用于实现 ansible 配置管理的脚本.
playbook 其实就是一个字典组成的列表. 一个 playbook 就是一组 play 组成的列表. 一个 play 由 host 的无序集合与 task 的有序列表组成. 每一个 task 由一个模块构成.
ansible 中的 True/False 和 yes/no
模块参数(如 update_cache=yes)对于值的处理, 使用字符串传递:
- 真值
yes,on,1,true
- 假值
no,off,0,false
其他使用 YAML 解析器来处理:
- 真值
true,True,TRUE,yes,Yes,YES,on,On,ON,y,Y
- 假值
false,False,FALSE,no,No,NO,off,Off,OFF,n,N
推荐做法:
- 模块参数: yes/no
- 其他地方: True,False
playbook 文件的执行方法:
- 使用 ansible-playbook 命令
$ ansible-playbook myplaybook.yml
- shebang
$ chmod +x myplaybook.yml
$ head -n 1 myplaybook.yml
#!/usr/bin/env ansible-playbook
$ ./myplaybook.yml
当 Ansible 开始运行 playbook 的时候, 他做的第一件事就是从他连接到的服务器上收集各种信息. 这些信息包括操作系统,主机名,网络接口等.
建立 nginx web 服务器
$ cat web-notls.yml
- name: Configure webserver with nginx and tls
hosts: webservers
sudo: true
vars:
key_file: /etc/nginx/ssl/nginx.key
cert_file: /etc/nginx/ssl/nginx.crt
conf_file: /etc/nginx/sites-available/default
server_name: localhost
tasks:
- name: install nginx
apt: name=nginx update_cache=yes cache_valid_time=3600
- name: create directories for ssl certificates
file: path=/etc/nginx/ssl state=directory
- name: copy TLS key
copy: src=files/nginx.key desc={{ key_file }} owner=root mode=06--
notify: restart nginx
- name: copy TLS certificate
copy: src=files/nginx.crt dest={{ cert_file }}
notify: restart nginx
- name: copy nginx config file
copy: src=files/nginx.conf.j2 dest={{ conf_file }}
notify: restart nginx
- name: enable configuration
file: dest=/etc/nginx/sites-enabled/default src={{ conf_file }} state=link
notify: restart nginx
- name: copy index.html
template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html mode=0644
handlers:
- name: restart nginx
service: name=nginx state=restarted
内部变量
- ansible_managed : 和模板文件生成时间相关的信息.
inventory 文件
使用 .ini 格式, 默认为 hosts 文件.
[webservers]
testserver ansible_ssh_host=127.0.0.1 ansible_ssh_port=22
YAML 文件格式
- 文件开始.
---
如果没有---标记, 也不影响 ansible 的运行.
- 注释: #
- 字符串 : 即使字符串中有空格, 也无需使用引号.
- 布尔型 : 有多种, 推荐使用 True/False
- 列表: 使用-作为分隔符
- 标准列表
- My Fair Lady
- Oklahoma
- The Pirates of Penzance
- 内联式列表
[My Fair Lady, Oklahoma, The Pirates of Penzance]
- 字典:
- 标准字典
name: tom
age: 12
job: manager
- 内联式字典
{name: tom, age: 12, job: manager}
- 折行: 使用大于号(>)表示折行
|
|