Skip to content

Commit fd98952

Browse files
committed
Fix: Race between layer and Lambda update (#5927)
1 parent 6ae5db5 commit fd98952

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Delete all but the latest published version of every AWS Lambda function in the
3+
current deployment.
4+
"""
5+
6+
import logging
7+
8+
from azul import (
9+
config,
10+
require,
11+
)
12+
from azul.lambdas import (
13+
Lambdas,
14+
)
15+
from azul.logging import (
16+
configure_script_logging,
17+
)
18+
19+
log = logging.getLogger(__name__)
20+
21+
22+
def main():
23+
require(config.terraform_component == '',
24+
'This script cannot be run with a Terraform component selected',
25+
config.terraform_component)
26+
Lambdas().delete_stale_function_versions()
27+
28+
29+
if __name__ == '__main__':
30+
configure_script_logging(log)
31+
main()

src/azul/lambdas.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,18 @@ def reset_lambda_roles(self):
202202
time.sleep(1)
203203
else:
204204
break
205+
206+
def delete_stale_function_versions(self):
207+
"""
208+
Delete all but the latest published version of every AWS Lambda function
209+
in the current deployment.
210+
"""
211+
log.info('Deleting stale versions of AWS Lambda functions')
212+
for function in self.list_lambdas(deployment=config.deployment_stage,
213+
all_versions=True):
214+
if function.version == '$LATEST':
215+
log.info('Skipping latest version %r', function.name)
216+
else:
217+
log.info('Deleting version %r of %r', function.version, function.name)
218+
self._lambda.delete_function(FunctionName=function.name,
219+
Qualifier=function.version)

src/azul/terraform.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,10 @@ def tf_config(self, app_name):
708708
for resource in resources['aws_lambda_function'].values():
709709
assert 'layers' not in resource
710710
resource['layers'] = ['${aws_lambda_layer_version.dependencies.arn}']
711+
# Publishing the Lambda function as a new version prevents a race
712+
# condition when there's a dependency between updates to the
713+
# function's configuration and its code.
714+
resource['publish'] = True
711715
env = config.es_endpoint_env(
712716
es_endpoint=(
713717
aws.es_endpoint

terraform/Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ import_resources: rename_resources
4343
plan: import_resources
4444
terraform plan
4545

46+
.PHONY: delete_stale_function_versions
47+
delete_stale_function_versions: import_resources check_python
48+
python $(project_root)/scripts/delete_stale_function_versions.py
49+
4650
.PHONY: apply
47-
apply: import_resources
51+
apply: delete_stale_function_versions
4852
ifeq ($(AZUL_PRIVATE_API),1)
4953
# For private API we need the VPC endpoints to be created first so that the
5054
# aws_lb_target_group_attachment can iterate over the network_interface_ids.
@@ -53,7 +57,7 @@ endif
5357
terraform apply
5458

5559
.PHONY: auto_apply
56-
auto_apply: import_resources
60+
auto_apply: delete_stale_function_versions
5761
ifeq ($(AZUL_PRIVATE_API),1)
5862
# See `apply` above
5963
terraform apply -auto-approve -target aws_vpc_endpoint.indexer -target aws_vpc_endpoint.service

0 commit comments

Comments
 (0)