我有ansible角色,其任务委托给localhost:
- name: Test role
hosts: my_hosts
gather_facts: no
tasks:
- name: Register remote hosts
include_role: name=register_remote_hosts
delegate_to: localhost
角色register_remote_systems必须适用于my_hosts中的每个主机,但必须从调用Ansible的框中运行,这就是为什么有delegate_to。
role_remote_hosts角色检查localhost上的特定应用程序,如果没有安装,则会创建虚拟环境,然后安装它:
- name: Check if my_app is installed system-wide
shell: |
my_app --version >/dev/null 2>&1
register: my_app_cmd
failed_when: my_app_cmd.rc not in [0, 127]
- name: Install My App
block:
- name: Create temporary directory for my_app
tempfile:
state: directory
suffix: my_app
register: my_app_temp
- name: Create virtual environment
command: virtualenv "{{ my_app_temp.path }}"
- name: Install my_app
pip:
name: my_app
state: latest
virtualenv: "{{ my_app_temp.path }}"
virtualenv_site_packages: yes
- name: Set Virtual Environment variable
set_fact:
venv_activate: "source {{ my_app_temp.path }}/bin/activate"
when: my_app_cmd.rc != 0
- name: Use my_app
shell: |
{{ venv_activate | default('echo "Using my_app from system path"') }}
my_app --version
一切都很好,但如果my_hosts中有很多主机,那么就会创建很多venv。
创建角色的最佳方法是什么,重新使用安装了my_app的相同venv。请注意,角色包含在许多不同的剧本中,我不想在每个使用“注册远程主机”角色的剧本中添加其他角色。在使用其他剧本之前,创建venv当然存在并发问题。
以上解决方案有效,我可以忍受它,但也许在Ansible中有更好的设计模式来解决这些问题。
答案 0 :(得分:1)
解决方案是放置run_once(感谢@ssbarnea):
when: my_app_cmd.rc != 0
run_once: yes