adrianhesketh.com

Install AWS Amplify CLI with Nix

I switched to using nix-darwin (https://github.com/LnL7/nix-darwin) to install and update various base packages on my system a few months ago. I intend to get around to using it to define the tools in use within various projects I’m working on, rather than installing things globally, but I’m quite happy with the base setup I’ve got for day-to-day work for the moment.

Some development tools are built in scripting languages like Ruby, Python and Node.js which means users have to have an appropriate version of Python or Node installed, or use brew or some other package manager to make sure that dependencies are installed.

AWS Amplify is written in Node.js, so one way to install it would be to use Node’s package manager (npm) to install it as a “global package”: npm install -g @aws-amplify/cli, in fact, that’s what the documentation suggests to do.

In the nix world, this doesn’t make much sense because the whole point of nix is to create a shell that just contains the tools you need, and to be able to create reproducible environments, so we’d want to create a “nix expression” that describes the packages we want installed in that shell. Manual steps are not what we want.

Nix has thousands of packages in its repository (https://github.com/NixOS/nixpkgs) that can be searched on the Web at https://nixos.org/nixos/packages.html or at the command line with nix search <term>. At the time of writing, AWS Amplify wasn’t a package, and I needed to get some work done with it, so I couldn’t wait around for a pull request to get merged.

Node.js packages are handled in nix by using the node2nix tool. This tool works out what files and dependencies need to be installed for each Node package and creates “nix expressions” that define them, so the first thing to do was to add node2nix to my system by adding it to the environment.systemPackages variable in my darwin-configuration.nix file:

environment.systemPackages =
  [
    pkgs.nodePackages.node2nix
    pkgs.tmux
    pkgs.tree
    pkgs.unzip
    pkgs.wget
    pkgs.yarn
    pkgs.zip
  ];

I keep my complete darwin-configuration.nix file in a git repository at at https://github.com/a-h/dotfiles/blob/master/.nixpkgs/darwin-configuration.nix in case I need to rebuild a system.

By executing a darwin-rebuild switch, my system now had node2nix installed and ready for use. The next thing I needed to do was to work out how to use it. I found this blog post to be particularly helpful http://nicknovitski.com/nix-npm-install

Next, I had to work out how to create a nix expression for the node packages I wanted to install. I created a new directory called node-env inside the directory that stores my darwin-configuration.nix file and created a node-packages.json file within it, containing the name of the AWS Amplify CLI package.

[
  "@aws-amplify/cli"
]

With that in place, I could run node2nix:

node2nix -i node-packages.json

The output was a set of nix expressions (node-packages.nix, node-env.nix and default.nix). I then needed to merge these into my overall system configuration and include the package in my systemPackages.

To do this, I needed to import the default.nix from the darwin-configuration.nix file.

I chose to import it as a variable called nodePackages. Once imported, I could then add AWS Amplify in the environment.systemPackages as nodePackages."@aws-amplify/cli":


{ config, pkgs, ... }:

let

  nodePackages = import ./node-env/default.nix {
    inherit pkgs;
  };

in

{
  environment.variables = { EDITOR = "vim"; };

  environment.systemPackages =
    [
      nodePackages."@aws-amplify/cli"
      pkgs.nodePackages.node2nix
      pkgs.tmux
      pkgs.tree
      pkgs.unzip
      pkgs.wget
      pkgs.yarn
      pkgs.zip
    ];

  # Create /etc/bashrc that loads the nix-darwin environment.
  programs.zsh.enable = true;  # default shell on catalina
  # programs.fish.enable = true;

  # Used for backwards compatibility, please read the changelog before changing.
  # $ darwin-rebuild changelog
  system.stateVersion = 4;
}

With another darwin-rebuild switch, I was then able to run the AWS Amplify CLI with the usual amplify command. To validate that it’s been installed via nix, I used which amplify to show the location:

$ which amplify
/run/current-system/sw/bin/amplify