-
-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Expand file tree
/
Copy pathamazon-image.nix
More file actions
142 lines (120 loc) · 4.31 KB
/
amazon-image.nix
File metadata and controls
142 lines (120 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# Configuration for Amazon EC2 instances. (Note that this file is a
# misnomer - it should be "amazon-config.nix" or so, not
# "amazon-image.nix", since it's used not only to build images but
# also to reconfigure instances. However, we can't rename it because
# existing "configuration.nix" files on EC2 instances refer to it.)
{
config,
lib,
pkgs,
...
}:
let
inherit (lib) mkDefault mkIf;
cfg = config.ec2;
in
{
imports = [
../profiles/headless.nix
# Note: While we do use the headless profile, we also explicitly
# turn on the serial console on ttyS0 below. This is because
# AWS does support accessing the serial console:
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configure-access-to-serial-console.html
./ec2-data.nix
./amazon-init.nix
];
config = {
assertions = [ ];
boot.growPartition = true;
fileSystems."/" = mkIf (!cfg.zfs.enable) (
lib.mkDefault {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
autoResize = true;
}
);
fileSystems."/boot" = mkIf (cfg.efi || cfg.zfs.enable) (
lib.mkDefault {
# The ZFS image uses a partition labeled ESP whether or not we're
# booting with EFI.
device = "/dev/disk/by-label/ESP";
fsType = "vfat";
}
);
services.zfs.expandOnBoot = mkIf cfg.zfs.enable "all";
boot.zfs.devNodes = mkIf cfg.zfs.enable "/dev/";
boot.extraModulePackages = [
config.boot.kernelPackages.ena
];
boot.initrd.availableKernelModules = [ "nvme" ];
boot.kernelParams =
let
# Amazon recommends setting this to the highest possible value for a good EBS
# experience, which prior to 4.15 was 255.
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html#timeout-nvme-ebs-volumes
nvmeTimeout =
if lib.versionAtLeast config.boot.kernelPackages.kernel.version "4.15" then "4294967295" else "255";
in
[
"console=ttyS0,115200n8"
"random.trust_cpu=on"
"nvme_core.io_timeout=${nvmeTimeout}"
];
# Prevent the nouveau kernel module from being loaded, as it
# interferes with the nvidia/nvidia-uvm modules needed for CUDA.
# Also blacklist xen_fbfront to prevent a 30 second delay during
# boot.
boot.blacklistedKernelModules = [
"nouveau"
"xen_fbfront"
];
boot.loader.grub.device = if cfg.efi then "nodev" else "/dev/xvda";
boot.loader.grub.efiSupport = cfg.efi;
boot.loader.grub.efiInstallAsRemovable = cfg.efi;
boot.loader.timeout = 1;
boot.loader.grub.extraConfig = ''
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal_output console serial
terminal_input console serial
'';
systemd.services.fetch-ec2-metadata = {
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
path = with pkgs; [
bzip2
curl
file
gzip
lzip
mktemp
xz
zstd
];
script = builtins.readFile ./ec2-metadata-fetcher.sh;
serviceConfig.Type = "oneshot";
serviceConfig.StandardOutput = "journal+console";
};
# Amazon-issued AMIs include the SSM Agent by default, so we do the same.
# https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html
services.amazon-ssm-agent.enable = true;
# Allow root logins only using the SSH key that the user specified
# at instance creation time.
services.openssh.enable = true;
services.openssh.settings.PermitRootLogin = "prohibit-password";
# Enable the serial console on ttyS0
systemd.services."serial-getty@ttyS0".enable = true;
# Creates symlinks for block device names.
services.udev.packages = [ pkgs.amazon-ec2-utils ];
# Force getting the hostname from EC2.
networking.hostName = mkDefault "";
# Always include cryptsetup so that Charon can use it.
environment.systemPackages = [ pkgs.cryptsetup ];
# EC2 has its own NTP server provided by the hypervisor
networking.timeServers = [ "169.254.169.123" ];
# udisks has become too bloated to have in a headless system
# (e.g. it depends on GTK).
services.udisks2.enable = false;
};
meta.maintainers = with lib.maintainers; [ arianvp ];
}