1 { config, lib, pkgs, ... }:
6 cfg = config.virtualisation.amazon-init;
9 #!${pkgs.runtimeShell} -eu
11 echo "attempting to fetch configuration from EC2 user data..."
14 export PATH=${pkgs.lib.makeBinPath [ config.nix.package config.systemd.package pkgs.gnugrep pkgs.git pkgs.gnutar pkgs.gzip pkgs.gnused pkgs.xz config.system.build.nixos-rebuild]}:$PATH
15 export NIX_PATH=nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels
17 userData=/etc/ec2-metadata/user-data
19 # Check if user-data looks like a shell script and execute it with the
20 # runtime shell if it does. Otherwise treat it as a nixos configuration
22 if IFS= LC_ALL=C read -rN2 shebang < $userData && [ "$shebang" = '#!' ]; then
23 # NB: we cannot chmod the $userData file, this is why we execute it via
24 # `pkgs.runtimeShell`. This means we have only limited support for shell
25 # scripts compatible with the `pkgs.runtimeShell`.
26 exec ${pkgs.runtimeShell} $userData
29 if [ -s "$userData" ]; then
30 # If the user-data looks like it could be a nix expression,
31 # copy it over. Also, look for a magic three-hash comment and set
32 # that as the channel.
33 if sed '/^\(#\|SSH_HOST_.*\)/d' < "$userData" | grep -q '\S'; then
34 channels="$(grep '^###' "$userData" | sed 's|###\s*||')"
35 while IFS= read -r channel; do
36 echo "writing channel: $channel"
37 done < <(printf "%s\n" "$channels")
39 if [[ -n "$channels" ]]; then
40 printf "%s" "$channels" > /root/.nix-channels
44 echo "setting configuration from EC2 user data"
45 cp "$userData" /etc/nixos/configuration.nix
47 echo "user data does not appear to be a Nix expression; ignoring"
51 echo "no user data is available"
59 options.virtualisation.amazon-init = {
64 Enable or disable the amazon-init service.
69 config = mkIf cfg.enable {
70 systemd.services.amazon-init = {
72 description = "Reconfigure the system from EC2 userdata on startup";
74 wantedBy = [ "multi-user.target" ];
75 after = [ "multi-user.target" ];
76 requires = [ "network-online.target" ];
80 "/run/current-system/sw"
83 restartIfChanged = false;
84 unitConfig.X-StopOnRemoval = false;
88 RemainAfterExit = true;
92 meta.maintainers = with maintainers; [ arianvp ];