LoginSignup
3

More than 3 years have passed since last update.

Ansible Playbookのリファクタリング

Last updated at Posted at 2018-12-03

はじめに

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

そこでまず、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は使わなくなりましたが、2つに分かれてしまい、
何をしたいのか分かりづらくなってしまいました。

lineinfile + copy → 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

なので、以下のようにファイルコピーだけでOKです。

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

OSの仕組みを知ることで、よりシンプルな書き方ができました。

おわりに

今回は比較的簡単な例でしたが、
Ansibleはコードによる自動化をするだけではなく、改善点を洗い出すために有効です。

例えば failed_when: false などでごまかしている場合は、
終了コードが0でないプログラムがあります。

fileモジュールで force=yes をつけている場合は、
そもそも手順が前後している場合があります。

AnsibleはYAMLで書くためプログラマブル要素が低めですが、
それを欠点と捉えるのではなく、改善のためのシグナルを提供していると考えればいいと思います。

だから自分はAnsibleを使ってて楽しいです( ´ω`)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3