playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联合起来按事先编排的机制完成某一任务。
playbook 分为四大任务块:
Target section: 定义将要执行playbook的远程主机组。
Variable section: 定义playbook运行时需要使用的变量。
Task section: 定义将要在远程主机上执行的任务列表。
Handler section: 定义task执行完成以后需要调用的任务。
一个完整的例子:
1 2 3 4 5 6 7 8 9 10 11 - hosts: mfs_node user: root vars: - motd_warning: 'WARNING: Use by ACME Employees ONLY' tasks: - name: setup a MOTD copy: dest=/etc/motd content="{{ motd_warning }}" notify: say someting handlers: - name: say someting command: echo "copy OK"
命令行执行 1 2 3 ansible-playbook -i inventory/devlop site.yaml ansible-playbook -i inventory/devlop site.yaml -l linux-node2 ansible-playbook -i inventory/devlop -e target=gsg_tmp -e role=php56 role.yml
ansible-playbook 常用参数
-C :只显示哪些有变更,但是不执行任何参数。
-D: 通常和-C参数一起使用,显示变化的内容。
-t:匹配tags。
-e: 增加扩展的参数。
-v: 显示详细内容。
-vvv: 显示更详细的内容。
Target section
hosts:定义远程的主机组。
user:执行该任务组的用户。
remote_user:与user相同。
sudo:如果设置为yes,执行该任务组的用户在执行任务的时候,获取root权限。
sudo_user:如果你设置user为tom,sudo为yes,sudo_user为jerry,则tom用户则会获取jerry用户的权限。
connection:通过什么方式连接到远程主机,默认为ssh。
gather_facts:除非你明确说明不需要在远程主机上执行setup模块,否则默认会自动执行。如果你确实不需要setup模块所传递过来的变量,你可以启用该选项。
Variable section vars vars_files vars_prompt setup
Task section task任务的编写方法 1 2 3 4 5 6 7 8 9 10 11 tasks: - name: install apache action: yum name=httpd state=installed #第一种方法 - name: configure apache copy: src=files/httpd.conf dest=/etc/httpd/conf/httpd.conf #第二种方法 - name: restart apache service: name: httpd state: restarted #第三种方法
task任务中的常用模块 template template模块是Ansible中最常用的模块之一。它可以让你设计一个框架式的配置文件,如何把Anisble需要的值插入到合适的位置。其中Jinja2模板尤为复杂,其中可以包含条件、循环、宏。
1 2 3 tasks: - name: copy config file to remote server template: src=named.conf.j2 dest=/etc/named.conf
named.conf.j2 模板的内容
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 28 29 30 31 32 33 34 35 36 37 38 39 # {{ ansible_managed }} options { listen-on port 53 { 127.0.0.1; {% for ip in ansible_all_ipv4_addresses %} {{ ip }}; {% endfor %} }; listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; }; zone "." IN { type hint; file "named.ca"; }; include "/etc/named.rfc1912.zones"; include "/etc/named.root.key"; {# Variables for zone config #} {% if 'authorativenames' in group_names %} {% set zone_type = 'master' %} {% set zone_dir = 'data' %} {% else %} {% set zone_type = 'slave' %} {% set zone_dir = 'slaves' %} {% endif %} zone "internal.example.com" IN { type {{ zone_type }}; file "{{ zone_dir }}/internal.example.com"; {% if 'authorativenames' not in group_names %} masters { 192.168.2.2; }; {% endif %} };
set_fact set_fact模块可以让你在远程受管机器上执行脚本的过程中来计算我们需要的值,这些值可以被用在模板或者变量中。这些值有点类似setup模块中的参数,只不过setup模块是以单台主机为单位的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - hosts: mysqlservers tasks: - name: install MySql yum: name=mysql-server state=installed - name: Calculate InnoDB buffer pool size set_fact: innodb_buffer_pool_size_mb="{{ ansible_memtotal_mb /2 }}" - name: Configure MySQL template: src=templates/my.cnf.j2 dest=/etc/my.cnf owner=root group=root mode=0644 notify: restart mysql - name: Start MySQL service: name=mysqld state=started enabled=yes handlers: - name: restart mysql service: name=mysqld state=restarted
1 2 3 4 5 6 7 8 9 [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 innodb_buffer_pool_size = {{ innodb_buffer_pool_size_mb|default(128) }}M [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid
补充一个官方的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # Example setting host facts using key=value pairs - set_fact: one_fact="something" other_fact="{{ local_var * 2 }}" # Example setting host facts using complex arguments - set_fact: one_fact: something other_fact: "{{ local_var * 2 }}" # As of 1.8, Ansible will convert boolean strings ('true' , 'false' , 'yes' , 'no' ) # to proper boolean values when using the key=value syntax, however it is still # recommended that booleans be set using the complex argument style: - set_fact: one_fact: true other_fact: false
pause 暂停模块可以让我们在playbook中暂停一段时间,可以指定一个时间段,或者提示用户继续。在命令行模式中,这没什么用,但是在playbook中,这很有用处。 暂停模块通常被用在当我们需要用户来提供一个确认来继续的时候,或者在一个特殊的时间点手动确认。比如你更新一个web应用程序之后,你需要用户在接受用户的连接之前,手工确认一切Ok。这也可以用来提示用户一些可能出现的问题,并提供选项继续。Ansible会打印出服务器的名字,要求用户确认之后继续。如果在目标选项中设置了串行参数,Ansible会询问组里面的每一个主机。这种方式可以让用户在部署的时候,灵活的控制整个节奏,并监控整个交互过程。
1 2 3 4 5 - name: wait on user input pause: prompt="Warning! Detected slight issue. ENTER to continue CTRL-C to quit." - name: timed wait pause: seconds=30
wait_for wait_for模块用来检测一个tcp端口是否准备好接收远程连接,这是由远程主机来完成的。如果你只指定了端口,或者主机参数被设置为localhost,它会尝试连接远程受管主机。你可以用local_action参数来指定从控制机器来运行命令,并使用ansible_hostname做为主机参数来连接远程受管主机。这个模块在后台运行某些程序,或者启动某些进程需要一些时间的时候特别有用。
1 2 3 4 5 6 7 8 9 10 - hosts: webapps tasks: - name: Install Tomcat yum: name=tomcat6 state=installed - name: Start Tomcat service: name=tomcat6 state=started - name: Wait for Tomcat to start wait_for: port=8080 state=started
assemble assemble组装模块把多个受管主机的文件合并成一个文件,当配置文件不允许包含的时候,这非常有用,特别是在设置root用户的authorized_keys文件的时候。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - hosts: all tasks: - name: Make a Directory in /opt file: path=/opt/sshkeys state=directory owner=root group=root mode=0700 - name: Copy SSH keys over copy: src=keys/{{ item }}.pub dest=/opt/sshkeys/{{ item }}.pub owner=root group=root mode=0600 with_items: - dan - kate - mal - name: Make the root users SSH config directory file: path=/root/.ssh state=directory owner=root group=root mode=0700 - name: Build the authorized_keys file assemble: src=/opt/sshkeys dest=/root/.ssh/authorized_keys
add_host add_host 添加主机模块是playbook中一个强大的模块,它可以让你动态的添加受管主机到一个play中。我们可以使用uri模块从CMDB中获得主机信息然后添加他们。它还可以将主机加到组里面,如果组不存在的话还会自动创建它。这个模块仅需要主机名和组名2个参数,跟主机库存清单的配置一样,我们还可以添加扩展的参数像ansible_ssh_user , ansible_ssh_port等等。
group_by group_by 模块可以让我们根据主机的真实特性来进行分组,真实特性可以通过add_fact来实现(前面已经介绍过set_fact)。group_by模块只接受一个参数,key,同样组名的机器就被分到一个组里面。如果我们在这里使用变量,我们就可以把同一个操作系统类型、同一个拓扑结构的、或者其他我们希望的拥有同样特性的主机分成一组,组可以在子play中、模板中的目标选项被使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 - 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
get_url 将文件从HTTP,HTTPS或FTP下载到远程服务器。远程服务器必须能够直接访问远程资源。默认情况下,如果在目标主机上设置了环境变量 _proxy,那么请求将通过该代理发送。
1 2 3 4 5 - name: download foo.conf get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf mode=0440 - name: download file with sha256 check get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf sha256sum=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
debug 该模块在执行期间打印语句,可用于调试变量或表达式,而无需停止操作手册。用于与’when:’指令一起调试。
1 2 3 4 5 6 7 8 9 10 # Example that prints the loopback address and gateway for each host - debug: msg="System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}" - debug: msg="System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}" when: ansible_default_ipv4.gateway is defined - name: Display all variables/facts known for a host debug: var=hostvars[inventory_hostname] debug: msg="The varibale is {{ info['stdout'] }}"
查看shell的输出
1 2 3 4 5 - name: check oenresty shell: openresty -t register: message - debug: var=message.stdout_lines - debug: var=message.stderr_lines
fail 该模块无法通过自定义消息取得进展。当使用何时满足某个条件时,它可以用于救援。
1 2 3 # Example playbook using fail and when together - fail: msg="The system may not be provisioned according to the CMDB status." when: cmdb_status != "to-be-staged"
Handler section Handler 模块提供回调功能,在所有tasks任务执行完成后,才会执行Handler模块。
1 2 3 4 5 6 7 8 9 10 11 12 tasks: - name: template configuration file template: src=template.j2 dest=/etc/foo.conf notify: - restart memcached - restart apache handlers: - name: restart memcached service: name= memcached state=restarted - name: restart apache service: name=httpd state=restarted
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - hosts: all user: root tasks: - name: install memcached yum: name=memcached state=installed - name: set memcached size set_fact: memcached_size="{{ ansible_memtotal_mb /4 }}" - name: copy configurations template: src=templates/memcached.j2 dest=/etc/sysconfig/memcached notify: - restart memcached handlers: - name: restart memcached service: name=memcached state=restarted enabled=yes
·Handlers只会在Play的末尾运行一次;如果想在一个Playbook的中间运行Handlers,则需要使用meta模块来实现,例如:-meta:flush_handlers。
·如果一个Play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用mega模块的–force-handlers选项来强制执行Handlers,即使是Handlers所在的Play中途运行失败也能执行。
serial 参数的作用 你可以定义Ansible可以在一个特定时间同时控制多少主机,使用serial
关键词:
1 2 3 - name: test play hosts: webservers serial: 3
在上面的例子,如果我们有100台主机,3 台主机定义在组’webservers’ 可以在下面3个主机开始之前完全完成。
这个serial
关键词在Ansible 1.8 以后可以被定义为百分数,用来定义每一次操作一个play中百分之多少主机:
1 2 3 - name: test play hosts: websevers serial: "30%"
如果主机数不能被passes数量整除,最后的pass将会包含提醒信息。
ansible disable swap https://germaniumhq.com/2019/02/14/2019-02-14-Disabling-Swap-for-Kubernetes-in-an-Ansible-Playbook/
参考文档 ansible-examples ansible学习之四:Playbooks galaxy ansible 分享role配置文件的路径 ansible-playbook command tools