Ansible:条件任务模式&网站布局

时间:2015-03-04 19:18:03

标签: ansible ansible-playbook

我一直在玩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.ymlansible-playbook firewall.yml。我的目的是在将来设置一个真实的库存,以便我可以运行特定的角色 针对特定的主持人,但是现在我正在学习,这很有效。

大多数角色都是特定于平台的,需要sudo,这很好并且效果很好。

但是我的bootstrap.yml剧本需要在变量环境中运行:

  • 有时使用sudo(多用户环境)在osx系统上安装自制软件
  • 有时在没有sudo(单用户环境)的osx系统上安装自制程序
  • 有时会在特定位置(单用户桌面系统)安装其他自制程序应用程序
  • 有时会在特定位置(多用户桌面系统)安装其他自制程序应用程序
  • 有时在Ubuntu / BSD系统上使用包控制在系统范围内安装特定应用程序
  • 有时在$ HOME
  • 中的Ubuntu / BSD系统上使用本地构建脚本安装特定应用程序

根据环境的不同,最多有100个应用程序或者我想要引导 - 所有各种 我用于日常事务的实用程序 - 复制我的dotfiles,安装/更新bash / zsh,git, git-flow,hub,vim,tmux,mosh,weechat,base16,source-highlight,netcat,nmap,设置pip,virtualenv, virtualenvwrapper,以及其他约100件事。

作为一个例子,在多个环境中安装tmux的任务(在 python-like psuedocode中):

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

这种方法适用于我的几个系统,但在最基本的情况下都失败了(如评论所述)。它也是 缩放非常 - 因为我没有看到“重用”任何任务或使用多个/链式when表达式的方法 只需一项任务。

我开始玩其他几个我读过的解决方案:

  1. 使用-e传入一个标志,例如:use_sudo,但是再次,没有“任务重用”我将不得不写 每个应用程序/库的单独任务以考虑该标志。如果我也做了这个操作 系统(-e os=macosx),这会更糟糕。

  2. 在角色级别标记我的所有任务 - 这要求我通过操作系统将任务拆分为不同的角色而不是 “主题”,具有反直觉性,难以使用。

  3. 在任务级别标记我的所有任务 - 再次,没有任务重用,这似乎非常严重。

  4. 我考虑过查看插件/模块,看看我是否可以在Python中编写一些内容来启用if / else构造 在单个任务或“嵌套”任务中,如果我无法想象更简单的东西,那可能就是我要研究的内容 下。

  5. 那么,我做错了吗?有什么建议吗?

1 个答案:

答案 0 :(得分:1)

您可以使用条件导入 或者将“何时”应用于角色并包括在中描述 http://docs.ansible.com/ansible/latest/playbooks_conditionals.html