Skip to content

Commit 05bbc4d

Browse files
CCM-14149: Support Container Based Lambdas
1 parent f89fb8b commit 05bbc4d

7 files changed

Lines changed: 100 additions & 13 deletions

File tree

infrastructure/modules/lambda/README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
| <a name="input_filter_pattern"></a> [filter\_pattern](#input\_filter\_pattern) | Filter pattern to use for the log subscription filter | `string` | `""` | no |
2323
| <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 |
2424
| <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 |
25-
| <a name="input_function_code_dir"></a> [function\_code\_dir](#input\_function\_code\_dir) | The directory for this lambda | `string` | n/a | yes |
25+
| <a name="input_function_code_dir"></a> [function\_code\_dir](#input\_function\_code\_dir) | The directory for this lambda (required for Zip) | `string` | `null` | no |
2626
| <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 |
2727
| <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 |
2828
| <a name="input_function_name"></a> [function\_name](#input\_function\_name) | Base name of this lambda | `string` | n/a | yes |
29-
| <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 |
29+
| <a name="input_function_s3_bucket"></a> [function\_s3\_bucket](#input\_function\_s3\_bucket) | The bucket to upload Lambda packages to (required for Zip) | `string` | `null` | no |
3030
| <a name="input_group"></a> [group](#input\_group) | The name of the tfscaffold group | `string` | `null` | no |
3131
| <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 |
3232
| <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 |
@@ -44,7 +44,10 @@
4444
| <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 |
4545
| <a name="input_project"></a> [project](#input\_project) | The name of the tfscaffold project | `string` | n/a | yes |
4646
| <a name="input_region"></a> [region](#input\_region) | The AWS Region | `string` | n/a | yes |
47-
| <a name="input_runtime"></a> [runtime](#input\_runtime) | The runtime to use for the lambda function | `string` | n/a | yes |
47+
| <a name="input_runtime"></a> [runtime](#input\_runtime) | The runtime to use for the lambda function (required for Zip) | `string` | `null` | no |
48+
| <a name="input_package_type"></a> [package\_type](#input\_package\_type) | Lambda package type: Zip or Image | `string` | `"Zip"` | no |
49+
| <a name="input_image_uri"></a> [image\_uri](#input\_image\_uri) | ECR image URI for Image-based Lambda | `string` | `null` | no |
50+
| <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 |
4851
| <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 |
4952
| <a name="input_send_to_firehose"></a> [send\_to\_firehose](#input\_send\_to\_firehose) | Enable sending logs to firehose | `bool` | `true` | no |
5053
| <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 |

infrastructure/modules/lambda/data_archive_file_lambda.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
data "archive_file" "lambda" {
2+
count = var.package_type == "Zip" ? 1 : 0
23
type = "zip"
34
source_dir = "${path.root}/${var.function_code_base_path}/${var.function_code_dir}"
45

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
data "aws_iam_policy_document" "ecr" {
2+
statement {
3+
effect = "Allow"
4+
5+
actions = [
6+
"ecr:GetAuthorizationToken",
7+
"ecr:BatchGetImage",
8+
"ecr:GetDownloadUrlForLayer",
9+
"ecr:BatchCheckLayerAvailability",
10+
]
11+
12+
resources = ["*"]
13+
}
14+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
resource "aws_iam_role_policy" "ecr" {
2+
count = var.package_type == "Image" ? 1 : 0
3+
name = "${local.csi}-ecr"
4+
role = aws_iam_role.main.id
5+
policy = data.aws_iam_policy_document.ecr.json
6+
}

infrastructure/modules/lambda/lambda_function.tf

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,27 @@ resource "aws_lambda_function" "main" {
22
description = var.description
33
function_name = local.csi
44
role = aws_iam_role.main.arn
5-
handler = "${var.function_module_name}.${var.handler_function_name}"
6-
runtime = var.runtime
5+
handler = var.package_type == "Zip" ? "${var.function_module_name}.${var.handler_function_name}" : null
6+
runtime = var.package_type == "Zip" ? var.runtime : null
7+
package_type = var.package_type
78
publish = true
89
memory_size = var.memory
910
timeout = var.timeout
1011

11-
s3_bucket = aws_s3_object.lambda.bucket
12-
s3_key = aws_s3_object.lambda.key
13-
s3_object_version = aws_s3_object.lambda.version_id
12+
s3_bucket = var.package_type == "Zip" ? aws_s3_object.lambda[0].bucket : null
13+
s3_key = var.package_type == "Zip" ? aws_s3_object.lambda[0].key : null
14+
s3_object_version = var.package_type == "Zip" ? aws_s3_object.lambda[0].version_id : null
15+
16+
image_uri = var.package_type == "Image" ? var.image_uri : null
17+
18+
dynamic "image_config" {
19+
for_each = var.package_type == "Image" && var.image_config != null ? [1] : []
20+
content {
21+
entry_point = try(var.image_config.entry_point, null)
22+
command = try(var.image_config.command, null)
23+
working_directory = try(var.image_config.working_directory, null)
24+
}
25+
}
1426

1527
logging_config {
1628
application_log_level = var.application_log_level
@@ -19,12 +31,12 @@ resource "aws_lambda_function" "main" {
1931
system_log_level = var.system_log_level
2032
}
2133

22-
layers = compact(concat(
34+
layers = var.package_type == "Zip" ? compact(concat(
2335
var.layers,
2436
[
2537
var.enable_lambda_insights && var.lambda_at_edge == false ? "arn:aws:lambda:${var.region}:580247275435:layer:LambdaInsightsExtension:53" : null
2638
]
27-
))
39+
)) : []
2840

2941
environment {
3042
variables = var.lambda_env_vars

infrastructure/modules/lambda/s3_object_lambda.tf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
resource "aws_s3_object" "lambda" {
2+
count = var.package_type == "Zip" ? 1 : 0
23
bucket = var.function_s3_bucket
34
key = "${local.csi}.zip"
4-
source = data.archive_file.lambda.output_path
5+
source = data.archive_file.lambda[0].output_path
56

6-
source_hash = var.force_lambda_code_deploy ? data.archive_file.lambda.output_base64sha256 : null
7+
source_hash = var.force_lambda_code_deploy ? data.archive_file.lambda[0].output_base64sha256 : null
78

89
metadata = {
9-
hash = data.archive_file.lambda.output_base64sha256
10+
hash = data.archive_file.lambda[0].output_base64sha256
1011
function = local.csi
1112
commit = try(data.external.git_commit.result["sha"], "null")
1213
}

infrastructure/modules/lambda/variables.tf

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,44 @@ variable "log_retention_in_days" {
9292
variable "runtime" {
9393
type = string
9494
description = "The runtime to use for the lambda function"
95+
default = null
96+
97+
validation {
98+
condition = var.package_type != "Zip" || (var.runtime != null && var.runtime != "")
99+
error_message = "runtime must be set when package_type is Zip."
100+
}
101+
}
102+
103+
variable "package_type" {
104+
type = string
105+
description = "Lambda package type: Zip or Image"
106+
default = "Zip"
107+
108+
validation {
109+
condition = contains(["Zip", "Image"], var.package_type)
110+
error_message = "package_type must be either Zip or Image."
111+
}
112+
}
113+
114+
variable "image_uri" {
115+
type = string
116+
description = "ECR image URI for Image-based Lambda"
117+
default = null
118+
119+
validation {
120+
condition = var.package_type != "Image" || (var.image_uri != null && var.image_uri != "")
121+
error_message = "image_uri must be set when package_type is Image."
122+
}
123+
}
124+
125+
variable "image_config" {
126+
type = object({
127+
entry_point = optional(list(string))
128+
command = optional(list(string))
129+
working_directory = optional(string)
130+
})
131+
description = "Optional image configuration for Image-based Lambda"
132+
default = null
95133
}
96134

97135
variable "schedule" {
@@ -122,11 +160,23 @@ variable "function_code_base_path" {
122160
variable "function_code_dir" {
123161
type = string
124162
description = "The directory for this lambda"
163+
default = null
164+
165+
validation {
166+
condition = var.package_type != "Zip" || (var.function_code_dir != null && var.function_code_dir != "")
167+
error_message = "function_code_dir must be set when package_type is Zip."
168+
}
125169
}
126170

127171
variable "function_s3_bucket" {
128172
type = string
129173
description = "The bucket to upload Lambda packages to"
174+
default = null
175+
176+
validation {
177+
condition = var.package_type != "Zip" || (var.function_s3_bucket != null && var.function_s3_bucket != "")
178+
error_message = "function_s3_bucket must be set when package_type is Zip."
179+
}
130180
}
131181

132182
variable "function_include_common" {

0 commit comments

Comments
 (0)