terraform: expose providers to terraform 0.13

Terraform 0.13 adopts a new filesystem layout for plugins (illustrated below).

Terraform 0.12 and earlier
`plugins-dir/terraform-provider-aws_v3.7.0`

Terraform 0.13
`plugins-dir/registry.terraform.io/hashicorp/aws/3.7.0/linux_amd64/terraform-provider-aws_v3.7.0`

To support all packaged Terraform versions a shim is created at both locations.

This approach was inspired by https://github.com/numtide/generate-terraform-provider-shim

Terraform 0.13 provider documentation https://www.terraform.io/upgrade-guides/0-13.html#new-filesystem-layout-for-local-copies-of-providers

layout terraform providers filesystem in withPlugins
This commit is contained in:
Timothy Stott 2020-10-05 23:52:33 +01:00
parent 72cd428dd2
commit cd1b594767
2 changed files with 36 additions and 10 deletions

View File

@ -2,11 +2,16 @@
, buildGoPackage
, fetchFromGitHub
, callPackage
, runtimeShell
}:
let
list = lib.importJSON ./providers.json;
toDrv = data:
toDrv = name: data:
let
fallbackProviderSourceAddress = "nixpkgs/${data.owner}/${name}";
providerSourceAddress = data.provider-source-address or fallbackProviderSourceAddress;
in
buildGoPackage rec {
inherit (data) owner repo rev version sha256;
name = "${repo}-${version}";
@ -18,6 +23,9 @@ let
# Terraform allow checking the provider versions, but this breaks
# if the versions are not provided via file paths.
postBuild = "mv $NIX_BUILD_TOP/go/bin/${repo}{,_v${version}}";
passthru = {
inherit providerSourceAddress;
};
};
# Google is now using the vendored go modules, which works a bit differently
@ -48,7 +56,7 @@ let
});
# These providers are managed with the ./update-all script
automated-providers = lib.mapAttrs (_: toDrv) list;
automated-providers = lib.mapAttrs (toDrv) list;
# These are the providers that don't fall in line with the default model
special-providers = {

View File

@ -1,5 +1,5 @@
{ stdenv, lib, buildEnv, buildGoPackage, fetchFromGitHub, makeWrapper, coreutils
, runCommand, writeText, terraform-providers, fetchpatch }:
, runCommand, runtimeShell, writeText, terraform-providers, fetchpatch }:
let
goPackagePath = "github.com/hashicorp/terraform";
@ -59,6 +59,29 @@ let
let
actualPlugins = plugins terraform.plugins;
# Make providers available in Terraform 0.13 and 0.12 search paths.
pluginDir = lib.concatMapStrings (pl: let
inherit (pl) repo version GOOS GOARCH;
inherit (pl.passthru) providerSourceAddress;
shim = writeText "shim" ''
#!${runtimeShell}
exec ${pl}/bin/${repo}_v${version} \$@
'';
in ''
TF_0_13_PROVIDER_PATH=$out/plugins/${providerSourceAddress}/${version}/${GOOS}_${GOARCH}/${repo}_v${version}
mkdir -p "$(dirname $TF_0_13_PROVIDER_PATH)"
cp ${shim} "$TF_0_13_PROVIDER_PATH"
chmod +x "$TF_0_13_PROVIDER_PATH"
TF_0_12_PROVIDER_PATH=$out/plugins/${repo}_v${version}
cp ${shim} "$TF_0_12_PROVIDER_PATH"
chmod +x "$TF_0_12_PROVIDER_PATH"
''
) actualPlugins;
# Wrap PATH of plugins propagatedBuildInputs, plugins may have runtime dependencies on external binaries
wrapperInputs = lib.unique (lib.flatten
(lib.catAttrs "propagatedBuildInputs"
@ -87,15 +110,10 @@ let
inherit (terraform) name;
buildInputs = [ makeWrapper ];
buildCommand = ''
buildCommand = pluginDir + ''
mkdir -p $out/bin/
makeWrapper "${terraform}/bin/terraform" "$out/bin/terraform" \
--set NIX_TERRAFORM_PLUGIN_DIR "${
buildEnv {
name = "tf-plugin-env";
paths = actualPlugins;
}
}/bin" \
--set NIX_TERRAFORM_PLUGIN_DIR $out/plugins \
--prefix PATH : "${lib.makeBinPath wrapperInputs}"
'';