Skip to content

Commit

Permalink
Update makefile rule generate to create temp backend override (#4265)
Browse files Browse the repository at this point in the history
* Update makefile rule generate to create temp backend override

* Revert "Update makefile rule generate to create temp backend override"

This reverts commit d50cc31.

* Add generate backend override file and update make rule

* Update unit test

* Not make it a tf file when creating the override file
  • Loading branch information
hawflau authored Sep 30, 2022
1 parent ce97c4a commit 0ec02dc
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
35 changes: 34 additions & 1 deletion samcli/hook_packages/terraform/hooks/prepare/hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import hashlib
import logging
import shutil
import uuid

from samcli.lib.hook.exceptions import PrepareHookException, InvalidSamMetadataPropertiesException
from samcli.lib.utils import osutils
Expand Down Expand Up @@ -46,6 +47,7 @@
PropertyBuilderMapping = Dict[str, PropertyBuilder]

TERRAFORM_BUILD_SCRIPT = "copy_terraform_built_artifacts.py"
TF_BACKEND_OVERRIDE_FILENAME = "z_samcli_backend_override"

CFN_CODE_PROPERTIES = {
CFN_AWS_LAMBDA_FUNCTION: "Code",
Expand Down Expand Up @@ -802,6 +804,9 @@ def _generate_makefile(
if not os.path.exists(output_directory_path):
os.makedirs(output_directory_path, exist_ok=True)

# create z_samcli_backend_override.tf in output directory
_generate_backend_override_file(output_directory_path)

# copy copy_terraform_built_artifacts.py script into output directory
copy_terraform_built_artifacts_script_path = os.path.join(
Path(os.path.dirname(__file__)).parent.parent, TERRAFORM_BUILD_SCRIPT
Expand All @@ -814,6 +819,22 @@ def _generate_makefile(
makefile.writelines(makefile_rules)


def _generate_backend_override_file(output_directory_path: str):
"""
Generates an override tf file to use a temporary backend
Parameters
----------
output_directory_path: str
the output directory path to write the generated makefile
"""
statefile_filename = f"{uuid.uuid4()}.tfstate"
override_content = "terraform {\n" ' backend "local" {\n' f' path = "./{statefile_filename}"\n' " }\n" "}\n"
override_file_path = os.path.join(output_directory_path, TF_BACKEND_OVERRIDE_FILENAME)
with open(override_file_path, "w+") as f:
f.write(override_content)


def _get_relevant_cfn_resource(
sam_metadata_resource: SamMetadataResource, cfn_resources: Dict[str, Dict]
) -> Tuple[Dict, str]:
Expand Down Expand Up @@ -919,14 +940,26 @@ def _generate_makefile_rule_for_lambda_resource(
"""
target = _get_makefile_build_target(logical_id)
resource_address = sam_metadata_resource.resource.get("address", "")
move_override_recipe = _format_makefile_recipe(
"cp "
f"{Path(output_dir, TF_BACKEND_OVERRIDE_FILENAME).relative_to(terraform_application_dir)} "
f"./{TF_BACKEND_OVERRIDE_FILENAME}.tf"
)
init_command_recipe = _format_makefile_recipe("terraform init -reconfigure")
apply_command_template = "terraform apply -target {resource_address} -replace {resource_address} -auto-approve"
apply_command_recipe = _format_makefile_recipe(apply_command_template.format(resource_address=resource_address))
show_command_recipe = _format_makefile_recipe(
_build_show_command(
python_command_name, output_dir, resource_address, sam_metadata_resource, terraform_application_dir
)
)
return f"{target}{apply_command_recipe}{show_command_recipe}"
return (
f"{target}"
f"{move_override_recipe}"
f"{init_command_recipe}"
f"{apply_command_recipe}"
f"{show_command_recipe}"
)


def _build_show_command(
Expand Down
11 changes: 10 additions & 1 deletion tests/unit/hook_packages/terraform/hooks/prepare/test_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -2499,10 +2499,15 @@ def test_generate_makefile(
):
mock_os.path.exists.return_value = output_dir_exists

mock_copy_tf_backend_override_file_path = Mock()
mock_copy_terraform_built_artifacts_script_path = Mock()
mock_makefile_path = Mock()
mock_os.path.dirname.return_value = ""
mock_os.path.join.side_effect = [mock_copy_terraform_built_artifacts_script_path, mock_makefile_path]
mock_os.path.join.side_effect = [
mock_copy_tf_backend_override_file_path,
mock_copy_terraform_built_artifacts_script_path,
mock_makefile_path,
]

mock_makefile = Mock()
mock_open.return_value.__enter__.return_value = mock_makefile
Expand Down Expand Up @@ -2605,6 +2610,8 @@ def test_get_python_command_name_python_not_found(self, mock_run_side_effect, mo
@patch("samcli.hook_packages.terraform.hooks.prepare.hook._format_makefile_recipe")
def test_generate_makefile_rule_for_lambda_resource(self, format_recipe_mock, get_build_target_mock):
format_recipe_mock.side_effect = [
"\tcp .aws-sam-iacs/iacs_metadata/z_samcli_backend_override.tf ./z_samcli_backend_override.tf\n",
"\tterraform init -reconfigure\n",
"\tterraform apply -target null_resource.sam_metadata_aws_lambda_function -auto-approve\n",
"\tterraform show -json | python3 .aws-sam/iacs_metadata/copy_terraform_built_artifacts.py --expression "
'"|values|root_module|resources|[?address=="null_resource.sam_metadata_aws_lambda_function"]'
Expand All @@ -2624,6 +2631,8 @@ def test_generate_makefile_rule_for_lambda_resource(self, format_recipe_mock, ge
)
expected_makefile_rule = (
"build-function_logical_id:\n"
"\tcp .aws-sam-iacs/iacs_metadata/z_samcli_backend_override.tf ./z_samcli_backend_override.tf\n"
"\tterraform init -reconfigure\n"
"\tterraform apply -target null_resource.sam_metadata_aws_lambda_function -auto-approve\n"
"\tterraform show -json | python3 .aws-sam/iacs_metadata/copy_terraform_built_artifacts.py "
'--expression "|values|root_module|resources|[?address=="null_resource.sam_metadata_aws_lambda_function"]'
Expand Down

0 comments on commit 0ec02dc

Please sign in to comment.