From f9e317567234a4fb87bb648d992ef1abc78bc918 Mon Sep 17 00:00:00 2001 From: Tom Elliott Date: Thu, 13 Jun 2024 22:36:13 +0000 Subject: [PATCH] Add module path to working dir provider Allows modification of a module prior to apply. Added test to verify capability. --- rules/terraform.bzl | 18 +++++----- tests/modify_module_dir/BUILD | 20 ++++++++++++ tests/modify_module_dir/main.tf | 13 ++++++++ tests/modify_module_dir/test.bzl | 56 ++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 tests/modify_module_dir/BUILD create mode 100644 tests/modify_module_dir/main.tf create mode 100644 tests/modify_module_dir/test.bzl diff --git a/rules/terraform.bzl b/rules/terraform.bzl index e74b411..21d8bf2 100644 --- a/rules/terraform.bzl +++ b/rules/terraform.bzl @@ -5,7 +5,7 @@ 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"], + fields = ["module_path", "terraform_version", "terraform_binary_path"], ) def terraform_working_directory_impl(ctx): @@ -14,7 +14,7 @@ def terraform_working_directory_impl(ctx): module_default = ctx.attr.module[DefaultInfo] all_outputs = [] working_dir_prefix = ctx.label.name + "_working/" - working_dir = working_dir_prefix + module.working_directory + "/" + working_dir = working_dir_prefix + module.working_directory build_base_path = paths.dirname(ctx.build_file_path) for f in module_default.files.to_list(): @@ -50,7 +50,7 @@ cd {0} {4} $BASE_PATH/{1} $@ """.format( - build_base_path + "/" + working_dir, + build_base_path + "/" + working_dir + "/", ctx.executable.terraform.short_path, env_vars, prep_command, @@ -91,7 +91,7 @@ provider_installation { intermediates = [] # Create the terraformrc file - initrc = ctx.actions.declare_file(working_dir + "init.tfrc") + initrc = ctx.actions.declare_file(working_dir + "/init.tfrc") intermediates.append(initrc) ctx.actions.write( output = initrc, @@ -106,7 +106,7 @@ disable_checkpoint = true provider_info = provider[TerraformProviderInfo] for f in provider.files.to_list(): f_out = provider_info.file_to_subpath[f.path] - out = ctx.actions.declare_file(working_dir + "terraform.d/{0}".format(f_out)) + out = ctx.actions.declare_file(working_dir + "/terraform.d/{0}".format(f_out)) intermediates.append(out) ctx.actions.run_shell( @@ -116,9 +116,9 @@ disable_checkpoint = true command="cp $1 $2" ) - tf_lock = ctx.actions.declare_file(working_dir + ".terraform.lock.hcl") - dot_terraform = ctx.actions.declare_directory(working_dir + ".terraform") - dot_terraform_tar = ctx.actions.declare_file(working_dir + ".terraform.tar.gz") + tf_lock = ctx.actions.declare_file(working_dir + "/.terraform.lock.hcl") + dot_terraform = ctx.actions.declare_directory(working_dir + "/.terraform") + dot_terraform_tar = ctx.actions.declare_file(working_dir + "/.terraform.tar.gz") ctx.actions.run_shell( outputs=[tf_lock, dot_terraform], inputs=all_outputs + intermediates + [ctx.executable.terraform], @@ -177,7 +177,7 @@ disable_checkpoint = true runfiles = ctx.runfiles(all_outputs + [ctx.executable.terraform]) ), TerraformWorkingDirInfo( - module_working_directory = dot_terraform_tar.dirname, + module_path = working_dir, terraform_version = terraform_version, terraform_binary_path = ctx.executable.terraform.path, ) diff --git a/tests/modify_module_dir/BUILD b/tests/modify_module_dir/BUILD new file mode 100644 index 0000000..e746bfe --- /dev/null +++ b/tests/modify_module_dir/BUILD @@ -0,0 +1,20 @@ +load("@tf_modules//rules:module.bzl", "terraform_module") +load("@tf_modules//rules:terraform.bzl", "terraform_working_directory") +load(":test.bzl", "execute_test") + +terraform_module( + name = "provider", + srcs = ["main.tf"], + visibility = ["//visibility:public"], +) + +terraform_working_directory( + name = "terraform", + module = ":provider", + allow_provider_download = True, +) + +execute_test( + name = "terraform_test", + terraform_working_directory = ":terraform", +) diff --git a/tests/modify_module_dir/main.tf b/tests/modify_module_dir/main.tf new file mode 100644 index 0000000..fc1a3c0 --- /dev/null +++ b/tests/modify_module_dir/main.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + local = { + source = "hashicorp/local" + version = ">= 2.4.1" + } + } +} + +resource "local_file" "foo" { + source = "${path.module}/content.txt" + filename = "${path.module}/foo.bar" +} \ No newline at end of file diff --git a/tests/modify_module_dir/test.bzl b/tests/modify_module_dir/test.bzl new file mode 100644 index 0000000..c212ff3 --- /dev/null +++ b/tests/modify_module_dir/test.bzl @@ -0,0 +1,56 @@ +load("@tf_modules//rules:terraform.bzl", "TerraformWorkingDirInfo") + +def _execute_test_impl(ctx): + output = ctx.actions.declare_file(ctx.label.name + ".sh") + working_dir = ctx.attr.terraform_working_directory[DefaultInfo] + working_dir_info = ctx.attr.terraform_working_directory[TerraformWorkingDirInfo] + + ctx.actions.write( + output = output, + content = """ +#!/bin/bash + +MODULE_DIR="./$(dirname {terraform_binary})/{module_path}" + +echo "hello, world" > $MODULE_DIR/content.txt + +OUT=$(./{terraform_binary} apply -auto-approve -no-color) +if [ $? -ne 0 ]; +then + echo 'Plan failed'; + exit 1 +fi + +PASS=1 + +if [[ $(cat "$MODULE_DIR/foo.bar") != "hello, world" ]]; then + echo "FAIL: content of generated file was not as expected" + PASS=0 +fi + +if [[ $PASS == 0 ]]; then + echo "$OUT" + exit 1 +fi + """.format( + terraform_binary=working_dir.files_to_run.executable.short_path, + module_path=working_dir_info.module_path, + ), + is_executable = True, + ) + + return [ + DefaultInfo( + executable = output, + runfiles = working_dir.default_runfiles, + ), + ] + +execute_test = rule( + implementation = _execute_test_impl, + executable = True, + test = True, + attrs = { + "terraform_working_directory": attr.label(mandatory=True), + } +) \ No newline at end of file