我一直在玩ansible(我对配置管理很陌生,这不是我的dayjob),我正在努力找出模式化我的条件任务的最佳方法。
我已经构建了我的设置(git存储库,布局如下:
├── dotfiles (...)
├── bin (...)
└── playbooks
├── bootstrap.yml
├── firewall.yml
├── ids.yml
├── logserver.yml
├── pvr.yml
├── site.yml
├── log
└── roles
└── bootstrap
| ├── defaults
| │ └── main.yml
| └── tasks
| ├── apt-update.yml
| ├── apt-upgrade.yml
| ├── homebrew-user.yml
| ├── homebrew-install.yml
| ├── homebrew-update.yml
| ├── homebrew-upgrade.yml
| ├── main.yml
| ├── tmux-install.yml
| └── vim-install.yml
├── elk (...)
├── snort (...)
├── tor (...)
└── zentyal (...)
对于大多数场景,我都有一个用于构建角色的每个系统的剧本。我在本地运行剧本在每个主机上(在我的防火墙系统上,我登录,更新git存储库,并运行ansible-playbook bootstrap.yml
和CCD_ 2。我的意图是在未来建立一个真正的库存,这样我就可以运行特定的角色对抗特定的宿主,但就目前而言,在我学习的过程中,这很有效。
大多数角色都是特定于平台的,需要sudo,这很好,效果很好。
然而,我的bootstrap.yml
剧本需要在变量环境中运行:
- 有时使用sudo(多用户环境)在osx系统上安装自制程序
- 有时在没有sudo(单用户环境)的osx系统上安装自制程序
- 有时在特定位置安装额外的自制应用程序(单用户桌面系统)
- 有时在特定位置安装额外的自制应用程序(多用户桌面系统)
- 有时在Ubuntu/BSD系统上使用包控制在系统范围内安装特定的应用程序
- 有时使用本地构建脚本在$HOME中的Ubuntu/BSD系统上安装特定的应用程序
根据环境的不同,我想引导多达100个左右的应用程序——各种各样我用于日常事务的实用程序-复制我的点文件,安装/更新bash/zsh,git,git-flow,hub,vim,tmux,mosh,weechat,base16,source highlight,netcat,nmap,设置pip,virtualenv,虚拟说唱歌手,以及大约100种其他东西。
举一个例子,在多个环境中安装tmux的任务(在python-likepsuedocode中):
if ansible_distribution=='MacOSX':
if sudo_user is not None:
homebrew: name=tmux state=present sudo_user='homebrew'
else:
homebrew: name=tmux state=present
elif os=='Ubuntu':
if sudo_user is not None:
apt_repository: name='ppa:pi-rho' state: present)
apt: name=tmux state=present sudo_user='root')
else:
shell: tmux-ubuntu-build-local.sh
elif os=='BSD':
shell: tmux-bsd-build-local.sh
但是ansible似乎没有可用的基本if/else构造——只有when
构造。所以,我开始使用when
写入条件任务(包含在./playbooks/roles/bootstrap/main.yml
中):
---
# ./playbooks/roles/bootstrap/tmux.yml
# this always installs without sudo, which works on my laptop
# but fails on shared systems that use a 'homebrew' user
- name: install
when: ansible_distribution == 'MacOSX'
sudo: no
homebrew: name=tmux
# i only want to run this when I *want* to install tmux globally
# on some systems I just want to run a build script
# if i don't have root and visudo isn't properly configured, this fails
- name: add pi-rho/dev ppa
when: ansible_distribution == 'Ubuntu'
sudo: yes
apt_repository:
repo: 'ppa:pi-rho/dev'
state: present
# again, i don't always want to do this
- name: update cache
when: ansible_distribution == 'Ubuntu'
sudo: yes
apt: update_cache=yes
# this always attempts to install using sudo, which I don't want.
# on some systems I want to run a build script that installs tmux
# to the user's home directory instead
- name: install
when: ansible_distribution == 'Ubuntu'
sudo: yes
apt: name=tmux
# this installs a set of tmux plugins without sudo to my $HOME
# directory, i do always want this
- name: install plugins
sudo: no
git:
repo: '{{ item.repo }}'
dest: '{{ tmux_plugins_path }}/plugins/{{ item.name }}'
with_items: tmux_plugins
这种方法适用于我的几个系统,但在除最基本的情况外的所有情况下都失败了(正如评论所指出的)。它还scale非常差-因为我看不到"重用"任何任务或使用多个/链式when
表达式的方法只需一项任务。
我已经开始使用我读过的其他几个解决方案:
使用-e传递一个标志,例如:use_sudo,但如果没有"任务重用",我将不得不编写每个应用程序/库的单独任务,以说明标志。如果我在手术中也这样做系统(
-e os=macosx
),这种情况甚至更糟。在角色级别标记我的所有任务-这要求我按操作系统而不是"主题",这是一个反干扰的,很难处理。
在任务级别标记我的所有任务——同样,如果没有任务重用,这似乎扩展得非常糟糕。
我已经考虑过查看插件/模块,看看我是否可以用Python编写一些东西来启用if/else构造在单个任务或"嵌套"任务中,如果我不能想出更简单的方法,那可能就是我要研究的下一个
那么,我是不是做错了?有什么建议吗?
您可以使用条件导入或将"when"应用于角色并包含http://docs.ansible.com/ansible/latest/playbooks_conditionals.html