Terraform: how you override a version using nixpgks way

So I learned how to install terraform with specific pluggins:

    (terraform_0_11.withPlugins (p: [
      p.archive
      p.aws
      p.external
      p.gitlab
      p.grafana
      p.helm
      p.kubernetes
      p.local
      p.null
      p.random
      p.template
      p.tls
    ]))

but say i want a specific version of 0.11.10, should i first add stdenv.mkDerivation to this code: https://github.com/NixOS/nixpkgs/blob/820e450810cbac9636634f1eb95c75c4f7f24c43/pkgs/applications/networking/cluster/terraform/default.nix?

i’m not a big expert in nix yet, would love to hear suggestions here.

they way i used terraform/terragrunt before with installing specific version is using: tfenv/tgenv, but in nixos way that’s definitely redundant.

You can achieve this via an overlay. Here is an example how to override terraform 0.12 and a provider, as well as creating a package that includes a set of plugins:

let
  terraformOverlay = final: prev: {
    terraformFull = final.terraform_0_12.withPlugins (p: [ p.aws p.null ]);

    terraform_0_12 = prev.terraform_0_12.overrideAttrs (old: rec {
      name = "terraform-${version}";
      version = "0.12.28";
      src = prev.fetchFromGitHub {
        owner = "hashicorp";
        repo = "terraform";
        rev = "v${version}";
        sha256 = "05ymr6vc0sqh1sia0qawhz0mag8jdrq157mbj9bkdpsnlyv209p3";
      };
    });

    terraform-providers = prev.terraform-providers // {
      aws = prev.terraform-providers.aws.overrideAttrs (old: rec {
        name = "${old.repo}-${version}";
        version = "3.20.0";
        src = prev.fetchFromGitHub {
          owner = "hashicorp";
          repo = "terraform-provider-aws";
          rev = "v${version}";
          sha256 = "18zccjkdxzcprhpv3cn3b9fbp0h81pkj0dsygfz2islclljc3x17";
        };
        postBuild = "mv go/bin/${old.repo}{,_v${version}}";
      };
    };
  };
in import <nixpkgs> { overlays = [ terraformOverlay ]; }

thanks for taking the time.

can you tell i’m invoking it correctly:

❯ cat terraform.nix
let
  terraformOverlay = final: prev: {
    terraformFull = final.terraform_0_12.withPlugins (p: [ p.aws p.null ]);

    terraform_0_12 = prev.terraform_0_12.overrideAttrs (old: rec {
      name = "terraform-${version}";
      version = "0.12.28";
      src = prev.fetchFromGitHub {
        owner = "hashicorp";
        repo = "terraform";
        rev = "v${version}";
        sha256 = "05ymr6vc0sqh1sia0qawhz0mag8jdrq157mbj9bkdpsnlyv209p3";
      };
    });

    terraform-providers = prev.terraform-providers // {
      aws = prev.terraform-providers.aws.overrideAttrs (old: rec {
        name = "${old.repo}-${version}";
        version = "3.20.0";
        src = prev.fetchFromGitHub {
          owner = "hashicorp";
          repo = "terraform-provider-aws";
          rev = "v${version}";
          sha256 = "18zccjkdxzcprhpv3cn3b9fbp0h81pkj0dsygfz2islclljc3x17";
        };
        postBuild = "mv go/bin/${old.repo}{,_v${version}}";
      });
    };
  };
in import <nixpkgs> { overlays = [ terraformOverlay ]; }


❯ nix-build -E 'with import <nixpkgs> {} ; callPackage ./terraform.nix {}';
error: attempt to call something which is not a function but a set, at /nix/store/hmcb722lpf189pdqflxa7a4vh1bxflvg-nixos-21.03pre256292.296793637b2/nixos/lib/customisation.nix:69:16

So as you see in the bottom this is not a package, but an overlay passed to nixpkgs. What you are doing in your eval is doing the same import <nixpkgs> {} without overlay argument and then calling nixpkgs as a package.

If you rename that file to pkgs.nix instead you should be able to do nix-build pkgs.nix -A terraformFull

Then instead of import <nixpkgs> {} you would use import ./pkgs.nix.

There are many different ways to do this, so I would have to more about your use case in order to provide a more detailed answer.

ideally i would want to use nixpkgs with overriding a version, and i guess that should be pre-defined to able to accomplish that.

i think i could nix-shell/nix-build the version i need (with altered nixpkgs) and export the binary PATH when needed.

cheers.