あれやこれや仕事をしていると、使っているMacの乗り換えもなんだかんだでしばしば発生する。もう覚えていないが、2003年ごろにメインの仕事道具をMac OS Xにしてから、かれこれ十数台は乗り換えをしているだろう。M1もすでに2台めだ。
いちいち環境を構築するのは面倒だし時間もかかる。ここにかかる時間は、自分というサービスの障害復旧時間でもある。短いに越したことはない。
環境構築の自動化は、いつか試そうと思って数年やっていなかった。
数周遅れだが、やってみる。Infrastructure as Code (IaC) の一環である。
macOSでの環境構築は、Puppet, Chef, Ansibleなどいくつかツールがあったが、いまではhomebrewでBrewfileを使うのがよさそうだ。Brewfileにあれこれ書いておけば、brew bundleでそれらを一気にインストールできる。
homebrewにはcaskという仕組みもある。brewエコシステム自身が持っているパッケージ群だけでなく、brewの外側にある各種ソフトウェアのインストールも自動化できる。本来なら、それぞれのソフトについて、配布しているサイトに行き、手でダウンロードし、手でインストールしなければならない手順も「brew install --cask ほげほげ」で行えるし、Brewfileのなかに書いておけば自動化できる。
同様に、Mac App Storeに行って手でインストールするようなアプリも、masという仕組みでコマンドからインストールでき、自動化もできる。
Brewfileには、先頭にはまず各種のcaskルールを取り込むよう指定する。
tap "homebrew/cask"
caskのルールは Cask Cookbook — Homebrew Documentation を見るとざっとわかる。このアプリはここからダウンロードしてこうやってインストールするんだぜ的なことを記述するDSLだ。
加えて
cask_args appdir: "/Applications"
も書いておく。アプリのインストール先を明示し、かつ、インストールしたアプリがLaunchpadにきちんと登録されるようになるみたいだ。
このあとは、インストールしたいアプリをどんどん記載していく。
あるいは、brew bundle dumpとすると、現状インストールされているアプリが ~/Brewfile にダンプされるので、それを新環境を構築するためのBrewfileの雛形にするのも良いだろう。ただ、/Applications 以下にbrewやcaskやMac App Storeの管理とは関係なくインストールしたものまではbrew bundle dumpは面倒見てくれないので、あくまでも参考になる雛形として使うのがいいだろう。例えば、Mac App Store経由ではなく、わざわざ旧バージョンを入手して使っている /Applications/Xcode.app なんてものは、brew bundle dumpには出てこない。
brew自身が持っているアプリは、単にこんなふうに書けばよい。
brew "ffmpeg"
brew "gnupg"
brew "sqlite"
brew自身のパッケージではないけど、brewのcask機能でインストールしたいアプリも、同様に書ける。便利そうなイメージがわかるだろう。
cask "1password"
cask "abstract"
cask "adobe-creative-cloud"
cask "alfred"
cask "appcleaner"
cask "authy"
cask "dropbox"
cask "google-chrome"
cask "google-japanese-ime"
さらに、Mac App Storeに入ってるアプリはmasで記述すればよい。ただMac App Storeの場合、アプリ名は資本主義社会において似て非なるものが入り乱れたり変化したりするので、unique idも記載する。unique idは「mas search アプリ名」で検索できる。
mas "Microsoft To Do", id: 1274495053
mas "Slack", id: 803453959
ちなみにmas自体は単なるプログラムで、brew install masでインストールされる、brewエコシステム自体が持っているアプリの一つだ。Brewfileにmasの行が含まれていると、brewは自動的にbrew install masしてくれる。なのでBrewfileに「brew "mas"」を記載する必要はないのだが、僕はexplicitlyに書いちゃっている。
そんな感じでBrewfileに必要な道具を記載し、ふだんから適宜メンテナンスしていけば、イザというときにも最小の手間と時間消費で次の仕事Macをセットアップできる。
必ずしもすべてをBrewfileで扱う必要はないが、それはそれで、コメントとして記載していけば「必要なものはすべてこのファイルに書いてある」状態になり、筋のよい一本化になるので、良きだ。たとえばplenvやrbenvはbrewでもインストールできるけど、僕は手でgit cloneして入れてメンテしていくほうが好きだし、これらツールの趣旨やニーズにも合うので、Brewfileには
# brew "plenv" # better install using git clone
というコメントとしてしか書いていない。
あとはbrew bundleすれば、勝手に黙ってどしどしインストールされる。
ただ、その前にいったん手でMac App Storeを起動し、Apple IDでログインしておく必要がある。
あと、インストール中に管理者権限が必要となり、パスワードを聞かれることはしばしばある。うっかりしているとパスワード入力待ちの放置になってしまうので、ときおり端末を見てあげる必要がある。
インストールが終わったら、あとは設定しまくりになるわけだが、入っているソフトをどんどん設定していけばいいわけで、漏れが起きづらい。dotfileのたぐいも普段からgit管理しておけばいいし、パスワード類もすべて1passwordで管理していれば、面倒ではあれど、困らない。
意識すべきは、旧マシンからの ~/.gnupg と ~/.ssh のサルベージだ。さすがにこいつらはgit repoに突っ込むのはどうかな。半自動でgpg暗号してpushすることも考えたが、~/.gnupgを失った自分がdot-gnupg.tar.gz.gpgを前にして呆然とするコメディを想像すると、あんまいけてない。