-## [FIXME] 👻この記事を記載している最中にてをはなさないといけなくなったので、記事の中のサンプル手順書に 独自のコメント記法を残すこと。期限は、明日を目標にします
ちょっとZoomプラグインが作りたくて、おろしたままのMacに環境構築をするためのスクリプトをAIにつくらせたんだけど。
その際に 手順書とコメントの書き方TIpsを共有したいと思いました。ただ手順とかの書き方を話しても面白みがないので、大好きなAWS Transform Custom を触った際に感動した「手順化し再現性を作る仕組み」という設計思想に触れてみようと思います。
⚠️この記事では、TransformCustomの具体的な使い方やハウツーは記載しません。別途記事にします。まず選択肢としてのCustomの意義とIaC開発で覚えておくノウハウを誤共有させてください。
===
AWS Transform Custom と VibeCoding の違いポイントについて
TL;DR
- AWS Transform Custom は、サンプルコードを学習させてマイグレーションを「サービス化」する仕組み
- VibeCoding との決定的な違いは 再現性 — 「私の手元で動く」を「誰がやっても動く」に昇華できるか
- AI 時代こそ、導入手順の IaC 化 がエンジニアリングの基本に立ち返らせてくれる
- 事例として、Mac を新調したときの Zoom プラグイン開発環境セットアップ手順 を共有
- あわせて、後輩や同僚に 10 年伝え続けてきた 「コピペすれば絶対に動く手順書」の書き方 Tips もまとめます
はじめに: AWS Transform Custom とは
AWS Transform は、もともと Java や .NET、VMware 移行といった 大企業の安定スタック で使われている言語・基盤を対象にしたマイグレーション支援サービスです。
そして AWS Transform Custom を使うと、無印 Transform でサポートされていない言語・手順についても、自分たちで「マイグレーションのサービス」を組み立てる ことができます。
しかし現場で実際に出会うのはそうした王道スタックばかりではありません。
- 即時性 … 一旦動かすために書かれて、そのまま居座ってしまったシステム
- 学習コスト … 当時の流行りで採用されたが、今では触れる人が限られる言語
- 属人化 … 起案者や立ち上げメンバが抜けたあと、誰もメンテできなくなったシステム
たとえば PHP や Perl で書かれた社内の暫定システムが、いつの間にか中規模・大規模に育ち、「これ、バージョンアップ・マイグレーションしたいんですが…」という相談が舞い込んでくる。SI の現場ではよくある光景ではないでしょうか。
Transform Custom の 4 つの特徴
Transform Custom には大きく 4 つの特徴があります。本記事ではそのうちもっとも本質的だと感じる 1 つだけを取り上げます。
- サンプルの既存コード・正解コードを読み込ませることで、マイグレーションの特徴を学習させられる
残り 3 つの特徴と「実際に触ってみた」系の記事は、すでに先人たちがたくさん書いてくださっているので、そちらを参照していただくのがよいと思います。本記事ではここから一段視座を引いて、「なぜこれが価値があるのか」 を考えてみます。
VibeCoding との決定的な違い: 再現性
学んでいくうちに腑に落ちたのは、Transform Custom と VibeCoding によるマイグレーションの違い は次の一点に集約されるということです。
マイグレーションの仕組み自体を、裏側で手順化(Pipeline やコードに置き換えること)することで、後続の作業や大規模なマイグレーション自体の再現性を保てる
VibeCoding でマイグレーションを進める場合、その場の指示や追加の試行錯誤を重ねていくうちに、ハルシネーション や 過度なコンテキスト学習 によって、再現性を担保することが難しくなっていきます。
簡単にいうとこういうことです。
- 私の環境ではうまくマイグレートできた
- でも、同じ指示を 同僚が同じように与えても、必ず同じマイグレーション結果になるとは限らない
- まして、システムのマイナーバージョンが上がったり、対象ファイル数が桁違いになったときに 同じ品質を保証できる根拠 がない
これは、SI の仕事の根っこ ともいえる「同じ作業を、同じ品質で、繰り返し提供する」という基本に正面からぶつかる話です。
古くは、
- インフラの導入には、テキストベースの 手順書
- アプリケーションには、誰がやっても同じ結果を確認できる テスト観点ドキュメント
があり、これらが品質を担保し、作業を分担しても結果がブレないことを保証していました。ソフトウェアの正当性そのものを支える土台です。
AI による Cowork やメモリ機能といった新しい技術が次々生まれていますが、「導入の手順はちゃんと IaC されていますか?」 という問いは、むしろ今こそ重みを増していると感じます。
ケーススタディ: Zoom プラグイン開発環境を Mac で立ち上げる
長くなりましたが、ここからは実例です。
ある経緯で Zoom プラグインを開発する 機会があり、そのときの環境構築手順を残しておこうと思います(プラグインで何を作っているかは別記事で改めて公開予定)。
スタックの全体像
新品の Mac (Apple Silicon) 上で、Zoom プラグイン開発に必要な要素を一気に揃えます。
| レイヤ | 採用するもの |
|---|---|
| OS / 基盤 | macOS Sonoma+, Xcode CLT, Rosetta 2, Homebrew |
| バージョン管理 | Git + SSH (GitHub) |
| 言語ランタイム | Node.js 20 LTS (nvm), Python 3.12 (pyenv), pnpm |
| AWS 開発 | AWS CLI v2, AWS CDK, AWS SAM, Session Manager Plugin |
| コンテナ | Docker Desktop |
| 補助 CLI | jq, gh, ngrok, pre-commit, fzf, ripgrep など |
| エディタ | VS Code + AWS Toolkit / Amazon Q / GraphQL 拡張 |
| 認証 | AWS IAM Identity Center (SSO), GitHub CLI |
| 外部サービス | Zoom App Marketplace (開発者アカウント), ngrok |
これらを コピペだけで一気通貫に整える 手順書を、次節の README.txt として用意しました。
README.txt 全文
## ============================================================================
## [SPEC]Zoom プラグイン開発環境 - macOS 新品セットアップ手順
## ============================================================================
## [MEMO] 対象: Apple Silicon (M1/M2/M3/M4) macOS Sonoma 以降
## [NOTE]想定シェル: zsh (macOS 標準)
## [NOTE]実行方針: 上から順にターミナルへコピペで進行
## [MEMO]凡例:
## ## … 説明コメント (実行不要)
## ## [対話] … 途中で入力 / GUI 操作が必要なステップ
## ## [手動] … ブラウザや GUI での作業が必要なステップ
## ============================================================================
## ----------------------------------------------------------------------------
## Phase 0: 事前確認
## ----------------------------------------------------------------------------
## アーキテクチャ確認 (arm64 = Apple Silicon, x86_64 = Intel)
uname -m
## macOS バージョン確認
sw_vers
## ----------------------------------------------------------------------------
## Phase 1: 開発の土台 (Xcode CLT / Rosetta / Homebrew)
## ----------------------------------------------------------------------------
## [対話] Xcode Command Line Tools (Git/clang/make を含む)
## ダイアログが開くので「インストール」をクリック → 完了まで待つ (~10分)
xcode-select --install
## インストール完了の確認
xcode-select -p
## Rosetta 2 を導入 (Apple Silicon 専用、Intel バイナリ互換用)
sudo softwareupdate --install-rosetta --agree-to-license
## [対話] Homebrew のインストール
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
## Homebrew パスを zsh 起動時に通す (Apple Silicon は /opt/homebrew)
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
## 動作確認
brew --version
brew update
brew doctor
## ----------------------------------------------------------------------------
## Phase 2: Git と SSH 鍵 (GitHub 連携)
## ----------------------------------------------------------------------------
brew install git
git --version
## ## [SPEC] Git 初期設定 (※メールアドレスは自分のものに書き換える)
git config --global user.name "Your Name"
git config --global user.email "your-email@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase false
git config --global core.editor "code --wait"
## ## [SPEC] SSH 鍵の生成 (Ed25519、パスフレーズ無し)
ssh-keygen -t ed25519 -C "your-email@example.com" -f ~/.ssh/id_ed25519 -N ""
## ## [SPEC] SSH agent と Keychain 連携の設定
mkdir -p ~/.ssh && chmod 700 ~/.ssh
cat << 'EOF' >> ~/.ssh/config
Host github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
EOF
chmod 600 ~/.ssh/config
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
## 公開鍵をクリップボードにコピー
pbcopy < ~/.ssh/id_ed25519.pub
echo "公開鍵をクリップボードにコピーしました"
## ## [手動] GitHub の Settings > SSH and GPG keys > New SSH key で貼り付け登録
## ## https://github.com/settings/keys
## 登録後の接続テスト (Hi <username>! と返れば成功)
ssh -T git@github.com
## ----------------------------------------------------------------------------
## Phase 3: 言語ランタイム (Node.js / Python)
## ----------------------------------------------------------------------------
## ## [SPEC] Node.js を nvm 経由で管理 (LTS 切替が容易)
brew install nvm
mkdir -p ~/.nvm
cat << 'EOF' >> ~/.zshrc
## --- nvm ---
export NVM_DIR="$HOME/.nvm"
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"
[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"
EOF
source ~/.zshrc
## ## [SPEC] Node.js 20 LTS をインストール (Lambda / CDK と相性が良い)
nvm install 20
nvm alias default 20
node --version
npm --version
## pnpm (高速 npm 互換、モノレポ向き)
npm install -g pnpm
pnpm --version
## ## [SPEC] Python は pyenv で管理
brew install pyenv
cat << 'EOF' >> ~/.zshrc
## --- pyenv ---
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - zsh)"
EOF
source ~/.zshrc
pyenv install 3.12
pyenv global 3.12
python --version
pip --version
## ----------------------------------------------------------------------------
## Phase 4: AWS 開発ツール一式
## ----------------------------------------------------------------------------
brew install awscli
aws --version
brew install --cask session-manager-plugin
npm install -g aws-cdk
cdk --version
brew install aws-sam-cli
sam --version
brew install --cask amazon-q
## ----------------------------------------------------------------------------
## Phase 5: コンテナ (Docker Desktop)
## ----------------------------------------------------------------------------
## [対話] Docker Desktop インストール
brew install --cask docker
## [手動] Docker Desktop を起動 (初回はライセンス同意あり)
open -a Docker
## Docker Desktop 起動後に確認
docker --version
docker compose version
docker run --rm hello-world
## ----------------------------------------------------------------------------
## Phase 6: 補助 CLI ツール
## ----------------------------------------------------------------------------
brew install jq ## JSON 整形・抽出
brew install yq ## YAML 整形・抽出
brew install gh ## GitHub CLI
brew install tree ## ディレクトリ階層表示
brew install watch ## コマンド繰り返し実行
brew install httpie ## curl より見やすい HTTP クライアント
brew install ngrok ## ローカル -> 公開URL (Webhook 検証で使用)
brew install graphviz ## 構成図生成
brew install pre-commit ## Git hook 管理
brew install fzf ripgrep bat eza
## ----------------------------------------------------------------------------
## Phase 7: エディタ (VS Code) と拡張
## ----------------------------------------------------------------------------
brew install --cask visual-studio-code
code --install-extension dbaeumer.vscode-eslint
code --install-extension esbenp.prettier-vscode
code --install-extension amazonwebservices.aws-toolkit-vscode
code --install-extension amazonwebservices.amazon-q-vscode
code --install-extension ms-azuretools.vscode-docker
code --install-extension ms-python.python
code --install-extension graphql.vscode-graphql
code --install-extension redhat.vscode-yaml
code --install-extension github.copilot
code --install-extension eamodio.gitlens
## ----------------------------------------------------------------------------
## Phase 8: AWS 認証 (SSO 推奨)
## ----------------------------------------------------------------------------
## [対話] IAM Identity Center 構成の場合
aws configure sso
## [対話] あるいは個人検証用に IAM アクセスキーを使う場合
aws configure --profile zoom-plugin-dev
## 既定リージョンとプロファイルを zsh に固定
cat << 'EOF' >> ~/.zshrc
## --- AWS ---
export AWS_PROFILE=zoom-plugin-dev
export AWS_REGION=ap-northeast-1
export AWS_DEFAULT_REGION=ap-northeast-1
EOF
source ~/.zshrc
aws sts get-caller-identity
## ## [SPEC] CDK Bootstrap (リージョンごとに 1 回だけ実行)
cdk bootstrap aws://$(aws sts get-caller-identity --query Account --output text)/${AWS_REGION}
## ----------------------------------------------------------------------------
## Phase 9: GitHub CLI 認証
## ----------------------------------------------------------------------------
## [対話] ブラウザでデバイスフローのコード入力
gh auth login -h github.com -p ssh -w
gh auth status
## ----------------------------------------------------------------------------
## Phase 10: Zoom 開発者アカウント (ブラウザ作業)
## ----------------------------------------------------------------------------
## ## [手動] Zoom App Marketplace で以下を実施
## ## 1) https://marketplace.zoom.us/develop/create にアクセス
## ## 2) 用途に合わせてアプリを新規作成
## ## 3) Scopes / Webhook / Redirect URL 等を設定
## ## 4) Client ID / Client Secret / Webhook Secret Token を控える
## ## [手動] ngrok アカウントで AuthToken 取得後に設定
ngrok config add-authtoken YOUR_NGROK_AUTH_TOKEN_HERE
## ----------------------------------------------------------------------------
## Phase 11: プロジェクトのスキャフォールド
## ----------------------------------------------------------------------------
mkdir -p ~/work && cd ~/work
## ## [SPEC] GitHub にリポジトリを作る場合
gh repo create zoom-plugin --private --clone --description "Zoom plugin (AWS backend)"
cd zoom-plugin
mkdir -p infra services frontend docs
## ## [SPEC] CDK インフラプロジェクト
( cd infra && cdk init app --language typescript )
## ## [SPEC] Frontend (Vite + React + Zoom Apps SDK)
npm create vite@latest frontend -- --template react-ts
( cd frontend && npm install @zoom/appssdk )
cat << 'EOF' > .gitignore
node_modules/
dist/
build/
.env
.env.local
cdk.out/
.aws-sam/
*.log
.DS_Store
.vscode/
.idea/
coverage/
EOF
## ## [SPEC] pre-commit フック (秘匿情報の混入防止)
cat << 'EOF' > .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
- id: detect-private-key
EOF
pre-commit install
## ----------------------------------------------------------------------------
## Phase 12: 最終動作確認
## ----------------------------------------------------------------------------
echo ""
echo "=================== セットアップ確認 ==================="
echo "OS arch: $(uname -m)"
echo "Homebrew: $(brew --version | head -n1)"
echo "Git: $(git --version)"
echo "Node: $(node --version)"
echo "npm: $(npm --version)"
echo "pnpm: $(pnpm --version)"
echo "Python: $(python --version)"
echo "AWS CLI: $(aws --version)"
echo "AWS CDK: $(cdk --version)"
echo "AWS SAM: $(sam --version)"
echo "Docker: $(docker --version)"
echo "GitHub CLI: $(gh --version | head -n1)"
echo "ngrok: $(ngrok version)"
echo "VS Code: $(code --version | head -n1)"
echo "AWS Identity: $(aws sts get-caller-identity --query Arn --output text 2>/dev/null || echo 'NOT CONFIGURED')"
echo "========================================================"
これを上から順に貼り付けていけば、新品の Mac が Zoom プラグイン開発できる状態 になります。
ngrok のトークンと Git の user.email だけは個人のものに置換してください。
「コピペすれば絶対に動く手順書」の書き方 Tips
ここで本題のもうひとつ。
手順書を渡したのに「コメントとワンライナーが混在している」「変数が嵐のように出てきて、どこを書き換えればいいかわからない」「行ごとに判断しながらコピペするのが煩雑」… こういうフィードバックを後輩からもらった経験はないでしょうか。
私が 10 年以上、開発メンバーや後輩に伝え続けてきた 「コピペしたら絶対に動く手順を書こうね」 のルールを共有します。
Tip 1: コメントは ## で始める
説明文(コメント)の先頭には必ず ## を付けます。
シェルや多くの言語で # 始まりは「コードのコメント」ですが、本気の手順書のコメントは ## または //// のように 2 つ重ねる のがコツです。
# これはコード自体のコメント (実装の都合で書かれた注釈)
## これは手順書のコメント (読者に向けた説明)
こうすることで、
- コード本来のコメント (
#1 つ) - 手順書 / 仕様書としてのコメント (
##2 つ)
を視覚的に見分けられるようになります。Grep でも ^## で手順書コメントだけを抜き出せて便利です。
Tip 2: ヘッダには「目的」「ゴール」「申し送り」を必ず書く
ファイルの先頭ヘッダには、
- このスクリプト / 手順の 目的
- 終わったときに 何が達成されているか (ゴール)
- 未完成部分・既知の問題・申し送り事項
を必ず書きます。これがないと、引き継いだ人は 「このコマンド群を最後まで実行していいのか」 すら判断できません。
Tip 3: コメントには分類タグを付ける
これが本記事で一番伝えたい部分です。コメントに [SPEC|DEBUG|FIXME|MEMO|NOTE|TODO|BUGIT|REF] のタグ を付けることで、レビュー観点や検索性が劇的に上がります。
## [SPEC] … 仕様や実装の概要
## [DEBUG] … 動作確認用の一時コード
## [FIXME] … 暫定対応 / 将来必ず直すコード
## [MEMO] … 公式 / 定数 / 計算式の根拠
## [NOTE] … SPEC の補足説明
## [TODO] … 当日内に対応する作業
## [BUGIT] … 判断保留中、レビューでの相談事項
## [REF] … 参考にしたドキュメントや記事の URL
それぞれの使い分けはこんなイメージです。
[SPEC] — 仕様の概要
コメントの 大半はこれ です。「なぜこのコマンドを実行するのか」「実装が何を意図しているか」を 1〜2 行で。
## [SPEC] Node.js は LTS の 20 系で固定。Lambda Node20 ランタイムと揃える。
nvm install 20
[DEBUG] — 一時的な動作確認
シェル実行直前の変数差し替えや、テスト用のコードに使います。コメントアウトされた状態で残しておくと、単体テストや動作確認がワンタッチで済みます。
## [DEBUG] 本番では削除。手元検証時だけ有効化する。
# export AWS_PROFILE=local-test
# aws s3 ls
[FIXME] — 暫定対応
やっつけコード、強引な正規表現、仮の値などに付けます。
ただし 私はローカルルールとして、[FIXME] には必ず「いつ直すか」「どう直すか」を書かないとレビューで Reject します。後継者への敬意です。
## [FIXME] 2026-06 までに正規ルールへ差し替え。
## 本来は IAM ロールの ARN を Parameter Store から取得すべき。
ROLE_ARN="arn:aws:iam::123456789012:role/temp-deploy"
[MEMO] — 計算式や根拠
公式・定数・チューニング根拠など、コードや式の展開内容 を残すのに使います。円周率の計算式、フェルミ推定の根拠、スループット計算式などはここに。
## [MEMO] 並列度の根拠: vCPU 4 × ハイパースレッド 2 × 安全係数 0.75 ≒ 6
PARALLELISM=6
[NOTE] — SPEC の補足
[MEMO] と似ていますが、こちらは [SPEC] の詳細情報 を書く位置づけにしています。
## [SPEC] CDK Bootstrap はリージョンごとに 1 回だけ。
## [NOTE] 既に他プロジェクトで実施済みの場合は本コマンドはスキップ可。
cdk bootstrap aws://${ACCOUNT_ID}/${REGION}
[TODO] — 本日中に処理する作業
その日の作業中に「あとで戻ってくる」場所に貼ります。
私は 退勤 1 時間前に grep -rn TODO で検索し、git push 前にできる限り潰す というルールを自分に課しています。
どうしても当日に終わらなければ、[FIXME] か [BUGIT] に降格して「いつ直すか」「役割」を明記して帰ります。
## [TODO] アクセスキーを Secrets Manager に移す
[BUGIT] — 判断保留 / 申し送り
修正が必要だが 判断がつかない 場合に、判断できなかった理由と意図を書いてレビューに上げます。
[BUGIT] が残っているコードはマージ禁止 をローカルルールにしています。
## [BUGIT] このリトライ回数 3 は経験則。SLA に応じて要見直し。
## 性能試験のあと、A 案 (指数バックオフ) / B 案 (固定 3 回) を選定する。
RETRY_COUNT=3
[REF] — 参照元の明示
公式ドキュメントが第一ですが、Qiita や個人ブログを参考にした場合は URL を残します。
何のために参照したか も書いておくと、後で読んだ自分や同僚に親切です。
## [REF] Apple Silicon の Homebrew パスについて
## https://docs.brew.sh/Installation
## (デフォルトインストール先が /usr/local から /opt/homebrew に変わった経緯確認)
eval "$(/opt/homebrew/bin/brew shellenv)"
Tip 4: 1 行 = 1 アクション、変数は冒頭に集約
ワンライナーで && 連結しすぎると、失敗箇所の切り分けができません。基本は 1 行 1 コマンド。
変数定義は ファイル冒頭または Phase 冒頭にまとめて、利用箇所では ${VAR} のみが見えるようにします。
これらをルール化するだけで、「読者が脳内パースする量」が半分以下 になります。
おわりに: Transform Custom を上手く使うために
ここまで書いて改めて思うのは、Transform Custom も手順書もやっていることは同じ だということです。
- マイグレーションの「やり方」を、1 回限りの口伝え ではなく、Pipeline / コード / 手順書 として残す
- 残った成果物を、別のメンバが 別のタイミングで 実行しても 同じ結果を再現できる ことを保証する
VibeCoding が悪いという話ではありません。立ち上がりの速さや探索フェーズの威力はむしろ大きい。
ただ、SI として顧客に納める瞬間 には、再現性 — つまり「誰がやっても同じ結果」 — を担保する手段に切り替える必要があります。そこに Transform Custom や IaC や、本記事で紹介したような手順書のお作法が効いてきます。
おすすめの使い分けは次のようなイメージです。
| フェーズ | 主役 | 補助 |
|---|---|---|
| 探索 / PoC | VibeCoding | 走り書き手順書 |
| 仕様化 / レビュー | 手作業 + ペアプロ | Transform Custom (試走) |
| 本番マイグレーション | Transform Custom + IaC | 手順書 (人間判断ポイントのみ) |
| 引き継ぎ / 保守 | 手順書 + IaC | AI による補助参照 |
AI で何でもできそうに見える時代だからこそ、「私の手元で動いた」を「誰がやっても動く」に翻訳し続けられる人 が、結局のところ強いのではないかと思います。
そしてその翻訳の入口として、まずは身近な開発環境構築から ## を付けて手順を残すこと から始めてみるのはいかがでしょうか。
それでは、よい AI とのお付き合いを 🍵
この記事で紹介したもの
- AWS Transform Custom の本質 — 再現性のあるマイグレーション
- Mac (Apple Silicon) を Zoom プラグイン開発環境にするまでの全コマンド
- 10 年来の手順書記法 (
##二重コメント +[SPEC|DEBUG|FIXME|MEMO|NOTE|TODO|BUGIT|REF]タグ)