Ansible Playbook的重构

首先

使用Ansible时我喜欢的一点是,尽管可以偷懒,但也可以改进代码,写得更漂亮。

因此,我会写下我实际进行的代码重构。(内容有些改动)

我正在CentOS 7上进行确认。

Ansible以前的版本

第一步如下所示。

    /etc/profile に以下の内容を書き込む
if [ "$USER" != "foo" ]; then
  export FOO=BAR
fi

从这里开始。

首先坦率地实施

使用Ansible原生方式实现时,可以使用blockinfile命令编写如下内容:

- name: /etc/profile に環境設定を追加
  blockinfile:
    path: /etc/profile
    block: |
      if [ "$USER" != "foo" ]; then
        export FOO=BAR
      fi
  become: yes

在这种情况下,将以下内容写入/etc/profile的末尾。

# BEGIN ANSIBLE MANAGED BLOCK
if [ "$USER" != "foo" ]; then
  export FOO=BAR
fi
# END ANSIBLE MANAGED BLOCK

blockinfile是代碼中的難聞味道

这样也没问题。冪等性得到保证。

然而,”BEGIN ANSIBLE MANAGED BLOCK”和”END ANSIBLE MANAGED BLOCK”的存在感觉有点不太好。如果有人不小心删除它们,会产生奇怪的结果。

在我看来,blockinfile模块很难处理,所以我会尽量避免使用它。但并不意味着这个模块本身有问题。这只是给人一种可以改进的信号。也就是所谓的代码异味。

blockinfile → lineinfile + copy

blockinfile 可以被替换为 lineinfile 加上 copy。

所以我们首先决定使用lineinfile。
就像这样。

- name: foo.shを /etc/profile.foo としてコピー
  copy:
    src: foo.sh
    dest: /etc/profile.foo
  become: yes

- name: profile.fooを読み込み
  lineinfile:
    path: /etc/profile
    line: source /etc/profile.foo
  become: yes

尽管blockinfile已经不再使用,但现在分散成两个部分,
导致了想要做什么变得不太清楚。

使用lineinfile + copy指令进行复制。

然而从根本上说,并不需要修改 /etc/profile。
只需按照 /etc/profile 中所述,在 /etc/profile.d 目录下放置扩展名为 .sh 或 sh.local 的文件,它将自动读取并执行。

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

所以,只需将文件复制即可。

- name: foo.sh を /etc/profile.d 以下にコピー(bash起動時に読み込まれる)
  copy:
    src: foo.sh
    dest: /etc/profile.d/foo.sh
  become: yes

通过了解操作系统的机制,我能够以更简洁的方式进行写作。

最后

虽然这次例子相对简单,但Ansible不仅可以实现基于代码的自动化,还能够发现改进点。

如果通过 failed_when: false 等手段进行掩饰,
那么存在终止代码非零的程序。

如果在file模块中设置了force=yes,
则可能会存在步骤先后颠倒的情况。

Ansible以YAML为编写语言,因此其可编程元素较低。然而,我们不应该将此视为缺点,而应该将其视为提供改进机会的信号。

所以我很喜欢使用Ansible,感觉很愉快呢( ´ω`)

广告
将在 10 秒后关闭
bannerAds