How do I set up Wi-Fi declaratively with static IPv4/IPv6 configuration?

My usecase is to permanently connect a NixOS-based NAS to my network over Wi-Fi with a declaratively configured SSID/PSK pair and a static IPv4/IPv6/DNS/gateway configuration. I’d like to specify everything in /etc/nixos/configuration.nix and not have to use CLI utilities to (imperatively) set up the Wi-Fi link.

Currently, the only way I could get a static IP working (without DHCP) was to use networking.networkmanager.enable = true; and set up the WLAN connection and IP via nmcli, but I’d rather avoid this. If I remove the networking.networkmanager.enable declaration and instead enable networking.wireless.enable as well as configure my Wi-Fi network inside networking.wireless.networks and:

networking.interfaces.wlp1s0.useDHCP = false;
networking.interfaces.wlp1s0.ipv4.addresses = [{
  address = "10.16.6.1";
  prefixLength = 16;
}];

It seems like the WLAN access point gets connected to (at L2 at least) but my NAS never gets an IP address via what I assume is wpa_supplicant (enabled by networking.wireless).

I also know I could just use DHCP and set up an IP reservation on my router. While I will also probably eventually do that as well, I want my device to be able to grab an IPv4 (and eventually v6 when I get around to setting that up) by itself.

Anyone with a similar setup? Any ideas?

Thanks

It seems like the WLAN access point gets connected to (at L2 at least) but my NAS never gets an IP

What do you mean with “gets an IP”? The interface is not being set up with the static addresses after you’ve activated the NixOS configuration?

Or, If you mean why you don’t receive an address via DHCP, well… you’ve disabled it.

via what I assume is wpa_supplicant (enabled by networking.wireless ).

If you mean why doesn’t wpa_supplicant gets you an IP address; it has nothing to do with DHCP or even TCP/IP: it’s a daemon that solely performs link-layer authentication and encryption.

networking.interfaces.wlp1s0.useDHCP = false;
networking.interfaces.wlp1s0.ipv4.addresses = [{
address = “10.16.6.1”;
prefixLength = 16;
}];

This seems ok, though you also need to set the default gateway and MTU, if it’s not the usual 1500 bytes.

I also know I could just use DHCP and set up an IP reservation on my router.

You really should: if you don’t, the DHCP server may hand out your address to another host, and if that doesn’t perform duplicate address detection you will get a conflict. Unlikely on a /16, but it will definitely happen on a /24 subnet.