dotfiles に Ansible Playbook を導入した

最近、4年間使っていた MacBook Air が突然壊れてしまい、新しい MacBook Pro を購入しました。

新しいマシンを手に入れたらまず最初にやることは dotfiles のデプロイです。これまでの dotfiles のデプロイはお手製のシェルスクリプトによって行っていましたが、色々問題を抱えていたため、機会があれば Ansible Playbook を導入したいと考えていました。今がそのタイミングだなと感じたので実際にやってみました。

github.com

各 role の紹介

Best Practices — Ansible Documentation に従い ansible-playbook/roles 以下に各 role を配置しています。

ansible-playbook/roles
├── anyenv
├── apt
├── cli
├── dotfiles
├── homebrew
├── homebrew_cask
├── powerline
├── system
├── vscode
└── zsh

anyenv

anyenv と anyenv によってインストールされる xxenv をインストールするための role です。
anyenv の README にある通りに git cloneanyenv install --init を実行しています。
anyenv のインストール先を anyenv.install_dir という変数で指定できる仕組みにしています。この状態で anyenv install --init を実行するには PATH に anyenv があるディレクトリへのパスを追加する必要がありますが、 このパスに ~ が含まれていると anyenv コマンドの lookup ができないという問題がありました。そこで今回は regex_replace を使って ~lookup('env', 'HOME') の値で置き換えるようにしています。

https://github.com/odanado/dotfiles/blob/145ff7278708f7a0cd5f1cf6e18ba145f0cdaef4/ansible-playbook/roles/anyenv/tasks/main.yml#L20

apt

apt でインストールするパッケージを管理する role です。
特に変なことはしていません。

cli

cli ツールのインストールを管理する role です。
GitHub Releases にアップロードされている cli ツールのバイナリファイルダウンロードし、指定のディレクトリに配置する機能があります。この機能は ansible-playbook/roles/cli/files/installer.sh に実装しています。複数あるファイルの中から OS と CPU の種類を判定して適切なファイルをダウンロードする仕組みはかなり雑になっています。今後インストールする cli ツールが増えるたびにちょっとずつ改善していくつもりです。

dotfiles

dotfiles をデプロイする role です。
.tmux.conf や .gitconfig のシンボリックリンクをホームディレクトリに向けて生成しています。

homebrew/homebrew_cask

homebrew/homebrew_cask でインストールするパッケージを管理する role です。
特に変なことはしていません。

powerline

powerline を導入するための role です。
pip で powerline をインストールして、config を ~/.config/powerlineシンボリックリンクを作成しています。

system

Macdefaults の値などを管理する role です。
スクリーンキャプチャの名前や保存先の変更などをここで行っています。

vscode

VSCode拡張機能を管理する role です。
code --list-extensions でインストール済みの拡張機能を取得して、インストールしていない拡張機能だけをインストールするようにしています。

https://github.com/odanado/dotfiles/blob/145ff7278708f7a0cd5f1cf6e18ba145f0cdaef4/ansible-playbook/roles/vscode/tasks/main.yml#L10

そのうち設定ファイルのデプロイも行うようにしたいです。

zsh

zshrc のデプロイや zplug のインストールを行う role です。
zsh の plugin 管理には zplug を使用しているのでインストールを行っています。
zplug install の実行も ansible から行いたかったのですが、エラーが出て解決できなかったためここでは行っていません。

Github Action によるテスト自動化

Github Action では Linux だけでなく macOS のサーバを用いたテストを実行できるため、macOSUbuntu の両方でセットアップが成功することをテストしています。

Ubuntu のテストは Docker コンテナ上で実行しています。最初は docker-compose を用いてホストマシンからコンテナ内に対してコマンドを実行していました。しかしこの方法ではローカルでは再現しない tty 周りエラーでハマりました。ググっても解決策が見つからず時間もなかったため、docker コマンドを直接実行する方法に変更しました。

https://github.com/odanado/dotfiles/blob/145ff7278708f7a0cd5f1cf6e18ba145f0cdaef4/.github/workflows/ubuntu.yml

今のところ trigger は push だけですが、cron で定期的に壊れていないことをチェックするようにしたいです。

参考

Ansible Playbook を使って macOS の初期化を行う話はネット上に数多く存在し大変参考になりました。