首页 文章

如何使用Ansible自动执行一次性任务?

提问于
浏览
1

我正在使用Ansible为我们的一些构建环境自动化VM配置,例如设置 PATH 和代理环境变量,安装全局Node.js工具等 . 这很好用,并且很容易在多个主机上自动执行常见的设置任务 . 所有任务都通过Ansible roles 分开,以分离职责和额外的可重用性 .

现在我遇到以下问题:安装了新软件包后,我需要更改 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 回答

  • 2

    您使用的是哪个版本的Ansible?由于您所描述的内容看起来像一个错误,因为 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

    我不太确定我完全理解你的问题,但其中任何一个都会起作用......

    (1)在 .profile 中有一条专用行,用于添加删除的路径 . 所以除了 .profile 中的所有其他 PATH 之外,你还有一条线

    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`语句 .

相关问题