👾

コマンド一発でAnsible含めて自動でMacの環境構築する

2024/01/24に公開

そういえば以前にM1Maxの特盛MacBookProを買って環境構築するためにAnsibel使って〜というのをまとめようと思ったのに,時間が経ってしまって今度はM2のMacBookAirを購入したので改めてMacの環境構築をすることになった.
これまではbashで諸々のインストールコマンドを叩くようなスクリプトを書いていたのだけど,今回はAnsibleを使った環境構築をしたいと思って記録を残していこうと思う.

前提として

公式ページの説明によると

Ansibleは、プロビジョニング、構成管理、アプリケーションのデプロイメント、オーケストレーション、その他多くのITプロセスを自動化する、オープンソースのIT自動化エンジンです。ソフトウェアのインストール、日常的に行うタスクの自動化、インフラストラクチャのプロビジョニング、セキュリティとコンプライアンスの向上、システムへのパッチ適用、組織全体での自動化の共有に、Ansible自動化を使用できます。
RedHad: Ansibleの基本を学ぶ

ということです.

ちなみにAnsible(アンシブル)というのは映画化もされたEnder's Game(邦題:エンダーのゲーム)をはじめとしたいくつかのSF小説で登場する超光速通信デバイスの名前から来ているらしい[1].光より速いくらい超高速で環境構築出来ちゃうぜ!みたいなノリなのかもしれない.

AnsibleにしろChefにしろ,サーバ側(管理する側)とクライアント側(管理される側)のPCがあって,本来であれば複数のPCの環境構築をそれぞれ行うところを,サーバからのコマンドでクライアント側をまとめて環境構築できるのが良い所.ただChefだとクライアント側にChefをインストールする必要があるところをAnsibleは環境構築される側には何も入れる必要がないというのが特徴のようだ.エージェントレスという説明がされている.

正し,今回はリモートのサーバの環境構築をする訳ではなく,MacでMac自身の環境構築をするというシチュエーションなので,結局最初にAnsibleをインストールしなければならない.
Homebrewは既にあるものとして,brew install ansibleでインストールできる.
(けど今回はこの辺もスクリプトを使って自動化してしまう.)

また,Chefだと少なからずRubyのコードを書く必要があるけど,AnsibleはYAML形式のファイルを書いていくのでコードを書くということは必要がないっぽい.これが便利と捉えるか,どう動いているのかわからんと考えるのかは人に寄りそう.自分はこれまでBashのスクリプトで環境構築していたのでコード書けばいいじゃん的な気持ちはある.

どちらにせよ,Infrastructure as Codeという考え方が重要になってくる.
環境構築をするとどうしても「何を」「どうしたのか」という細かな手順やインストールしたソフトウェアなど,どんな手順で入れた,とか,何を入れたとか,そういうものが分からなくなってしまうので,PCの環境構築に関わることは全てどんな形式であれコードとして記述されたものに従って行うのがヒューマンエラーがなくて良いという考え方だ.
自分がこれまでやっていたBashのコードでもできるだけ汎用性のあるようにやってはいたものの,細かい部分まで自分で書かないといけないので簡単なインストールだけでも割と冗長な処理をする必要があったりして面倒だった.また,冪等性[2]を保つようにコードを書く必要があるので注意が必要になる.

例えば昔はこんな感じのBashファイルをいちいち書いていた

以前に使っていたスクリプトの最初の方を抜き出してみた.

#!/bin/bash

###########
#Xcodeの確認
###########
echo -e "\n\n----------Xcodeの存在確認----------\n"
if type "xcode-select" >/dev/null 2>&1; then
  echo -e "✅ Xcode already exist"
else
  echo -e ">>> Xcode was not exists\n>>> Please install Xcode from AppStore."
  return 2> /dev/null
  exit
fi

###########
# Homebrew
###########
echo -e "\n\n----------Homebrewの存在確認----------\n"
if type "brew" >/dev/null 2>&1; then
  echo -e "✅ brew already exist"
else
  echo -e ">>> Homebrew was not exist\n>>> Please install Homebrew\n>>> [https://brew.sh/index_ja]"
  return 2> /dev/null
  exit
fi

###########
# fishの設定ファイル
###########
echo -e "\n\n----------fish-shell----------\n"
if type "fish" >/dev/null 2>&1; then
	echo -e "✅ fish-shell was already exist\n"
else
	brew install fish
fi

if [ -d ~/.config/fish ]; then
	echo -e "✅ directry ~/.config/fish was already exist\n"
else
	mkdir -p ~/.config/fish
fi
ln -nfs ~/dotfiles/mac/.config/fish/config.fish ~/.config/fish/config.fish

if [ -e ~/.config/fish/functions/fisher.fish ]; then
  echo -e "✅ fisherman was already exist\n"
else
  echo "❌ fisherman was not exist"
  curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
  fish
  fisher -v
fi

if [ -d ~/.config/fisher/github.com/0rax/fish-bd ];then
	echo -e "✅ bd command was already exist\n"
else
	fisher add 0rax/fish-bd
fi

###########
# brew install
###########
echo -e "\n\n----------最低限brew installするやつ----------\n"
brew_install_list=("git" "rmtrash" "nkf" "tree" "wget" "anyenv" "direnv" "peco" "tmux")
for item in ${brew_install_list[@]}; do
	if type $item >/dev/null 2>&1; then
		echo -e "✅ $item was already exist\n"
	else
		echo ">>>$item was not exist"
		brew install $item
	fi		
done

if type "convert" >/dev/null 2>&1; then
	echo -e "✅ imagemagick was already exist\n"
else
	echo -e ">>>imagemagick was not exist"
	brew install imagemagick
fi

if type "nvim" >/dev/null 2>&1; then
	echo -e "✅ neovim was already exist\n"
else
	echo -e ">>>neovim was not exist"
	brew install neovim
fi

けど,いちいちシェルスクリプトで自分で書くのはかなりしんどいので管理が面倒だしやりたくない.

方針

ググってみると色々なベストプラクティス的なのがあるのだけど,自分としては自分のMacを設定するだけなのでできるだけ最小限でやりたい.今回は1ファイルでできるだけ完結できるようなやり方でやってみました(おそらく邪道なのだと思う)
また,本当に最小限の作業で環境構築できるように以下のような流れで環境構築できるように構築することを目指しました

方針としては

  1. 買ってきたMacを開封してAppleIDの設定をする
  2. Homebrewをインストールする
  3. オリジナルのスクリプトを読み込む
  4. ビールを片手に眺める
  5. 手動でしかできなさそうなことを仕方なくする

この流れを目指す

オリジナルのスクリプト部分

自分が作ったスクリプトだとこんな感じ

curl -sfSL setup.shinyaoguri.com | sh -s

これをターミナルに打ち込んで実行するだけでAnsibleのインストールからセットアップまで全ての作業をやってくれます.

ファイル構成としては

shinyaoguri/setup
$ tree
.
├── LICENSE
├── README.md
├── ansible_arm64_mac.yml
├── arm64_mac_setup.sh
├── config.fish
└── setup.sh

↑で最初に入力したコマンドはここのsetup.shを実行しています

setup.shでは,OSを判定して専用のスクリプトを読み込む[3]ことをしています.

読み込まれるスクリプトがarm64_mac_setup.shです.
ここでは,そもそもHomebrewとかAnsibleのインストールをやっています.Ansibleで環境構築したいけど,そもそも最初はAnsibleすら入っていない訳なのでね...

で,インストールしたら最後,ansible_arm64_mac.ymlを読み込んでAnsibleで環境構築する訳です.その際,別のリポジトリdotfilesを落としてきてシンボリックリンクを作ったりもしています.

ansibleのplaybookが1ファイルだけなのでちょっと可読性は低いかもしれませんが,自分はこの方がシンプルで好きです.

手作業でやるもの

例えば,

  • Macのタッチパッドのフィードバックをどうこうする
  • デスクトップ背景をいい感じに変える
  • フォントをインストールする(自動化できそうな気もする)
    • 自動でインストールできるように修正しました
  • 各種アプリケーションのログインや設定など
  • anyenvから各々nodenvとかを入れる(自動化してしまっても良い気がする)
  • AppStoreでインストールするもの
    • 自動でインストールできるように修正しました
  • 等々

作ったもの

https://github.com/shinyaoguri/setup
https://github.com/shinyaoguri/dotfiles

脚注
  1. Wikipedia:アンシブル ↩︎

  2. aws:べき等性とは? ↩︎

  3. 今のところ今回使うarm64のMac用のものだけ作った ↩︎

Discussion