'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:
- 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?
- 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 |
