Operating Systems Azure

CentOS 7.4 Minimal on Azure User Guide

| Product: CentOS 7.4 Minimal on Azure

Overview

This guide covers the deployment and configuration of CentOS 7.4 Minimal (CentOS Linux 7.4.1708, with a reduced package set) on Microsoft Azure using cloudimg's pre configured virtual machine image from the Azure Marketplace.

CentOS Linux is a community rebuild of Red Hat Enterprise Linux, binary compatible with RHEL 7; 7.4.1708 is the point release corresponding to RHEL 7.4. This image is provided deliberately for legacy-migration workloads: teams moving software that is certified against one specific CentOS 7 / RHEL 7 point release, and needing a clean, hardened, lean base pinned to exactly that release while they re-platform.

This image sits at the intersection of two properties, and you should pick it only if you want both:

  • It is pinned to the 7.4.1708 minor release. It is not the terminal CentOS 7.9.2009. Every repository names the frozen 7.4.1708 vault literally, so yum update cannot walk the machine forward onto 7.9. If you want the last CentOS 7 release, use cloudimg's CentOS 7 Minimal image instead.
  • It has a reduced package set. The packages an Azure guest cannot use have been removed. If you want the full package set at this same minor, use cloudimg's CentOS 7.4 image instead.

All of these are separate listings and you can run any combination of them.

End-of-life and minor-pin notice — read this first

There are two disclosures here, and they are independent. Both matter.

1. CentOS Linux 7 reached end-of-life on 30 June 2024. The upstream CentOS Project no longer produces any updates for it, including security updates. Consequently:

  • This image is patched only to its capture date, from the frozen CentOS 7.4.1708 vault (vault.centos.org). "Fully patched" therefore means patched to the last packages that will ever exist for this point release.
  • After the end-of-life date, no further upstream security updates are published. Over time the image will carry unpatched vulnerabilities that cannot be remediated by updating CentOS 7, because upstream ships nothing further.
  • This image is provided for legacy-migration use. Plan a migration to a supported distribution such as AlmaLinux, Rocky Linux, CentOS Stream, or a current RHEL for any workload that must remain secure.

2. Pinning to 7.4.1708 also forgoes the packages published in later CentOS 7 minors. This is a deliberate trade of currency for reproducibility, and it is the reason this listing exists:

  • CentOS 7.4.1708 was superseded upstream by 7.9.2009. A machine pinned here will never receive the packages that only ever shipped in that later minor, even though they exist and even though they predate end-of-life.
  • Concretely, this image's enabled repositories offer 12,455 packages (base 9,591 + updates 2,416 + extras 448), against 16,771 in the terminal 7.9.2009 tree. That gap of 4,316 packages is real and you should size it against your requirement before choosing this image.
  • What you get in exchange is a build target that does not move. If your certified software matrix names RHEL 7.4 specifically, this is the point release it names.

The stock CentOS 7 repositories point at mirror.centos.org, which was retired at end-of-life. This image has already repointed every repository to the CentOS 7.4.1708 vault, so yum keeps working — against the frozen, pinned package set — out of the box.

Removing packages changes neither disclosure. A smaller package set means fewer components that can carry a vulnerability, which is a genuine benefit on an end-of-life platform, but it is not a substitute for migrating.

What makes this the Minimal image

Every number below was measured during the build of this image, on the same kernel, against the same frozen vault snapshot and on the same day, against cloudimg's standard CentOS 7.4 image that this one is cut from. That matters: the comparison is against this image's own standard sibling at the same point release, not against a different CentOS 7 minor. The image ships the comparison itself at /usr/share/cloudimg/centos-7.4-minimal.manifest, so you can verify it on your own running machine rather than taking this page's word for it.

Standard CentOS 7.4 CentOS 7.4 Minimal Difference
Installed packages 307 274 33 fewer
Package payload on disk 755 MB 538 MB 217 MB smaller (29%)
Root filesystem used at build time 1,064 MB 753 MB 311 MB smaller
Externally reachable TCP listeners 22 22 unchanged
Loopback listeners mail transport on 25, time on 323 time on 323 mail transport removed

Package payload — the total on-disk size owned by installed packages — is the exact and reproducible measure of the trim, and it is the figure the image's own manifest quotes. Root-filesystem used space also moves with logs, caches and journal state, so treat it as indicative and run df -h / on your own machine for its live value; a freshly deployed virtual machine reports less than the build-time figure above, because the build logs are cleared before capture.

The removals are chosen on one test: can an Azure virtual machine ever use this? Nothing was removed to hit a size target, and nothing the platform needs to boot, network, authenticate, patch or be managed by Azure was touched.

Removed Why an Azure guest cannot use it
linux-firmware 126 MB of firmware for physical network cards, GPUs, wireless radios and storage controllers. An Azure virtual machine has none of that hardware: its disks and network are the in kernel Hyper V synthetic drivers, which load no firmware at all.
17 × iwl*-firmware 56 MB of Intel wireless network adapter firmware, iwl7265-firmware alone accounting for 30 MB. A Hyper V guest has one synthetic network interface and no wireless radio to load them into.
alsa-firmware, alsa-tools-firmware, alsa-lib Sound card firmware and the loader tooling for it. There is no audio device on an Azure virtual machine.
ivtv-firmware, aic94xx-firmware Firmware for a Hauppauge TV capture card and an Adaptec SAS controller respectively.
microcode_ctl CPU microcode updates. A guest cannot apply microcode; the Azure host does it.
postfix, mariadb-libs A local mail transport listening on 127.0.0.1:25 and ::1:25. A minimal base ships no mail server, and removing it closes both listeners.
btrfs-progs btrfs is deprecated and unsupported on CentOS 7, and Azure images use xfs.
tuned Tuning profile daemon. Azure guests use the platform defaults.
qemu-guest-agent The KVM and QEMU guest agent, left behind by the installer that built the base. Azure uses the Azure Linux Agent instead, so this was a live daemon doing nothing.
kexec-tools Crash dump tooling. kdump reserves memory on a small virtual machine for a dump path a marketplace image never uses.
dracut-config-rescue Rescue boot image generation, which produces a boot entry that cannot start on Azure.
NetworkManager-team, teamd Network interface teaming. Azure networking is a single synthetic interface and is never a team.

Why this image trims more than cloudimg's CentOS 7 Minimal. The standard CentOS 7.4 image this one is cut from is produced by a fresh installation from the CentOS 7.4.1708 vault tree, and a stock CentOS @core installation includes the wireless, sound and capture card firmware above. The upstream CentOS 7 cloud image that the CentOS 7 Minimal listing descends from had already had those stripped out before cloudimg ever saw it. Same removal policy, different starting point, larger saving here.

What was deliberately kept. binutils looks like an obvious 22 MB saving and is not removable on CentOS 7: /usr/bin/nm is required by kmod, and the dependency cascade from there reaches openssh and systemd. The same applies to wpa_supplicant (required by NetworkManager), cracklib-dicts, grub2-tools-extra, bind-export-libs, nss-tools, shared-mime-info, kbd-misc, python-babel and gettext. Every candidate in the build was checked with rpm -e --test and against the full yum removal transaction before anything was erased, so this image contains no package removed by force and no broken dependency. The build also proves the check itself still works, by confirming it refuses to remove glibc, systemd and yum before any real removal is attempted.

NFS is worth a specific note: nfs-utils and rpcbind are not part of the CentOS 7.4.1708 @core package set to begin with, so the Minimal trim did not remove them — they were never installed. The rpcbind units are nevertheless left disabled and masked in this image, so installing an NFS client later cannot silently reopen port 111 without you asking for it. Step 7 covers restoring NFSv3.

What's included

  • CentOS Linux 7.4.1708 (Core), binary compatible with RHEL 7.4, with a reduced package set
  • A standard (non-LVM) single-partition xfs root
  • Every available 7.4.1708 vault package applied at build time (patched to capture date)
  • Repositories repointed to vault.centos.org/7.4.1708 so yum keeps working post-EOL, pinned to this minor
  • Exactly one kernel installed, 3.10.0-693.21.1.el7 — the last kernel the 7.4 vault published
  • Azure Linux Agent (WALinuxAgent) as the sole provisioning agent — cloud-init is deliberately not installed (see Step 6)
  • Chronyd for NTP time synchronisation
  • SELinux in enforcing mode
  • firewalld enabled and active, allowing SSH
  • A package set manifest at /usr/share/cloudimg/centos-7.4-minimal.manifest
  • Gen1 Hyper V virtual machine support (BIOS boot)
  • 24/7 cloudimg support

Platform: Microsoft Azure (Gen1 Hyper V) Default user: azureuser

Security posture

  • No baked-in credentials: the root password is locked, and there is no shipped SSH key
  • SSH host keys are regenerated on first boot, so no two virtual machines share an identity
  • SSH is key only: password authentication and root login are both disabled
  • SELinux is enforcing, with the targeted policy
  • Exactly one externally reachable TCP listener, sshd on port 22
  • The rpcbind RPC listener on port 111 is disabled and masked
  • No local mail transport, and therefore no listener on port 25
  • Two firewalls are in force: the Azure Network Security Group and the guest's own firewalld
  • No swap is baked into the image; Azure manages swap on the ephemeral resource disk

Prerequisites

Before deploying this image, ensure you have:

  1. An active Microsoft Azure subscription
  2. Access to the Azure Portal or Azure CLI
  3. An SSH key pair for Linux VM access
  4. 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

  1. Navigate to the Azure Marketplace and search for "CentOS 7.4 Minimal cloudimg"
  2. Select the image and click Create
  3. Configure the basics:
  4. Subscription: Select your Azure subscription
  5. Resource Group: Create new or select existing
  6. Virtual Machine Name: Enter a name for your VM
  7. Region: Select your preferred Azure region
  8. Size: Standard_B2s recommended
  9. Under Administrator Account, select SSH public key and enter your key
  10. Under Inbound Port Rules, allow SSH (port 22)
  11. Click Review + Create, then Create

Option B: Azure CLI

az vm create \
  --resource-group myResourceGroup \
  --name my-centos-74-minimal-vm \
  --image cloudimg:centos:centos74min: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-74-minimal-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.

A note on sudo in the commands below

Several of the tools used in this guide — ss, getenforce, sshd, firewall-cmd — live in /usr/sbin. On CentOS 7, /usr/sbin is added to a non-root user's PATH only by /etc/profile, which a login shell reads but a one-shot remote command such as ssh azureuser@host 'ss -tln' never does. Typed interactively they would work; pasted into a script they would fail with command not found. Every command below is therefore written with sudo, which both fixes the path and is required for the full output anyway. This is CentOS 7 behaviour, not something specific to this image.

Step 3: Confirm the release and the minor pin

The pin is half of what you are buying, so check it explicitly. rpm writes the minor as 7-4.1708, so verify the package as well as the release string:

cat /etc/centos-release
rpm -q centos-release
grep -E '^(NAME|VERSION|ID|VERSION_ID)=' /etc/os-release
uname -rm
rpm -qa | wc -l

Expected output:

CentOS Linux release 7.4.1708 (Core)
centos-release-7-4.1708.el7.centos.x86_64
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
VERSION_ID="7"
3.10.0-693.21.1.el7.x86_64 x86_64
274

/etc/os-release reports only VERSION_ID="7" — CentOS 7 does not record the minor there, which is exactly why /etc/centos-release and rpm -q centos-release are the authoritative checks. (CentOS 7's /etc/os-release also has no PLATFORM_ID field; that was introduced in the el8 line.)

Terminal showing cat of etc centos-release reporting CentOS Linux release 7.4.1708 Core, os-release fields ID centos and VERSION_ID 7, uname reporting the 3.10.0-693 el7 kernel on x86_64, and rpm reporting 274 installed packages

Step 4: Confirm the minimal package set

This is the other half of what you are choosing, so verify it directly. The manifest is generated during the build and shipped in the image:

cat /usr/share/cloudimg/centos-7.4-minimal.manifest
rpm -q linux-firmware iwl7265-firmware alsa-firmware postfix microcode_ctl || echo "(absent by design in the Minimal image)"
df -h /

Expected output (the manifest is abridged here; the full list of 33 removals prints on your machine):

cloudimg CentOS 7.4 Minimal — package-set manifest
Generated at build time: 2026-09-10T21:06:24Z

Cut from the cloudimg standard 'CentOS 7.4' image (CentOS Linux release 7.4.1708 (Core) , kernel 3.10.0-693.21.1.el7.x86_64),
measured on the same kernel and the same day, against the same frozen 7.4.1708 vault.

Standard CentOS 7.4 : 307 packages, 755 MB of package payload
CentOS 7.4 Minimal  : 274 packages, 538 MB of package payload
Delta               : -33 packages, -217 MB of package payload

Package payload is the total on-disk size owned by installed packages, which is the
exact and reproducible measure of the trim. Root-filesystem USED space additionally
moves with logs, caches and journal state, so it is not quoted here as a fixed
figure: it was 1064 MB on the standard image at the moment the baseline
was taken, and this image ships smaller still after its build logs are cleared.
Run 'df -h /' on your own machine for its live value.

Removed (not needed by an Azure guest):
  - linux-firmware
  - iwl7265-firmware
  - iwl7260-firmware
  ...
package linux-firmware is not installed
package iwl7265-firmware is not installed
package alsa-firmware is not installed
package postfix is not installed
package microcode_ctl is not installed
(absent by design in the Minimal image)
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        10G  831M  9.2G   9% /

Your df figures will differ: the root filesystem grows to fill whatever OS disk you asked for, and used space moves with logs and caches. The package counts and the payload figures in the manifest are the fixed, verifiable numbers.

The is not installed lines are the point of the image, not an error. The manifest lists every removal, why it was safe on Azure, which packages were deliberately kept because removing them would break CentOS 7, and the 7.4.1708 pin.

The 10G above is this image's own OS disk size, not a limit on yours. Root growth is not automatic on this image, because cloud-init is deliberately not installed (see Step 6). growpart and xfs_growfs are preinstalled for it: give the VM a larger OS disk, then run sudo growpart /dev/sda 1 followed by sudo xfs_growfs /. Both work on the mounted filesystem, so no reboot is needed. If the partition already fills the disk, growpart reports NOCHANGE and exits non zero — that is the expected answer, not a failure.

Terminal showing the shipped cloudimg package set manifest reporting the standard CentOS 7.4 image at 307 packages and 755 MB against this Minimal image at 274 packages and 538 MB, a delta of minus 33 packages and minus 217 MB, the list of removed firmware and tooling packages, and rpm confirming linux firmware iwl7265 firmware alsa firmware postfix and microcode are not installed

Step 5: Verify the security posture

Confirm SELinux is enforcing, root is locked, SSH is key only, and that exactly one port is reachable from the network:

sudo getenforce
sudo passwd -S root
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|pubkeyauthentication) '
sudo ss -tln | awk '$1=="LISTEN"{print $1, $4}'
sudo ss -uln | awk '$1=="UNCONN"{print $1, $4}'

Expected output:

Enforcing
root LK 2009-12-22 -1 -1 -1 -1 (Alternate authentication scheme in use.)
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
LISTEN *:22
LISTEN :::22
UNCONN *:68
UNCONN 127.0.0.1:323
UNCONN *:29380
UNCONN :::63421
UNCONN ::1:323

Read the second column, which is the local address the socket is bound to — not the peer address, which is the next column along and would make an outbound connection look like a listener. The only externally reachable TCP listener is sshd on port 22.

The UDP list needs a word of explanation, because it looks busier than it is. All three non-loopback UDP sockets belong to a single dhclient process — the DHCP client every Azure virtual machine must run to hold its network lease. *:68 is the DHCP client port proper; the two high-numbered sockets are the ephemeral IPv4 and IPv6 sockets the ISC client opens alongside it, and they are numbered randomly at every boot, so the exact numbers on your machine will differ from the ones above. Confirm the ownership rather than the numbers:

sudo ss -ulnp | awk '$1=="UNCONN"'

Every non-loopback row should name dhclient. 127.0.0.1:323 and ::1:323 are chrony's time synchronisation control socket, reachable only from the machine itself. Nothing here is a network service accepting inbound connections, and the Network Security Group admits only port 22 in any case.

root LK means the root password is locked: there is no password that logs in as root, and PermitRootLogin no refuses the connection before any password would be consulted.

Note what is not in that list: the standard CentOS 7.4 image also binds a local mail transport on 127.0.0.1:25 and ::1:25. This image removed it with the package.

Two ss formatting details are worth knowing if you script against this output, because CentOS 7.4 ships iproute-3.10 rather than the 4.x series later minors carry. It prints IPv6 addresses unbracketed:::22 and ::1:323, not [::]:22 and [::1]:323 — and it does not support the -H / --no-header flag: ss -H -tln exits 255 and prints nothing at all. A script that uses -H here gets an empty result, which is easily mistaken for "no listeners". Drop the header with a filter instead, as the commands above do with awk '$1=="LISTEN"'.

Terminal showing getenforce reporting Enforcing, passwd reporting root as LK meaning locked, the effective sshd policy reporting permitrootlogin no passwordauthentication no and pubkeyauthentication yes, and ss reporting only port 22 listening on TCP with the dhclient sockets and chrony on UDP

Step 6: Verify the vault update path and Azure integration

Because CentOS 7 is end-of-life, its original mirrors are gone. This image repoints every repository to the CentOS 7.4.1708 vault, so yum keeps working against the frozen package set for this minor. Confirm that, and that the Azure Linux Agent survived the package trim:

yum repolist enabled
grep '^baseurl' /etc/yum.repos.d/CentOS-Base.repo
sudo yum -q check-update; echo "check-update exit: $?"
systemctl is-active waagent
systemctl is-enabled waagent
rpm -q cloud-init || echo "cloud-init: not installed (waagent is the sole provisioning agent)"
systemctl is-active chronyd

Expected output:

repo id                    repo name                                      status
base/x86_64                CentOS-7.4.1708 - Base (vault)                  9,591
extras/x86_64              CentOS-7.4.1708 - Extras (vault)                  448
updates/x86_64             CentOS-7.4.1708 - Updates (vault)               2,416
repolist: 12,455
baseurl=https://vault.centos.org/7.4.1708/os/$basearch/
baseurl=https://vault.centos.org/7.4.1708/updates/$basearch/
baseurl=https://vault.centos.org/7.4.1708/extras/$basearch/
baseurl=https://vault.centos.org/7.4.1708/centosplus/$basearch/
check-update exit: 0
active
enabled
package cloud-init is not installed
cloud-init: not installed (waagent is the sole provisioning agent)
active

Every one of those paths names 7.4.1708 literally rather than the $releasever variable the stock configuration uses. That literal path is the pin: it is what stops yum update from moving the machine to 7.9. Three of the four repositories are enabled; centosplus ships in the file but is disabled, as it is on a stock CentOS 7, which is why repolist totals the other three.

check-update returning 0 means no newer packages exist in this minor's vault: the image is patched to the end of what 7.4.1708 will ever contain. No further security updates will ever be published upstream, for this minor or for CentOS 7 at all. For anything beyond legacy migration, move to a supported distribution.

waagent is what lets Azure provision your SSH key, regenerate the SSH host keys, set the hostname, run extensions and report VM health, so it should always be active and enabled. The package trim deliberately protects it: an image that saved space by dropping the Azure Linux Agent would not provision at all.

On this image the Azure Linux Agent is the sole provisioning agent, and cloud-init is not installed. That is deliberate, and it is not part of the Minimal trim — the standard CentOS 7.4 image this one is cut from does not ship cloud-init either. The Azure Linux Agent that ships with CentOS 7.4 refuses to provision at all if it finds cloud-init running alongside it, so exactly one of the two has to own provisioning, and on this image that is the agent. Leaving cloud-init out is what makes the image provision reliably and receive your key on first boot.

Two consequences worth planning for:

  • If your workflow depends on cloud-init specifically — #cloud-config user data, for example — this is not the image for it; use a CentOS Stream, AlmaLinux or Rocky Linux image instead. Custom data supplied at create time is still delivered to /var/lib/waagent/CustomData, so a first-boot script of your own can read it there.
  • The root filesystem is not grown automatically. growpart and xfs_growfs ship preinstalled for the manual procedure described in Step 4.

Terminal showing the CentOS 7.4.1708 release and centos-release package, yum repolist with base updates and extras repointed to the 7.4.1708 vault totalling 12,455 packages, yum check-update exiting 0 meaning patched to the final packages for this minor, and the Azure Linux Agent reporting active and enabled with cloud-init deliberately absent alongside chronyd

Step 7: Putting back anything you need

Nothing in this image is removed by force, so anything trimmed reinstalls normally from the vault. If you need a package that is not here, install it the usual way with sudo yum install -y <package>.

Three cases are worth calling out:

  • Mail delivery. postfix is not installed, so there is no /usr/sbin/sendmail and cron cannot mail job output to MAILTO. If you need local mail, sudo yum install -y postfix followed by sudo systemctl enable --now postfix restores exactly the standard image's behaviour, including the loopback listener on port 25.
  • NFS. Neither nfs-utils nor rpcbind ships in the CentOS 7.4.1708 @core set, so neither is installed here — this is not something the Minimal trim took away. Install the client with sudo yum install -y nfs-utils when you need it. That pulls in rpcbind, whose units this image leaves masked so the portmapper on port 111 cannot come up unasked: NFSv4 does not need it, so mounting NFSv4 works immediately. NFSv3 does need it — enable it with sudo systemctl unmask rpcbind.socket followed by sudo systemctl enable --now rpcbind.socket.
  • Firmware. The firmware packages are the bulk of the saving and are removed because Azure's synthetic devices load no firmware. If you are moving this image to physical hardware or to a hypervisor that passes through real devices, reinstall with sudo yum install -y linux-firmware before you do.

Reinstalling a trimmed package is supported and safe. It simply returns that part of the image to the standard CentOS 7.4 behaviour, and it comes from the same pinned vault, so it cannot break the minor pin.

Step 8: Networking and the two firewalls

This image has two firewalls, and a new port has to be opened in both. This catches people out, because most cloud images ship with the guest firewall off.

  1. The Azure Network Security Group is the outer control plane for inbound and outbound traffic, configured in the Azure Portal or with az network nsg rule create. The image advertises a single inbound port, SSH on 22.
  2. firewalld runs inside the guest, enabled and active, in the public zone. It permits ssh and dhcpv6-client and nothing else.

Confirm both the listeners and the guest firewall's current state:

sudo ss -tlnp
sudo systemctl is-enabled firewalld
sudo systemctl is-active firewalld
sudo firewall-cmd --list-all

Expected output:

State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128          *:22                       *:*                   users:(("sshd",pid=909,fd=3))
LISTEN     0      128         :::22                      :::*                   users:(("sshd",pid=909,fd=4))
enabled
active
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: ssh dhcpv6-client
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

Your sshd process id will differ; the addresses and ports are the part that matters.

To open a service — HTTPS, say — add it in the Network Security Group and in firewalld. On the guest side that is sudo firewall-cmd --permanent --add-service=https followed by sudo firewall-cmd --reload; sudo firewall-cmd --list-all should then show https alongside ssh. Opening it in only one of the two is the usual reason a port appears unreachable when everything else looks correct: if the NSG rule is present but the connection still times out, check firewalld before you look anywhere else.

If your policy is to run without a guest firewall and rely on the NSG alone, sudo systemctl disable --now firewalld does that — but open the port in the NSG first, and be aware you are removing a layer the image ships with.

Common Use Cases

  • Running legacy software whose support matrix names RHEL 7.4 or CentOS 7.4 specifically, while you re-platform
  • A lean, immovable base for building and validating packages against a fixed point-release ABI, where a smaller image means faster provisioning and fewer components to review
  • Reproducing a historical build or a customer-reported defect against exactly the package set that shipped in 7.4.1708, with the least possible surrounding software
  • Lift-and-shift of an on-premises CentOS 7.4 estate into Azure as a migration staging step, on a reduced attack surface

For any workload that must stay secure long term, migrate to AlmaLinux, Rocky Linux, CentOS Stream, or a current RHEL — CentOS 7 receives no further upstream security updates at any minor.

Troubleshooting

Cannot connect via SSH

  1. Verify the VM is in Running state in the Azure Portal
  2. Check that port 22 is allowed in the Network Security Group
  3. Ensure you are using the correct username: azureuser
  4. 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.

A command or tool is missing

This is the Minimal image, so some tooling present on the standard CentOS 7.4 image is not installed. Check the manifest to see whether a package was removed deliberately, then reinstall it from the vault if you need it:

awk '/^Removed/,/^$/' /usr/share/cloudimg/centos-7.4-minimal.manifest

Remember also that /usr/sbin is not on a non-root PATH on CentOS 7 in a non-interactive shell — if a command works when you type it but not from a script, try sudo or the full path before concluding it is missing.

Package manager cannot reach a mirror

CentOS 7's original mirrors were retired at end-of-life. This image already points at the vault, but if you add a third-party .repo that still references mirror.centos.org you will see 404s. Repoint it to https://vault.centos.org/7.4.1708/... or remove it. Confirm nothing active still references the retired mirrors:

grep -REl '^[[:space:]]*(baseurl|mirrorlist)[[:space:]]*=.*mirror(list)?\.centos\.org' /etc/yum.repos.d/ || echo "no ACTIVE repo line references a retired mirror"

Match active configuration lines only, as above. A plain grep -R mirror.centos.org /etc/yum.repos.d/ also matches the explanatory comment this image writes into CentOS-Base.repo and the commented-out #baseurl= lines that stock CentOS 7 ships in its disabled repository files, so it reports hits on a perfectly correct machine.

Checking the minor pin is still intact

If you suspect something has repointed a repository, list what yum actually resolves rather than reading the files:

yum repolist enabled
sudo yum -q repolist -v 2>/dev/null | awk '/^Repo-baseurl/{print $3}'

Every line must begin https://vault.centos.org/7.4.1708/. On this image that command prints:

https://vault.centos.org/7.4.1708/os/x86_64/
https://vault.centos.org/7.4.1708/extras/x86_64/
https://vault.centos.org/7.4.1708/updates/x86_64/

The most direct way to break the pin is to enable CentOS-CR.repo, which stock CentOS 7 ships disabled and which carries packages staged for the next point release. Leave it disabled unless you intend to leave 7.4.

The root filesystem did not grow

Unlike most cloud images, this one does not grow the root filesystem automatically, because cloud-init is not installed (Step 6 explains why). Grow it by hand after enlarging the OS disk:

lsblk /dev/sda
df -h /

Then sudo growpart /dev/sda 1 followed by sudo xfs_growfs /. If growpart prints NOCHANGE and exits non zero, the partition already fills the disk and there is nothing to claim.

Azure agent not running

Check the agent's status:

systemctl status waagent --no-pager

If it is not running, start and enable it with sudo systemctl enable --now waagent.

Important Notes

CentOS Linux 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 GPL, 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. Neither pinning to a back-catalogue point release nor removing packages changes any licence term.

CentOS Linux 7 reached end-of-life on 30 June 2024 and receives no further upstream security updates. This image is patched only to its capture date, from the frozen CentOS 7.4.1708 vault, and is provided for legacy-migration use. It is also pinned to the 7.4.1708 minor release, so it forgoes the packages published in CentOS 7.9.2009 — that is a deliberate trade of currency for reproducibility. Plan a migration to a supported distribution (AlmaLinux, Rocky Linux, CentOS Stream, or a current RHEL) for any workload that must remain secure.

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.

Support

For assistance with this image, contact cloudimg support: