2015-04-28 31 views
1

我使用Ansible为我们的一些构建环境(例如,设置PATH和代理环境变量,安装全局Node.js工具等。这很好,而且很容易在多个主机上自动执行常见的设置任务。所有的任务都被分成Ansible roles以分离责任和额外的可重用性。如何使用Ansible自动执行一次性任务?

现在我遇到了以下情况:安装新软件包后,我需要更改PATH环境变量 - 它不再需要我以前作为Ansible安装程序的一部分添加的条目。

因此,自然我继续并更新了用于为新环境设置PATH变量的Ansible任务,并删除了自定义条目(我使用lineinfile任务创建了PATH条目)。

lineinfile: 
    dest: ~/.profile 
    regexp: "^export {{ item.regexp }}" 
    line: "export {{ item.line }}" 
    create: yes 
    with_items: 
    - { regexp: 'PATH', line: 'PATH=:~/bin:~/node_modules/.bin:$PATH' } 

我从上面的line部分项目中删除了一项。如您所见,lineinfile任务仅检查文件中是否存在条目export PATH,如果不存在,则使用export PATH=:~/bin:~/node_modules/.bin:$PATH创建该条目。

现在我的问题:由于lineinfile任务只验证条目是否存在,但不检查完整值,所以我需要确保所有现有的环境都已更新。我如何去做这件事?

有没有一种方法,使lineinfile陈述足够聪明,以验证该行的内容为好,即确保精确的线条我想存在(同时避免重复PATH项)?或者这太复杂了?

我想到了(终于做)的另一件事情是创建一个一次性的剧本,更新在所有环境中的PATH变量:

lineinfile: 
    dest: ~/.profile 
    backrefs: yes 
    regexp: "^export PATH=(.*)/opt/foo/bar/baz/bin[\\:]*(.*)" 
    line: "export PATH=\\1\\2" 

这是一个常见的场景 - 为单创建剧本关闭任务?好处是,剧本可以在所有主机上运行并避免手动工作。除此之外,可重用性很小,因为我只希望这样做一次。

这是正确的方式去解决这个问题,还是有更好,更聪明的方式来完成这样的任务?

回答

2

您使用的是哪个Ansible的版本是?因为你所描述的看起来像一个bug,因为lineinfile模块应该检测到线路已经改变并更新它。我只是复制粘贴你的第一个任务(只是改变了文件的路径),一切正常。

这是第一次运行:

➜ ~ % ansible-playbook test.yml 

PLAY [all] ******************************************************************** 

TASK: [lineinfile ] *********************************************************** 
changed: [localhost] => (item={'regexp': 'PATH', 'line': 'PATH=:~/bin:~/node_modules/.bin:$PATH'}) 

PLAY RECAP ******************************************************************** 
localhost     : ok=1 changed=1 unreachable=0 failed=0 

比我从路径删除~/bin并再次运行整个事情:

➜ ~ % ansible-playbook test.yml 

PLAY [all] ******************************************************************** 

TASK: [lineinfile ] *********************************************************** 
changed: [localhost] => (item={'regexp': 'PATH', 'line': 'PATH=:~/node_modules/.bin:$PATH'}) 

PLAY RECAP ******************************************************************** 
localhost     : ok=1 changed=1 unreachable=0 failed=0 

,你可以看到检测模块,我改变了变量和它更新文件。所以所有的作品都应该如此。

+0

谢谢!我是个白痴 - 不知道我做错了什么。你是对的,它按预期工作。我回顾了我的真实代码(上面是一个例子),做了一些修改,并开始工作。 – nwinkler

0

我不太确定我完全明白你的问题,但要么这些工作......

(1)具备.profile为您添加删除路径单一的专用线。所以除了您的所有其他PATH东西在.profile,你有一个线

export PATH=~/foo/removable:$PATH # ANSIBLE MANAGED 
您使用 line_in_file模块添加和删除

(2)利用该/etc/profile.d目录,然后添加(通过copytemplate) and remove a file /etc/profile.d/temporary-path.sh that contains your temporary export`声明。