CentOS Stream 10 LVM on Azure User Guide
Overview
This guide covers the deployment and configuration of CentOS Stream 10 LVM on Microsoft Azure using cloudimg's pre configured virtual machine image from the Azure Marketplace.
CentOS Stream is a free, open source Linux distribution: the continuously delivered upstream development branch of Red Hat Enterprise Linux 10, produced by the CentOS Project and sponsored by Red Hat. This image is the LVM variant: the root filesystem lives on a Logical Volume Manager logical volume rather than on a plain disk partition. LVM lets you grow the root filesystem online, add disks to the volume group and take snapshots, without repartitioning or downtime. Because Stream 10 is a rolling release, there are no minor releases to track: applying updates always rolls you forward within Stream 10.
What's included:
- CentOS Stream 10, the upstream of RHEL 10, RHEL 10 compatible
- An LVM partitioned root: volume group
cs, logical volumeroot, formatted xfs - Every available Stream 10 update applied at build time
- dnf-automatic armed, so the machine keeps applying security updates on its own
- Azure Linux Agent (waagent) and cloud-init for Azure integration
- Chronyd for NTP time synchronisation
- SELinux in enforcing mode
- BaseOS, AppStream and CRB repositories enabled, so your update path is intact
- Gen2 Hyper V virtual machine support
- 24/7 cloudimg support
Platform: Microsoft Azure (Gen2 Hyper V)
Default user: azureuser
Security posture
This image ships with no known credential. There is no default password and no baked in SSH key:
- The root account password is locked, so no one can log in as root with a password.
PasswordAuthenticationis disabled in the SSH daemon, so every login is by key.PermitRootLoginis set tono, so root cannot be reached over SSH at all.- The only key that works is the public key you supply when you create the virtual machine. Azure injects it into
azureuserat first boot, so no two machines you launch ever share a secret. - The machine identity and the SSH host keys are regenerated uniquely on every instance, so no two machines share a host key either.
- SELinux is left in enforcing mode, the CentOS Stream default.
Prerequisites
Before deploying this image, ensure you have:
- An active Microsoft Azure subscription
- Access to the Azure Portal or Azure CLI
- An SSH key pair for Linux VM access
- Familiarity with Azure VM management
Recommended VM Size: Standard_B2s (2 vCPU, 4 GB RAM) or larger.
Step 1: Deploy the Virtual Machine
Option A: Azure Portal
- Navigate to the Azure Marketplace and search for "CentOS Stream 10 LVM cloudimg"
- Select the image and click Create
- Configure the basics:
- Subscription: Select your Azure subscription
- Resource Group: Create new or select existing
- Virtual Machine Name: Enter a name for your VM
- Region: Select your preferred Azure region
- Size:
Standard_B2srecommended - Under Administrator Account, select SSH public key and enter your key
- Under Inbound Port Rules, allow SSH (port 22)
- Click Review + Create, then Create
Option B: Azure CLI
az vm create \
--resource-group myResourceGroup \
--name my-centos-stream-10-lvm-vm \
--image cloudimg:centos-stream:stream10lvm:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
Step 2: Connect via SSH
Run these on your own workstation, not on the VM. Find the public IP, then connect:
az vm show --resource-group myResourceGroup --name my-centos-stream-10-lvm-vm --show-details --query publicIps -o tsv
ssh azureuser@<vm-ip>
There is no password to enter. If SSH asks you for one, the key you supplied at create time is not the key your client is offering.
Step 3: Confirm the release
Check that the machine is the CentOS Stream 10 release you expect:
cat /etc/centos-release
grep -E '^(NAME|VERSION|ID|PLATFORM_ID)=' /etc/os-release
uname -rm
Expected output:
CentOS Stream release 10
NAME="CentOS Stream"
VERSION="10"
ID="centos"
PLATFORM_ID="platform:el10"
6.12.0-55.el10.x86_64 x86_64
The kernel version carries an el10 tag. That is the marker that the machine is CentOS Stream 10, the upstream of RHEL 10.

Step 4: Verify the LVM root layout
This is the defining feature of this image. The root filesystem is a logical volume, not a plain partition. Confirm the layout:
lsblk -o NAME,TYPE,MOUNTPOINT,SIZE,FSTYPE
findmnt /
sudo vgs
sudo lvs
Expected output:
NAME TYPE MOUNTPOINT SIZE FSTYPE
sda disk 10G
├─sda1 part /boot/efi 600M vfat
├─sda2 part /boot 1000M xfs
└─sda3 part 8.4G LVM2_member
└─cs-root lvm / 8.4G xfs
TARGET SOURCE FSTYPE OPTIONS
/ /dev/mapper/cs-root xfs rw,relatime,...
VG #PV #LV #SN Attr VSize VFree
cs 1 1 0 wz--n- 8.41g 0
LV VG Attr LSize
root cs -wi-ao---- 8.41g
Root is /dev/mapper/cs-root, a logical volume in the cs volume group. The lvm type against / in lsblk is the proof that this is the LVM variant.

Growing the root filesystem
Because root is an LV, you can grow it online. If you resize the OS disk larger in Azure first (stop the VM, set a larger disk size, start it), then grow the partition, the physical volume, the logical volume and the xfs filesystem in sequence:
# grow partition 3 to fill the enlarged disk
sudo growpart /dev/sda 3
# grow the physical volume into the enlarged partition
sudo pvresize /dev/sda3
# extend the logical volume to use all free space in the volume group
sudo lvextend -l +100%FREE /dev/cs/root
# grow the xfs filesystem to fill the enlarged logical volume (xfs grows mounted)
sudo xfs_growfs /
You can also add a second data disk to the volume group and extend root across both, which is the main reason to run an LVM root:
sudo pvcreate /dev/sdc
sudo vgextend cs /dev/sdc
sudo lvextend -l +100%FREE /dev/cs/root
sudo xfs_growfs /
Step 5: Check the patch level
The image is fully updated at build time. dnf check-update returns exit code 100 when updates are pending and 0 when none are:
sudo dnf check-update
echo "exit code: $?"
dnf repolist --enabled
This image also arms dnf-automatic, so security updates are downloaded and applied on a timer without any action from you. Because Stream 10 is rolling, running an update always moves you to the current Stream 10 package set:
sudo dnf upgrade -y
sudo systemctl reboot # only if a new kernel was installed
Step 6: Verify the security posture
Confirm SELinux is enforcing, root is locked, and SSH is key only:
getenforce
sudo passwd -S root
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|pubkeyauthentication)'
Expected output:
Enforcing
root LK 2009-12-22 -1 -1 -1 -1 (Password locked.)
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no

Step 7: Verify Azure integration and unattended updates
Confirm the Azure Linux Agent, cloud-init and time synchronisation are healthy, that unattended security updates are armed, and check your resources:
systemctl is-active waagent
systemctl is-enabled waagent
cloud-init --version
systemctl is-enabled dnf-automatic.timer
systemctl is-active chronyd
df -h /
free -h
waagent is what lets Azure provision your SSH key, resize the OS disk, run extensions and report VM health, so it should always be active and enabled. dnf-automatic.timer being enabled is what keeps the machine applying security updates on its own after launch.

Step 8: Networking and the firewall
The Azure Network Security Group is the control plane for inbound and outbound traffic, and it is the first and usually the only place you need to open a port. The image advertises a single inbound port, SSH on 22.
This image binds no unnecessary listeners. Unlike the stock cloud image, it does not even ship rpcbind (the RPC helper that would otherwise listen on port 111), because NFSv4, the CentOS Stream 10 default, does not use it. If you need NFSv3, install and enable it:
sudo dnf install -y rpcbind
sudo systemctl enable --now rpcbind.socket
Confirm what is listening before you open anything:
ss -tlnp
On a fresh machine the only listener is sshd on port 22. If your policy requires a host firewall as well, firewalld is installed and running with the SSH service already allowed:
sudo firewall-cmd --list-services
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Step 9: Install software
AppStream carries the application packages. Search it, then install what you need:
dnf search nginx
sudo dnf install -y nginx
sudo systemctl enable --now nginx
To add another administrator, create the account with sudo adduser <name>, add it to the wheel group with sudo usermod -aG wheel <name>, then copy your public key into /home/<name>/.ssh/authorized_keys with mode 600 and the .ssh directory mode 700, owned by that user.
Common Use Cases
- RHEL 10 compatible application hosting where LVM managed storage is a requirement
- Workloads that need to grow the root filesystem online without downtime
- Estates that add data disks to a machine over its lifetime and want them pooled under one filesystem
- A staging or development base that tracks what is coming next in RHEL 10
Troubleshooting
Cannot connect via SSH
- Verify the VM is in Running state in the Azure Portal
- Check that port 22 is allowed in the Network Security Group
- Ensure you are using the correct username:
azureuser - Verify your SSH key matches the one you supplied at create time. Password login is disabled by design, so a wrong key cannot fall back to a password prompt.
To see which key your client is actually offering, run ssh -v azureuser@<vm-ip> from your workstation and look for the Offering public key lines.
Azure agent not running
sudo systemctl status waagent
sudo systemctl enable --now waagent
Package manager issues
Refresh the metadata cache first:
sudo dnf clean all
sudo dnf makecache
If repositories are unreachable, check DNS resolution with getent hosts mirror.stream.centos.org. Install bind-utils if you want dig and nslookup available.
A service is blocked and the logs mention SELinux
SELinux is enforcing on this image. Rather than disabling it, look at what was denied:
sudo ausearch -m AVC -ts recent 2>/dev/null || echo "no recent AVC denials"
Important Notes
CentOS Stream is free and open source. It is not covered by a single licence: it is a distribution assembled from thousands of independently packaged components, each carrying its own terms, including the GPLv2, LGPL, MIT, BSD, Apache 2.0 and MPL. Every package's terms are readable with rpm -qi <package> and under /usr/share/licenses/. No subscription, licence key or Red Hat entitlement is required.
CentOS Stream 10 is a rolling release. There are no minor releases: applying updates keeps you on the current Stream 10 package set, which is the code that flows into the next RHEL 10 minor.
CentOS is a trademark of Red Hat, Inc. The name is used here nominatively, only to identify the distribution this image contains. cloudimg is not affiliated with, endorsed by or sponsored by Red Hat or the CentOS Project.
Support
For assistance with this image, contact cloudimg support:
- Website: www.cloudimg.co.uk
- Product Catalogue: www.cloudimg.co.uk/products
- User Guides: www.cloudimg.co.uk/guides
- SLA: 24 hour response guaranteed