dotfilesをansibleで管理していて、やめた


まえがき

dotfilesをansibleで管理していた話を書く。

結論

  • ローカルPCだけならAnsible使わなくてよかった
  • 普通のシェルスクリプトか、スクリプト言語で良い
  • 最終的にAnsible使わないようにした

背景

もともとシェルスクリプトでdotfilesを管理していました。
他の記事でもあるように、至って普通のシンボリックリンクをはるだけのスクリプトです。

ですが、ちょうど仕事でAnsibleを書くことが近い内にありそうだったので、勉強も兼ねて、シェルスクリプトで書いていたものをAnsibleで書き直しました。
ここからdotfilesをAnsibleで管理するのが始まりました。

結局、管理がつらくなってスクリプトで書くように戻しました。
Ansibleで管理していたときのものは別ブランチで保存しています。
以下です。

dotfilesの構成

当時のdotfilesの構成は以下です。

.
|-- ansible
|   |-- roles
|-- ConEmu.xml
|-- README.adoc
|-- bash
|   |-- bashrc
|   |-- conf.plugins.d
|   `-- plugins.sh
|-- bin
|-- code
|   |-- README.md
|   |-- dump_extentions.sh
|   |-- extensions.txt
|   `-- user
|-- config.nims
|-- docker-compose.yml
|-- git
|   `-- commit.template
|-- i3
|   `-- config
|-- krita.shortcuts
|-- lib
|   `-- sh
|-- note.md
|-- setup.sh
|-- spacemacs
|-- termite
|   `-- config
|-- tmux.conf
|-- user-dirs.dirs
|-- vim
|   |-- README.adoc
|   |-- after
|   |-- colors
|   |-- conf.d
|   |-- conf.plugins.d
|   |-- dict
|   |-- gvimrc
|   |-- init.vim
|   |-- plugins.vim
|   |-- template
|   |-- vimperatorrc
|   |-- vimrc
|   |-- vimrc.min
|   `-- vrapperrc
`-- zsh
    |-- README.md
    |-- conf.d
    |-- img
    |-- plugins.zsh
    `-- zshrc

21 directories, 45 files

vimrcやbashrcは単一のファイルではなく、分割して管理したくてディレクトリで切るような構成にしています。
あとbashとzshで設定を分けていたり、bashからもzshからも参照するものはlib/shに配置していたりと、依存関係が複雑です。

roleとplaybookの構成

dotfiles/ansibleに配置していました。
roleわけはこんな感じです。

clojure/tasks
common_deploy
common_setup/tasks
docker/tasks
font
git/tasks
go
i3
nim
nodejs/tasks
python/tasks
shell
terminal
vim
vscode

ツールをインストールし、設定ファイルを配置するのをひとつのroleにまとめています。

Ansibleはべき統制を保つように書けるので、こういうまとめ方が良いのかな、と思ってやりました。
nimだけアップデートしたい、Goだけアップデートしたい、みたいなこともしかたったのもあります。

で、playbookはこんな感じ。

- hosts: localhost
  connection: local
  vars_files:
    - "vars/env.yml"
  roles:
    - role: common_deploy
    - role: nodejs
      tags: [update]
    - role: python
      tags: [update]
    - role: git
    - role: go
    - role: docker
    - role: vim
      tags: [update]
    - role: shell
    - role: i3
    - role: terminal
    - role: font
    - role: vscode
    - role: nim

何か良くなかったか

結局Ansibleで書いたplaybookをシェルスクリプトに戻すことになりました。
何がまずかったのか?

書きづらい

個人的にはスクリプトのほうが書きやすいし読みやすいです。
プロビジョニング方法をYAMLで書けることのメリットは
複数人で書いても書き方に大きく差が生まれない、スクリプトを読めない/書けない人でもメンテができることです。
複数人で保守するときの、技術に対する理解度の差を減らすための一つの方法がAnsibleのYAMLです。

別にdotfilesは僕が書いて僕しか保守しないなら、僕が一番書きやすいやつで書けばいいじゃんと思うようになりました。
AnsibleのYAMLで条件分岐を表現するのがめんどくさくて、書きにくいです。

roleわけの意味がほぼ無い

Ansibleは複数のリモート環境をプロビジョニングするためのツールで、そのときに効力を発揮します。
同じミドルウェアをセットアップするけれど、サーバの役割が違う、というときに、ミドルウェア単位でroleを分けたりすることで、roleを使い回すことができ、プロビジョニングの設定の二重管理を抑止できます。
これが非常に強力です。

しかしながら、ローカルPCは一つしかないのでroleわけしても、別のなにかの設定で使い回すことがないので、あんまり嬉しくないです。
むしろファイルが別れてしまって、どこに何の設定があるのかわからなくなって、返ってメンテが大変でした。

思い返せば1ファイルに全部のタスクを平で書くのもやり方としてはあったかも。

感想

まぁ、勉強の一環として試してみたAnsibleでしたが、
結果的にはdotfilesの管理をAnsibleでやったおかげで、Ansibleの使い方、書き方、ベストプラクティスや、ドキュメントの調べ方の勉強になりました。

仕事でもプライベートで運用してるサーバでもAnsibleは使っていて、勉強として使ったことの意義は大きかったと感じます。

ですが、自分しか保守しないローカルPCなら普通にシェルやスクリプト言語のほうが楽ですね。

最強の dotfiles 駆動開発と GitHub で管理する運用方法にもあるように、シェルが良いと思います。

僕は最終的にNimScriptでdotfilesのリンクを貼るようにまた書き直しました。
一ファイルに全部書いてます。

これdotfilesの記事じゃなくてansibleの記事なのでは・・・?

以上です。