目前,我正从人偶切换到Ansible,我对某些概念或至少Ansible的工作方式感到困惑。
有关设置的一些信息:
我正在使用Ansible Best Practices中的示例,并以几个角色(剧本)等类似方式来构造我的项目。
我正在使用Vagrant进行配置,并且该框是Saucy64 VBox。
混乱的来历:
当我配置并运行ansible时,任务开始执行,然后是通知堆栈。
例:
最后任务:
TASK: [mysql | delete anonymous MySQL server user for localhost] **************
<127.0.0.1> REMOTE_MODULE mysql_user user='' state=absent
changed: [default] => {"changed": true, "item": "", "user": ""}
然后先通知:
NOTIFIED: [timezone | update tzdata] ******************************************
<127.0.0.1> REMOTE_MODULE command /usr/sbin/dpkg-reconfigure --frontend noninteractive tzdata
changed: [default] => {"changed": true, "cmd": ["/usr/sbin/dpkg-reconfigure", "--frontend", "noninteractive", "tzdata"], "delta": "0:00:00.224081", "end": "2014-02-03 22:34:48.508961", "item": "", "rc": 0, "start": "2014-02-03 22:34:48.284880", "stderr": "\nCurrent default time zone: 'Europe/Amsterdam'\nLocal time is now: Mon Feb 3 22:34:48 CET 2014.\nUniversal Time is now: Mon Feb 3 21:34:48 UTC 2014.", "stdout": ""}
现在一切都很好。随着角色的增加,越来越多的通知卡住了。
现在问题来了。
通知失败时,设置将照常停止。但是,通知堆栈为空!这意味着将不会执行所有在故障之后的通知!
如果是这样的话,那么如果您更改了apache的虚拟主机设置,并收到了有关apache服务重新加载的通知,那么它将丢失。
让我们举个例子(伪郎):
- name: Install Apache Modules
notify: Restart Apache
- name: Enable Vhosts
notify: Reload Apache
- name: Install PHP
command: GGGGGG # throws an error
执行以上操作时:
现在,这一切似乎都合乎逻辑,但是Ansible再次尝试变得聪明(no!*)堆积通知,因此重新加载和重新启动apache将导致在配置结束时一次重新启动apache。这意味着所有通知都将失败!!!
现在对于某些人来说,这里也很好。他们会说,嘿,只要重新运行配置,通知就会启动,因此apache最终将被重新加载,站点将再次启动。不是这种情况。
在更正了用于安装php的代码之后,在脚本的第二次运行中,由于设计原因,通知将不会运行。为什么?
这就是为什么:Ansible将成功执行的任务标记为“完成/绿色”,因此不会为这些任务注册任何通知。设置将成功,并且为了触发通知并因此重新启动apache,您可以执行以下操作之一:
这很令人沮丧,因为需要彻底清理盒子,还是使用Ansible无法正确理解某些内容?
还有另一种方法可以“回收” /重放/强制执行通知吗?
是的,与Puppet相比,这是Ansible的缺点之一。木偶是声明性的,不会像Ansible(或Chef)那样出错。它有其优点和缺点,例如,Puppet需要一些时间才能开始运行,因为它需要编译其目录。
因此,如果您的Ansible脚本出错,那么您的通知更新将不会发生,这是正确的。解决这个问题的唯一方法是使用条件语句。在您的剧本中,您可以执行以下操作:
- name: My cool playbook
hosts: all
vars:
force_tasks: 0
tasks:
- name: Apache install
action: apt pkg=$item state=latest
with_items:
- apache2
- apache2-mpm-prefork
- name: Restart apache
action: service name=apache2 state=restart
when: force_tasks
然后,当您运行剧本时,可以将force_tasks作为环境变量传递:
ansible-playbook -i my_inventory -e "force_tasks=True" my_ansible_playbook.yml
您可以使用标签以类似方式完成此操作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句