4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AnsibleAdvent Calendar 2018

Day 4

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

4
3
0

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
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?