← Recipes

阅读中文版本

Harden Cloud-Init User Data

Keep user data minimal, never embed secrets, disable password SSH, and use cloud-init only for bootstrap before configuration management takes over.

~30 mincloud-initsecurityinfrastructure

Task

Make cloud-init user data safe and minimal instead of a long script with baked-in credentials.

When to use this

User data contains secrets and a sprawling script, so it is visible in instance metadata and becomes an unmaintainable second configuration system.

Prerequisites

  • A cloud that supports cloud-init
  • A configuration management or image pipeline for ongoing config

Steps

1. Restrict user data to bootstrap: users, SSH keys, and a one-time fetch of real config.

Expected output: User data stays small and auditable.

2. Fetch secrets at runtime from a secret manager, never embed them.

Expected output: Instance metadata never exposes credentials.

3. Disable password authentication and root SSH login.

Expected output: Access is key-based only.

4. Hand ongoing configuration to configuration management or a baked image.

curl -s http://169.254.169.254/latest/user-data | head

Expected output: There is one source of truth for config.

Troubleshooting

Problem

Secrets visible in metadata

Solution

Anyone with access to the instance can read user data; rotate any secret that was embedded and move it to a secret manager.

Problem

Long user-data script fails partway

Solution

Keep bootstrap idempotent and log errors; use a proper image pipeline for complex setup.

Limitations

  • User data is visible to anyone who can query instance metadata, so it must be treated as non-secret.
  • Bootstrap via cloud-init adds boot-time dependency on external services for secrets and config.

Context

Make cloud-init user data safe and minimal instead of a long script with baked-in credentials. User data contains secrets and a sprawling script, so it is visible in instance metadata and becomes an unmaintainable second configuration system.

Steps

  1. Restrict user data to bootstrap: users, SSH keys, and a one-time fetch of real config. Expected: User data stays small and auditable.
  2. Fetch secrets at runtime from a secret manager, never embed them. Expected: Instance metadata never exposes credentials.
  3. Disable password authentication and root SSH login. Expected: Access is key-based only.
  4. Hand ongoing configuration to configuration management or a baked image. Expected: There is one source of truth for config.
#cloud-config
users:
  - name: deploy
    ssh_authorized_keys: [ssh-ed25519 AAAA...]
ssh_pwauth: false
disable_root: true
runcmd:
  - [ sh, -c, "curl -fsSL https://config.example.com for real config" ]

Verify

  • User data stays small and auditable.
  • Instance metadata never exposes credentials.
  • Access is key-based only.
  • There is one source of truth for config.

Limits

  • User data is visible to anyone who can query instance metadata, so it must be treated as non-secret.
  • Bootstrap via cloud-init adds boot-time dependency on external services for secrets and config.