aerospike: 7.2.0.4 -> 7.2.0.6 (#373809)
[NixPkgs.git] / nixos / modules / services / system / cloud-init.nix
blob372fa8aac80457e2c0cf8a810785280fd3e0e734
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
7 let
8   cfg = config.services.cloud-init;
9   path =
10     with pkgs;
11     [
12       cloud-init
13       iproute2
14       nettools
15       openssh
16       shadow
17       util-linux
18       busybox
19     ]
20     ++ lib.optional cfg.btrfs.enable btrfs-progs
21     ++ lib.optional cfg.ext4.enable e2fsprogs
22     ++ lib.optional cfg.xfs.enable xfsprogs
23     ++ cfg.extraPackages;
24   hasFs = fsName: lib.any (fs: fs.fsType == fsName) (lib.attrValues config.fileSystems);
25   settingsFormat = pkgs.formats.yaml { };
26   cfgfile = settingsFormat.generate "cloud.cfg" cfg.settings;
29   options = {
30     services.cloud-init = {
31       enable = lib.mkOption {
32         type = lib.types.bool;
33         default = false;
34         description = ''
35           Enable the cloud-init service. This services reads
36           configuration metadata in a cloud environment and configures
37           the machine according to this metadata.
39           This configuration is not completely compatible with the
40           NixOS way of doing configuration, as configuration done by
41           cloud-init might be overridden by a subsequent nixos-rebuild
42           call. However, some parts of cloud-init fall outside of
43           NixOS's responsibility, like filesystem resizing and ssh
44           public key provisioning, and cloud-init is useful for that
45           parts. Thus, be wary that using cloud-init in NixOS might
46           come as some cost.
47         '';
48       };
50       btrfs.enable = lib.mkOption {
51         type = lib.types.bool;
52         default = hasFs "btrfs";
53         defaultText = lib.literalExpression ''hasFs "btrfs"'';
54         description = ''
55           Allow the cloud-init service to operate `btrfs` filesystem.
56         '';
57       };
59       ext4.enable = lib.mkOption {
60         type = lib.types.bool;
61         default = hasFs "ext4";
62         defaultText = lib.literalExpression ''hasFs "ext4"'';
63         description = ''
64           Allow the cloud-init service to operate `ext4` filesystem.
65         '';
66       };
68       xfs.enable = lib.mkOption {
69         type = lib.types.bool;
70         default = hasFs "xfs";
71         defaultText = lib.literalExpression ''hasFs "xfs"'';
72         description = ''
73           Allow the cloud-init service to operate `xfs` filesystem.
74         '';
75       };
77       network.enable = lib.mkOption {
78         type = lib.types.bool;
79         default = false;
80         description = ''
81           Allow the cloud-init service to configure network interfaces
82           through systemd-networkd.
83         '';
84       };
86       extraPackages = lib.mkOption {
87         type = lib.types.listOf lib.types.package;
88         default = [ ];
89         description = ''
90           List of additional packages to be available within cloud-init jobs.
91         '';
92       };
94       settings = lib.mkOption {
95         description = ''
96           Structured cloud-init configuration.
97         '';
98         type = lib.types.submodule {
99           freeformType = settingsFormat.type;
100         };
101         default = { };
102       };
104       config = lib.mkOption {
105         type = lib.types.str;
106         default = "";
107         description = ''
108           raw cloud-init configuration.
110           Takes precedence over the `settings` option if set.
111         '';
112       };
114     };
116   };
118   config = lib.mkIf cfg.enable {
119     services.cloud-init.settings = {
120       system_info = lib.mkDefault {
121         distro = "nixos";
122         network = {
123           renderers = [ "networkd" ];
124         };
125       };
127       users = lib.mkDefault [ "root" ];
128       disable_root = lib.mkDefault false;
129       preserve_hostname = lib.mkDefault false;
131       cloud_init_modules = lib.mkDefault [
132         "migrator"
133         "seed_random"
134         "bootcmd"
135         "write-files"
136         "growpart"
137         "resizefs"
138         "update_hostname"
139         "resolv_conf"
140         "ca-certs"
141         "rsyslog"
142         "users-groups"
143       ];
145       cloud_config_modules = lib.mkDefault [
146         "disk_setup"
147         "mounts"
148         "ssh-import-id"
149         "set-passwords"
150         "timezone"
151         "disable-ec2-metadata"
152         "runcmd"
153         "ssh"
154       ];
156       cloud_final_modules = lib.mkDefault [
157         "rightscale_userdata"
158         "scripts-vendor"
159         "scripts-per-once"
160         "scripts-per-boot"
161         "scripts-per-instance"
162         "scripts-user"
163         "ssh-authkey-fingerprints"
164         "keys-to-console"
165         "phone-home"
166         "final-message"
167         "power-state-change"
168       ];
169     };
171     environment.etc."cloud/cloud.cfg" =
172       if cfg.config == "" then { source = cfgfile; } else { text = cfg.config; };
174     systemd.network.enable = lib.mkIf cfg.network.enable true;
176     systemd.services.cloud-init-local = {
177       description = "Initial cloud-init job (pre-networking)";
178       wantedBy = [ "multi-user.target" ];
179       # In certain environments (AWS for example), cloud-init-local will
180       # first configure an IP through DHCP, and later delete it.
181       # This can cause race conditions with anything else trying to set IP through DHCP.
182       before = [
183         "systemd-networkd.service"
184         "dhcpcd.service"
185       ];
186       path = path;
187       serviceConfig = {
188         Type = "oneshot";
189         ExecStart = "${pkgs.cloud-init}/bin/cloud-init init --local";
190         RemainAfterExit = "yes";
191         TimeoutSec = "infinity";
192         StandardOutput = "journal+console";
193       };
194     };
196     systemd.services.cloud-init = {
197       description = "Initial cloud-init job (metadata service crawler)";
198       wantedBy = [ "multi-user.target" ];
199       wants = [
200         "network-online.target"
201         "cloud-init-local.service"
202         "sshd.service"
203         "sshd-keygen.service"
204       ];
205       after = [
206         "network-online.target"
207         "cloud-init-local.service"
208       ];
209       before = [
210         "sshd.service"
211         "sshd-keygen.service"
212       ];
213       requires = [ "network.target" ];
214       path = path;
215       serviceConfig = {
216         Type = "oneshot";
217         ExecStart = "${pkgs.cloud-init}/bin/cloud-init init";
218         RemainAfterExit = "yes";
219         TimeoutSec = "infinity";
220         StandardOutput = "journal+console";
221       };
222     };
224     systemd.services.cloud-config = {
225       description = "Apply the settings specified in cloud-config";
226       wantedBy = [ "multi-user.target" ];
227       wants = [ "network-online.target" ];
228       after = [
229         "network-online.target"
230         "cloud-config.target"
231       ];
233       path = path;
234       serviceConfig = {
235         Type = "oneshot";
236         ExecStart = "${pkgs.cloud-init}/bin/cloud-init modules --mode=config";
237         RemainAfterExit = "yes";
238         TimeoutSec = "infinity";
239         StandardOutput = "journal+console";
240       };
241     };
243     systemd.services.cloud-final = {
244       description = "Execute cloud user/final scripts";
245       wantedBy = [ "multi-user.target" ];
246       wants = [ "network-online.target" ];
247       after = [
248         "network-online.target"
249         "cloud-config.service"
250         "rc-local.service"
251       ];
252       requires = [ "cloud-config.target" ];
253       path = path;
254       serviceConfig = {
255         Type = "oneshot";
256         ExecStart = "${pkgs.cloud-init}/bin/cloud-init modules --mode=final";
257         RemainAfterExit = "yes";
258         TimeoutSec = "infinity";
259         StandardOutput = "journal+console";
260       };
261     };
263     systemd.targets.cloud-config = {
264       description = "Cloud-config availability";
265       requires = [
266         "cloud-init-local.service"
267         "cloud-init.service"
268       ];
269     };
270   };
272   meta.maintainers = [ lib.maintainers.zimbatm ];