1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let cfg = config.services.cloud-init; 6 path = with pkgs; [ cloud-init nettools utillinux e2fsprogs shadow dmidecode openssh ]; 7 configFile = pkgs.writeText "cloud-init.cfg" '' 8users: 9 - root 10 11disable_root: false 12preserve_hostname: false 13 14cloud_init_modules: 15 - migrator 16 - seed_random 17 - bootcmd 18 - write-files 19 - growpart 20 - resizefs 21 - set_hostname 22 - update_hostname 23 - update_etc_hosts 24 - ca-certs 25 - rsyslog 26 - users-groups 27 28cloud_config_modules: 29 - emit_upstart 30 - disk_setup 31 - mounts 32 - ssh-import-id 33 - set-passwords 34 - timezone 35 - disable-ec2-metadata 36 - runcmd 37 - ssh 38 39cloud_final_modules: 40 - rightscale_userdata 41 - scripts-vendor 42 - scripts-per-once 43 - scripts-per-boot 44 - scripts-per-instance 45 - scripts-user 46 - ssh-authkey-fingerprints 47 - keys-to-console 48 - phone-home 49 - final-message 50 - power-state-change 51''; 52in 53{ 54 options = { 55 56 services.cloud-init = { 57 58 enable = mkOption { 59 type = types.bool; 60 default = false; 61 description = '' 62 Enable the cloud-init service. This services reads 63 configuration metadata in a cloud environment and configures 64 the machine according to this metadata. 65 66 This configuration is not completely compatible with the 67 NixOS way of doing configuration, as configuration done by 68 cloud-init might be overriden by a subsequent nixos-rebuild 69 call. However, some parts of cloud-init fall outside of 70 NixOS's responsibility, like filesystem resizing and ssh 71 public key provisioning, and cloud-init is useful for that 72 parts. Thus, be wary that using cloud-init in NixOS might 73 come as some cost. 74 ''; 75 }; 76 77 }; 78 79 }; 80 81 config = mkIf cfg.enable { 82 83 systemd.services.cloud-init-local = 84 { description = "Initial cloud-init job (pre-networking)"; 85 wantedBy = [ "multi-user.target" ]; 86 wants = [ "local-fs.target" ]; 87 after = [ "local-fs.target" ]; 88 path = path; 89 serviceConfig = 90 { Type = "oneshot"; 91 ExecStart = "${pkgs.cloud-init}/bin/cloud-init -f ${configFile} init --local"; 92 RemainAfterExit = "yes"; 93 TimeoutSec = "0"; 94 StandardOutput = "journal+console"; 95 }; 96 }; 97 98 systemd.services.cloud-init = 99 { description = "Initial cloud-init job (metadata service crawler)"; 100 wantedBy = [ "multi-user.target" ]; 101 wants = [ "local-fs.target" "cloud-init-local.service" "sshd.service" "sshd-keygen.service" ]; 102 after = [ "local-fs.target" "network.target" "cloud-init-local.service" ]; 103 before = [ "sshd.service" "sshd-keygen.service" ]; 104 requires = [ "network.target "]; 105 path = path; 106 serviceConfig = 107 { Type = "oneshot"; 108 ExecStart = "${pkgs.cloud-init}/bin/cloud-init -f ${configFile} init"; 109 RemainAfterExit = "yes"; 110 TimeoutSec = "0"; 111 StandardOutput = "journal+console"; 112 }; 113 }; 114 115 systemd.services.cloud-config = 116 { description = "Apply the settings specified in cloud-config"; 117 wantedBy = [ "multi-user.target" ]; 118 wants = [ "network.target" ]; 119 after = [ "network.target" "syslog.target" "cloud-config.target" ]; 120 121 path = path; 122 serviceConfig = 123 { Type = "oneshot"; 124 ExecStart = "${pkgs.cloud-init}/bin/cloud-init -f ${configFile} modules --mode=config"; 125 RemainAfterExit = "yes"; 126 TimeoutSec = "0"; 127 StandardOutput = "journal+console"; 128 }; 129 }; 130 131 systemd.services.cloud-final = 132 { description = "Execute cloud user/final scripts"; 133 wantedBy = [ "multi-user.target" ]; 134 wants = [ "network.target" ]; 135 after = [ "network.target" "syslog.target" "cloud-config.service" "rc-local.service" ]; 136 requires = [ "cloud-config.target" ]; 137 path = path; 138 serviceConfig = 139 { Type = "oneshot"; 140 ExecStart = "${pkgs.cloud-init}/bin/cloud-init -f ${configFile} modules --mode=final"; 141 RemainAfterExit = "yes"; 142 TimeoutSec = "0"; 143 StandardOutput = "journal+console"; 144 }; 145 }; 146 147 systemd.targets.cloud-config = 148 { description = "Cloud-config availability"; 149 requires = [ "cloud-init-local.service" "cloud-init.service" ]; 150 }; 151 }; 152}