cloud-init-coder について
cloud-init-coderは、クラウドインスタンスの初期化に使うcloud-init設定の作成を支援するスキルです。ユーザーやパッケージの設定、セキュリティ、サービス、ファイル、インフラテンプレートを扱います。
主な機能
- 01ユーザー作成とSSH設定
- 02パッケージとリポジトリの導入
- 03Dockerとsystemdサービスの設定
- 04ファイル作成とファイアウォール設定
- 05Terraform/OpenTofuテンプレートの利用
- 06cloud-init実行のデバッグ
活用シーン
- 01クラウドインスタンスの初回起動準備
- 02SSHアクセスの強化とユーザー設定
- 03Docker、Web、システムサービスの展開
- 04cloud-init設定の問題調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill cloud-init-coderインストール後、Claude Code で/cloud-init-coderを入力して読み込まれたか確認します。
詳細
Cloud-Init Coder
概要
Cloud-init は、クロスプラットフォームのクラウドインスタンス初期化における業界標準です。初回起動時に実行され、インスタンスが利用可能になる前にユーザー、パッケージ、ファイル、サービスを設定します。
基本フォーマット
Cloud-init の設定は #cloud-config で始まります:
#cloud-config
package_update: true
packages:
- nginx
- docker.io
ユーザー管理
デプロイユーザーの作成
#cloud-config
users:
- name: deploy
groups: docker, sudo
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA... [email protected]
複数ユーザー
#cloud-config
users:
- default # Keep cloud provider's default user
- name: deploy
groups: docker
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA... key1
- name: monitoring
groups: adm
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA... monitoring-key
パッケージのインストール
基本パッケージ
#cloud-config
package_update: true
package_upgrade: true
packages:
- docker.io
- docker-compose-plugin
- nginx
- certbot
- python3-certbot-nginx
- fail2ban
- ufw
カスタムリポジトリから
#cloud-config
apt:
sources:
docker:
source: "deb [arch=amd64] https://download.docker.com/linux/ubuntu $RELEASE stable"
keyid: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
packages:
- docker-ce
- docker-ce-cli
- containerd.io
SSH のセキュリティ強化
宣言的な SSH ロックダウン
runcmd の sed コマンドではなく、宣言的な ssh_pwauth: false を優先します:
#cloud-config
ssh_pwauth: false # Disable password auth at cloud-init level
runcmd:
# Additional hardening via sshd_config
- sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
- systemctl restart sshd
SSH の完全なセキュリティ強化
#cloud-config
ssh_pwauth: false # Declarative - cleaner than sed
runcmd:
# Disable root login (or use prohibit-password for key-only root)
- sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
- sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# Disable password authentication (backup for ssh_pwauth)
- sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
# Increase keepalive for stable connections
- sed -i 's/^#\?ClientAliveInterval.*/ClientAliveInterval 60/' /etc/ssh/sshd_config
- sed -i 's/^#\?ClientAliveCountMax.*/ClientAliveCountMax 10/' /etc/ssh/sshd_config
# Restart SSH
- systemctl restart sshd
Docker のセットアップ
Compose を使用した Docker
#cloud-config
package_update: true
packages:
- docker.io
- docker-compose-plugin
groups:
- docker
users:
- name: deploy
groups: docker
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA...
runcmd:
- systemctl enable --now docker
- usermod -aG docker deploy
カスタムデーモン設定を使用した Docker
#cloud-config
write_files:
- path: /etc/docker/daemon.json
content: |
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
runcmd:
- systemctl enable --now docker
ファイルの作成
設定ファイルの書き込み
#cloud-config
write_files:
- path: /etc/nginx/sites-available/app
content: |
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
owner: root:root
permissions: '0644'
- path: /opt/app/.env
content: |
RAILS_ENV=production
PORT=3000
owner: deploy:deploy
permissions: '0600'
ファイルのダウンロード
#cloud-config
runcmd:
- curl -fsSL https://example.com/setup.sh -o /opt/setup.sh
- chmod +x /opt/setup.sh
- /opt/setup.sh
サービスの設定
サービスの有効化と起動
#cloud-config
runcmd:
- systemctl enable --now docker
- systemctl enable --now nginx
- systemctl enable --now fail2ban
systemd サービスの作成
#cloud-config
write_files:
- path: /etc/systemd/system/myapp.service
content: |
[Unit]
Description=My Application
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User=deploy
WorkingDirectory=/opt/app
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
runcmd:
- systemctl daemon-reload
- systemctl enable --now myapp
ファイアウォールの設定
UFW のセットアップ
#cloud-config
packages:
- ufw
runcmd:
- ufw default deny incoming
- ufw default allow outgoing
- ufw allow ssh
- ufw allow http
- ufw allow https
- ufw --force enable
Terraform/OpenTofu との連携
インラインのユーザーデータ
resource "digitalocean_droplet" "app" {
name = "app-server"
image = "ubuntu-22-04-x64"
size = "s-1vcpu-1gb"
region = "nyc1"
user_data = <<-EOT
#cloud-config
package_update: true
packages:
- docker.io
- docker-compose-plugin
users:
- name: deploy
groups: docker
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ${var.deploy_ssh_key}
runcmd:
- systemctl enable --now docker
EOT
}
テンプレートファイル
# templates/cloud-init.yaml
#cloud-config
package_update: true
packages:
- docker.io
users:
- name: ${username}
groups: docker
ssh_authorized_keys:
- ${ssh_key}
# main.tf
resource "digitalocean_droplet" "app" {
user_data = templatefile("${path.module}/templates/cloud-init.yaml", {
username = var.deploy_user
ssh_key = var.deploy_ssh_key
})
}
本番環境向け完全な例
#cloud-config
package_update: true
package_upgrade: true
packages:
- docker.io
- docker-compose-plugin
- fail2ban
- ufw
- unattended-upgrades
groups:
- docker
users:
- name: deploy
groups: docker, sudo
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA... deploy-key
write_files:
- path: /etc/docker/daemon.json
content: |
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}
- path: /etc/fail2ban/jail.local
content: |
[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 3
bantime = 3600
runcmd:
# Docker
- systemctl enable --now docker
# SSH hardening
- sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
- sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
- sed -i 's/^#\?ClientAliveInterval.*/ClientAliveInterval 60/' /etc/ssh/sshd_config
- sed -i 's/^#\?ClientAliveCountMax.*/ClientAliveCountMax 10/' /etc/ssh/sshd_config
- systemctl restart sshd
# Firewall
- ufw default deny incoming
- ufw default allow outgoing
- ufw allow ssh
- ufw allow http
- ufw allow https
- ufw --force enable
# Fail2ban
- systemctl enable --now fail2ban
# Auto-updates
- systemctl enable --now unattended-upgrades
final_message: "Cloud-init completed after $UPTIME seconds"
サーバーのチューニング
パフォーマンスとクリーンアップ
#cloud-config
runcmd:
# Reduce swap usage (better for databases/apps with their own memory management)
- |
if ! grep -q "vm.swappiness=10" /etc/sysctl.conf; then
echo "vm.swappiness=10" >> /etc/sysctl.conf
sysctl -p
fi
# Set timezone
- timedatectl set-timezone UTC # Or: Europe/Berlin, America/New_York
# Cleanup
- apt-get autoremove -y
- apt-get clean
スワップ値
| 値 | 動作 |
|---|---|
0 | OOM を回避する場合にのみスワップします |
10 | スワップを最小限に抑えます(アプリに推奨) |
60 | Ubuntu のデフォルト |
100 | 積極的にスワップします |
デバッグ
Cloud-Init のステータスを確認する
# View cloud-init status
cloud-init status
# View cloud-init logs
cat /var/log/cloud-init.log
cat /var/log/cloud-init-output.log
# Re-run cloud-init (for testing)
sudo cloud-init clean
sudo cloud-init init
よくある問題
| 問題 | 原因 | 解決方法 |
|---|---|---|
| YAML の解析エラー | インデントが正しくない | 2 スペースのインデントを使い、YAML を検証します |
| ユーザーが作成されない | users: キーがない | users: がルートレベルにあることを確認します |
| パッケージがインストールされない | package_update: false | package_update: true に設定します |
| SSH キーが拒否される | キーの形式が正しくない | 公開鍵の文字列全体を使います |
| サービスが起動しない | 順序の依存関係 | systemd ユニットで After= を使います |
コメント
Markdown 対応