'AWS CDK: lambda permissions and EFS mount

I am trying to declare in my stack a lambda function with an EFS mount. The lambda has a custom execution role with arn

arn:aws:iam::ACCOUNTID:role/service-role/ROLENAME

i.e. it was created in the stack using

lambda_role = aws_iam.Role(..., path="/service-role/", ...)

The code snippet declaring the lambda is

_lambda.Function(
                self,
                id="myId",
                runtime=_lambda.Runtime.PYTHON_3_8,
                code=_lambda.Code.asset('lambda'),
                handler='my_module.lambda_handler',
                role=lambda_role,
                function_name="function-name",
                timeout=core.Duration.seconds(30),
                vpc=vpc,
                filesystem=_lambda.FileSystem.from_efs_access_point(access_point, '/efs')
        )

The deployment fails with this error:

API: iam:PutRolePolicy User: USERNAME is not authorized to perform: iam:PutRolePolicy on resource: role service-role with an explicit deny

That "role service-role" in the error message seemed weird, so I inspected the synthesized CF template, and noticed this section:

  lambdarolePolicy2FC0B982:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        ** policy giving elasticfilesystem:ClientWrite and elasticfilesystem:ClientMount permissions**
      PolicyName: lambdarolePolicy2FC0B982
      Roles:
        - Fn::Select:
            - 1
            - Fn::Split:
                - /
                - Fn::Select:
                    - 5
                    - Fn::Split:
                        - ":"
                        - Fn::ImportValue: sgmkr-iam-arn-mr

That ImportValue maps to the arn of the lambda execution role. The problem I see is with the string manipulation, which does not seem to take into account the fact that the role has a path. The result of that chain of Select/Split is indeed "service-role", not the proper role name.

I have two questions:

  1. why is CDK trying to add extra permissions to a role I defined? I already added the needed permissions to the relevant role, and I really don't want anything added to it. Moreover, in my setup, iam:PutRolePolicy calls are strictly regulated, so this would almost certainly fail. That's the very reason I pass my own role. How can I switch off this automatic policy generation?
  2. why is CDK ignoring the role path? Is this intended?

Thanks for your help,

Andrea.



Solution 1:[1]

The easiest workaround would I could think of would be using "role name" instead "role ARN".

Instead

role_arn = iam.Role.from_role_arn(self, "Role", role_arn=<role_arn>)

Use:

role_name = iam.Role.from_role_name(self, "Role", role_name=<role_name>)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Daniel Rodriguez