@@ -741,6 +741,113 @@ def test_function_datasource_set_with_none():
741741 assert none_datasource
742742
743743
744+ class TestSamFunctionRoleResolver (TestCase ):
745+ """
746+ Tests for resolving IAM role property values in SamFunction
747+ """
748+
749+ def setUp (self ):
750+ self .function = SamFunction ("foo" )
751+ self .function .CodeUri = "s3://foobar/foo.zip"
752+ self .function .Runtime = "foo"
753+ self .function .Handler = "bar"
754+ self .kwargs = {
755+ "intrinsics_resolver" : IntrinsicsResolver ({}),
756+ "event_resources" : [],
757+ "managed_policy_map" : {},
758+ "resource_resolver" : ResourceResolver ({}),
759+ "conditions" : {"Conditions" : {}},
760+ }
761+
762+ def test_role_none_creates_execution_role (self ):
763+ self .function .Role = None
764+ cfn_resources = self .function .to_cloudformation (** self .kwargs )
765+ generated_roles = [x for x in cfn_resources if isinstance (x , IAMRole )]
766+
767+ self .assertEqual (len (generated_roles ), 1 ) # Should create execution role
768+
769+ def test_role_explicit_arn_no_execution_role (self ):
770+ test_role = "arn:aws:iam::123456789012:role/existing-role"
771+ self .function .Role = test_role
772+
773+ cfn_resources = self .function .to_cloudformation (** self .kwargs )
774+ generated_roles = [x for x in cfn_resources if isinstance (x , IAMRole )]
775+ lambda_function = next (r for r in cfn_resources if r .resource_type == "AWS::Lambda::Function" )
776+
777+ self .assertEqual (len (generated_roles ), 0 ) # Should not create execution role
778+ self .assertEqual (lambda_function .Role , test_role )
779+
780+ def test_role_fn_if_no_aws_no_value_keeps_original (self ):
781+ role_conditional = {
782+ "Fn::If" : ["Condition" , "arn:aws:iam::123456789012:role/existing-role" , {"Ref" : "iamRoleArn" }]
783+ }
784+ self .function .Role = role_conditional
785+
786+ kwargs = dict (self .kwargs )
787+ kwargs ["conditions" ] = {"Condition" : True }
788+
789+ cfn_resources = self .function .to_cloudformation (** self .kwargs )
790+ generated_roles = [x for x in cfn_resources if isinstance (x , IAMRole )]
791+ lambda_function = next (r for r in cfn_resources if r .resource_type == "AWS::Lambda::Function" )
792+
793+ # Should not create a role if a role is passed in for both cases
794+ self .assertEqual (len (generated_roles ), 0 )
795+ self .assertEqual (lambda_function .Role , role_conditional )
796+
797+ def test_role_fn_if_both_no_value_creates_execution_role (self ):
798+ role_conditional = {"Fn::If" : ["Condition" , {"Ref" : "AWS::NoValue" }, {"Ref" : "AWS::NoValue" }]}
799+ self .function .Role = role_conditional
800+
801+ kwargs = dict (self .kwargs )
802+ kwargs ["conditions" ] = {"Condition" : True }
803+
804+ cfn_resources = self .function .to_cloudformation (** self .kwargs )
805+ generated_roles = [x for x in cfn_resources if isinstance (x , IAMRole )]
806+
807+ self .assertEqual (len (generated_roles ), 1 )
808+
809+ def test_role_fn_if_first_no_value_creates_conditional_role (self ):
810+ role_conditional = {"Fn::If" : ["Condition" , {"Ref" : "AWS::NoValue" }, {"Ref" : "iamRoleArn" }]}
811+ self .function .Role = role_conditional
812+
813+ kwargs = dict (self .kwargs )
814+ kwargs ["conditions" ] = {"Condition" : True }
815+
816+ cfn_resources = self .function .to_cloudformation (** self .kwargs )
817+ generated_roles = [x for x in cfn_resources if isinstance (x , IAMRole )]
818+ lambda_function = next (r for r in cfn_resources if r .resource_type == "AWS::Lambda::Function" )
819+
820+ self .assertEqual (len (generated_roles ), 1 )
821+ self .assertEqual (
822+ lambda_function .Role , {"Fn::If" : ["Condition" , {"Fn::GetAtt" : ["fooRole" , "Arn" ]}, {"Ref" : "iamRoleArn" }]}
823+ )
824+
825+ def test_role_fn_if_second_no_value_creates_conditional_role (self ):
826+ role_conditional = {"Fn::If" : ["Condition" , {"Ref" : "iamRoleArn" }, {"Ref" : "AWS::NoValue" }]}
827+ self .function .Role = role_conditional
828+
829+ kwargs = dict (self .kwargs )
830+ kwargs ["conditions" ] = {"Condition" : True }
831+
832+ cfn_resources = self .function .to_cloudformation (** self .kwargs )
833+ generated_roles = [x for x in cfn_resources if isinstance (x , IAMRole )]
834+ lambda_function = next (r for r in cfn_resources if r .resource_type == "AWS::Lambda::Function" )
835+
836+ self .assertEqual (len (generated_roles ), 1 )
837+ self .assertEqual (
838+ lambda_function .Role , {"Fn::If" : ["Condition" , {"Ref" : "iamRoleArn" }, {"Fn::GetAtt" : ["fooRole" , "Arn" ]}]}
839+ )
840+
841+ def test_role_get_att_no_execution_role (self ):
842+ role_get_att = {"Fn::GetAtt" : ["MyCustomRole" , "Arn" ]}
843+ self .function .Role = role_get_att
844+
845+ cfn_resources = self .function .to_cloudformation (** self .kwargs )
846+ lambda_function = next (r for r in cfn_resources if r .resource_type == "AWS::Lambda::Function" )
847+
848+ self .assertEqual (lambda_function .Role , role_get_att )
849+
850+
744851class TestSamCapacityProvider (TestCase ):
745852 """Tests for SamCapacityProvider"""
746853
0 commit comments