Skip to content

Commit 508f0d5

Browse files
authored
feat: Add support for separate deployments of infra and code (#175)
1 parent afbf7bd commit 508f0d5

File tree

6 files changed

+76
-3
lines changed

6 files changed

+76
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
55
<a name="unreleased"></a>
66
## [Unreleased]
77

8-
8+
- feat: Add `ignore_source_code_hash` variable to allow the lambda function resource to be managed by terraform but have the function code managed externally
99

1010
<a name="v2.9.0"></a>
1111
## [v2.9.0] - 2021-08-20

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,32 @@ module "lambda_function_existing_package_local" {
106106
}
107107
```
108108

109+
### Lambda Function or Lambda Layer with the deployable artifact maintained separately from the infrastructure
110+
111+
If you want to manage function code and infrastructure resources (such as IAM permissions, policies, events, etc) in separate flows (e.g., different repositories, teams, CI/CD pipelines).
112+
113+
Disable source code tracking to turn off deployments (and rollbacks) using the module by setting `ignore_source_code_hash = true` and deploy a _dummy function_.
114+
115+
When the infrastructure and the dummy function is deployed, you can use external tool to update the source code of the function (eg, using [AWS CLI](https://docs.aws.amazon.com/cli/latest/reference/lambda/update-function-code.html)) and keep using this module via Terraform to manage the infrastructure.
116+
117+
Be aware that changes in `local_existing_package` value may trigger deployment via Terraform.
118+
119+
```hcl
120+
module "lambda_function_externally_managed_package" {
121+
source = "terraform-aws-modules/lambda/aws"
122+
123+
function_name = "my-lambda-externally-managed-package"
124+
description = "My lambda function code is deployed separately"
125+
handler = "index.lambda_handler"
126+
runtime = "python3.8"
127+
128+
create_package = false
129+
local_existing_package = "./lambda_functions/code.zip"
130+
131+
ignore_source_code_hash = true
132+
}
133+
```
134+
109135
### Lambda Function with existing package (prebuilt) stored in S3 bucket
110136

111137
Note that this module does not copy prebuilt packages into S3 bucket. This module can only store packages it builds locally and in S3 bucket.
@@ -664,6 +690,7 @@ No modules.
664690
| <a name="input_function_name"></a> [function\_name](#input\_function\_name) | A unique name for your Lambda Function | `string` | `""` | no |
665691
| <a name="input_handler"></a> [handler](#input\_handler) | Lambda Function entrypoint in your code | `string` | `""` | no |
666692
| <a name="input_hash_extra"></a> [hash\_extra](#input\_hash\_extra) | The string to add into hashing function. Useful when building same source path for different functions. | `string` | `""` | no |
693+
| <a name="input_ignore_source_code_hash"></a> [ignore\_source\_code\_hash](#input\_ignore\_source\_code\_hash) | Whether to ignore changes to the function's source code hash. Set to true if you manage infrastructure and code deployments separately. | `bool` | `false` | no |
667694
| <a name="input_image_config_command"></a> [image\_config\_command](#input\_image\_config\_command) | The CMD for the docker image | `list(string)` | `[]` | no |
668695
| <a name="input_image_config_entry_point"></a> [image\_config\_entry\_point](#input\_image\_config\_entry\_point) | The ENTRYPOINT for the docker image | `list(string)` | `[]` | no |
669696
| <a name="input_image_config_working_directory"></a> [image\_config\_working\_directory](#input\_image\_config\_working\_directory) | The working directory for the docker image | `string` | `null` | no |

examples/complete/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ Note that this example may create resources which cost money. Run `terraform des
4040
| <a name="module_lambda_function"></a> [lambda\_function](#module\_lambda\_function) | ../../ | |
4141
| <a name="module_lambda_function_existing_package_local"></a> [lambda\_function\_existing\_package\_local](#module\_lambda\_function\_existing\_package\_local) | ../../ | |
4242
| <a name="module_lambda_function_for_each"></a> [lambda\_function\_for\_each](#module\_lambda\_function\_for\_each) | ../../ | |
43+
| <a name="module_lambda_function_with_package_deploying_externally"></a> [lambda\_function\_with\_package\_deploying\_externally](#module\_lambda\_function\_with\_package\_deploying\_externally) | ../../ | |
4344
| <a name="module_lambda_layer_local"></a> [lambda\_layer\_local](#module\_lambda\_layer\_local) | ../../ | |
4445
| <a name="module_lambda_layer_s3"></a> [lambda\_layer\_s3](#module\_lambda\_layer\_s3) | ../../ | |
46+
| <a name="module_lambda_layer_with_package_deploying_externally"></a> [lambda\_layer\_with\_package\_deploying\_externally](#module\_lambda\_layer\_with\_package\_deploying\_externally) | ../../ | |
4547
| <a name="module_lambda_with_mixed_trusted_entities"></a> [lambda\_with\_mixed\_trusted\_entities](#module\_lambda\_with\_mixed\_trusted\_entities) | ../../ | |
4648
| <a name="module_lambda_with_provisioned_concurrency"></a> [lambda\_with\_provisioned\_concurrency](#module\_lambda\_with\_provisioned\_concurrency) | ../../ | |
4749
| <a name="module_s3_bucket"></a> [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | |

examples/complete/main.tf

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,26 @@ module "lambda_layer_local" {
167167
source_path = "${path.module}/../fixtures/python3.8-app1"
168168
}
169169

170+
####################################################
171+
# Lambda Layer with package deploying externally
172+
# (e.g., using separate CI/CD pipeline)
173+
####################################################
174+
175+
module "lambda_layer_with_package_deploying_externally" {
176+
source = "../../"
177+
178+
create_layer = true
179+
180+
layer_name = "${random_pet.this.id}-layer-local"
181+
description = "My amazing lambda layer (deployed from local)"
182+
compatible_runtimes = ["python3.8"]
183+
184+
create_package = false
185+
local_existing_package = "../fixtures/python3.8-zip/existing_package.zip"
186+
187+
ignore_source_code_hash = true
188+
}
189+
170190
###############################
171191
# Lambda Layer (storing on S3)
172192
###############################
@@ -277,6 +297,24 @@ module "lambda_function_for_each" {
277297
local_existing_package = "${path.module}/../fixtures/python3.8-zip/existing_package.zip"
278298
}
279299

300+
####################################################
301+
# Lambda Function with package deploying externally
302+
# (e.g., using separate CI/CD pipeline)
303+
####################################################
304+
305+
module "lambda_function_with_package_deploying_externally" {
306+
source = "../../"
307+
308+
function_name = "${random_pet.this.id}-lambda-with-package-deploying-externally"
309+
handler = "index.lambda_handler"
310+
runtime = "python3.8"
311+
312+
create_package = false
313+
local_existing_package = "../fixtures/python3.8-zip/existing_package.zip"
314+
315+
ignore_source_code_hash = true
316+
}
317+
280318
###########
281319
# Disabled
282320
###########

main.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ resource "aws_lambda_function" "this" {
2929
package_type = var.package_type
3030

3131
filename = local.filename
32-
source_code_hash = (local.filename == null ? false : fileexists(local.filename)) && !local.was_missing ? filebase64sha256(local.filename) : null
32+
source_code_hash = var.ignore_source_code_hash ? null : (local.filename == null ? false : fileexists(local.filename)) && !local.was_missing ? filebase64sha256(local.filename) : null
3333

3434
s3_bucket = local.s3_bucket
3535
s3_key = local.s3_key
@@ -100,7 +100,7 @@ resource "aws_lambda_layer_version" "this" {
100100
compatible_runtimes = length(var.compatible_runtimes) > 0 ? var.compatible_runtimes : [var.runtime]
101101

102102
filename = local.filename
103-
source_code_hash = (local.filename == null ? false : fileexists(local.filename)) && !local.was_missing ? filebase64sha256(local.filename) : null
103+
source_code_hash = var.ignore_source_code_hash ? null : (local.filename == null ? false : fileexists(local.filename)) && !local.was_missing ? filebase64sha256(local.filename) : null
104104

105105
s3_bucket = local.s3_bucket
106106
s3_key = local.s3_key

variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,12 @@ variable "artifacts_dir" {
493493
default = "builds"
494494
}
495495

496+
variable "ignore_source_code_hash" {
497+
description = "Whether to ignore changes to the function's source code hash. Set to true if you manage infrastructure and code deployments separately."
498+
type = bool
499+
default = false
500+
}
501+
496502
variable "local_existing_package" {
497503
description = "The absolute path to an existing zip-file to use"
498504
type = string

0 commit comments

Comments
 (0)