From 7ffbe7868997b36db287927b75bde6d11670898d Mon Sep 17 00:00:00 2001 From: Tonye Jack Date: Sun, 16 Mar 2025 01:02:41 -0600 Subject: [PATCH] fix: bug with lambda function updates (#1) ## Resolves the ResourceConflictException error when updating an existing lambda function ``` Bundling: 'service.py' Bundling: '.envrc' Bundling: 'requirements.txt' Bundling: 'Makefile' Bundling: 'event.json' Bundling: 'README.md' Bundling: 'requirements-dev.txt' Bundling: '.gitignore' Updating your Lambda function Traceback (most recent call last): File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/bin/lambda", line 213, in cli() File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/click/core.py", line 716, in __call__ return self.main(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/click/core.py", line 696, in main rv = self.invoke(ctx) ^^^^^^^^^^^^^^^^ File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/click/core.py", line 1060, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/click/core.py", line 889, in invoke return ctx.invoke(self.callback, **ctx.params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/click/core.py", line 534, in invoke return callback(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/bin/lambda", line 117, in deploy aws_lambda.deploy( File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/aws_lambda/aws_lambda.py", line 138, in deploy update_function( File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/aws_lambda/aws_lambda.py", line 744, in update_function ret = client.update_function_configuration(**kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/botocore/client.py", line 570, in _api_call return self._make_api_call(operation_name, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/botocore/context.py", line 124, in wrapper return func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "/Users/tonyejack/.virtualenvs/sync_waf_ips-srms/lib/python3.11/site-packages/botocore/client.py", line 1031, in _make_api_call raise error_class(parsed_response, operation_name) botocore.errorfactory.ResourceConflictException: An error occurred (ResourceConflictException) when calling the UpdateFunctionConfiguration operation: The operation cannot be performed at this time. An update is in progress for resource: arn:aws:lambda:us-east-2:659424869662:function:sync_waf_ips make: *** [deploy] Error 1 ``` --- aws_lambda/aws_lambda.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/aws_lambda/aws_lambda.py b/aws_lambda/aws_lambda.py index 0b5ca88..2859de1 100644 --- a/aws_lambda/aws_lambda.py +++ b/aws_lambda/aws_lambda.py @@ -704,10 +704,14 @@ def update_function( Publish=True, ) - # Wait for function to be updated + # Wait for function code to be updated waiter = client.get_waiter('function_updated') + print("Waiting for code update to complete...") waiter.wait(FunctionName=cfg.get("function_name")) + # Add a short delay to allow propagation + time.sleep(5) + kwargs = { "FunctionName": cfg.get("function_name"), "Role": role, @@ -745,7 +749,21 @@ def update_function( }, ) - ret = client.update_function_configuration(**kwargs) + # Retry configuration update in case of conflicts + retries = 5 + for attempt in range(retries): + try: + print("Updating function configuration...") + ret = client.update_function_configuration(**kwargs) + break + except client.exceptions.ResourceConflictException as e: + print(f"Conflict detected. Retrying... ({attempt + 1}/{retries})") + time.sleep(10) # Wait before retrying + else: + raise Exception(f"Failed to update function configuration after {retries} retries.") + + # Add a short delay to allow propagation + time.sleep(5) concurrency = get_concurrency(cfg) if concurrency > 0: