Skip to content

Commit

Permalink
Add support for creating backend files at runtime
Browse files Browse the repository at this point in the history
Add a "reconfigure" param for working directories that force an init for each command.

Add a provider for working directories to provide paths to the actual module.
  • Loading branch information
theothertomelliott committed May 10, 2024
1 parent d18d29e commit 2a80a25
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 5 deletions.
29 changes: 24 additions & 5 deletions rules/terraform.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ load("@tf_modules//rules:module.bzl", "TerraformModuleInfo")
load("@tf_modules//rules:provider.bzl", "TerraformProviderInfo")
load("@tf_modules//toolchains/terraform:toolchain.bzl", "TerraformExecutableInfo")

TerraformWorkingDirInfo = provider(
doc = "Contains information about a Terraform working directory",
fields = ["module_working_directory", "terraform_version", "terraform_binary_path"],
)

def terraform_working_directory_impl(ctx):
module = ctx.attr.module[TerraformModuleInfo]
terraform_version = ctx.attr.terraform[TerraformExecutableInfo].version
Expand All @@ -29,6 +34,10 @@ def terraform_working_directory_impl(ctx):

prep_command = "tar -xvzf .terraform.tar.gz > /dev/null"

reconfigure_cmd = ""
if ctx.attr.reconfigure:
reconfigure_cmd = "$BASE_PATH/{} init -input=false -reconfigure".format(ctx.executable.terraform.short_path)

# Create the script that runs Terraform
ctx.actions.write(
output = ctx.outputs.executable,
Expand All @@ -38,12 +47,14 @@ BASE_PATH=$(pwd)
{2}
cd {0}
{3}
{4}
$BASE_PATH/{1} $@
""".format(
build_base_path + "/" + working_dir,
ctx.executable.terraform.short_path,
env_vars,
prep_command,
reconfigure_cmd,
),
)

Expand Down Expand Up @@ -159,11 +170,18 @@ disable_checkpoint = true
if terraform_version < "0.14":
all_outputs += intermediates

return DefaultInfo(
executable = ctx.outputs.executable,
files = depset(all_outputs),
runfiles = ctx.runfiles(all_outputs + [ctx.executable.terraform])
)
return [
DefaultInfo(
executable = ctx.outputs.executable,
files = depset(all_outputs),
runfiles = ctx.runfiles(all_outputs + [ctx.executable.terraform])
),
TerraformWorkingDirInfo(
module_working_directory = dot_terraform_tar.dirname,
terraform_version = terraform_version,
terraform_binary_path = ctx.executable.terraform.path,
)
]

terraform_working_directory = rule(
implementation = terraform_working_directory_impl,
Expand All @@ -180,5 +198,6 @@ terraform_working_directory = rule(
"tf_vars": attr.string_dict(),
"providers": attr.label_list(providers = [TerraformProviderInfo]),
"allow_provider_download": attr.bool(default=False),
"reconfigure": attr.bool(default=False, doc="Run `terraform init -reconfigure` before each operation to accept changes in backend configuration."),
},
)
23 changes: 23 additions & 0 deletions tests/backend_init/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
load("@tf_modules//rules:module.bzl", "terraform_module")
load("@tf_modules//rules:terraform.bzl", "terraform_working_directory")

terraform_module(
name = "provider",
srcs = ["main.tf"],
visibility = ["//visibility:public"],
)

terraform_working_directory(
name = "terraform",
module = ":provider",
allow_provider_download = True,
reconfigure = True,
)

sh_test(
name = "terraform_test",
size = "small",
srcs = ["test.sh"],
data = [":terraform"],
)

13 changes: 13 additions & 0 deletions tests/backend_init/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_providers {
local = {
source = "hashicorp/local"
version = ">= 2.4.1"
}
}
}

resource "local_file" "foo" {
content = "foo!"
filename = "${path.module}/foo.bar"
}
49 changes: 49 additions & 0 deletions tests/backend_init/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

STATE_DIR=$(mktemp -d)

MODULE_DIR=./tests/backend_init/terraform_working/tests/backend_init

BACKEND_FILE="$MODULE_DIR/local_backend.tf"
cat > "$BACKEND_FILE" <<-EOF
terraform {
backend "local" {
path = "$STATE_DIR/terraform.tfstate"
}
}
EOF

if [ -f $STATE_DIR/terraform.tfstate ]; then
echo "Temp tfstate file should not exist before apply"
exit 1
fi

OUT=$(./tests/backend_init/terraform apply -auto-approve -no-color)
if [ $? -ne 0 ];
then
echo 'Apply failed';
exit 1
fi

PASS=1

function expect_output() {
if [[ "$OUT" != *"$1"* ]]; then
echo "FAIL: Expected text '$1'"
PASS=0
fi
}

expect_output "+ resource \"local_file\" \"foo\" {"
expect_output "1 to add"

if [[ $PASS == 0 ]]; then
echo "$OUT"
exit 1
fi

if [ ! -f $STATE_DIR/terraform.tfstate ]; then
echo "Temp tfstate file should exist after apply"
exit 1
fi

0 comments on commit 2a80a25

Please sign in to comment.