Help us understand the problem. What is going on with this article?

Ansible Playbookのリファクタリング

More than 1 year has passed since last update.

はじめに

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を使ってて楽しいです( ´ω`)

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away