1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 cfg = config.services.amazon-ssm-agent;
9
10 # The SSM agent doesn't pay attention to our /etc/os-release yet, and the lsb-release tool
11 # in nixpkgs doesn't seem to work properly on NixOS, so let's just fake the two fields SSM
12 # looks for. See https://github.com/aws/amazon-ssm-agent/issues/38 for upstream fix.
13 fake-lsb-release = pkgs.writeScriptBin "lsb_release" ''
14 #!${pkgs.runtimeShell}
15
16 case "$1" in
17 -i) echo "nixos";;
18 -r) echo "${config.system.nixos.version}";;
19 esac
20 '';
21
22 sudoRule = {
23 users = [ "ssm-user" ];
24 commands = [
25 {
26 command = "ALL";
27 options = [ "NOPASSWD" ];
28 }
29 ];
30 };
31in
32{
33 imports = [
34 (lib.mkRenamedOptionModule
35 [ "services" "ssm-agent" "enable" ]
36 [ "services" "amazon-ssm-agent" "enable" ]
37 )
38 (lib.mkRenamedOptionModule
39 [ "services" "ssm-agent" "package" ]
40 [ "services" "amazon-ssm-agent" "package" ]
41 )
42 ];
43
44 options.services.amazon-ssm-agent = {
45 enable = lib.mkEnableOption "Amazon SSM agent";
46 package = lib.mkPackageOption pkgs "amazon-ssm-agent" { };
47 };
48
49 config = lib.mkIf cfg.enable {
50 # See https://github.com/aws/amazon-ssm-agent/blob/mainline/packaging/linux/amazon-ssm-agent.service
51 systemd.services.amazon-ssm-agent = {
52 inherit (cfg.package.meta) description;
53 wants = [ "network-online.target" ];
54 after = [ "network-online.target" ];
55 wantedBy = [ "multi-user.target" ];
56
57 path = [
58 fake-lsb-release
59 pkgs.coreutils
60 "/run/wrappers"
61 "/run/current-system/sw"
62 ];
63
64 serviceConfig = {
65 ExecStart = "${cfg.package}/bin/amazon-ssm-agent";
66 KillMode = "process";
67 # We want this restating pretty frequently. It could be our only means
68 # of accessing the instance.
69 Restart = "always";
70 RestartPreventExitStatus = 194;
71 RestartSec = "90";
72 };
73 };
74
75 # Add user that Session Manager needs, and give it sudo.
76 # This is consistent with Amazon Linux 2 images.
77 security.sudo.extraRules = [ sudoRule ];
78 security.sudo-rs.extraRules = [ sudoRule ];
79
80 # On Amazon Linux 2 images, the ssm-user user is pretty much a
81 # normal user with its own group. We do the same.
82 users.groups.ssm-user = { };
83 users.users.ssm-user = {
84 isNormalUser = true;
85 group = "ssm-user";
86 };
87
88 environment.etc."amazon/ssm/seelog.xml".source =
89 "${cfg.package}/etc/amazon/ssm/seelog.xml.template";
90
91 environment.etc."amazon/ssm/amazon-ssm-agent.json".source =
92 "${cfg.package}/etc/amazon/ssm/amazon-ssm-agent.json.template";
93
94 };
95}