面倒な開発環境の構築はchezmoiに任せよう
この記事は「ビギナーズ Advent Calendar 2025」の10日目の記事です。
はじめに
本記事の執筆には、誤字脱字チェックや表現の調整のみに生成AIを活用しています.
また筆者の心の声を以下のようにトグルで記載しています.
心の声
せっかく心を込めて執筆した記事でも上記のような注意書きをしないと疑わなければいけない世の中,チョットツライ
TL;DR
以下の状況を前提としたうえで,chezmoi(公式DOC)を利用して開発端末のセットアップ速度向上を目指します.
- 流動性の高いプロジェクトでソフトウェア開発をする
- メンバーの開発能力がそこまで担保されていない
- メンバーは参画する時にまっさらな状態の端末を利用開始する,または既に所属している人が参画者ごとにセットアップを実施する
対象読者
主にJTC(出典)と俗に表現されるSIerまたはSES企業においてソフトウェア開発業務に関するプロジェクトに所属する方を対象読者とします.
また,JTCの深淵を覗いてみたいモダン企業のエンジニアでも楽しめるようにユーモア強めで執筆したいと思います.
心の声
多重下請け構造やこれに伴うルール自体を根本的に改善するのは難しく,大変多くの時間と労力がかかります.
そこで小手先の技術を導入することでチームビルディングのうちのPCセットアップを効率化して爆速で新しいメンバーに開発に携わってもらおうという魂胆です.
流動性の高いチームにおけるソフトウェア開発の問題点
人月で工数や費用を計上する大規模なプロジェクトではチームメンバーの流動性が極めて高い場合が多いです.
1ヶ月単位で開発メンバーが増減・入れ替えが発生することによりプロジェクト自体のキャッチアップや開発環境の構築が必要なタイミングが多く,これだけで少なくないコストがかかります.
以下はこの事実から考えられる問題点をまとめた表になります.
| 問題点ID | 問題点 | 困る人 |
|---|---|---|
| PRB_0 | 開発環境の変更が必要な度に環境構築書類の更新作業が発生する | 既存メンバ |
| PRB_1 | 環境構築書類が最新版でない場合,プロジェクト設定ファイルの理解や既存メンバへのヒアリングが必要 | 新規開発者,既存開発者 |
| PRB_2 | 自力でセットアップすることが困難なメンバも少なからず参画することにより,既存開発者のリソースを新規参画者に回す必要がある | 既存開発者 |
| PRB_3 | 開発者ごとに貸与されるPCのOSが異なる場合がある | 開発者全員 |
これらの問題点を起点として要件を確認してみました.
何をしたいのか
先述の問題点から必要な機能要件をまとめたものが以下の表です.
| 機能ID | 概要 | 解決する問題点 | 詳細 |
|---|---|---|---|
| REQ_0 | 手順書の軽量化 | PRB_0, PRB_2 | 書類管理に掛かるコストを継続的に削減したい |
| REQ_1 | 開発環境への追従 | PRB_0, PRB_1 | 最新の開発環境に継続的に追随できるようにしたい |
| REQ_2 | 複数プロジェクトへの対応 | PRB_3 | WEBアプリのみならずネイティブアプリ開発にも対応したい |
上記の要求を解決する方法を情報収集をしたところ,結論としてはchezmoi(公式DOC)と呼ばれるOSSに出会いました.
chezmoiとは
chezmoi(発音記号:ʃe-mwa;カタカナフランス語:シェモア)はフランス語で「私の家」という意味とのことです.
自分の家のレイアウトを管理するように,自分の端末の開発環境を管理できるツールです.
Dotfileを管理することが主軸のツールではありますが,今回はこのchezmoiを用いてできるかぎり要件にそった環境構築手法を構築してみました.
心の声
フランス語って読みづらいですけど、なんとなくおしゃれに感じてしまいますね.
chezmoiが提供する機能
今回の機能要件を満たすためにchezmoiが提供する機能(非機能要件)をまとめたものが以下の表です
| 非機能ID | 概要 | 対応する機能 | 詳細 |
|---|---|---|---|
| FET_0 | One-lineバイナリで実行可能 | REQ_0 | curlやwget等で実行できるため導入手順が少なくなる |
| FET_1 | 設定ファイルで管理可能 | REQ_1 | Git管理してGitHubにアップロードし,リポジトリ参照で環境構築が可能 |
| FET_2 | 設定ファイルをテスト可能 | REQ_1 | CI上で設定ファイルが形式的に有効かどうかをチェック可能 |
| FET_3 | 冪等性を意識した実装が可能 | REQ_1 | (もちろん実装によりますが)shellスクリプト等を用いて既にインストール済みのツール検知などができるため,冪等性を担保することも可能.これにより既に環境構築済みのエンジニアにも過不足なく差分だけ適用可能 |
| FET_4 | 複数のOSに対応 | REQ_2 | 概ね有名どころのOSはサポートされている |
概ね期待する機能がchezmoiに実装されていることが分かったので,実装に移りましょう.
既存の環境セットアップフロー
本記事ではMacにおけるHomebrewを経由した環境構築を例に挙げます.
既存のプロジェクトでは以下に相当する内容が手順書に書かれており,1ページずつ開発者が確認と実行を行なっていました.
- ターミナルを開いてね
- 「 https://brew.sh/ja/ 」 にアクセスしてコマンドをコピーしてね
- ターミナルに貼り付けて実行してね
- .zprofile開いて おまじないの呪文① をコピペしてね(PATHを通す)
- ターミナルに おまじないの呪文② をコピペして実行してね(zshプロファイル読み込み)
- ターミナルでhomebrewが使えることを確認してね
- 〜以降,必要なツールごとにコマンドをコピペしてインストール作業が永遠に続く〜
インストールが必要なツールの個数分手順書が必要となることが多いので大規模なプロジェクトになるほど線形的に手順書が肥大化し,管理コストが
これはいけません.
こんなときchezmoiをうまく使うと以下の流れで完了します
chezmoi導入後の環境セットアップフロー
- ターミナルを開いてね
-
sh -c "$(curl -fsLS get.chezmoi.io)を実行してね -
chezmoi init {{対応するリモートリポジトリ}}を実行してね
なんということでしょう.匠の技によりあれだけ肥大化していたインストール手順が3ステップになりました.
インストールが必要なツールの数に依存しない状態,いわゆる
実装例
今回は実装したプロジェクトから一部抜粋する形で汎用的な実装例を挙げます.
ディレクトリ構成
.
├── .chezmoidata
│ └── packages.yaml
├── dot_zprofile
├── run_01_install-homebrew.sh.tmpl
└── run_02_install-packages.sh.tmpl
└── run_03_install_languages.sh.tmpl
.chezmoidata/packages.yaml
chezmoiコマンド実行時の変数として設定可能なファイルです.
後に記述する.tmplファイルから読み込むことができます.
今回は以下を記載しています.
- homebrew経由でインストールするツールやアプリ
- 使用する言語のバージョン
.chezmoidata/packages.yamlの実装例
packages:
darwin:
brews:
- 'git'
- 'nodenv'
casks:
- 'google-chrome'
- 'visual-studio-code'
languages:
nodejs:
# https://nodejs.org/en/about/previous-releases
versions:
- '20.12.2'
version_stable: '20.12.2'
dot_zprofile
このファイルに書いた内容が.zprofileとして環境にセットされます.
# homebrew
eval "$(/opt/homebrew/bin/brew shellenv)"
# nodenv
eval "$(nodenv init -)"
run*.sh.tmpl
.tmpl拡張子のファイルはテンプレートファイルとして認識され,OSごとにカスタマイズしたshellコマンドを実行することができます.
複数のテンプレートが存在する場合は辞書順実行されるとのこと.
今回は3つのファイルに分割して実装した例を挙げます.
-
run_01_install-homebrew.sh.tmpl
→ homebrew自体のインストールスクリプトの実行 -
run_02_install-packages.sh.tmpl
→.chezmoidata/packages.yamlに記載したライブラリ等のインストールを実施 -
run_03_install-languages.sh.tmpl
→.chezmoidata/packages.yamlに記載した言語のバージョンをインストール・指定
詳細の説明は省きますが,冪等性の担保はこの部分で実施しています.
ご興味ある方は実装例を覗いてみてください.
run_01_install-homebrew.sh.tmplの実装
#!/bin/bash
{{ if eq .chezmoi.os "darwin" }}
if type brew > /dev/null 2>&1; then
echo すでにHomebrew(brewコマンド)が利用可能です.次のステップに進みます.
else
echo Homebrew(brewコマンド)をインストールします.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo Homebrewのパスを追加します.
source ~/.zshrc
source ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
fi
{{ end }}
run_02_install-packages.sh.tmplの実装
#!/bin/bash
{{ if eq .chezmoi.os "darwin" -}}
brew bundle --file=/dev/stdin <<EOF
{{ range .packages.darwin.brews -}}
brew {{ . | quote }}
{{ end -}}
{{ range .packages.darwin.casks -}}
cask {{ . | quote }}
{{ end -}}
EOF
{{ end -}}
run_03_install-packages.sh.tmplの実装
#!/bin/bash
source ~/.zshrc
if command -v nodenv > /dev/null 2>&1; then
{{ range .languages.nodejs.versions -}}
nodenv install {{ . | quote }}
{{ end -}}
nodenv global {{ .languages.nodejs.version_stable | quote }}
else
echo nodenvコマンドが見つかりません.Node.jsのインストールをスキップします.
fi
導入効果はあったか
Homebrew経由でのツールインストールや設定,開発言語の設定などは先述の3ステップで完了することができ,新規参画された方からの初歩的な技術的な問い合わせは大変に削減されました.
プロジェクトが大きくなるとインストールにかかる時間が多くなりますが,常に張り付いてインストール状況を確認しなくて済むので十分にメリットを享受できそうです.
課題
あくまでもchezmoiは個人利用を想定したツールのため,複数人での利用や複数プロジェクトでの利用は工夫が必要,というか結構無理して使っている節があります.
chezmoiからforkして複数人・複数プロジェクトを前提とした別のツール「cheznous(シェヌ,nousは私たちの意)」的なものを作ってみるのがよいかもしれません.
参考資料
NTT DATA公式アカウントです。 技術を愛するNTT DATAの技術者が、気軽に楽しく発信していきます。 当社のサービスなどについてのお問い合わせは、 お問い合わせフォーム nttdata.com/jp/ja/contact-us/ へお願いします。