如果希望在控制主机本地运行一个特定的任务,可以使用local_action语句。
假设我们需要配置的远程主机刚刚启动,如果我们直接运行playbook,可能会因为sshd服务尚未开始监听而导致失败,我们可以在控制主机上使用如下示例来等待被控端sshd端口监听:
- name: wait for ssh server to be running
local_action: wait_for
args:
port: 22
host: "{{ inventory_hostname }}"
search_regex: OpenSSH
在有些时候,我们希望运行与选定的主机或主机组相关联的task,但是这个task又不需要在选定的主机或主机组上执行,而需要在另一台服务器上执行。
这种特性适用于以下场景:
可以使用delegate_to语句来在另一台主机上运行task:
- name: enable alerts for web servers
hosts: webservers
tasks:
- name: enable alerts
nagios: action=enable_alerts service=web host="{{ inventory_hostname }}"
delegate_to: nagios.example.com
如果delegate_to: 127.0.0.1的时候,等价于local_action
默认情况下,ansible会并行的在所有选定的主机或主机组上执行每一个task,但有的时候,我们会希望能够逐台运行。最典型的例子就是对负载均衡器后面的应用服务器进行更新时。通常来讲,我们会将应用服务器逐台从负载均衡器上摘除,更新,然后再添加回去。我们可以在play中使用serial语句来告诉ansible限制并行执行play的主机数量。
下面是一个在amazon EC2的负载均衡器中移除主机,更新软件包,再添加回负载均衡的配置示例:
- name: upgrade pkgs on servers behind load balancer
hosts: myhosts
serial: 1
tasks:
- name: get the ec2 instance id and elastic load balancer id
ec2_facts:
- name: take the host out of the elastic load balancer id
local_action: ec2_elb
args:
instance_id: "{{ ansible_ec2_instance_id }}"
state: absent
- name: upgrade pkgs
apt:
update_cache: yes
upgrade: yes
- name: put the host back n the elastic load balancer
local_action: ec2_elb
args:
instance_id: "{{ ansible_ec2_instance_id }}"
state: present
ec2_elbs: "{{ items }}"
with_items: ec2_elbs
在上述示例中,serial的值为1,即表示在某一个时间段内,play只在一台主机上执行。如果为2,则同时有2台主机运行play。
一般来讲,当task失败时,ansible会停止执行失败的那台主机上的任务,但是继续对其他 主机执行。在负载均衡的场景中,我们会更希望ansible在所有主机执行失败之前就让play停止,否则很可能会面临所有主机都从负载均衡器上摘除并且都执行失败导致服务不可用的场景。这个时候,我们可以使用serial语句配合max_fail_percentage语句使用。max_fail_percentage
表示当最大失败主机的比例达到多少时,ansible就让整个play失败。示例如下:
- name: upgrade pkgs on fservers behind load balancer
hosts: myhosts
serial: 1
max_fail_percentage: 25
tasks:
......
假如负载均衡后面有4台主机,并且有一台主机执行失败,这时ansible还会继续运行,要让Play停止运行,则必须超过25%,所以如果想一台失败就停止执行,我们可以将max_fail_percentage的值设为24。如果我们希望只要有执行失败,就放弃执行,我们可以将max_fail_percentage的值设为0。
某些时候,我们希望某个task只执行一次,即使它被绑定到了多个主机上。例如在一个负载均衡器后面有多台应用服务器,我们希望执行一个数据库迁移,只需要在一个应用服务器上执行操作即可。
可以使用run_once语句来处理:
- name: run the database migrateions
command: /opt/run_migrateions
run_once: true
还可以与local_action配合使用,如下:
- name: run the task locally, only once
local_action: command /opt/my-custom-command
run_once: true
还可以与delegate_to配合使用,让这个只执行一次的任务在指定的机器上运行:
- name: run the task locally, only once
command: /opt/my-custom-command
run_once: true
delegate_to: app.a1-61-105.dev.unp
我们在命令行下执行某些命令的时候,这些命令可能会需要依赖环境变量。比如在安装某些包的时候,可能需要通过代理才能完成完装。或者某个脚本可能需要调用某个环境变量才能完成运行。
ansible 支持通过environment
关键字来定义一些环境变量。
在如下场景中可能需要用到环境变量:
下面是一个简单示例:
---
- name: upload a remote file to aws s3
hosts: test
tasks:
- name: install pip
yum:
name: python-pip
state: installed
- name: install the aws tools
pip:
name: awscli
state: present
- name upload file to s3
shell aws s3 put-object --bucket=my-test-bucket --key={{ ansible_hostname }}/fstab --body=/etc/fstab --region=eu-west-1
environment:
AWS_ACCESS_KEY_ID: xxxxxx
AWS_SECRET_ACCESS_KEY: xxxxxx
事实上,environment也可以存储在变量当中:
- hosts: all
remote_user: root
vars:
proxy_env:
http_proxy: http://proxy.example.com:8080
https_proxy: http://proxy.bos.example.com:8080
tasks:
- apt: name=cobbler state=installed
environment: proxy_env
用于终止当前playbook的执行,通常与条件语句组合使用,当满足条件时,终止当前play的运行。可以直接由failed_when取代。
选项只有一个:
示例:
- fail: msg="The system may not be provisioned according to the CMDB status."
when: cmdb_status != "to-be-staged"
在执行playbook时,不可避免会遇到一些错误。ansible默认处理错误的机制是遇到错误就停止执行。但有些时候,有些错误是计划之中的。我们希望忽略这些错误,以让playbook继续往下执行。这个时候就需要用到ignore_erros
了:
tasks:
- name: test approve
shell: /usr/local/bin/kubectl get csr | grep 'Pending'
register: result
ignore_errors: True
failed_when
是指当满足某个条件时,ansible即主动触发失败。
failed_when
其实是ansible的一种错误处理机制,是由fail
模块使用了when
条件语句的组合效果。如下示例表示,如果在command_result
存在错误输出,且错误输出中,包含了FAILED
字串,即返回失败状态:
- name: this command prints FAILED when it fails
command: /usr/bin/example-command -x -y -z
register: command_result
failed_when: "'FAILED' in command_result.stderr"
我们也可以直接通过fail
模块和when
条件语句,写成如下:
- name: this command prints FAILED when it fails
command: /usr/bin/example-command -x -y -z
register: command_result
ignore_errors: True
- name: fail the play if the previous command did not succeed
fail: msg="the command failed"
when: " command_result.stderr and 'FAILED' in command_result.stderr"
ansible一旦执行返回失败,后续操作就会中止,所以failed_when通常可以用于满足某种条件时主动中止playbook运行的一种方式。
当我们控制一些远程主机执行某些任务时,当任务在远程主机上成功执行,状态发生更改时,会返回changed状态响应,状态未发生更改时,会返回OK状态响应,当任务被跳过时,会返回skipped状态响应。我们可以通过changed_when
来手动更改changed
响应状态。示例如下:
- shell: /usr/bin/billybass --mode="take me to the river"
register: bass_result
changed_when: "bass_result.rc != 2" #只有该条task执行以后,bass_result.rc的值不为2时,才会返回changed状态
# this will never report 'changed' status
- shell: wall 'beep'
changed_when: False #当changed_when为false时,该条task在执行以后,永远不会返回changed状态
原文:https://www.cnblogs.com/breezey/p/10996651.html