1 { config, lib, pkgs, ... }:
6 cfg = config.services.cloud-init;
16 ++ optional cfg.btrfs.enable btrfs-progs
17 ++ optional cfg.ext4.enable e2fsprogs
18 ++ optional cfg.xfs.enable xfsprogs
21 hasFs = fsName: lib.any (fs: fs.fsType == fsName) (lib.attrValues config.fileSystems);
22 settingsFormat = pkgs.formats.yaml { };
23 cfgfile = settingsFormat.generate "cloud.cfg" cfg.settings;
27 services.cloud-init = {
32 Enable the cloud-init service. This services reads
33 configuration metadata in a cloud environment and configures
34 the machine according to this metadata.
36 This configuration is not completely compatible with the
37 NixOS way of doing configuration, as configuration done by
38 cloud-init might be overridden by a subsequent nixos-rebuild
39 call. However, some parts of cloud-init fall outside of
40 NixOS's responsibility, like filesystem resizing and ssh
41 public key provisioning, and cloud-init is useful for that
42 parts. Thus, be wary that using cloud-init in NixOS might
47 btrfs.enable = mkOption {
49 default = hasFs "btrfs";
50 defaultText = literalExpression ''hasFs "btrfs"'';
52 Allow the cloud-init service to operate `btrfs` filesystem.
56 ext4.enable = mkOption {
58 default = hasFs "ext4";
59 defaultText = literalExpression ''hasFs "ext4"'';
61 Allow the cloud-init service to operate `ext4` filesystem.
65 xfs.enable = mkOption {
67 default = hasFs "xfs";
68 defaultText = literalExpression ''hasFs "xfs"'';
70 Allow the cloud-init service to operate `xfs` filesystem.
74 network.enable = mkOption {
78 Allow the cloud-init service to configure network interfaces
79 through systemd-networkd.
83 extraPackages = mkOption {
84 type = types.listOf types.package;
87 List of additional packages to be available within cloud-init jobs.
93 Structured cloud-init configuration.
95 type = types.submodule {
96 freeformType = settingsFormat.type;
105 raw cloud-init configuration.
107 Takes precedence over the `settings` option if set.
115 config = mkIf cfg.enable {
116 services.cloud-init.settings = {
117 system_info = mkDefault {
120 renderers = [ "networkd" ];
124 users = mkDefault [ "root" ];
125 disable_root = mkDefault false;
126 preserve_hostname = mkDefault false;
128 cloud_init_modules = mkDefault [
142 cloud_config_modules = mkDefault [
148 "disable-ec2-metadata"
153 cloud_final_modules = mkDefault [
154 "rightscale_userdata"
158 "scripts-per-instance"
160 "ssh-authkey-fingerprints"
168 environment.etc."cloud/cloud.cfg" =
169 if cfg.config == "" then
170 { source = cfgfile; }
172 { text = cfg.config; }
175 systemd.network.enable = mkIf cfg.network.enable true;
177 systemd.services.cloud-init-local = {
178 description = "Initial cloud-init job (pre-networking)";
179 wantedBy = [ "multi-user.target" ];
180 # In certain environments (AWS for example), cloud-init-local will
181 # first configure an IP through DHCP, and later delete it.
182 # This can cause race conditions with anything else trying to set IP through DHCP.
183 before = [ "systemd-networkd.service" "dhcpcd.service" ];
187 ExecStart = "${pkgs.cloud-init}/bin/cloud-init init --local";
188 RemainAfterExit = "yes";
189 TimeoutSec = "infinity";
190 StandardOutput = "journal+console";
194 systemd.services.cloud-init = {
195 description = "Initial cloud-init job (metadata service crawler)";
196 wantedBy = [ "multi-user.target" ];
198 "network-online.target"
199 "cloud-init-local.service"
201 "sshd-keygen.service"
203 after = [ "network-online.target" "cloud-init-local.service" ];
204 before = [ "sshd.service" "sshd-keygen.service" ];
205 requires = [ "network.target" ];
209 ExecStart = "${pkgs.cloud-init}/bin/cloud-init init";
210 RemainAfterExit = "yes";
211 TimeoutSec = "infinity";
212 StandardOutput = "journal+console";
216 systemd.services.cloud-config = {
217 description = "Apply the settings specified in cloud-config";
218 wantedBy = [ "multi-user.target" ];
219 wants = [ "network-online.target" ];
220 after = [ "network-online.target" "cloud-config.target" ];
225 ExecStart = "${pkgs.cloud-init}/bin/cloud-init modules --mode=config";
226 RemainAfterExit = "yes";
227 TimeoutSec = "infinity";
228 StandardOutput = "journal+console";
232 systemd.services.cloud-final = {
233 description = "Execute cloud user/final scripts";
234 wantedBy = [ "multi-user.target" ];
235 wants = [ "network-online.target" ];
236 after = [ "network-online.target" "cloud-config.service" "rc-local.service" ];
237 requires = [ "cloud-config.target" ];
241 ExecStart = "${pkgs.cloud-init}/bin/cloud-init modules --mode=final";
242 RemainAfterExit = "yes";
243 TimeoutSec = "infinity";
244 StandardOutput = "journal+console";
248 systemd.targets.cloud-config = {
249 description = "Cloud-config availability";
250 requires = [ "cloud-init-local.service" "cloud-init.service" ];
254 meta.maintainers = [ maintainers.zimbatm ];