1 { config, lib, pkgs, ... }:
6 cfg = config.virtualisation.azure.agent;
8 provisionedHook = pkgs.writeScript "provisioned-hook" ''
10 /run/current-system/systemd/bin/systemctl start provisioned.target
18 options.virtualisation.azure.agent = {
21 description = "Whether to enable the Windows Azure Linux Agent.";
23 verboseLogging = mkOption {
25 description = "Whether to enable verbose logging.";
27 mountResourceDisk = mkOption {
29 description = "Whether the agent should format (ext4) and mount the resource disk to /mnt/resource.";
35 config = lib.mkIf cfg.enable {
37 assertion = config.networking.networkmanager.enable == false;
38 message = "Windows Azure Linux Agent is not compatible with NetworkManager";
41 boot.initrd.kernelModules = [ "ata_piix" ];
42 networking.firewall.allowedUDPPorts = [ 68 ];
45 environment.etc."waagent.conf".text = ''
47 # Microsoft Azure Linux Agent Configuration
50 # Enable extension handling. Do not disable this unless you do not need password reset,
51 # backup, monitoring, or any extension handling whatsoever.
54 # How often (in seconds) to poll for new goal states
55 Extensions.GoalStatePeriod=6
57 # Which provisioning agent to use. Supported values are "auto" (default), "waagent",
58 # "cloud-init", or "disabled".
59 Provisioning.Agent=auto
61 # Password authentication for root account will be unavailable.
62 Provisioning.DeleteRootPassword=n
64 # Generate fresh host key pair.
65 Provisioning.RegenerateSshHostKeyPair=n
67 # Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto".
68 # The "auto" option is supported on OpenSSH 5.9 (2011) and later.
69 Provisioning.SshHostKeyPairType=ed25519
71 # Monitor host name changes and publish changes via DHCP requests.
72 Provisioning.MonitorHostName=y
74 # How often (in seconds) to monitor host name changes.
75 Provisioning.MonitorHostNamePeriod=30
77 # Decode CustomData from Base64.
78 Provisioning.DecodeCustomData=n
80 # Execute CustomData after provisioning.
81 Provisioning.ExecuteCustomData=n
83 # Algorithm used by crypt when generating password hash.
84 #Provisioning.PasswordCryptId=6
86 # Length of random salt used when generating password hash.
87 #Provisioning.PasswordCryptSaltLength=10
89 # Allow reset password of sys user
90 Provisioning.AllowResetSysUser=n
92 # Format if unformatted. If 'n', resource disk will not be mounted.
93 ResourceDisk.Format=${if cfg.mountResourceDisk then "y" else "n"}
95 # File system on the resource disk
96 # Typically ext3 or ext4. FreeBSD images should use 'ufs2' here.
97 ResourceDisk.Filesystem=ext4
99 # Mount point for the resource disk
100 ResourceDisk.MountPoint=/mnt/resource
102 # Create and use swapfile on resource disk.
103 ResourceDisk.EnableSwap=n
105 # Size of the swapfile.
106 ResourceDisk.SwapSizeMB=0
108 # Comma-separated list of mount options. See mount(8) for valid options.
109 ResourceDisk.MountOptions=None
111 # Enable verbose logging (y|n)
112 Logs.Verbose=${if cfg.verboseLogging then "y" else "n"}
114 # Enable Console logging, default is y
117 # Enable periodic log collection, default is n
120 # How frequently to collect logs, default is each hour
121 Logs.CollectPeriod=3600
126 # Root device timeout in seconds.
127 OS.RootDeviceScsiTimeout=300
129 # How often (in seconds) to set the root device timeout.
130 OS.RootDeviceScsiTimeoutPeriod=30
132 # If "None", the system default version is used.
133 OS.OpensslPath=${pkgs.openssl_3.bin}/bin/openssl
135 # Set the SSH ClientAliveInterval
136 # OS.SshClientAliveInterval=180
138 # Set the path to SSH keys and configuration files
141 # If set, agent will use proxy server to access internet
145 # Detect Scvmm environment, default is n
149 # Lib.Dir=/var/lib/waagent
152 # DVD.MountPoint=/mnt/cdrom/secure
155 # Pid.File=/var/run/waagent.pid
158 # Extension.LogDir=/var/log/azure
163 # Enable RDMA management and set up, should only be used in HPC images
166 # Enable checking RDMA driver version and update
167 # OS.CheckRdmaDriver=y
169 # Enable or disable goal state processing auto-update, default is enabled
172 # Determine the update family, this should not be changed
173 # AutoUpdate.GAFamily=Prod
175 # Determine if the overprovisioning feature is enabled. If yes, hold extension
176 # handling until inVMArtifactsProfile.OnHold is false.
178 EnableOverProvisioning=n
180 # Allow fallback to HTTP if HTTPS is unavailable
181 # Note: Allowing HTTP (vs. HTTPS) may cause security risks
184 # Add firewall rules to protect access to Azure host node services
187 # How often (in seconds) to check the firewall rules
188 OS.EnableFirewallPeriod=30
190 # How often (in seconds) to remove the udev rules for persistent network interface
191 # names (75-persistent-net-generator.rules and /etc/udev/rules.d/70-persistent-net.rules)
192 OS.RemovePersistentNetRulesPeriod=30
194 # How often (in seconds) to monitor for DHCP client restarts
195 OS.MonitorDhcpClientRestartPeriod=30
198 services.udev.packages = [ pkgs.waagent ];
200 # Provide waagent-shipped udev rules in initrd too.
201 boot.initrd.services.udev.packages = [ pkgs.waagent ];
202 # udev rules shell out to chmod, cut and readlink, which are all
203 # provided by pkgs.coreutils, which is in services.udev.path, but not
204 # boot.initrd.services.udev.binPackages.
205 boot.initrd.services.udev.binPackages = [ pkgs.coreutils ];
207 networking.dhcpcd.persistent = true;
209 services.logrotate = {
211 settings."/var/log/waagent.log" = {
213 frequency = "monthly";
218 systemd.targets.provisioned = {
219 description = "Services Requiring Azure VM provisioning to have finished";
222 systemd.services.consume-hypervisor-entropy =
224 description = "Consume entropy in ACPI table provided by Hyper-V";
226 wantedBy = [ "sshd.service" "waagent.service" ];
227 before = [ "sshd.service" "waagent.service" ];
229 path = [ pkgs.coreutils ];
232 echo "Fetching entropy..."
233 cat /sys/firmware/acpi/tables/OEM0 > /dev/random
235 serviceConfig.Type = "oneshot";
236 serviceConfig.RemainAfterExit = true;
237 serviceConfig.StandardError = "journal+console";
238 serviceConfig.StandardOutput = "journal+console";
241 systemd.services.waagent = {
242 wantedBy = [ "multi-user.target" ];
243 after = [ "network-online.target" "sshd.service" ];
244 wants = [ "network-online.target" ];
266 # for useradd, usermod
269 pkgs.util-linux # for (u)mount, fdisk, sfdisk, mkswap
271 # waagent's Microsoft.OSTCExtensions.VMAccessForLinux needs Python 3
274 # waagent's Microsoft.CPlat.Core.RunCommandLinux needs lsof
277 description = "Windows Azure Agent Service";
278 unitConfig.ConditionPathExists = "/etc/waagent.conf";
280 ExecStart = "${pkgs.waagent}/bin/waagent -daemon";
285 # waagent will generate files under /etc/sudoers.d during provisioning
286 security.sudo.extraConfig = ''
287 #includedir /etc/sudoers.d