diff --git a/README.md b/README.md
index debbc13..af595f0 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,22 @@
 # tritonshell
 ### a nix devshell for triton
+
+0. If you're already on NixOS jump to 2.
+1. [Install nix](https://nixos.org/download.html)
+
+    1. Now, make sure you're ready to nix with flakes, this should give you some output:
+    ```
+    nix flake --help
+    ```
+    2. Otherwise, proceed to enable flakes (still an experimental feature in `nix`):
+       https://nixos.wiki/wiki/Flakes#Installing_flakes
+
+2. Get this nix flake template:
+```
+nix flake new 'git+https://git.greenbaum.cloud/greenbaum.cloud/tritonshell'
+```
+
+3. Ready to go:
+```
+nix develop
+```
diff --git a/flake.lock b/flake.lock
index 5a0a314..497947e 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "devshell": {
       "locked": {
-        "lastModified": 1642188268,
-        "narHash": "sha256-DNz4xScpXIn7rSDohdayBpPR9H9OWCMDOgTYegX081k=",
+        "lastModified": 1643393796,
+        "narHash": "sha256-+wb2OFWJjXUZw3HQezACc9Lj/5uuhNpUtrjDiIYw8H4=",
         "owner": "numtide",
         "repo": "devshell",
-        "rev": "696acc29668b644df1740b69e1601119bf6da83b",
+        "rev": "fff3dc6e4538f6df85ee3027f13cc7730b23f61d",
         "type": "github"
       },
       "original": {
@@ -32,11 +32,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1642768189,
-        "narHash": "sha256-XuUHXFzJWuSDo7dzpjTbHrjk37lAdTyk05sypXsqv1g=",
+        "lastModified": 1643630271,
+        "narHash": "sha256-E49xk1KCW+0211Lnmhdt5WvVzUI3Se8Y74N6pUkraPU=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "e31e42dfdee3922a618b37c6d5f55603c24d86a0",
+        "rev": "17f073ee6b61d2afcd2a3ce5c4e360436f68bef4",
         "type": "github"
       },
       "original": {
@@ -64,16 +64,16 @@
     },
     "nixpkgsUnstable": {
       "locked": {
-        "lastModified": 1643000262,
-        "narHash": "sha256-8hrbufiCcZgicU8UvHaRkruYuzM8z3lJvQkSh9ezMEg=",
+        "lastModified": 1643347846,
+        "narHash": "sha256-O0tyXF//ppRpe9yT1Uu5n34yI2MWDyY6ZiJ4Qn5zIkE=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "cc68710784ffe0ee035ee7b726656c44566cac94",
+        "rev": "5bb20f9dc70e9ee16e21cc404b6508654931ce41",
         "type": "github"
       },
       "original": {
         "owner": "nixos",
-        "ref": "nixpkgs-unstable",
+        "ref": "nixos-unstable",
         "repo": "nixpkgs",
         "type": "github"
       }
diff --git a/flake.nix b/flake.nix
index 29e169a..ca8ef62 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,134 +1,50 @@
 {
-  description = "Development environment for nix'ing with triton";
+  description = "devs & ops environment for nix'ing with triton";
 
   inputs.devshell.url = "github:numtide/devshell";
   inputs.flake-utils.url = "github:numtide/flake-utils";
   inputs.nixpkgs.url = "github:nixos/nixpkgs/release-21.11";
-  inputs.nixpkgsUnstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
+  inputs.nixpkgsUnstable.url = "github:nixos/nixpkgs/nixos-unstable";
   inputs.nixpkgs20-09.url = "github:nixos/nixpkgs/release-20.09";
 
   outputs = { self, flake-utils, devshell, nixpkgs, nixpkgsUnstable, nixpkgs20-09 }:
     flake-utils.lib.eachDefaultSystem (system: {
-      packages.triton-utils =
-        let
-          pkgs = import nixpkgs {
-            inherit system;
-          };
-        in
-        pkgs.stdenv.mkDerivation {
-          pname = "triton-utils";
-          version = "0.0.1";
-          src = pkgs.lib.cleanSource ./.;
 
-          installPhase = ''
-              mkdir -p $out/bin $out/share/certs
-              cd ./utils
-              cp ./cacert-2021-10-26.pem $out/share/certs
-              cp ./triton-docker.env.sh $out/bin
-              cp ./ttp.sh $out/bin
-              cp ./unset-env.sh $out/bin
-          '';
-        };
+      # Internal utility package with shell function and env vars helper.
+      # These get source'd in devshell.bash.extra when starting tritonshell
+      packages.triton-utils = import ./pkgs/triton-utils.nix { inherit nixpkgs; inherit system; };
+
       devShell =
-        let
-          pkgs = import nixpkgs {
-            inherit system;
+      let
+        pkgs = import nixpkgs {
+          inherit system;
 
-            overlays = [ devshell.overlay ];
-          };
-          pkgsUnstable = import nixpkgsUnstable {
-            inherit system;
-
-            overlays = [ devshell.overlay ];
-          };
-          pkgs20-09 = import nixpkgs20-09 {
-            inherit system;
-
-            overlays = [ devshell.overlay ];
-          };
-        in
-        pkgs.devshell.mkShell {
-          name = "tritonshell";
-
-          devshell.interactive = {
-            PS1_util = pkgs.lib.noDepEntry ''
-              if [[ -n "''${PRJ_ROOT:-}" ]]; then
-                # Print the path relative to $PRJ_ROOT
-                rel_root() {
-                  local path
-                  path=$(${pkgs.coreutils}/bin/realpath --relative-to "$PRJ_ROOT" "$PWD")
-                  if [[ $path != . ]]; then
-                    echo " $path "
-                  fi
-                }
-              else
-                # If PRJ_ROOT is unset, print only the current directory name
-                rel_root() {
-                  echo " \W "
-                }
-              fi
-            '';
-            PS1.text = ''
-              PS1='\[\033[38;5;202m\][$TRITON_PROFILE@tritonshell]$(rel_root)\$ \[\033[0m\]'
-            '';
-          };
-
-          commands = [
-            {
-              package = pkgs.devshell.cli;
-              help = "Per project developer environments";
-            }
-            {
-              package = pkgsUnstable.nodePackages.triton;
-              category = "triton & manta tools";
-              name = "triton";
-              help = "Triton DC CLI (https://docs.joyent.com/public-cloud/api/triton-cli)";
-            }
-            {
-              package = pkgsUnstable.nodePackages.manta;
-              category = "triton & manta tools";
-              name = "manta";
-              help = "Manta CLI (https://apidocs.joyent.com/manta/index.html#cli)";
-            }
-          ];
-
-          devshell.packages = [
-            pkgs.bash-completion
-            # use docker-compose version 1.26.2 for best triton API compatibility
-            pkgs20-09.docker-compose
-            # used in ./utils/triton-docker.env.sh
-            pkgs.nodePackages.json
-            self.packages.${system}.triton-utils
-            pkgsUnstable.terraform
-            pkgs.python39Packages.ansible
-          ];
-
-          env = [
-            # workaround for TLS certs bug in docker-compose, CERTIFICATE_VERIFY_FAILED
-            # see: https://github.com/joyent/triton-docker-cli/issues/17
-            {
-              name = "CURL_CA_BUNDLE";
-              value = "${self.packages.${system}.triton-utils}/share/certs/cacert-2021-10-26.pem";
-            }
-            {
-              name = "NOMAD_ADDR";
-              value = "https://nomad.service.consul:4646";
-            }
-            {
-              name = "VAULT_ADDR";
-              value = "https://nomad.service.consul:8200";
-            }
-          ];
-
-          bash = {
-            extra = ''
-              source ${self.packages.${system}.triton-utils}/bin/triton-docker.env.sh
-              source ${self.packages.${system}.triton-utils}/bin/ttp.sh
-              if [ "$(uname)" == "Darwin" ]; then
-                source $DEVSHELL_DIR/share/bash-completion/bash_completion
-              fi
-            '';
-          };
+          overlays = [ devshell.overlay ];
         };
-    });
+        pkgsUnstable = import nixpkgsUnstable {
+          inherit system;
+
+          overlays = [ devshell.overlay ];
+        };
+        pkgs20-09 = import nixpkgs20-09 {
+          inherit system;
+
+          overlays = [ devshell.overlay ];
+        };
+
+        # HINT: add your extra pkgs here,
+        # they'll get appended to devshell.packages in ./tritonshell.nix
+        extraDevshellPkgs = [
+          pkgsUnstable.consul
+          pkgsUnstable.nomad
+          pkgsUnstable.terraform
+          pkgsUnstable.vault
+        ];
+
+      in
+        import ./tritonshell.nix { inherit extraDevshellPkgs devshell pkgs pkgsUnstable pkgs20-09 self system; };
+      }) // {
+        # merge this into the attr set above
+        defaultTemplate.description = "nix flake new 'git+https://git.greenbaum.cloud/greenbaum.cloud/tritonshell'";
+      };
 }
diff --git a/pkgs/triton-utils.nix b/pkgs/triton-utils.nix
new file mode 100644
index 0000000..91ba0b6
--- /dev/null
+++ b/pkgs/triton-utils.nix
@@ -0,0 +1,20 @@
+{ nixpkgs, system, ... }:
+let
+  pkgs = import nixpkgs {
+    inherit system;
+  };
+in
+pkgs.stdenv.mkDerivation {
+  pname = "triton-utils";
+  version = "0.0.1";
+  src = pkgs.lib.cleanSource ./.;
+
+  installPhase = ''
+      mkdir -p $out/bin $out/share/certs
+      cd ./utils
+      cp ./cacert-2021-10-26.pem $out/share/certs
+      cp ./triton-docker.env.sh $out/bin
+      cp ./ttp.sh $out/bin
+      cp ./unset-env.sh $out/bin
+  '';
+}
diff --git a/utils/cacert-2021-10-26.pem b/pkgs/utils/cacert-2021-10-26.pem
similarity index 100%
rename from utils/cacert-2021-10-26.pem
rename to pkgs/utils/cacert-2021-10-26.pem
diff --git a/utils/triton-docker.env.sh b/pkgs/utils/triton-docker.env.sh
similarity index 100%
rename from utils/triton-docker.env.sh
rename to pkgs/utils/triton-docker.env.sh
diff --git a/utils/ttp.sh b/pkgs/utils/ttp.sh
similarity index 100%
rename from utils/ttp.sh
rename to pkgs/utils/ttp.sh
diff --git a/utils/unset-env.sh b/pkgs/utils/unset-env.sh
similarity index 100%
rename from utils/unset-env.sh
rename to pkgs/utils/unset-env.sh
diff --git a/tritonshell.nix b/tritonshell.nix
new file mode 100644
index 0000000..707fb5b
--- /dev/null
+++ b/tritonshell.nix
@@ -0,0 +1,89 @@
+{ extraDevshellPkgs, devshell, pkgs, pkgsUnstable, pkgs20-09, self, system, ... }:
+pkgs.devshell.mkShell {
+  # devshell docs: https://numtide.github.io/devshell/modules_schema.html
+  name = "tritonshell";
+
+  devshell.interactive = {
+    PS1_util = pkgs.lib.noDepEntry ''
+      if [[ -n "''${PRJ_ROOT:-}" ]]; then
+        # Print the path relative to $PRJ_ROOT
+        rel_root() {
+          local path
+          path=$(${pkgs.coreutils}/bin/realpath --relative-to "$PRJ_ROOT" "$PWD")
+          if [[ $path != . ]]; then
+            echo " $path "
+          fi
+        }
+      else
+        # If PRJ_ROOT is unset, print only the current directory name
+        rel_root() {
+          echo " \W "
+        }
+      fi
+    '';
+    PS1.text = ''
+      PS1='\[\033[38;5;202m\][$TRITON_PROFILE@tritonshell]$(rel_root)\$ \[\033[0m\]'
+    '';
+  };
+
+  commands = [
+    {
+      package = pkgs.devshell.cli;
+      help = "Per project developer environments";
+    }
+    {
+      package = pkgsUnstable.nodePackages.triton;
+      category = "triton & manta tools";
+      name = "triton";
+      help = "Triton DC CLI (https://docs.joyent.com/public-cloud/api/triton-cli)";
+    }
+    {
+      package = pkgsUnstable.nodePackages.manta;
+      category = "triton & manta tools";
+      name = "manta";
+      help = "Manta CLIs (https://apidocs.joyent.com/manta/index.html#cli)";
+    }
+  ];
+
+  devshell.packages = [
+    pkgs.bash-completion
+    # use docker-compose version 1.26.2 for best triton API compatibility
+    pkgs20-09.docker-compose
+    # used in ./utils/triton-docker.env.sh
+    pkgs.nodePackages.json
+    pkgs.bunyan-rs
+    self.packages.${system}.triton-utils
+    pkgs.ansible
+  ] ++ extraDevshellPkgs;
+
+  env = [
+    # workaround for TLS certs bug in docker-compose, CERTIFICATE_VERIFY_FAILED
+    # see: https://github.com/joyent/triton-docker-cli/issues/17
+    {
+      name = "CURL_CA_BUNDLE";
+      value = "${self.packages.${system}.triton-utils}/share/certs/cacert-2021-10-26.pem";
+    }
+    {
+      name = "CONSUL_HTTP_ADDR";
+      value = "http://consul.service.consul:8500";
+    }
+    {
+      name = "NOMAD_ADDR";
+      value = "https://nomad.service.consul:4646";
+    }
+    {
+      name = "VAULT_ADDR";
+      value = "https://nomad.service.consul:8200";
+    }
+  ];
+
+  bash = {
+    extra = ''
+      source ${self.packages.${system}.triton-utils}/bin/triton-docker.env.sh
+      source ${self.packages.${system}.triton-utils}/bin/ttp.sh
+      if [ "$(uname)" == "Darwin" ]; then
+        source $DEVSHELL_DIR/share/bash-completion/bash_completion
+      fi
+    '';
+  };
+}