Using cloud-init to produce bootable ssh-ready Raspberry Pi SD cards
Raspberry Pi OS Trixie images released on November 24, 2025 and later support cloud-init, making it easy to configure bootable SD cards for your personal needs.
This is super convenient but it comes with a security trade-off: cloud-init
files live on the SD card's FAT boot partition which remains mounted at
/boot/firmware after boot. These files are still present on the running Pi
and can be read by unprivileged processes.
Here I demonstrate how to use cloud-init to set up Wi-Fi and SSH, so that your Pi is ready to use remotely without having to connect it to a monitor and keyboard first. This example grants passwordless sudo to the initial user so that we don't need to expose a password hash.
After flashing the Pi OS image, copy the following to /network-config on the
boot filesystem:
# The following config sets up Wi-Fi and/or ethernet access
network:
# See https://netplan.readthedocs.io/en/latest/netplan-yaml/
version: 2
# NetworkManager is the default network manager on Raspberry Pi OS
renderer: NetworkManager
wifis:
wlan0:
# Resolve IP dynamically via DHCP
dhcp4: true
# Set the Wi-Fi country code for legal channel/power limits
regulatory-domain: "US"
access-points:
# SSID
"<SSID>":
# password
password: "<WIFI-PASSWORD>"
ethernets:
eth0:
# Resolve IP dynamically via DHCP
dhcp4: true
and the following to /user-data, also on the boot filesystem:
#cloud-config
# The line above is a required magic header
# Hostname, but to actually access this locally, we need to set up mDNS (see
# below) and connect via <HOSTNAME>.local
hostname: <HOSTNAME>
# Updates /etc/hosts to match the hostname
manage_etc_hosts: true
users:
# name is the username that we use to ssh
- name: <USERNAME>
# display name
gecos: <DISPLAY-NAME>
# login shell
shell: /bin/bash
# public keys allowed to SSH in
ssh_authorized_keys:
- ssh-ed25519 <SSH-PUBLIC-KEY> <EMAIL>
# Allow this user to run any command via sudo without a password prompt
sudo: ALL=(ALL) NOPASSWD:ALL
# Lock the account password so login is SSH-key-only
lock_passwd: true
# `false` disables SSH password authentication, so logins are key-only
ssh_pwauth: false
# enables the SSH server
enable_ssh: true
packages:
# Sets up mDNS so we can connect via <HOSTNAME>.local
- avahi-daemon
I'll explore more secure alternatives in a future post.
If you enjoyed this post, please let me know on Twitter or Bluesky.
Posted April 12, 2026.
Tags: #linux