Open-source project
Azure/WALinuxAgent avatar
Azure/WALinuxAgent

WALinuxAgent: the agent every Azure Linux VM depends on

Microsoft Azure Linux Guest Agent

580 stars400 forksPythonApache-2.0

At a glance

What is it?
The Microsoft Azure Linux Agent is the waagent daemon that provisions a Linux VM, manages its resource disk and network, runs Microsoft and partner-authored VM extensions, and talks to the Azure Fabric Controller over a boot-time DVD and a REST endpoint. It suits anyone building custom images for Azure, and it is a component the platform expects to already be present.
Who is it for?
WALinuxAgent is worth reading if you build custom Linux images for Azure, because the deprovision and re-provision cycle is the part that goes wrong quietly, with SSH host keys, the root password and DHCP leases all left behind unless the configuration flags are set, and because the release scheme here is unusual and needs explaining. It is the wrong tool if you are not on Azure at all, and the wrong tool if you want a general purpose configuration management agent.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the agent actually does on a fresh VM

The Microsoft Azure Linux Agent, waagent, manages Linux provisioning and VM interaction with the Azure Fabric Controller. The project documentation lists the functionality for Linux IaaS deployments, and it is a list of things a virtual machine genuinely cannot do for itself before it has an address or a user.

Image provisioning is the largest group. The agent creates a user account, configures the SSH authentication types, deploys SSH public keys and key pairs, sets the host name, publishes that host name to the platform DNS, reports the SSH host key fingerprint to the platform, and manages the resource disk by formatting and mounting it and configuring swap space.

Networking is the second group, and the two items are about surviving the platform rather than about configuring anything. It manages routes to improve compatibility with platform DHCP servers, and it ensures the stability of the network interface name.

Kernel is a short group with two specific tasks: configuring virtual NUMA, which is disabled for kernels older than 2.6.37, and configuring SCSI timeouts for the root device, which could be remote.

Then diagnostics, which is console redirection to the serial port, and SCVMM deployments, which is detecting and bootstrapping the VMM agent for Linux when running in a System Center Virtual Machine Manager 2012R2 environment.

And the last group is the one that makes the agent a platform component rather than a setup script. The VM Extension feature injects a component authored by Microsoft and Partners into the Linux VM to enable software and configuration automation, with a reference implementation on GitHub at azure-linux-extensions. Extensions are how Azure runs a script, installs a package or reconfigures a machine, and they run through this agent.

Two channels from the platform, and one of them is a DVD

The information flow from the platform to the agent happens over two channels, and the design is worth understanding because it explains the agent's startup behaviour.

The first is a boot-time attached DVD for IaaS deployments. The DVD includes an OVF-compliant configuration file, and that file contains all the provisioning information other than the actual SSH key pairs. The key pairs are deliberately excluded and arrive by another route, which is a small security decision: the boot media is readable by anything that can read the disc, so the secrets are not on it.

The second is a TCP endpoint exposing a REST API, used to obtain deployment and topology configuration.

So a new VM has a configuration file handed to it on a virtual disc, and then it phones home to a REST endpoint for the topology. Everything the agent knows about the VM it is running on comes from those two sources, which is also why the agent is not a general purpose tool you can point at any machine and expect it to do anything useful.

The repository structure reflects the size of the job. There is an azurelinuxagent/ package holding the implementation, a config/ directory with the configuration samples, an init/ directory for service definitions, a bin/ directory, a doc/ directory, a ci/ directory, tests/ and tests_e2e/ directories, __main__.py at the root, a setup.py, and both requirements.txt and test-requirements.txt. There is also a MAINTENANCE.md, a CODEOWNERS file, a NOTICE file, a SECURITY.md, a makepkg.py script and a MANIFEST.

Installing: one supported route and several advanced ones

The installation section makes a distinction that is easy to skim and important to respect. Installing via your distribution's package repository is the only method that is supported.

Everything else is offered for what the project documentation calls more advanced options, such as installing to a custom location or creating custom images. The warning is that installing from source may override customisations done to the agent by your distribution, and that this method is meant only for advanced users, with very limited support.

The source route uses setuptools:

bash
    sudo python setup.py install --register-service

And for Python 3:

bash
    sudo python3 setup.py install --register-service

The full set of options is visible with:

bash
    sudo python setup.py install --help

There is a third route for people who need to go further, which is customizing your own RPM or DEB packages using the configuration samples in the deb and rpm sections, and that is also described as being for advanced users with very limited support.

The agent's log file is kept at /var/log/waagent.log, which is the first place to look when a provisioning step misbehaves.

The upgrade path mirrors the install path. Upgrading via the distribution's package repository or using automatic updates are the only supported methods, and the source route is again for advanced users:

bash
    sudo python setup.py install --force

The service restart afterwards differs by distribution, which is a small but annoying detail. For most Linux distributions it is:

bash
    sudo service waagent restart

For Ubuntu, the service is named differently:

bash
    sudo service walinuxagent restart

And for CoreOS it is systemd:

bash
    sudo systemctl restart waagent

Proxy configuration is a per-distribution systemd drop-in

The HTTP proxy section is more detailed than one would expect from a system agent, and the reason is that the environment variable definitions differ per distribution.

The agent uses an HTTP proxy if one is provided through the http_proxy variable for http requests or https_proxy for https requests. There is a stated limitation: due to limitations of Python, the agent does not support HTTP proxies requiring authentication. The agent also bypasses the proxy if no_proxy is set.

The operational detail is that defining those variables for the agent service varies across distros. For distros using systemd, the common approach is to use Environment or EnvironmentFile in the Service section of the service definition, for example with an override or a drop-in file, and the project documentation points at systemctl edit for overrides. The example given is a drop-in file:

bash
    # cat /etc/systemd/system/walinuxagent.service.d/http-proxy.conf
    [Service]
    Environment="http_proxy=http://proxy.example.com:80/"
    Environment="https_proxy=http://proxy.example.com:80/"
    #

Two behaviours follow from this that are easy to miss. The agent passes its environment to the VM extensions it executes, including http_proxy and https_proxy, so a proxy defined for the agent is also defined for every extension it launches. And the HttpProxy.Host and HttpProxy.Port configuration variables, if used, override the environment settings, and those configuration variables are local to the agent process and are not passed to the extensions.

So there are two routes to a proxy, with different reach. Environment variables reach the extensions, configuration variables do not. In an environment where extensions need the proxy, that difference decides which mechanism you use.

Deprovision is the command that matters for image builders

The command line interface has two flags and a small set of commands, and one of the commands is the reason many people end up reading this repository.

The flags are -verbose, to increase verbosity of a specified command, and -force, to skip the interactive confirmation for some commands. The -help command lists the supported commands and flags.

The -deprovision command attempts to clean the system and make it suitable for re-provisioning. The list of what it deletes is specific: all SSH host keys, but only if Provisioning.RegenerateSshHostKeyPair is set to y in the configuration file; nameserver configuration in /etc/resolv.conf; the root password from /etc/shadow, again only if Provisioning.DeleteRootPassword is y; cached DHCP client leases; and it resets the host name to localhost.localdomain.

Those two configuration flags are the whole mechanism, and they are worth reading carefully because they are conditional. A host key that is not regenerated is a host key that ships in your image, which means every machine cloned from that image presents the same key and the SSH host key check tells the user nothing.

The documentation attaches a warning that is easy to miss and expensive to ignore. Deprovision does not guarantee that the image is cleared of all sensitive information and suitable for redistribution. So the command is a helper, not a guarantee, and a team publishing a base image needs to verify the result rather than assume the tool has done it.

The other half of the picture is the configuration file, and the samples in the config/ directory are what you set Provisioning.RegenerateSshHostKeyPair and Provisioning.DeleteRootPassword in.

The release scheme and the branch split are unusual

Two things about how this project is released and branched are worth knowing before you pin anything.

The first is the branch policy. Testing is done using the develop branch, which can be unstable, and the project documentation says that for a stable build you should use the master branch instead. The default branch of the repository is master, and the code coverage badge points at develop, which is consistent with develop being where the daily work lands.

The second is the tag naming. The three most recent releases are pre-v2.17.0.1 from 2026-10-12, v2.16.0.2 from 2026-07-14 and pre-v2.16.0.3 from 2026-08-27. The pre- tags carry an explanation in their description: marked as a pre-release while it is deployed to production, and it will be marked as latest when the deployment completes.

That is a release process where a build is tagged as a pre-release on purpose, deployed to production first, and only promoted to the latest tag after the rollout finishes. The practical consequence for anyone consuming the tags is that the tag list is not a simple version history, and a script that picks the newest tag will sometimes get a pre- tag whose deployment has not finished.

The last push to the repository was on 2026-10-21, so the work is current. The licence is Apache-2.0, with a LICENSE.txt and a NOTICE file in the tree, and the primary language is Python.

One more detail belongs in the dependency story. The project documentation's requirements list still names Python 2.6+, while the packaging file in the repository declares distro with a python_version marker of 3.8 or above, along with pyasn1 and passlib for Python 3.13 and above. The documentation and the packaging metadata are describing different eras, and the packaging metadata is the one that decides what your installer will actually resolve.

Where WALinuxAgent is the wrong tool

The first limit is that it only makes sense on Azure. The agent is configured by a boot-time DVD and a platform REST endpoint, and the provisioning data it consumes is Azure's. Running it on a non-Azure machine gives you a daemon with no configuration source, which is not a useful thing to deploy.

The second is that it is a platform component rather than a tool you choose. The project documentation says the supported distribution list is the one maintained by Microsoft for Azure, and that the agent can be used on other distributions as well, but development, testing and support for those are done by the open source community. In other words, on an endorsed distribution you are running Microsoft's build, and off it you are running a community's.

The third is the source-install trap. The documentation is unusually clear that installing from source may override the customisations your distribution has made to the agent, and that the support for that method is very limited. A team that needs a custom location or a custom image build is therefore taking on a component that the platform also depends on, and a mismatch between the agent on disk and the agent the platform expects is a class of bug that surfaces at provisioning time rather than at build time.

The fourth is the deprovision warning again, and it deserves repeating as a limitation rather than a caveat. The command does not guarantee the image is clean, so a base image pipeline that treats it as a final step is making an assumption the documentation explicitly declines to support.

The fifth is the dependency footprint. The agent needs Python, OpenSSL, OpenSSH, filesystem utilities including sfdisk, fdisk, mkfs and parted, the password tools chpasswd and sudo, the text tools sed and grep, and the network tools ip-route and iptables. That is a long list of system packages, and a hardened or minimal image has to carry all of them for provisioning to work.

The last point is the operational one. The agent is how Azure runs extensions on your VM, and a machine where the agent is misconfigured, stopped or replaced by a source build is a machine where extension-based automation silently stops. The last push was on 2026-10-21 and the repository is not archived, so the code is being worked on, but the version you get is the one your distribution ships unless you take the unsupported route.

Editorial conclusion

WALinuxAgent is worth reading if you build custom Linux images for Azure, because the deprovision and re-provision cycle is the part that goes wrong quietly, with SSH host keys, the root password and DHCP leases all left behind unless the configuration flags are set, and because the release scheme here is unusual and needs explaining. It is the wrong tool if you are not on Azure at all, and the wrong tool if you want a general purpose configuration management agent. Before you install or customise it, check the three things the documentation is specific about: that installing from source is explicitly limited to advanced users, with very limited support, and may override customisations your distribution has made to the agent, so the distribution package repository is the only supported route; that the proxy configuration has to be set differently on every distribution because the environment variable definitions vary, with a systemd drop-in shown as the pattern; and that the packaging metadata declares distro for Python 3.8 and above while the project documentation's stated dependency list still says Python 2.6+, which is the kind of discrepancy that makes you read the packaging rather than the documentation.

Frequently asked questions

How do I install the Azure Linux Agent?

Installing via your distribution's package repository is the only supported method. A source install uses setuptools with sudo python setup.py install --register-service, or sudo python3 setup.py install --register-service for Python 3, and that route is documented as for advanced users with very limited support, since it may override customisations your distribution made to the agent.

What does the waagent -deprovision command remove?

It deletes all SSH host keys if Provisioning.RegenerateSshHostKeyPair is set to y, nameserver configuration in /etc/resolv.conf, the root password from /etc/shadow if Provisioning.DeleteRootPassword is set to y, and cached DHCP client leases, and it resets the host name to localhost.localdomain. The documentation warns that deprovision does not guarantee the image is cleared of all sensitive information.

How do I configure an HTTP proxy for the Azure Linux Agent?

Set the http_proxy and https_proxy environment variables, and the agent will bypass the proxy when no_proxy is set, though it does not support proxies requiring authentication. The way to define them varies by distribution, and for systemd distros the project documentation shows a drop-in file at /etc/systemd/system/walinuxagent.service.d/http-proxy.conf using Environment entries in the Service section. The HttpProxy.Host and HttpProxy.Port configuration variables override the environment but are not passed to VM extensions.

Official sources

  1. Azure/WALinuxAgent on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/azure-walinuxagent.svg)](https://hysenlabs.com/projects/azure-walinuxagent)

Was this useful?