@@ -394,7 +394,24 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
394394 intrinsics_resolver ,
395395 get_managed_policy_map ,
396396 )
397- self ._make_lambda_role (lambda_function , intrinsics_resolver , execution_role , resources , conditions )
397+
398+ if lambda_function .Role is None :
399+ lambda_function .Role = execution_role .get_runtime_attr ("arn" )
400+ resources .append (execution_role )
401+ elif is_intrinsic_if (lambda_function .Role ):
402+ role_changes = self ._make_lambda_role (lambda_function , intrinsics_resolver , execution_role )
403+
404+ if role_changes ["should_append_role" ]:
405+ resources .append (execution_role )
406+
407+ if role_changes ["lambda_role_value" ] is not None :
408+ lambda_function .Role = role_changes ["lambda_role_value" ]
409+
410+ if role_changes ["execution_role_condition" ] is not None :
411+ execution_role .set_resource_attribute ("Condition" , role_changes ["execution_role_condition" ])
412+
413+ if role_changes ["new_condition" ] is not None :
414+ conditions .update (role_changes ["new_condition" ])
398415
399416 try :
400417 resources += self ._generate_event_resources (
@@ -417,46 +434,48 @@ def _make_lambda_role(
417434 lambda_function : LambdaFunction ,
418435 intrinsics_resolver : IntrinsicsResolver ,
419436 execution_role : IAMRole ,
420- resources : List [Any ],
421- conditions : Dict [str , Any ],
422- ) -> None :
423- lambda_role = lambda_function .Role
424-
425- if lambda_role is None :
426- resources .append (execution_role )
427- lambda_function .Role = execution_role .get_runtime_attr ("arn" )
428-
429- elif is_intrinsic_if (lambda_role ):
430-
431- # We need to create and if else condition here
432- role_resolved_value = intrinsics_resolver .resolve_parameter_refs (lambda_role )
433- role_condition , role_if , role_else = role_resolved_value .get ("Fn::If" )
434-
435- is_both_intrinsic_no_values = is_intrinsic_no_value (role_if ) and is_intrinsic_no_value (role_else )
437+ ) -> Dict [str , Any ]:
438+ """
439+ Analyzes lambda role requirements and returns the changes needed.
436440
437- # Create a role only when no value is in either of the conditions
438- if is_intrinsic_no_value (role_if ) or is_intrinsic_no_value (role_else ):
439- resources .append (execution_role )
441+ Returns:
442+ Dict containing:
443+ - 'should_append_role': bool - whether to append execution_role to resources
444+ - 'lambda_role_value': Any - value to set for lambda_function.Role
445+ - 'execution_role_condition': str|None - condition to set on execution_role
446+ - 'new_condition': Dict|None - new condition to add to conditions dict
447+ """
448+ lambda_role = lambda_function .Role
449+ execution_role_arn = execution_role .get_runtime_attr ("arn" )
440450
441- # both are none values, we always need to create a role
442- if is_both_intrinsic_no_values :
443- lambda_function .Role = execution_role .get_runtime_attr ("arn" )
451+ result = {
452+ "should_append_role" : False ,
453+ "lambda_role_value" : None ,
454+ "execution_role_condition" : None ,
455+ "new_condition" : None ,
456+ }
444457
445- # first value is none so we should create condition ? create : [2]
446- # create a condition for IAM role to only create on if case
447- elif is_intrinsic_no_value (role_if ):
448- lambda_function .Role = make_conditional (
449- role_condition , execution_role .get_runtime_attr ("arn" ), role_else
450- )
451- execution_role .set_resource_attribute ("Condition" , f"{ role_condition } " )
452-
453- # second value is none so we should create condition ? [1] : create
454- # create a condition for IAM role to only create on else case
455- # with top level condition that negates the condition passed
456- elif is_intrinsic_no_value (role_else ):
457- lambda_function .Role = make_conditional (role_condition , role_if , execution_role .get_runtime_attr ("arn" ))
458- execution_role .set_resource_attribute ("Condition" , f"NOT{ role_condition } " )
459- conditions [f"NOT{ role_condition } " ] = make_not_conditional (role_condition )
458+ # We need to create and if else condition here
459+ role_resolved_value = intrinsics_resolver .resolve_parameter_refs (lambda_role )
460+ role_condition , role_if , role_else = role_resolved_value .get ("Fn::If" )
461+
462+ # first value is none so we should create condition ? create : [2]
463+ # create a condition for IAM role to only create on if case
464+ if is_intrinsic_no_value (role_if ):
465+ result ["lambda_role_value" ] = make_conditional (role_condition , execution_role_arn , role_else )
466+ result ["execution_role_condition" ] = f"{ role_condition } "
467+ result ["should_append_role" ] = True
468+
469+ # second value is none so we should create condition ? [1] : create
470+ # create a condition for IAM role to only create on else case
471+ # with top level condition that negates the condition passed
472+ elif is_intrinsic_no_value (role_else ):
473+ result ["lambda_role_value" ] = make_conditional (role_condition , role_if , execution_role_arn )
474+ result ["execution_role_condition" ] = f"NOT{ role_condition } "
475+ result ["new_condition" ] = {f"NOT{ role_condition } " : make_not_conditional (role_condition )}
476+ result ["should_append_role" ] = True
477+
478+ return result
460479
461480 def _construct_event_invoke_config ( # noqa: PLR0913
462481 self ,
0 commit comments