尋常でないもふもふ

a software engineer blog

Ansibleでファイルの編集

Ansible で設定ファイルの編集をしたいとき用です。 3つのモジュールが用意されています。

ユースケース

Amazon Linux では最初から EPEL リポジトリがインストールされています。RedHat 系の OS であれば yum install epel-release でインストールできます。これによって ansible など、一般にそこそこ使うパッケージもインストールできるようになります。

ですが、Amazon Linux では /etc/yum.repos.d/epel.repo の設定ファイルによって EPEL リポジトリがデフォルトで無効化されています。今回のユースケースではこの epel.repo ファイルを有効化することを目的とします。

[epel]
name=Extra Packages for Enterprise Linux 6 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 6 - $basearch - Debug
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
gpgcheck=1

[epel-source]
name=Extra Packages for Enterprise Linux 6 - $basearch - Source
#baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
gpgcheck=1

/etc/yum.repos.d/epel.repo は上記のような内容になっています。[epel] セクションで enabled=0 となっています。これを enabled=1 とすることがゴールです。

lineinfile モジュール

lineinfile モジュールは単一行を編集する目的のモジュールです。 以下のようなロールを書くことができます。

---
- name: edit epel setting
  lineinfile:
    state: present
    dest: /etc/yum.repos.d/epel.repo
    regexp: '^enabled=0$'
    line: 'enabled=1'
  • state=present ─ 編集されててなければ編集するという意味
  • dest ─ 編集対象のファイル
  • regexp ─ ここに書かれた正規表現にマッチしたものが編集対象
  • line ─ 編集する値

これで ansible-playbook コマンドで実行すると、[epel] セクションではなく、[epel-source] セクションが enabled=1 となってしまいます。 これは最後にマッチされたもののみ適用される仕様だからです。 最初にマッチしたもの、あるいは◯番目にマッチしたもの、というオプションがあっても良さそうですが、どうやらないようです。

replace モジュール

続いて replace モジュールを使ってみましょう。Ansible 1.6 から追加されたモジュールです。

---
- name: edit epel setting
  replace:
    state: present
    dest: /etc/yum.repos.d/epel.repo
    regexp: '^enabled=0$'
    replace: 'enabled=1'

これを実行すると、[epel], [epel-debuginfo], [epel-source] のすべてのセクションで enabled=1 となってしまいます。今回のケースだとこれも使いにくいです。

ini_file モジュール

結局、どうすれば良いかというと、epel.repo ファイルはたまたま INI 形式なので、ini_file を使えば実現できます。

---
- name: edit epel setting
  ini_file:
    state: present
    dest: /etc/yum.repos.d/epel.repo
    section: epel
    option: enabled
    value: 1

section で [epel] を指定でき、option/value で名前と値を指定できます。

INI 形式じゃない場合は copy モジュールを使って ファイルごと差し替えるか、Ansible による冪等性の恩恵は受けられませんが、shell モジュールに置換のコマンドを直接書くしかなさそうです。