概要
新しい Mac を買ったとき、こんなことをやりますよね。
- Homebrew 入れる
- 開発用 CLI ツール(git, node, docker…)入れる
- VS Code / Slack / Chrome など GUI アプリ入れる
- Finder や Dock の表示設定を自分好みに変える
- SSH 鍵作る、ターミナルをいい感じのテーマにする
これを毎回手作業でやるのが面倒なので、Ansible で自動化することにしました。
ついでに Ansible の概念や使い方も、実践しながら覚えてしまおう という記事です。
尚、全てを完全に自動化することはできないので、「自動化できる部分」「自動化できない部分」も棲み分けしながら書いています。
また、記事の最後に、実際の自動化ファイルの入手方法を公開します。
AI 使わないの?
全ての作業を低レイヤーから AI に任せるのではなく、単純化できるものはプログラムで正確に再現性を担保し、それを AI からも使える様にするのが合理的だと考えています。
AI は優秀なツールですが、計算機ではなく 推論機 です。同じ処理を実行しても出力結果が 100% 同じはになりません。確実に再現性がある出力を期待する場合は、コスト面を見ても、プログラム化することが適切だと考えます。
その意味で、再現性が重要な「環境構築」というタスクは、確実に AI 任せではくプログラム化すべきタスク だと言えます。
また、Ansible を一度用意すれば、手元ですぐに動かせるし、何が導入されるのかを利用者である人間が把握・管理しやすく、AI に処理内容を指示する場合も 「〇〇のインストールも構成に追加して」、「〇〇の設定も構成に追加して、終わったら Ansible のプレイブックを実行して」 などとメンテや管理がしやすいです。
前提
私のマシンスペックです(執筆現在)。
- マシン: MacBook Pro
- チップ: M5
- メモリ: ユニファイドメモリ 32 GB
- ストレージ: SSD 1TB
- OS: macOS Tahoe 26.1
- ツール
- Homebrew 5.0.1
- Ansible 2.19.4
Mac マシンの OS バージョン差で「設定のキー名」が変わることもあるので、Playbook(※ 後述)を作るときは実機で動かしながら微調整する イメージで見てください。
Ansible とは?
Ansible(アンシブル)とは、ざっくり一言でいうと、「サーバーや PC の "ソフトウェアのインストール"、"初期設定"、"環境構築" などを、コード(YAML 形式)で自動化できるツール」 です。
「このマシン(PC, サーバー)はこういう状態になっていて欲しい」 という "あるべき姿" を YAML で宣言しておき、その宣言が書かれた YAML ファイルを Ansible に渡すと 足りないものだけ入れて、設定を反映してくれます。
音楽でいろんな楽器が集まった演奏・団体を "オーケストラ" と言いますが、IT の文脈では、異なるツールや設定管理を「協調的に」管理することを "オーケストレーション" と呼んだりします。
Ansible は、PC やサーバー等のマシンに対して、複数のインストールや設定を自動化できるため、オーケストレーションツール とも呼ばれます。
何が嬉しいのか
- なによりも、マシンの初期設定や構築作業が自動化できる。楽。
- 自動構築のレシピを何度実行しても、レシピの中の「足りないものだけ」を補完してくれる
- 他のオーケストレーションツールより軽量で簡単
- 管理・メンテナンスがしやすい
- 変数を切り出すことができるので、同じ構成の自動構築を、異なる ID / アカウント に対して自動化できる
- YAML 形式で宣言を用意するので見やすい
- YAML ファイルを分割してモジュール化もできるので管理しやすい
今回の使い方
オーケストレーションの考え方には、「ターゲット」と「ホスト」という概念があります。
- ターゲット(または、リモート):処理される側。つまり、自動構築の処理対象。通常は「エージェント」と呼ばれるツールが導入されるが、Ansible の場合は導入不要
- ホスト(または、マネージド):処理する側。こちら側に Ansible がインストールされる
本来は、遠隔操作で複数のマシン(ターゲット)に対して、SSH で同じ環境を再現できる技術 ですが、今回は Ansible が入るマシン自体(ホスト)にに対して、導入・自動構築をする方法 を紹介します。
今回は、個人向けの環境構築自動化としての内容で、会社の情報システム部門の方が新入社員のPCを用意する場合や、研究開発チームが複数のマシンを用意して環境構築する場合などは、本来の使い方である「ホストマシンから SSH で環境構築する」という使い方が有用です。
しかし、組織向けにも利用できることは可能なので、もしバックオフィス業務で「毎回 PC の準備作業・環境構築が大変だ」などの悩みがある方は、1つの参考にしていただければと思います🙌
本記事の最後に、自動化ファイルと使い方のメモを同梱した GitHub リポジトリを公開中です(突然、変更・非公開にする可能性もありますので、ご了承ください)
特徴
Ansible のよく出てくる特徴を、Mac 初期設定に絡めて整理するとこんな感じです。
-
エージェントレス
- 処理対象(ターゲット)に「エージェント」と呼ばれる専用ソフトを入れなくていい
- 競合製品である "Chef"(シェフ) などは、エージェントが必要
- 基本は
ssh(ローカルの場合はconnection: local)で動く
- 処理対象(ターゲット)に「エージェント」と呼ばれる専用ソフトを入れなくていい
-
宣言的(「あるべき状態」を書く)
- 「Chrome がインストールされていること」
「Finder の拡張子表示が ON であること」
という ゴール状態を YAML に書く
- 「Chrome がインストールされていること」
-
冪等(べきとう)性
- すでにその状態なら「何もしない」
- 足りないものだけ入れてくれる
- 何回実行しても、結果は同じになる という性質のこと
-
YAML で読める・書ける
- JSON ほどカタい感じじゃなく、
「設定ファイル」という感覚でスッと読める
- JSON ほどカタい感じじゃなく、
詳細は、「Red Hat の解説ページ」や、「公式ドキュメントページ」などでも確認できます。
Ansible の基本的な使い方
Ansible について、基本的な概念と使い方をざっくりと説明します。
ただし、ホストマシン自身に環境構築をする前提の基礎知識です。
1. インベントリ(どのマシンに対して実行するか)
ホストマシンとなる Mac 自身に対して実行するので、このファイルは 今回不要です。
ただ、本来はターゲットを指定した以下のようなファイルを用意します。
myhosts:
hosts:
my_host_01:
ansible_host: 192.0.2.50
my_host_02:
ansible_host: 192.0.2.51
my_host_03:
ansible_host: 192.0.2.52
2. Playbook(何をするか)
例えば、ローカルマシンに Homebrew で Google Chrome ブラウザを入れたい場合:
- hosts: localhost # ローカルマシンを指定
connection: local # ローカルへの接続設定
tasks:
- name: Homebrew で Google Chrome ブラウザを入れる
community.general.homebrew_cask:
name: google-chrome
state: present
- name: Gitユーザー名を設定
git_config:
name: user.name
scope: global
value: "Your Name"
- name: Gitメールアドレスを設定
git_config:
name: user.email
scope: global
value: "your.email@example.com"
以下の例のように、「何度実行しても同じ結果になる」 様に書く必要があります。
- Git のユーザー名が既に設定されてたら、Git のユーザー設定処理をスキップする
- SSH 鍵が既に存在したら、同じ名称の鍵作成はスキップする
- 設定に必要な前提となるコマンドやデータが存在しなかったら、その設定処理はスキップする
3. 実行する
プレイブックを実行すれば、設定内容を実行してくれます。
ansible-playbook setup.yml
実践的な使い方
上記は最低限の動作手順ですが、実際には以下の様な方法を併用して、柔軟に再利用できるように変数を活用します。
1. 変数ファイルを利用する
上記の例では、Git のユーザー名やメールアドレスの設定値をベタ書きしています。
しかし、そこだけ別の値に書き換えようとすると、他の記載を間違って変えてしまったり、設定内容が縦長になると探しにくかったりします。
また、GitHub などで管理するときに、プレイブックを共有する場合は、設定ファイルだけを変更すればチームで再利用しやすくなります。
なので、そういった値は、以下のように変数専用の設定ファイルに切り出します(名前は任意で OK)。
---
# Git設定
git_user_name: "Your Name"
git_user_email: "your.email@example.com"
git_editor: vim
# ...他の変数も必要に応じて追加...
変数を使った書き方に変更
- hosts: localhost
connection: local
# 変数設定ファイルを呼び出す
vars_files:
- vars.yml
tasks:
- name: Gitユーザー名を設定
git_config:
name: user.name
scope: global
value: "{{ git_user_name }}" # 変数を使用
- name: Gitメールアドレスを設定
git_config:
name: user.email
scope: global
value: "{{ git_user_email }}" # 変数を使用
2. ファクト(facts)を利用する
ファクト(facts)とは、Ansible が自動で収集する、ターゲットマシン固有情報 です。
環境構築対象の「IPアドレス」「ホスト名」「ホームディレクトリパス」などの固有情報を指し、Ansible はこれを自動で収集して変数として利用することができます。
ファクトを使えば、同じ環境構築を、複数の異なるホスト名のマシンに、固有のユーザー名などを使って自動化できるということです。
ファクト(facts)の確認方法
ファクトとして収集・利用できる情報は ansible localhost -m setup で確認できます。
# 確認コマンド
$ ansible localhost -m setup
# 実行結果
[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | SUCCESS => {
"ansible_facts": {
"ansible_architecture": "arm64",
"ansible_date_time": {
"date": "2025-11-15",
"time": "20:12:50",
"tz": "JST",
"weekday": "土曜日",
"weekday_number": "6",
},
"ansible_distribution": "MacOSX",
"ansible_dns": {
"nameservers": [
"192.168.1.1"
]
},
"ansible_env": {
"ANTHROPIC_API_KEY": "sk-ant-*****", # AI ツールの API key なども取得できる
"HOME": "/Users/{ユーザー名}",
"HOMEBREW_CELLAR": "/opt/homebrew/Cellar",
"HOMEBREW_PREFIX": "/opt/homebrew",
"HOMEBREW_REPOSITORY": "/opt/homebrew",
"INFOPATH": "/opt/homebrew/share/info:/opt/homebrew/share/info:",
"LANG": "ja_JP.UTF-8",
"USER": "{ユーザー名}",
},
"ansible_hostname": "{ホストマシン名}",
:
:
:
},
"changed": false
}
オプション -a "filter=***" で、特定の情報だけフィルタリングできます。
# 確認コマンド (ansible_env だけを確認)
$ ansible localhost -m setup -a "filter=ansible_env"
# 実行結果
[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | SUCCESS => {
"ansible_facts": {
"ansible_env": {
"ANTHROPIC_API_KEY": "sk-ant-*****",
"HOME": "/Users/{ユーザー名}",
"HOMEBREW_CELLAR": "/opt/homebrew/Cellar",
"HOMEBREW_PREFIX": "/opt/homebrew",
"HOMEBREW_REPOSITORY": "/opt/homebrew",
"INFOPATH": "/opt/homebrew/share/info:/opt/homebrew/share/info:",
"LANG": "ja_JP.UTF-8",
"USER": "{ユーザー名}",
},
},
"changed": false
}
ファクト(facts)の使い方
プレイブックでは、gather_facts フラグを有効化することで、ファクト情報を収集・利用できます。
- hosts: localhost
connection: local
# ファクトを自動収集する設定
gather_facts: yes
tasks:
- name: SSH鍵ディレクトリの存在確認
file:
path: "{{ ansible_env.HOME }}/.ssh" # ansible_env の HOME を使用する
state: directory
mode: '0700'
3. タスク(Role)を分割する
プレイブックに全ての処理を書くと、導入・設定が増えるほど縦長になりメンテナンスが難しくなってしまいます。
処理内容を見直したり構成を変えたりする際は、実行タスクをブロック毎に分けておいた方がメンテナンスが楽になります。そのために、"Role" という仕組みを利用して、roles/task/***.yml にタスクを分けましょう。
Git 設定をまとめる
---
- name: Gitをインストール
homebrew:
name: git
state: present
- name: Git設定ファイルの場所を確認
stat:
path: "{{ ansible_env.HOME }}/.gitconfig"
register: gitconfig_check
- name: Gitユーザー名を設定(未設定の場合)
git_config:
name: user.name
scope: global
value: "{{ git_user_name }}"
when: git_user_name is defined
- name: Gitメールアドレスを設定(未設定の場合)
git_config:
name: user.email
scope: global
value: "{{ git_user_email }}"
when: git_user_email is defined
SSH 鍵の生成処理をまとめる
---
- name: SSH鍵ディレクトリの存在確認
file:
path: "{{ ansible_env.HOME }}/.ssh"
state: directory
mode: '0700'
- name: SSH鍵の存在確認
stat:
path: "{{ ansible_env.HOME }}/.ssh/{{ ssh_key_name }}"
register: ssh_key_check
- name: SSH鍵を生成
openssh_keypair:
path: "{{ ansible_env.HOME }}/.ssh/{{ ssh_key_name }}"
type: "{{ ssh_key_type | default('ed25519') }}"
size: "{{ ssh_key_size | default(omit) }}"
comment: "{{ ssh_key_comment }}"
state: present
when: not ssh_key_check.stat.exists
Role を分けた処理を呼び出す
---
- name: MacBook Pro セットアップ
hosts: localhost
connection: local
gather_facts: yes
vars_files:
- vars.yml
# 分割した Role を順に実行する
roles:
- git
- ssh_key
4. ansible-galaxy / コレクション を使用する
Git や Homebrew などの便利ツールは、Ansible コミュニティのネットワーク上に既に部品として公開されています。それらを使って導入すると、構築が楽に早く済みます。
-
ansible-galaxy: Ansible における パッケージ管理ツール の様なものです(Node.js でいう
npm、Python でいうpip、Ruby でいうgem的な位置付け) -
Collection(コレクション):
ansible-galaxyコマンドで使用できる、Ansible の機能拡張パッケージ そのものを指します(Node.js で例えるとnode_modules)。具体的には以下- モジュール(
homebrew_caskなど) - プラグイン
- ロール
- ドキュメント
- モジュール(
具体的な使い方
Homebrew を使って Chrome ブラウザや Cursor エディタなどを導入する Role を作成(※ 事前に Homebrew が手動 or Ansible で導入されている前提)
community.general というコレクションの中にある homebrew_cask というモジュールを使って、Homebrew を使うことができます(brew install などが使えます)。
- name: Homebrew で各アプリケーションをインストール (Cask)
community.general.homebrew_cask: # 👈 ここで コレクションとモジュールを指定
name:
- visual-studio-code # 👈 ここに brew install したいものを列挙
- cursor
- google-chrome
- discord
state: present
become: false
プレイブックのファイル等で事前にコレクションを宣言すれば、名前空間の記載を 省略 して、モジュール名のみにすることもできます。
---
- name: プレイブック
hosts: localhost
connection: local
collections:
- community.general # 👈 ここで使用を宣言する
tasks:
- name: Homebrew で各アプリケーションをインストール (Cask)
homebrew_cask # 👈 コレクション名を省略できる
name:
- visual-studio-code
- cursor
- google-chrome
- discord
state: present
git_config などは Ansible のコア ansible.builtin に含まれるるモジュールのため、最初から省略して問題ないです。
# モジュール名のみで記載(通常)
- name: Gitメールアドレスを設定(未設定の場合)
git_config: # 👈 簡単に記載
name: user.email
scope: global
value: "{{ git_user_email }}"
# 名前空間も明示する場合
- name: Gitメールアドレスを設定(未設定の場合)
ansible.builtin.git_config: # 👈 詳細に明示
name: user.email
scope: global
value: "{{ git_user_email }}"
インストール済みのコレクションを確認
「そもそも、いま何のコレクションが入っているんや?」 などを確認する方法です。
以降のコマンド全てを使う必要はないですが、パッケージ類の存在や中身を確認する方法として有用です。
# 現在、インストール済みのコレクション一覧
ansible-galaxy collection list
# community.generalが含まれているか確認
ansible-galaxy collection list | grep community.general
コレクション内のモジュール一覧を表示
# community.generalのドキュメント一覧
ansible-doc -l | grep community.general
# より見やすく表示
ansible-doc -l community.general
特定のモジュールのドキュメントを表示
# openssh_keypairモジュールのドキュメント
ansible-doc community.general.openssh_keypair
# homebrewモジュールのドキュメント
ansible-doc community.general.homebrew
インストール先のファイルを直接確認
# インストール場所を確認
ansible-galaxy collection list community.general --format yaml
# 実際のファイルを確認 (上記)
ls -la {「インストール場所を確認」で取得した "ansible_collections" までのパス}/community/general/
# (Opt) Windows など、Homebrew で Ansible を導入していないケースでは、通常以下のパス
ls -la ~/.ansible/collections/ansible_collections/community/general/
# プラグイン一覧
ls -la {「インストール場所を確認」で取得した "ansible_collections" までのパス}/community/general/plugins/modules/
# (Opt) Windows など、Homebrew で Ansible を導入していないケースでは、通常以下のパス
ls ~/.ansible/collections/ansible_collections/community/general/plugins/modules/
詳細は、オンラインでも調べられます(以下、GitHub リポジトリ)。
5. "冪等性" を担保する様に書く
Ansible 自体は 冪等(べきとう)性 を保つ作りになっていますが、自分で書く宣言内容も 冪等性 が守られるように意識しましょう。
❶ 存在確認には、Shell モジュールよりファイルシステムモジュールを使用する
冪等性を保つために 「すでにツールはインストールされているか?」 を確認する際、Shell(シェル) で確認するのではなく、Ansible が提供する ファイルシステムモジュール を採用することが推奨されます。
-
Shell モジュール
- 目的 : シェルコマンドを実行する
- 特徴 : パイプ、リダイレクト、環境変数などシェルの機能が使える
- 例1 :
shell: echo $HOME | grep user - 例2 :
java --version,which javaなど
-
ファイルシステムモジュール
-
stat: ファイル/ディレクトリの存在や属性を確認 -
file: ファイル/ディレクトリの作成、削除、権限変更 -
copy: ファイルのコピー -
template: テンプレートファイルの展開
-
# shellモジュールでチェックする (非推奨)
- shell: test -f /path/to/file
# stat モジュールでチェックする (推奨)
- stat:
path: /path/to/file
Ansible の仕様上、ファイルシステムでチェックした方が、予期しない副作用がなく安全で、冪等性を保証できるためです。
また、後述する if 分岐(条件分岐)を考慮する際も、ファイルシステムの方が宣言が直感的で分かりやすいです。
# Shell コマンドで確認する方式(非推奨)
- name: Homebrew がインストールされているか確認
command: which brew
register: homebrew_check
failed_when: false
changed_when: false
- name: Homebrew をインストール
shell: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
when: homebrew_check.rc != 0 # 👈 条件分岐
# ------------------------------
# ファイルシステムで確認する方式(推奨)
- name: Homebrew がインストールされているか確認
stat:
path: /opt/homebrew/bin/brew
register: homebrew_check
- name: Homebrew をインストール
shell: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
when: not homebrew_check.stat.exists # 👈 条件分岐
❷ 条件分岐で実行/スキップを制御する
Ansible では「if 文」のような 条件分岐 が可能です。
-
registerで判定対象を変数化し、whenで変数を確認して条件を判定 - ファイルシステムの
statを使えば、{変数}.stat.existsで存在確認が可能 -
notを使って、true/false を反転できる
「Homebrew がまだインストールされていなかったら、インストールする」の例
- name: Homebrew がインストールされているか確認
stat:
path: /opt/homebrew/bin/brew
register: homebrew_check # 👈 ❶ 結果を格納
- name: Homebrew をインストール
shell: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
when: not homebrew_check.stat.exists # 👈 ❷ 存在確認
何が起きているか?
stat を使ってファイルパスが存在すれば true, なければ false の結果に。
↓
register にその結果を格納する。
↓
when で結果を判断。「存在していない(not で反転し true となる)」場合のみ、インストールステップを実行する
このようなフローで、未設定のものだけを実行 して、冪等性を担保します。
when ディレクティブの条件判定方法には色々ある
上記の 変数.stat.exists 以外にも色々と条件判定に使えるものがあ流ので、一部だけ紹介します。
-
定義済みか否か:対象の変数が定義されているかどうかをチェック。意外とよく使います
変数 is defined変数 is not defined
-
比較演算子:2つの値を比較する
X == YX != YX > YX <= Y- などなど...
-
論理演算子:論理和、否定など
条件A and 条件B条件A or 条件B-
not条件` - and 結合する場合は、こんなふうにも書ける
when: - 条件A - 条件B
-
含む/含まない:配列に該当する値が含まれるかなどをチェック
-
A in [X, Y, Z](値A が含まれていたら true) -
A not in [X, Y, Z](値A が含まれていなかったら true)
-
※ 今回、反復処理(loop) については、不要なので触れません。
Homebrew の冪等性の保証
Homebrew のインストールはリスト形式でまとめて指定しますが、state の部分が present に設定されていれば冪等性が保たれます。
- 導入済みの場合 : スキップ(変更なし)
- 未導入の場合 : インストール実行
- name: Homebrew パッケージをインストール (Formulae - CLI)
community.general.homebrew:
name:
- docker
- uv
# ...他にも色々
state: present # 👈 ここが "present" なら OK
become: false
- name: Homebrew アプリケーションをインストール (Cask - GUI)
community.general.homebrew_cask:
name:
- visual-studio-code
- google-chrome
- slack
# ...他にも色々
state: present # 👈 ここが "present" なら OK
become: false
自動化の事前準備
では、基本的な使い方やコツを踏まえた上で、いよいよ自動化していきましょう。その前に事前にしなければいけないことがこちら💁♂️
PC 初期設定時に含まれるやつ
PC を購入した場合、最初に以下の手順をすることになる(はず)。
-
iCloud 設定(Apple アカウントにサインイン)
- ログイン後に、本当にサインインされているか、念のため確認しておくのが良い
-
OS アップデート自動設定
- PC の自動アプデ設定を ON にする
手動で導入が必要なもの
まず、必要なツールをインストールして、Ansible が動くところまでを手でやります。ここは自動化しづらい部分です。
Command Line Tools のインストール
macOS だと必ず必要なコレ(※ かなり時間かかります。コーヒーでも飲みながらゆっくり待ちましょう☕️)
xcode-select --install
Homebrew のインストール
多くのツールは、Ansible 内でこれを使って導入されます。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
公式ページはこちら
Homebrew インストールコマンド実行時は以下のように入力を求められる。
# こう表示したら、パスワードを入れて Enter キー(入力内容は表示されません)
==> Checking for `sudo` access (which may request your password)...
Password:
# 途中でこう聞かれたら Enter キーを押す
Press RETURN/ENTER to continue or any other key to abort:
# 再びパスワードを聞かれるので、入力して Enter キー
==> /usr/bin/sudo /usr/bin/install -d -o root -g wheel -m 0755 /opt/homebrew
Password:
# 処理が完了して入力できる状態が返ってくるまで、しばらく待ちましょう〜☕️
# 以下に、次に実行すべきコマンドが表示されます。1行ずつコピペで実行しましょう
==> Next steps:
- Run these commands in your terminal to add Homebrew to your PATH:
# ① 以下を実行します👇
echo >> /Users/{ユーザー名}/.zprofile
# ② 次に、以下を実行します👇
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/{ユーザー名}/.zprofile
# ③ 最後に、以下を実行します👇
eval "$(/opt/homebrew/bin/brew shellenv)"
- Run brew help to get started
- Further documentation:
https://docs.brew.sh
最後の書き込みコマンドが成功したか確認
# 確認コマンド(先頭の "$" マークはコピーしないでください)
$ cat .zprofile
# 以下が表示されていれば OK
eval "$(/opt/homebrew/bin/brew shellenv)"
Ansible のインストール
Homebrew を使って Ansible を導入します。以下のコマンドでインストールしましょう。
brew install ansible
尚、Ansible をインストールすると、Python で動くツールなので、Python も一緒に自動でインストールされます(ただし、コマンドは python3)。他にも、OpenSSL や SQLite(DB)、Tree など色んなものが同梱されます。
% brew list
==> Formulae
# Ansible のインストールで一緒に入った CLI ツールたち
ansible cffi libssh openssl@3 readline xz
ca-certificates cryptography libyaml pycparser sqlite
certifi libsodium mpdecimal python@3.13 tree
==> Casks
# ここ(GUI ツール)はまだ何もインストールされない
自動化の手順
各種ファイルを自分で用意し、実際のそれを使って実行するまでの手順です。
ディレクトリ/ファイルを用意
ファイルの中身は空っぽのままで良いので、必要な設定作業やインストールしたいツールの分だけディレクトリとファイルを用意する。
/ 管理ディレクトリ
├── README.md # どんな設定がされるか、導入されるツール、使い方などを簡単に記載
├── roles # プレイブックによって自動化するタスクを配下に用意
│ ├── git # 例1 )Git インストール・初期設定など
│ │ └── tasks
│ │ └── main.yml
│ └── ssh_key # 例2 )SSH 鍵の作成・初期設定など
│ └── tasks
│ └── main.yml
├── setup_macbook.yml # 実際にコマンドで呼び出す「プレイブック」
└── vars.yml # ユーザー名・メールアドレス等の個人情報などをまとめる設定ファイル
変数を外部に切り出す
メールアドレスやユーザー名などのアカウント情報などは、変更しても処理に影響がないように設定専用ファイルとして用意しておく。
---
# Git 設定
git_user_name: "Your Name"
git_user_email: "your.email@example.com"
git_editor: vim
# SSH 鍵設定
ssh_key_name: id_ed25519 # ペア鍵のファイル名となる
ssh_key_comment: "custom@hostname" # コメントアウトすると自動生成
Ansible プレイブック用意
---
- name: MacBook Pro セットアップ # プレイブック名
hosts: localhost # ローカルホストを指定
connection: local # ローカルホストを指定
gather_facts: yes # ターゲット(今回はホストマシン)の情報を自動収集する
vars_files:
- vars.yml
vars:
# デフォルト値(vars.ymlで上書き可能)
ssh_key_comment: "{{ ansible_env.USER }}@{{ ansible_hostname }}"
roles:
- homebrew
- git
- ssh_key
実行
プレイブックを実行して環境構築を待ちましょう☕️
ansible-playbook setup_macbook.yml
最後に、導入確認 して終わり(完)。
以上で、ある程度のツールを自動で導入できました 🙌
予めプレイブックを用意しておけば、「実行」するだけで、新しく購入したマシンや他のマシンにも環境構築を再現できます。
今回導入・設定したもの
※ 手動で入れたものも含む
| # | 導入・設定内容 | 用途など |
|---|---|---|
| 1 | Command Line Tools | macOS で必要になる基本ツール(手動) |
| 2 | Homebrew | macOS/Linux 用のパッケージ管理ツール(手動) |
| 3 | Ansible | オーケストレーションツール(手動) |
| 4 | uv | Python 管理ツール |
| 5 | Podman | コンテナツール(Docker の代わり) |
| 6 | Podman Desktop | コンテナツール(Docker Desktop の代わり) |
| 7 | VS Code | 開発エディタ |
| 8 | Cursor | 開発エディタ |
| 9 | Windsurf | 開発エディタ |
| 10 | Zed | 開発エディタ |
| 11 | Android Studio | 開発エディタ |
| 12 | IntelliJ IDEA | 開発エディタ(CE: Community 版) |
| 13 | Google Chrome | Web ブラウザ |
| 14 | Brave | Web ブラウザ |
| 15 | ChatGPT Atlas | Web ブラウザ |
| 16 | Slack | コミュニケーションツール |
| 17 | Discord | コミュニケーションツール |
| 18 | Zoom | ビデオ会議ツール |
| 19 | ChatGPT | AI アシスタント(デスクトップ用) |
| 20 | Claude | AI アシスタント(デスクトップ用) |
| 21 | Claude Code | AI アシスタント(CLIツール) |
| 22 | Codex CLI | AI アシスタント(CLIツール) |
| 23 | Gemini CLI | AI アシスタント(CLIツール) |
| 24 | Warp | AI アシスタント |
| 25 | LM Studio | ローカル LLM 実行環境 |
| 26 | Ollama | ローカル LLM 実行環境 |
| 27 | Godot | ゲームエンジン |
| 28 | ffmpeg | マルチメディアフレームワーク |
| 29 | AWS CLI | AWS 管理ツール(CLI) |
| 30 | Firebase CLI | Firebase 管理ツール(CLI) |
| 31 | Vercel CLI | Vercel 管理ツール(CLI) |
| 32 | Volta | パッケージ管理ツール(JS 系) |
| 33 | Git | バージョン管理ツール |
| 34 | Git 初期設定 | 変数ファイルにセットした値で自動設定 |
| 35 | SSH 鍵作成 | 変数ファイルにセットした値で自動生成 |
| 36 | SSH 設定 | GitHub から SSH でクローンなどするための設定 |
| 37 | GitHub CLI | GitHub CLI 導入 |
| 38 | OS設定(副ボタン設定) | トラックパッドの副ボタンを「二本指でタップ」に設定 |
| 39 | OS設定(DT 表示設定) | デスクトップのアイコン配置を「グリッドに沿う」に設定 |
| 40 | OS設定(Finder 表示設定) | Finder の初期表示をホームディレクトリに設定 |
| 41 | OS設定(Finder 表示設定) | Finder のパスバーを表示 |
| 42 | OS設定(Finder 表示設定) | Finder のステータスバーを表示 |
| 43 | OS設定(ファイル拡張子) | ファイルの拡張子を常に表示 |
これが完全放置で導入・設定完了するのは非常に助かりました 🙌✨
※「私、開発エディタ入れすぎだなぁ〜」と感じました。。
構成に書いたけど入れなかったもの
「プレイブックのコメントアウトを外して有効化したらすぐ入る。だけど、重たいし今はいいや…」 と思って入れなかったものです。
| # | 導入・設定内容 | 用途など |
|---|---|---|
| 1 | Microsort 365 スイート | Office ツール全部入りのやつ |
| 2 | Unity Hub | Unity 含む、パッケージ管理ツール |
| 3 | Docker/Docker Desktop | コンテナツール(Podman を入れたので不要) |
自動化できず入らなかったもの
-
Xcode: macOS/iOS のアプリ開発エディタです。これは手動で入れましょう。
- 常に最新版を使う人:App Store から入手
- 特定バージョンで固定したりバージョンダウンするケースがある人:Apple Developer サイトから入手
- Comet: Perplexity の Web ブラウザ。まだ Homebrew などの方法がなかったため。
まとめ
- Ansible は環境構築などを自動化できる 「オーケストレーションツール」
- インストールするツールや PC 設定などを "レシピ化" することができる
- 宣言的なので、メンテ・管理が楽
- AI との相性も◎。(使わせる、構成を考えさせる等)
- 冪等(べきとう)性 を保つのがコツ
- "コレクション" を活用して有名なツールの導入・設定も簡単に
Ansible のプレイブックを公開します
実際に利用可能な Ansible のファイルを GitHub に公開します。ライセンスもありません。
欲しい方は、以下に注意した上で、ご自由にダウンロード・クローンして再利用いただけます(コミットやプッシュなどはできません)。
免責事項
インストールや設定内容は、必ずご自身の利用マシンに合わせた内容に修正してからご利用ください。利用にあたって発生する事象やエラー、損害等については、当方は責任を負いません。予めご了承ください。
おまけ:なぜ Homebrew と Ansible の導入は自動化しなかったのか?
まず、前提知識をお伝えすると
- Ansible は Python が入っていれば
pipインストールで導入が可能 - Homebrew は
〜/install.shのコマンドを叩けば導入が可能なので、Ansible が先にあれば自動化可能
つまり、「Python さえあれば Ansible をインストールできるのだから、他のツールも含めて Homebrew のイントールから自動化できたのではないか?」 と言う疑問にぶつかります。それは当然の疑問だと思います。
結論、「好みの問題」 ではあります。
ただ、私の観点は "できるだけ管理コストを減らしたい" を優先しました。
メリット/デメリットの比較
1. Python と Ansible のみ手動でインストールする方式
- メリット:Homebrew の導入部分から自動化できる
- デメリット:
- マシンにグローバルで pip インストールするので、グローバルパッケージを汚す(汚さない方法もあるけど、やや面倒だった)
- Homebrew を使うことが前提の構成なので、pip インストールだと、Homebrew に加えてパッケージを管理する場所(気にする場所)が増える
- 現在の macOS はデフォルトで Python が入らなくなった(正確には、Apple 標準の Python ランタイムが廃止された)ため、結局何かしらの管理ツールで Python を入れる必要がある。しかし、Homebrew 以外で Python をする場合、個別のインストール作業をするか、別のパッケージ管理ツールを使い、管理する場所(気にする箇所)が増える
2. Homebrew まで手動でインストールし、Ansible も brew で導入する方式
- メリット:
- Ansible を最初に導入すれば、Python を含めて必要なツールは同時に全て入る
- Ptyhon の管理も、Ansible の管理も、アップデートを含めて Homebrew で完結できて楽
- グローバルの pip も汚さない
- デメリット:Homebrew と Ansible を手動で入れなければならない
天秤にかけた結果、Homebrew までは手動にする方がメリットを感じた
Python をゴリゴリ使う環境のユーザー、あるいは、そもそも brew コマンドが使えない Windows ユーザーならば、Python の管理ツールを導入・運用すると思うので、Homebrew 手動前提でなくて良いと思います。
ただ、私は Python 自体を管理ツールを使ってまで管理・運用する機会はそこまで多くなく、Homebrew で管理する方が総合的に楽で、管理・運用面でも十分であったため、Homebrew 以降の作業を自動化する方針を採用しました。
(都合上、導入したツールの中に uv を入れていますが、使用頻度はかなり低い)
そもそも Homebrwe のインストール、Ansible のインストールは非常に軽量なので、初期設定の数が増えることのデメリットは非常に小さいと感じ、将来的なメンテが長期的に懸念される方が、比較的には負担だと感じたのです。
👉 イニシャルコスト < ランニングコスト の観点
ただし、冪等性を保証するために、タスクの手前で 「万が一、Homebrew が無かったらインストールする」 というステップは必要に応じて入れています。
本記事の内容や観点は、あくまで一つの参考としてご検討くださいませ。