Skip to content

Commit

Permalink
test: adding integration testing to test supporting terraform nested …
Browse files Browse the repository at this point in the history
…directories project structure (#5748)

* feat: support terraform project structure that does not have everything in root module directory

* test: adding integration testing to test supporting terraform nested directories project structure

* fix the terraform config, remove the aws provider configuration.
  • Loading branch information
moelasmar authored Aug 10, 2023
1 parent 5bf62cd commit 6fd3389
Show file tree
Hide file tree
Showing 10 changed files with 383 additions and 0 deletions.
4 changes: 4 additions & 0 deletions tests/integration/buildcmd/build_integ_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def get_command_list(
build_in_source=None,
mount_with=None,
config_file=None,
project_root_dir=None,
):
command_list = [self.cmd, "build"]

Expand Down Expand Up @@ -150,6 +151,9 @@ def get_command_list(
if config_file is not None:
command_list += ["--config-file", config_file]

if project_root_dir is not None:
command_list += ["--terraform-project-root-path", project_root_dir]

return command_list

def verify_docker_container_cleanedup(self, runtime):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from parameterized import parameterized, parameterized_class

from samcli.lib.utils.colors import Colored
from tests.integration.buildcmd.test_build_terraform_applications import (
BuildTerraformApplicationIntegBase,
BuildTerraformApplicationS3BackendIntegBase,
Expand Down Expand Up @@ -52,6 +53,27 @@ def test_exit_failed_use_container_no_build_image_hooks(self):
)
self.assertNotEqual(return_code, 0)

def test_exit_failed_project_root_dir_no_hooks(self):
cmdlist = self.get_command_list(beta_features=True, project_root_dir="/path")
_, stderr, return_code = self.run_command(cmdlist)
process_stderr = stderr.strip()
self.assertRegex(
process_stderr.decode("utf-8"),
"Error: Missing option --hook-name",
)
self.assertNotEqual(return_code, 0)

def test_exit_failed_project_root_dir_not_parent_of_current_directory(self):
cmdlist = self.get_command_list(beta_features=True, hook_name="terraform", project_root_dir="/path")
_, stderr, return_code = self.run_command(cmdlist)
process_stderr = stderr.strip()
self.assertRegex(
process_stderr.decode("utf-8"),
"Error: /path is not a valid value for Terraform Project Root Path. It should "
"be a parent of the current directory that contains the root module of the terraform project.",
)
self.assertNotEqual(return_code, 0)

def test_exit_failed_use_container_short_format_no_build_image_hooks(self):
cmdlist = self.get_command_list(beta_features=True, hook_name="terraform")
cmdlist += ["-u"]
Expand Down Expand Up @@ -384,3 +406,60 @@ def test_invoke_function(self):
overrides=None,
expected_result="{'message': 'Hello World'}",
)


@skipIf(
(not RUN_BY_CANARY and not CI_OVERRIDE),
"Skip Terraform test cases unless running in CI",
)
class TestBuildTerraformApplicationsSourceCodeAndModulesAreNotInRootModuleDirectory(BuildTerraformApplicationIntegBase):
terraform_application = Path("terraform/application_outside_root_directory")

functions = [
("aws_lambda_function.function1", "hello world 1"),
("module.function2.aws_lambda_function.this", "hello world 1"),
("module.function7.aws_lambda_function.this[0]", "hello world 1"),
]

def setUp(self):
super().setUp()
self.project_dir = self.working_dir
self.working_dir = f"{self.working_dir}/root_module"

def tearDown(self):
if self.project_dir:
self.working_dir = self.project_dir
super().tearDown()

@parameterized.expand(functions)
def test_build_and_invoke_lambda_functions(self, function_identifier, expected_output):
command_list_parameters = {
"beta_features": True,
"hook_name": "terraform",
"function_identifier": function_identifier,
"project_root_dir": "./..",
}
build_cmd_list = self.get_command_list(**command_list_parameters)
LOG.info("command list: %s", build_cmd_list)
stdout, stderr, return_code = self.run_command(build_cmd_list)
terraform_beta_feature_prompted_text = (
f"Supporting Terraform applications is a beta feature.{os.linesep}"
f"Please confirm if you would like to proceed using AWS SAM CLI with terraform application.{os.linesep}"
"You can also enable this beta feature with 'sam build --beta-features'."
)
experimental_warning = (
f"{os.linesep}Experimental features are enabled for this session.{os.linesep}"
f"Visit the docs page to learn more about the AWS Beta terms "
f"https://aws.amazon.com/service-terms/.{os.linesep}"
)
self.assertNotRegex(stdout.decode("utf-8"), terraform_beta_feature_prompted_text)
self.assertIn(Colored().yellow(experimental_warning), stderr.decode("utf-8"))
LOG.info("sam build stdout: %s", stdout.decode("utf-8"))
LOG.info("sam build stderr: %s", stderr.decode("utf-8"))
self.assertEqual(return_code, 0)

self._verify_invoke_built_function(
function_logical_id=function_identifier,
overrides=None,
expected_result={"statusCode": 200, "body": expected_output},
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
variable "source_code" {
type = string
}

variable "function_name" {
type = string
}

variable "layers" {
type = list
default = []
}

resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda2"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_lambda_function" "this" {
filename = var.source_code
handler = "app.lambda_handler"
runtime = "python3.8"
function_name = var.function_name
role = aws_iam_role.iam_for_lambda.arn
layers = var.layers
timeout = 300
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
variable "source_code" {
type = string
}

variable "name" {
type = string
}

resource "aws_lambda_layer_version" "layer" {
filename = var.source_code
layer_name = var.name

compatible_runtimes = ["python3.8"]
}

output "arn" {
value = aws_lambda_layer_version.layer.arn
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash
src_code=$1
build_path=$2
output_name=$3
resource_type=$4
echo "building ${resource_type} ${src_code} into ${build_path}"

temp_path=${build_path}/tmp_building/${output_name}
if [[ "${resource_type}" == "Layer" ]]; then
temp_path=${build_path}/tmp_building/${output_name}/python
echo "new path ${temp_path}"
fi

mkdir -p ${build_path}
mkdir -p ${build_path}/tmp_building
mkdir -p ${build_path}/tmp_building/${output_name}
mkdir -p ${temp_path}
rm -rf ${temp_path}/*

cp -r $src_code/* ${temp_path}
pip install -r ${temp_path}/requirements.txt -t ${temp_path}/.
current=$(pwd)
cd ${build_path}/tmp_building/${output_name}
zip -r ${output_name} .
cd ${current}
mv "${build_path}/tmp_building/${output_name}/${output_name}" "${build_path}/$output_name"
rm -rf ${build_path}/tmp_building/${output_name}
rm -rf ${build_path}/tmp_building
Loading

0 comments on commit 6fd3389

Please sign in to comment.