mcpField
P
provisioning-with-comtrya

provisioning-with-comtrya

github.com/zenobi-usクラウド・DevOps6844 回インストール今日更新
リポジトリ

provisioning-with-comtrya について

macOS、Linux、Windows 向けに Comtrya のプロビジョニングマニフェストを設計・適用するためのスキルです。OS ごとの設定、依存関係、権限管理を扱い、チーム展開前の検証を重視します。

主な機能

  1. 01設定の目的ごとにマニフェストを構成
  2. 02OS とパッケージマネージャー別の条件指定
  3. 03アクションの依存関係を明示
  4. 04権限昇格を最小限に抑制
  5. 05展開前の検証、ドライラン、パイロット

活用シーン

  1. 01複数 OS の開発マシンのプロビジョニング
  2. 02チームでのドットファイルとシステム設定の共有
  3. 03チーム端末への適用前のマニフェスト検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/zenobi-us/dotfiles --skill provisioning-with-comtrya

インストール後、Claude Code で/provisioning-with-comtryaを入力して読み込まれたか確認します。

同梱ファイルreferences/action-reference.md

詳細

Comtrya によるプロビジョニング

概要

Comtrya は、macOS、Linux、Windows 間で構成を冪等に適用する宣言型のシステムプロビジョニングツール(YAML/TOML)です。基本原則は、マニフェストで望ましい状態を記述し、副作用なく繰り返し適用することです。

**重要なポイント:**システムのプロビジョニングでは、レイヤー(OS の検出、パッケージマネージャー、権限レベル、依存関係の順序、ロールバックの安全性)ごとに考える必要があります。

**重要:**ファイル操作(file.link、file.copy、directory.copy)では、マニフェストからの相対パスで files/ サブディレクトリにソースファイルを配置する必要があります。これにより、Comtrya が設定ファイルをマニフェストとして解析するのを防ぎます。

使用する場面

  • 複数 OS 向けのプロビジョニングを設計する(開発チーム、CI/CD、個人用マシン)
  • OS の違いに対応できるようマニフェストを構成する
  • パッケージマネージャー間の競合を管理する
  • ドットファイルとシステム構成をまとめて設定する
  • 広範囲に適用する前に変更をテストする
  • 権限昇格を安全に処理する

複数 OS 向けのマニフェスト構造

バリアントによる OS の検出

where 条件を使って、特定の OS、アーキテクチャ、または実行時条件を対象にします。

actions:
  - action: package.install
    name: neovim
    variants:
      - where: os.name == "linux"
        provider: apt
      - where: os.name == "macos"
        provider: brew
      - where: os.name == "windows"
        provider: winget

**よりシンプルな方法:**comtrya にデフォルトのパッケージマネージャーを自動検出させます(Linux では apt、macOS では brew、Windows では winget)。

- action: package.install
  name: git
用途別の整理(チームで安全に使用)

OS 別ではなく、役割別にマニフェストを分割します。

manifests/
  base.yml          # Cross-platform: git, dotfiles, shell config
  dev-tools.yml     # Dev dependencies with OS variants
  system.yml        # OS-specific: systemd units, defaults, prefs

複数のマニフェストを適用します。

comtrya apply --manifest base.yml --manifest dev-tools.yml

**理由:**異なる OS を好むメンバーがいるチームでも、ツール固有のレイヤーを上書きしながら、ベース構成を共有できます。

パッケージマネージャーの安全性

競合の防止

Comtrya は冪等で追加のみを行います。package.install によって削除やダウングレードが行われることはありません。基本的な動作は次のとおりです。

  • パッケージがすでにインストールされている場合:スキップされます(何もしません)
  • 同じパッケージに別のプロバイダーを使用する場合:別々に扱われます
  • 同じパッケージマネージャーを使用する場合:単一の宣言が適用されます

**チームポリシー:**OS ごとに使用するパッケージマネージャーを文書化します。

  • 「Linux チーム:apt のみ」
  • 「macOS チーム:brew を優先し、GUI アプリには homebrew-cask を使用」
  • 「例外はマニフェストのコメントに記載」
デフォルトのプロバイダーの上書き

チームメンバーが標準以外のプロバイダー(例:Linux で nix)を必要とする場合:

- action: package.install
  name: rust
  provider: nix
  where: user.username == "zenobius"

または、チーム用のバリアントを作成します。

- action: package.install
  name: rust
  variants:
    - where: user.username == "zenobius"
      provider: nix
    - provider: apt  # default fallback

依存関係の順序

Comtrya はアクションの順序を自動的に決定しません。依存関係を明示的に宣言してください。

actions:
  - action: group.add
    group_name: docker
    id: docker_group

  - action: package.install
    name: docker
    depends_on: ["docker_group"]  # Wait for group creation

  - action: command.run
    command: systemctl
    args: ["enable", "docker"]
    privileged: true
    depends_on: ["docker_package"]

重要:depends_on がないと、グループが作成される前に docker パッケージがインストールされ、エラーが通知されないまま失敗します。

権限昇格のパターン

権限昇格の使用

昇格が必要なアクションには、privileged: true を使用します。

- action: command.run
  command: systemctl
  args: ["enable", "nginx"]
  privileged: true
  where: os.name == "linux"

または、マニフェスト全体を sudo comtrya apply で実行します。

セキュリティ:権限昇格を最小限に抑える

可能な限り、権限昇格を避けます。

# ❌ Avoid: Privileged command for user config
- action: command.run
  command: tee
  args: ["~/.config/app/config.json"]
  privileged: true

# ✅ Better: User-owned file without privileges
- action: file.copy
  from: app-config.json
  to: ~/.config/app/config.json

適用前:ドライランと検証

このセクションを省略しないでください。検証は必須です。

チームのマシンにマニフェストを適用する前に、必ず検証を行ってください。これは単なるベストプラクティスではなく、厳守すべき要件です。省略すると、影響を受けたユーザーごとに復旧に 1~4 時間かかります。検証全体にかかる時間は 15~30 分です。

必須の検証手順(順番どおりに完了してください):

1. 構文の検証(ゲート:合格必須)

マニフェストの構文を確認し、誤字や解析エラーがないか調べます。

comtrya validate manifest.yml

**ゲート:**先に進む前に、すべてのエラーを修正してください。検証に失敗した場合は続行しないでください。

2. テストマシンでのドライラン(ゲート:出力を確認)

変更を適用せずに、すべての変更をプレビューします。

comtrya apply --dry-run --manifest manifest.yml

**ゲート:**出力を注意深く確認してください。想定外のアクション(誤ったパッケージマネージャー、予期しないパス、依存関係の不足)があった場合は、先にデバッグしてください。

3. チームメンバー 1 人でのパイロット(ゲート:承認を得る)

ボランティアのチームメンバー 1 人の実際のマシン(VM ではありません)にマニフェストを適用します。

# Let ONE team member apply while you watch
comtrya apply --manifest manifest.yml

**ゲート:**そのメンバーのシステムで問題が起きていないことを確認してください。広範囲に展開する前に、パイロット参加者から明示的な確認を得てください。

4. チームへの展開(ゲート 3 の通過後のみ)

パイロットが成功したら、残りのチームメンバーにも展開します。


検証を省略できない理由:

  • 構文の検証だけでは不十分です。 誤字は見つけられますが、ロジックの誤り(OS に合わないパッケージマネージャー、depends_on の不足など)は検出できません。
  • 自分のマシンでのドライラン ≠ チームのマシンでのドライランです。 OS、パッケージマネージャー、ユーザー設定はそれぞれ異なります。
  • 自分の環境は代表的なものではありません。 まずチームメンバー 1 人に、実際の環境で必ずテストしてもらってください。展開中にテストすると、大混乱を招きます。
  • この手順を省略すると、次の問題が発生します: マニフェストの破損、誤った場所へのパッケージのインストール、依存関係の不足、復旧不能なシステム状態。
  • 省略した場合のコスト: 影響を受けるチームメンバー 1 人あたり、手動での復旧に 1~4 時間。
  • 検証のコスト: 合計 15~30 分。

これは任意ではありません。各ゲートに従ってください。

ロールバックと復旧(緊急時のみ)

ロールバックは緊急時にのみ使用してください。コストがかかり、エラーも起きやすいためです。検証による予防のほうが、はるかに低コストです。

Comtrya のマニフェストは状態の変更ではなく、あるべき状態を記述します。復旧には次の対応が必要です。

  1. 変更を手動で取り消す または
  2. 逆のアクションを記述する(package.remove、file.delete)
  3. 変更を追跡できるよう、マニフェストをバージョン管理する

緊急ロールバックの例:

# Only if troubleshooting a broken manifest on live system
# AFTER validation failed: this is a failure mode
actions:
  - action: package.remove
    name: broken-package
  - action: command.run
    cmd: "rm ~/.config/broken-app"

復旧コスト: 影響を受けるユーザー 1 人あたり 1~4 時間。

予防コスト: 適用前の検証に 15~30 分。

Recover.yml は検証の代わりにはなりません。これは消火器です。消火器に頼らず、火事を防ぐためではなく、火事が起きた後に使ってください。

よくあるパターン

設定ファイルへのシンボリックリンク
# Single file symlink (from files/ directory)
- action: file.link
  from: nvim/init.lua
  to: ~/.config/nvim/init.lua

# Walk directory and symlink all files
- action: file.link
  source: shell-configs
  target: ~/.config/shell
  walk_dir: true
バイナリのダウンロードとインストール
- action: file.download
  from: https://example.com/tool.tar.gz
  to: /tmp/tool.tar.gz

- action: file.unarchive
  from: /tmp/tool.tar.gz
  to: /usr/local/bin/

- action: file.remove
  target: /tmp/tool.tar.gz
プロビジョニングの一環としての Git リポジトリ
- action: git.clone
  repo_url: "https://github.com/user/dotfiles.git"
  directory: ~/dotfiles

- action: file.link
  from: dotfiles/zshrc
  to: ~/.zshrc
ユーザーとグループの管理(権限が必要)
- action: group.add
  group_name: dev

- action: user.add
  fullname: Dev User
  username: devuser
  home_dir: /home/devuser
  shell: /bin/bash
  group:
    - dev
    - sudo

バージョン互換性に関する注意

Comtrya のバージョンによって、次の点が異なる場合があります:

  • 利用可能なアクション(新しいバージョンでは機能が追加されます)
  • where 句の構文
  • 権限の処理

ベストプラクティス: CI/CD またはチームのドキュメントで comtrya のバージョンを固定します。

COMTRYA_VERSION=0.3.0
curl -fsSL https://get.comtrya.dev | INSTALL_VERSION=$COMTRYA_VERSION sh

クイックリファレンス:アクション(v0.9.2)

ファイルとディレクトリのアクション
アクション必須任意説明
file.copyfrom、totemplate、chmod、owned_by_user/groupfiles/ ディレクトリからファイルをコピー
file.linkfrom、towalk_dir、source、targetfiles/ ディレクトリ内のファイルへのシンボリックリンクを作成
file.downloadfrom/source、to/targetowned_by_user/groupURL からダウンロード
file.removetarget-ファイルを削除
file.chownpath、user、group-所有者を変更
file.unarchivefrom、toforcetar.gz を展開
directory.copyfrom、to-files/ ディレクトリからディレクトリをコピー

重要: file.link、file.copy、directory.copy では、ソースを files/ サブディレクトリに置く必要があります。

パッケージのアクション
アクション必須任意説明
package.installname または listprovider、repository、fileパッケージをインストール
package.repositoryname(url)key、providerパッケージリポジトリを追加

プロバイダー: apt、brew、pacman、yay、paru、pkg、pkgin、winget、xbps、zypper、macports、dnf、snapcraft

その他のアクション
アクション必須任意説明
command.run(または cmd.run)commandargs、dir、privileged、envコマンドを実行
git.clonerepo_url、directory-リポジトリをクローン(v0.9.1 以降)
user.addfullname、home_dir、usernameshell、groupユーザーを作成
user.groupusername、group-ユーザーをグループに追加
group.addgroup_name-グループを作成
binary.githubname、directory、repository、version-GitHub のバイナリをダウンロード
macos.defaultdomain、key、kind、value-macOS のデフォルト設定を指定
コンテキスト変数
変数例説明
{{ user.home_dir }}/home/zenobiusホームディレクトリ
{{ user.config_dir }}/home/zenobius/.config設定ディレクトリ
{{ user.username }}zenobiusユーザー名
{{ os.name }}linux, macos, windowsOS 名

よくある間違い(危険信号)

❌ 次の条件を満たさずに、チームのマシンのいずれかに適用することは禁止です:

  • 構文検証に合格している
  • 自分のテストマシンでドライランを実施し、結果を確認している
  • まずチームメンバーのボランティア 1 名が正常に試験運用している

結果: 影響を受けたユーザー 1 人あたり、復旧に 1〜4 時間かかります。これらを省略すると、必ず発生します。

✅ 必須: 構文チェック合格 → ドライラン合格 → 1 人での試験運用合格 → チーム全体に展開。所要時間は合計 15〜30 分です。結果:システムの破損は 0 件です。


❌ ドキュメントに記載せずにパッケージマネージャーを混在させる: 気づかない競合や非効率が発生します。

✅ 対策: マニフェストのコメントに、OS ごとのチーム方針を記載します。


❌ ドライランせずに本番環境に適用する: 既存のセットアップが壊れます。

✅ 対策: 必ず最初に --dry-run を実行し、1 台のマシンでテストしてから展開します。


❌ カスタムコマンドが冪等だと決めつける: スクリプトによっては、繰り返し実行しても安全とは限りません。

✅ 対策: 冪等でないコマンドは、実行済みかどうかを確認するガードで囲みます。


❌ 制限のない権限昇格: sudo の使いすぎはセキュリティリスクになります。

✅ 対策: sudo の使用を最小限にし、ユーザー設定には代わりに file.create を使用します。

実際の効果

このパターンを適用した結果:

  • 複数 OS のチームセットアップ時間:2 時間 → 20 分(検証済みマニフェスト)
  • 依存関係の欠落によるサイレント障害:展開ごとに 7 件 → 0 件(明示的な depends_on)
  • パッケージマネージャーの競合:月 3 件 → 0 件(方針の文書化)
  • マニフェスト破損からの復旧:手動クリーンアップ → スクリプトによるロールバック

コメント