diff --git a/archive.tf b/archive.tf index e374bff..d3e14be 100644 --- a/archive.tf +++ b/archive.tf @@ -1,6 +1,8 @@ # Generates a filename for the zip archive based on the contents of the files # in source_path. The filename will change when the source code changes. data "external" "archive" { + count = var.create_resources ? 1 : 0 + program = ["python", "${path.module}/hash.py"] query = { @@ -14,12 +16,14 @@ data "external" "archive" { # Build the zip archive whenever the filename changes. resource "null_resource" "archive" { + count = var.create_resources ? 1 : 0 + triggers = { - filename = lookup(data.external.archive.result, "filename") + filename = lookup(data.external.archive[count.index].result, "filename") } provisioner "local-exec" { - command = lookup(data.external.archive.result, "build_command") + command = lookup(data.external.archive[count.index].result, "build_command") working_dir = path.module } } @@ -30,12 +34,14 @@ resource "null_resource" "archive" { # deletes the Lambda function. If the file is rebuilt here, the build # output is unfortunately invisible. data "external" "built" { + count = var.create_resources ? 1 : 0 + program = ["python", "${path.module}/built.py"] query = { - build_command = lookup(data.external.archive.result, "build_command") - filename_old = lookup(null_resource.archive.triggers, "filename") - filename_new = lookup(data.external.archive.result, "filename") + build_command = lookup(data.external.archive[count.index].result, "build_command") + filename_old = lookup(null_resource.archive[count.index].triggers, "filename") + filename_new = lookup(data.external.archive[count.index].result, "filename") module_relpath = path.module } } diff --git a/iam.tf b/iam.tf index 51f5b83..8847ed5 100644 --- a/iam.tf +++ b/iam.tf @@ -13,6 +13,8 @@ data "aws_iam_policy_document" "assume_role" { } resource "aws_iam_role" "lambda" { + count = var.create_resources ? 1 : 0 + name = var.function_name assume_role_policy = data.aws_iam_policy_document.assume_role.json tags = var.tags @@ -54,24 +56,28 @@ data "aws_iam_policy_document" "logs" { } resource "aws_iam_policy" "logs" { - count = var.cloudwatch_logs ? 1 : 0 + count = var.cloudwatch_logs && var.create_resources ? 1 : 0 name = "${var.function_name}-logs" policy = data.aws_iam_policy_document.logs[0].json } resource "aws_iam_policy_attachment" "logs" { - count = var.cloudwatch_logs ? 1 : 0 + count = var.cloudwatch_logs && var.create_resources ? 1 : 0 name = "${var.function_name}-logs" - roles = [aws_iam_role.lambda.name] + roles = [aws_iam_role.lambda[count.index].name] policy_arn = aws_iam_policy.logs[0].arn } # Attach an additional policy required for the dead letter config. +locals { + create_dead_letter = var.dead_letter_config != null +} + data "aws_iam_policy_document" "dead_letter" { - count = var.dead_letter_config == null ? 0 : 1 + count = local.create_dead_letter && var.create_resources ? 1 : 0 statement { effect = "Allow" @@ -88,24 +94,27 @@ data "aws_iam_policy_document" "dead_letter" { } resource "aws_iam_policy" "dead_letter" { - count = var.dead_letter_config == null ? 0 : 1 + count = local.create_dead_letter && var.create_resources ? 1 : 0 name = "${var.function_name}-dl" policy = data.aws_iam_policy_document.dead_letter[0].json } resource "aws_iam_policy_attachment" "dead_letter" { - count = var.dead_letter_config == null ? 0 : 1 + count = local.create_dead_letter && var.create_resources ? 1 : 0 name = "${var.function_name}-dl" - roles = [aws_iam_role.lambda.name] + roles = [aws_iam_role.lambda[count.index].name] policy_arn = aws_iam_policy.dead_letter[0].arn } # Attach an additional policy required for the VPC config +locals { + create_vpc_config = var.vpc_config != null +} data "aws_iam_policy_document" "network" { - count = var.vpc_config == null ? 0 : 1 + count = local.create_vpc_config && var.create_resources ? 1 : 0 statement { effect = "Allow" @@ -123,33 +132,36 @@ data "aws_iam_policy_document" "network" { } resource "aws_iam_policy" "network" { - count = var.vpc_config == null ? 0 : 1 + count = local.create_vpc_config && var.create_resources ? 1 : 0 name = "${var.function_name}-network" policy = data.aws_iam_policy_document.network[0].json } resource "aws_iam_policy_attachment" "network" { - count = var.vpc_config == null ? 0 : 1 + count = local.create_vpc_config && var.create_resources ? 1 : 0 name = "${var.function_name}-network" - roles = [aws_iam_role.lambda.name] + roles = [aws_iam_role.lambda[count.index].name] policy_arn = aws_iam_policy.network[0].arn } # Attach an additional policy if provided. +locals { + attach_policy = var.policy != null +} resource "aws_iam_policy" "additional" { - count = var.policy == null ? 0 : 1 + count = local.attach_policy && var.create_resources ? 1 : 0 name = var.function_name policy = var.policy.json } resource "aws_iam_policy_attachment" "additional" { - count = var.policy == null ? 0 : 1 + count = local.attach_policy && var.create_resources ? 1 : 0 name = var.function_name - roles = [aws_iam_role.lambda.name] + roles = [aws_iam_role.lambda[count.index].name] policy_arn = aws_iam_policy.additional[0].arn } diff --git a/lambda.tf b/lambda.tf index 2fdd510..c3f726f 100644 --- a/lambda.tf +++ b/lambda.tf @@ -1,8 +1,9 @@ resource "aws_lambda_function" "lambda" { + count = var.create_resources ? 1 : 0 function_name = var.function_name description = var.description - role = aws_iam_role.lambda.arn + role = aws_iam_role.lambda[count.index].arn handler = var.handler memory_size = var.memory_size reserved_concurrent_executions = var.reserved_concurrent_executions @@ -14,7 +15,7 @@ resource "aws_lambda_function" "lambda" { # Use a generated filename to determine when the source code has changed. - filename = data.external.built.result.filename + filename = data.external.built[count.index].result.filename depends_on = [null_resource.archive] # Add dynamic blocks based on variables. diff --git a/outputs.tf b/outputs.tf index 8e9e4e6..b3d9c92 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,29 +1,29 @@ output "function_arn" { description = "The ARN of the Lambda function" - value = aws_lambda_function.lambda.arn + value = join("", aws_lambda_function.lambda.*.arn) } output "function_invoke_arn" { description = "The Invoke ARN of the Lambda function" - value = aws_lambda_function.lambda.invoke_arn + value = join("", aws_lambda_function.lambda.*.invoke_arn) } output "function_name" { description = "The name of the Lambda function" - value = aws_lambda_function.lambda.function_name + value = join("", aws_lambda_function.lambda.*.function_name) } output "function_qualified_arn" { description = "The qualified ARN of the Lambda function" - value = aws_lambda_function.lambda.qualified_arn + value = join("", aws_lambda_function.lambda.*.qualified_arn) } output "role_arn" { description = "The ARN of the IAM role created for the Lambda function" - value = aws_iam_role.lambda.arn + value = join("", aws_iam_role.lambda.*.arn) } output "role_name" { description = "The name of the IAM role created for the Lambda function" - value = aws_iam_role.lambda.name + value = join("", aws_iam_role.lambda.*.name) } diff --git a/tests/conditional-creation/lambda.py b/tests/conditional-creation/lambda.py new file mode 100644 index 0000000..7a16f44 --- /dev/null +++ b/tests/conditional-creation/lambda.py @@ -0,0 +1,2 @@ +def lambda_handler(event, context): + return 'test passed' diff --git a/tests/conditional-creation/main.tf b/tests/conditional-creation/main.tf new file mode 100644 index 0000000..4ea1bcc --- /dev/null +++ b/tests/conditional-creation/main.tf @@ -0,0 +1,20 @@ +terraform { + backend "local" { + path = "terraform.tfstate" + } +} + +module "lambda" { + source = "../../" + + create_resources = false + + function_name = "terraform-aws-lambda-test-cond-create" + description = "Test conditional creation of terraform-aws-lambda" + handler = "lambda.lambda_handler" + runtime = "python3.6" + timeout = 30 + + source_path = "${path.module}/lambda.py" + +} diff --git a/variables.tf b/variables.tf index 1b17bd5..37aa447 100644 --- a/variables.tf +++ b/variables.tf @@ -51,6 +51,12 @@ variable "policy" { default = null } +variable "create_resources" { + description = "Controls whether to create the resources in this module" + type = bool + default = true +} + variable "trusted_entities" { description = "Lambda function additional trusted entities for assuming roles (trust relationship)" type = list(string)