2

我有一个部署 jenkins 的 ansible playbook,其中 jenkins config.xmljinja2 模板文件包含这个用于 AD 身份验证的片段:

<securityRealm class="hudson.plugins.active_directory.ActiveDirectorySecurityRealm" plugin="active-directory@1.39">
    <domain>{{ ldap_hostname }}/domain>
    <bindName>{{ ldap_bind_user }}</bindName>
    <bindPassword>{{ ldap_password }}</bindPassword>
    <server>{{ ldap_hostname }}:{{ ldap_port }}</server>
    <groupLookupStrategy>RECURSIVE</groupLookupStrategy>
    <removeIrrelevantGroups>false</removeIrrelevantGroups>
</securityRealm>

{{ ldap_password }}是来自保险库的明文密码。

问题是,当 jenkins 在 config.xml 部署后启动时,它会通过将明文密码替换为密码哈希来重写它。(散列似乎取决于目标主机,因为我们在不同的虚拟机上得到不同的散列)。虽然这通常是一件好事,但它使 playbook 的每次执行都将模板操作标记为已更改。

如何使这个播放脚本具有幂等性?

4

1 回答 1

5

我真的想不出一个很好的干净的方法来做到这一点,所以这可能会让人觉得有点折磨。

你有几个选项,取决于你想用它有多“正确”。

首先,您可以简单地告诉 Ansible 您不关心您是否对此文件进行任何更改,因此始终标记为未更改(绿色)。您可以changed_when: False在任务上执行此操作。

或者,您可以说您只想在第一次运行时对该文件进行模板化,之后它就脱离了 Ansible 的控制。这种方法对于引导安装然后想要管理自己的文件并且您永远不会考虑再次更改它们的东西很有用。为此,您可以摆脱类似的情况:

- name: check if jenkins config.xml file is there
  stat:
    path: path/to/config.xml
  register: config-xml_stat

- name: template jenkins config.xml if not already there
  template:
    src: path/to/config.xml.j2
    dest: path/to/config.xml
  when: config-xml_stat.exists == false

考虑到问题,您正在模板化某些东西,然后积极期待特定行会在 Ansible 的控制之外发生变化。此处的另一个选项是将文件模板化到与 Jenkins 期望的文件路径不同的文件路径(然后可以正常幂等),将其与 Jenkins 正在使用的文件进行比较,然后如果该行以外的任何内容不同复制 Jenkins 文件的顶部。你可以使用这样的东西来做到这一点:

- name: template jenkins config.xml.template
  template:
    src: path/to/config.xml.j2
    dest: path/to/config.xml.template

# We are expecting bindPassword to have changed so we can exclude this from the diff line count
- name: diff jenkins config.xml and config.xml.template
  shell: diff path/to/config.xml.template path/to/config.xml | grep -v bindPassword | wc -l
  register: config-xml_diff

# Diff will also output 2 extra lines that we don't care about. If there's more lines than this then we need to retemplate the config.xml
- name: template jenkins config.xml
  template:
    src: path/to/config.xml.j2
    dest: path/to/config.xml
  when: config-xml_diff.stdout != 2

最后一个有点笨拙和笨拙,但“更正确”,因为它正在积极检查文件的更改是否超出我们的预期,如果是,则重新模板化。

如果您决定走第三条路线,那么我建议结合检查以查看第二个选项是否存在,以使其在所做的事情上更加明显。没有它,如果 config.xml 文件不存在,那么您的 diff 任务将输出单行 ( diff: config.xml: No such file or directory),这仍然意味着您的第三个任务的条件计算结果正常,但这有点误导。

于 2015-11-24T16:13:08.447 回答