cloud-initでVPSの初期構築を自動化する

※本ページには広告(アフィリエイトプログラム等)が含まれます。

※本ページには広告(アフィリエイトプログラム等)が含まれます。サーバーの出力は 2026年8月16日時点で運用中の VPS(Debian 12・メモリ 958MB)から採取した実測値です。

🎯 結論:cloud-init は「あるとは限らない」。まず入っているか確かめる

結論から書きます。cloud-init は VPS の初期設定を自動化する定番ですが、すべてのイメージに入っているわけではありません。手元の環境で確認したところ、コマンドもサービスも設定ディレクトリも存在しませんでした。

解説記事の手順どおりに user-data を書いても、cloud-init が無ければ何も起きません。しかもエラーは出ません。「書いたのに反映されない」で時間を溶かす前に、1 コマンドで確認してください。

  • まず確認cloud-init --version が通るかどうか
  • 入っていればuser-data(cloud-config)で初期設定を宣言できる
  • ⚠️ 入っていなければ → 事業者のスタートアップスクリプトか、自前のスクリプト
  • 冪等ではない → 初回起動時のみ実行。2 回目は走らない

cloud-init とは何か

初回起動時に一度だけ走る仕組み

cloud-init は、サーバーが最初に起動したときに一度だけ実行される初期設定の仕組みです。ユーザーの作成、SSH 公開鍵の配置、パッケージの導入、ファイルの書き出し——このあたりを宣言的に書けます。

宣言的に書ける

手順書を人間が実行する代わりに、「こうなっていてほしい」を YAML で書くのが利点です。同じ user-data を使えば、何台でも同じ状態のサーバーが立ち上がります。

誰が渡すのか

user-data はクラウド事業者のコントロールパネルや API から渡します。この受け渡しの仕組み(データソース)が事業者ごとに違うため、「cloud-init 対応かどうか」は事業者とイメージの組み合わせで決まります。

⚠️ 入っていない環境がある

実際に確認するとこうなる

手元の VPS(Debian 12)で 4 つ確認しました。

$ cloud-init --version
bash: cloud-init: command not found

$ systemctl is-enabled cloud-init
Failed to get unit file state for cloud-init.service: No such file or directory

$ ls -d /etc/cloud
ls: cannot access '/etc/cloud': No such file or directory

$ ls -l /var/log/cloud-init.log
ls: cannot access '/var/log/cloud-init.log': No such file or directory

4 つとも不在です。この環境で user-data を書いても、読む側が存在しません。

確認の読み方

確認するもの 入っている場合 意味
cloud-init --version バージョンが出る 本体の有無
systemctl is-enabled cloud-init enabled 起動時に走るか
/etc/cloud ディレクトリが存在 設定の置き場
/var/log/cloud-init.log ログが存在 実際に走った証拠

いちばん確実なのは 4 つ目のログです。本体が入っていても、データソースが取れずに何もしないまま終わることがあります。ログが無ければ「走っていない」と断定できます。

起動時間の目安

参考までに、cloud-init が入っていない状態の起動時間です。

$ systemd-analyze
Startup finished in 1.788s (kernel) + 4.451s (userspace) = 6.240s

cloud-init が入るとここに初回だけ数秒〜数十秒が乗ります。2 回目以降の起動は速くなるので、初回の遅さだけを見て判断しないでください。

cloud-config の基本

最小構成

入っている環境なら、この程度から始められます。1 行目の #cloud-config必須で、これが無いと YAML として読まれません。

#cloud-config
users:
  - name: deploy
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-ed25519 AAAA... your-key

package_update: true
packages:
  - nginx
  - ufw

runcmd:
  - ufw allow 80/tcp
  - ufw --force enable

よく使うモジュール

キー やること
users ユーザー作成・SSH 公開鍵の配置・sudo 設定
packages パッケージの導入
write_files 設定ファイルの書き出し
runcmd 最後に任意のコマンドを実行
timezone タイムゾーンの設定

ログで確認する

$ sudo cat /var/log/cloud-init-output.log
$ sudo cloud-init analyze show

cloud-init-output.log には runcmd の標準出力がそのまま入ります。失敗はここにしか出ないことが多いので、うまくいかないときは最初に見てください。

⛔ 冪等ではない

2 回目は走らない

いちばん誤解されやすい点です。cloud-init の user-data は初回起動時にだけ実行されます。user-data を書き換えて再起動しても、何も起きません

だから設定変更には使えない

「サーバーの状態を宣言的に保つ」道具ではなく、「最初の 1 回を自動化する」道具です。継続的に状態を保ちたいなら構成管理ツールの領域になります。

やり直したいとき

検証中に何度も試したいなら、素直にインスタンスを作り直すのが確実です。状態をリセットするコマンドもありますが、中途半端に残った設定が原因の切り分けを難しくします。

入っていない場合の代替

3 つの選択肢

方法 向く場面 注意点
事業者のスタートアップスクリプト その事業者で完結する 他社に移すと使えない
自前の初期化スクリプト どこでも同じ手順にしたい 初回に手で 1 回叩く必要がある
構成管理ツール 台数が多い・継続的に管理する 学習コストと常駐の手間

1 台なら自前スクリプトで足りる

VPS が 1〜2 台なら、SSH で入って 1 回叩くスクリプトを用意するだけで十分です。cloud-init と違って何度でも流せるので、書き方さえ冪等にしておけば運用中の再適用にも使えます。

順序に注意

自前で書く場合、ネットワークが上がりきる前にパッケージ導入を始めないことだけ気をつけてください。cloud-init はこの順序制御を内部でやってくれますが、自前スクリプトでは自分で担保する必要があります。常駐させる処理は systemd の unit に寄せると、依存関係を宣言できて楽になります。

よくある質問

Q1. user-data を書いたのに反映されません

結論:まず cloud-init が入っているか確認してください。手元の VPS(Debian 12)ではコマンド・サービス・/etc/cloud・ログの 4 つすべてが不在でした。入っていない環境では user-data を書いてもエラーすら出ず、何も起きません。

Q2. 入っているかどうかの確実な確認方法は?

結論:/var/log/cloud-init.log の有無がいちばん確実です。本体が入っていてもデータソースが取れずに何もしないことがあるため、「実際に走った証拠」であるログを見るのが確実です。

Q3. user-data を書き換えて再起動すれば反映されますか?

結論:されません。初回起動時のみ実行されます。cloud-init は「最初の 1 回を自動化する」道具であって、状態を宣言的に保つ道具ではありません。試行錯誤するならインスタンスを作り直すのが確実です。

Q4. cloud-init が使えない VPS ではどうすればいいですか?

結論:事業者のスタートアップスクリプトか、自前の初期化スクリプトです。1〜2 台なら自前スクリプトで十分で、冪等に書いておけば運用中の再適用にも使えます。台数が増えたら構成管理ツールを検討してください。

Q5. runcmd が失敗しているか分かりません

結論:/var/log/cloud-init-output.log を見てください。runcmd の標準出力と標準エラーがそのまま入ります。失敗はここにしか出ないことが多く、コントロールパネル側には何も表示されません。

Q6. 起動が遅くなりませんか?

結論:初回だけ数秒〜数十秒増えます。参考までに、cloud-init が入っていない手元の環境の起動時間は 1.788 秒(カーネル)+ 4.451 秒(ユーザー空間)= 6.240 秒でした。2 回目以降は user-data が実行されないため、この差は初回限定です。

まとめ

cloud-init の記事は「入っている前提」で書かれていることが多いのですが、実際には入っていない VPS があります。手元の Debian 12 環境がまさにそれでした。

  • 🎯 最初にやることcloud-init --version/var/log/cloud-init.log の確認
  • 🎯 使えるなら#cloud-config で宣言的に。⛔ 初回のみ実行
  • 🎯 使えないなら → 1〜2 台は自前スクリプトで十分

出力は 2026年8月16日時点で運用中の VPS から採取したものです。初期設定の中身はさくらの VPS の初期セットアップ、常駐処理の設計はsystemd のユニットファイル、遮断の設定はufw の設定にまとめています。

読んで頂いて有り難うございます!