Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions infrastructure/modules/lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@
| <a name="input_filter_pattern"></a> [filter\_pattern](#input\_filter\_pattern) | Filter pattern to use for the log subscription filter | `string` | `""` | no |
| <a name="input_force_lambda_code_deploy"></a> [force\_lambda\_code\_deploy](#input\_force\_lambda\_code\_deploy) | If the lambda package in s3 has the same commit id tag as the terraform build branch, the lambda will not update automatically. Set to True if making changes to Lambda code from on the same commit for example during development | `bool` | `false` | no |
| <a name="input_function_code_base_path"></a> [function\_code\_base\_path](#input\_function\_code\_base\_path) | The base path to the sourcecode directories needed for this lambda | `string` | `"./"` | no |
| <a name="input_function_code_dir"></a> [function\_code\_dir](#input\_function\_code\_dir) | The directory for this lambda | `string` | n/a | yes |
| <a name="input_function_code_dir"></a> [function\_code\_dir](#input\_function\_code\_dir) | The directory for this lambda | `string` | `null` | no |
| <a name="input_function_include_common"></a> [function\_include\_common](#input\_function\_include\_common) | Include the 'common' lambda module with this lambda | `bool` | `true` | no |
| <a name="input_function_module_name"></a> [function\_module\_name](#input\_function\_module\_name) | The name of the function module as used by the lambda handler, e.g. index or exports | `string` | `"index"` | no |
| <a name="input_function_name"></a> [function\_name](#input\_function\_name) | Base name of this lambda | `string` | n/a | yes |
| <a name="input_function_s3_bucket"></a> [function\_s3\_bucket](#input\_function\_s3\_bucket) | The bucket to upload Lambda packages to | `string` | n/a | yes |
| <a name="input_function_s3_bucket"></a> [function\_s3\_bucket](#input\_function\_s3\_bucket) | The bucket to upload Lambda packages to | `string` | `null` | no |
| <a name="input_group"></a> [group](#input\_group) | The name of the tfscaffold group | `string` | `null` | no |
| <a name="input_handler_function_name"></a> [handler\_function\_name](#input\_handler\_function\_name) | The name of the lambda handler function (passed directly to the Lambda's handler option) | `string` | `"handler"` | no |
| <a name="input_iam_policy_document"></a> [iam\_policy\_document](#input\_iam\_policy\_document) | n/a | <pre>object({<br/> body = string<br/> })</pre> | `null` | no |
| <a name="input_image_config"></a> [image\_config](#input\_image\_config) | Optional image configuration for Image-based Lambda | <pre>object({<br/> entry_point = optional(list(string))<br/> command = optional(list(string))<br/> working_directory = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_image_repository_names"></a> [image\_repository\_names](#input\_image\_repository\_names) | ECR repository names allowed for Image-based Lambda | `list(string)` | `[]` | no |
| <a name="input_image_uri"></a> [image\_uri](#input\_image\_uri) | ECR image URI for Image-based Lambda | `string` | `null` | no |
| <a name="input_kms_key_arn"></a> [kms\_key\_arn](#input\_kms\_key\_arn) | KMS key arn to use for this function | `string` | n/a | yes |
| <a name="input_lambda_at_edge"></a> [lambda\_at\_edge](#input\_lambda\_at\_edge) | Whether this Lambda is a Lambda@Edge function | `bool` | `false` | no |
| <a name="input_lambda_dlq_message_retention_seconds"></a> [lambda\_dlq\_message\_retention\_seconds](#input\_lambda\_dlq\_message\_retention\_seconds) | The number of seconds to retain messages in the Lambda DLQ SQS queue | `number` | `1209600` | no |
Expand All @@ -41,10 +44,11 @@
| <a name="input_log_subscription_lambda_create_permission"></a> [log\_subscription\_lambda\_create\_permission](#input\_log\_subscription\_lambda\_create\_permission) | Whether to create a permission for the log forwarder. Set to false if using a generic one. | `bool` | `true` | no |
| <a name="input_log_subscription_role_arn"></a> [log\_subscription\_role\_arn](#input\_log\_subscription\_role\_arn) | The ARN of the IAM role to use for the log subscription filter | `string` | `""` | no |
| <a name="input_memory"></a> [memory](#input\_memory) | The amount of memory to apply to the created Lambda | `number` | n/a | yes |
| <a name="input_package_type"></a> [package\_type](#input\_package\_type) | Lambda package type: Zip or Image | `string` | `"Zip"` | no |
| <a name="input_permission_statements"></a> [permission\_statements](#input\_permission\_statements) | Statements giving an external source permission to invoke the Lambda function | <pre>list(object({<br/> action = optional(string)<br/> principal = string<br/> source_arn = optional(string)<br/> source_account = optional(string)<br/> statement_id = string<br/> }))</pre> | `[]` | no |
| <a name="input_project"></a> [project](#input\_project) | The name of the tfscaffold project | `string` | n/a | yes |
| <a name="input_region"></a> [region](#input\_region) | The AWS Region | `string` | n/a | yes |
| <a name="input_runtime"></a> [runtime](#input\_runtime) | The runtime to use for the lambda function | `string` | n/a | yes |
| <a name="input_runtime"></a> [runtime](#input\_runtime) | The runtime to use for the lambda function | `string` | `null` | no |
| <a name="input_schedule"></a> [schedule](#input\_schedule) | The fully qualified Cloudwatch Events schedule for when to run the lambda function, e.g. rate(1 day) or a cron() expression. Default disables all events resources | `string` | `""` | no |
| <a name="input_send_to_firehose"></a> [send\_to\_firehose](#input\_send\_to\_firehose) | Enable sending logs to firehose | `bool` | `true` | no |
| <a name="input_sns_destination"></a> [sns\_destination](#input\_sns\_destination) | SNS Topic ARN to be used for on-failure Lambda invocation records | `string` | `null` | no |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
data "archive_file" "lambda" {
count = local.package_type == "zip" ? 1 : 0
type = "zip"
source_dir = "${path.root}/${var.function_code_base_path}/${var.function_code_dir}"

Expand Down
26 changes: 26 additions & 0 deletions infrastructure/modules/lambda/data_iam_policy_document_ecr.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
data "aws_iam_policy_document" "ecr" {
statement {
effect = "Allow"

actions = [
"ecr:GetAuthorizationToken",
]

resources = ["*"]
}

statement {
effect = "Allow"

actions = [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchCheckLayerAvailability",
]

resources = [
for repo_name in var.image_repository_names :
"arn:aws:ecr:${var.region}:${var.aws_account_id}:repository/${repo_name}"
]
}
}
6 changes: 6 additions & 0 deletions infrastructure/modules/lambda/iam_role_policy_ecr.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "aws_iam_role_policy" "ecr" {
count = local.package_type == "image" ? 1 : 0
name = "${local.csi}-ecr"
role = aws_iam_role.main.id
policy = data.aws_iam_policy_document.ecr.json
}
26 changes: 19 additions & 7 deletions infrastructure/modules/lambda/lambda_function.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,27 @@ resource "aws_lambda_function" "main" {
description = var.description
function_name = local.csi
role = aws_iam_role.main.arn
handler = "${var.function_module_name}.${var.handler_function_name}"
runtime = var.runtime
handler = local.package_type == "zip" ? "${var.function_module_name}.${var.handler_function_name}" : null
runtime = local.package_type == "zip" ? var.runtime : null
package_type = title(local.package_type)
publish = true
memory_size = var.memory
timeout = var.timeout

s3_bucket = aws_s3_object.lambda.bucket
s3_key = aws_s3_object.lambda.key
s3_object_version = aws_s3_object.lambda.version_id
s3_bucket = local.package_type == "zip" ? aws_s3_object.lambda[0].bucket : null
s3_key = local.package_type == "zip" ? aws_s3_object.lambda[0].key : null
s3_object_version = local.package_type == "zip" ? aws_s3_object.lambda[0].version_id : null

image_uri = local.package_type == "image" ? var.image_uri : null

dynamic "image_config" {
for_each = local.package_type == "image" && var.image_config != null ? [1] : []
content {
entry_point = try(var.image_config.entry_point, null)
command = try(var.image_config.command, null)
working_directory = try(var.image_config.working_directory, null)
}
}

logging_config {
application_log_level = var.application_log_level
Expand All @@ -19,12 +31,12 @@ resource "aws_lambda_function" "main" {
system_log_level = var.system_log_level
}

layers = compact(concat(
layers = local.package_type == "zip" ? compact(concat(
var.layers,
[
var.enable_lambda_insights && var.lambda_at_edge == false ? "arn:aws:lambda:${var.region}:580247275435:layer:LambdaInsightsExtension:53" : null
]
))
)) : []

environment {
variables = var.lambda_env_vars
Expand Down
2 changes: 2 additions & 0 deletions infrastructure/modules/lambda/locals.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
locals {
module = "lambda"

package_type = lower(var.package_type)

# Compound Scope Identifier
csi = replace(
format(
Expand Down
7 changes: 4 additions & 3 deletions infrastructure/modules/lambda/s3_object_lambda.tf
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
resource "aws_s3_object" "lambda" {
count = local.package_type == "zip" ? 1 : 0
bucket = var.function_s3_bucket
key = "${local.csi}.zip"
source = data.archive_file.lambda.output_path
source = data.archive_file.lambda[0].output_path

source_hash = var.force_lambda_code_deploy ? data.archive_file.lambda.output_base64sha256 : null
source_hash = var.force_lambda_code_deploy ? data.archive_file.lambda[0].output_base64sha256 : null

metadata = {
hash = data.archive_file.lambda.output_base64sha256
hash = data.archive_file.lambda[0].output_base64sha256
function = local.csi
commit = try(data.external.git_commit.result["sha"], "null")
}
Expand Down
61 changes: 61 additions & 0 deletions infrastructure/modules/lambda/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,55 @@ variable "log_retention_in_days" {
variable "runtime" {
type = string
description = "The runtime to use for the lambda function"
default = null

validation {
condition = lower(var.package_type) != "zip" || (var.runtime != null && var.runtime != "")
error_message = "runtime must be set when package_type is Zip."
}
}

variable "package_type" {
type = string
description = "Lambda package type: Zip or Image"
default = "Zip"

validation {
condition = contains(["zip", "image"], lower(var.package_type))
error_message = "package_type must be either Zip or Image."
}
}

variable "image_uri" {
type = string
description = "ECR image URI for Image-based Lambda"
default = null

validation {
condition = lower(var.package_type) != "image" || (var.image_uri != null && var.image_uri != "")
error_message = "image_uri must be set when package_type is Image."
}
}

variable "image_config" {
type = object({
entry_point = optional(list(string))
command = optional(list(string))
working_directory = optional(string)
})
description = "Optional image configuration for Image-based Lambda"
default = null
}

variable "image_repository_names" {
type = list(string)
description = "ECR repository names allowed for Image-based Lambda"
default = []

validation {
condition = lower(var.package_type) != "image" || length(var.image_repository_names) > 0
error_message = "image_repository_names must include at least one repository name when package_type is Image."
}
}

variable "schedule" {
Expand Down Expand Up @@ -122,11 +171,23 @@ variable "function_code_base_path" {
variable "function_code_dir" {
type = string
description = "The directory for this lambda"
default = null

validation {
condition = lower(var.package_type) != "zip" || (var.function_code_dir != null && var.function_code_dir != "")
error_message = "function_code_dir must be set when package_type is Zip."
}
}

variable "function_s3_bucket" {
type = string
description = "The bucket to upload Lambda packages to"
default = null

validation {
condition = lower(var.package_type) != "zip" || (var.function_s3_bucket != null && var.function_s3_bucket != "")
error_message = "function_s3_bucket must be set when package_type is Zip."
}
}

variable "function_include_common" {
Expand Down
Loading