I'm trying to create a Role with some policies, which will differ from lambda to lambda. The ideal scenario would be to have a function where the role and policies are all created and then I'd just call the function and give it the name of the role and the policies I wanted attached, and it would create all of it. So far I have this:
Usage of lambda role creation:
...
const lambdarole = this.createLambdaRole( 'Test Role', [
'KMSLambdaPolicy',
'S3LambdaPolicy',
]);
...
Role and policies creation:
private createLambdaRole(roleName: string, policyName: string[]) {
const role = new Role(this, 'Role', {
roleName: roleName,
assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
description: 'Role for lambda access',
managedPolicies: [],
});
const kmspolicy = new ManagedPolicy(this, 'KMSLambdaPolicy', {
managedPolicyName: 'KMSLambdaPolicy',
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
actions: [
'kms:Decrypt',
'kms:GenerateDataKey',
'kms:DescribeKey'],
}),
],
});
const s3policy = new ManagedPolicy(this, 'S3LambdaPolicy', {
managedPolicyName: 'S3LambdaPolicy',
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
actions: [
's3:PutObject',
's3:GetObject',
's3:GetObjectAttributes'],
resources: ['*'],
}),
],
});
policyName.forEach(policyName => role.addManagedPolicy(policyName));
return role;
}
Currently I can't get it to work, and it gives the following error:
error TS2345: Argument of type 'string' is not assignable to parameter of type 'IManagedPolicy'.
Is what I want even possible?
Thank you in advance for anyone willing to help!
SOLUTION FOUND
I managed to make it work with the code bellow:
policyName.forEach(policyName => {
const importedPolicy = ManagedPolicy.fromManagedPolicyName(this, policyName, policyName);
role.addManagedPolicy(importedPolicy);
});
Note: addManagedPolicy
requires a scope, an id and a policy name. Since my policy ID's and names are the same, I just needed to call the array again (hence the this, policyName, policyName
).
The addManagedPolicy
expects an IManagedPolicy
object, but you provided a string instead.
// the managed policy definition is only needed once for your whole account,
// if you want to reuse it.
// It has to be unique if you want to map it by name.
// the following is an example for a customer-managed policy.
// the attribute `managedPolicyName` is the identifier for the
// import later on.
const kmspolicy = new ManagedPolicy(this, 'MP-KMSLambda', {
managedPolicyName: 'KMSLambdaPolicy'
// etc.
});
// the following role attachment can happen everywhere in your CDK application,
// e.g. in another construct or stack.
//
// The policyNames list need to have the same identifier as in
// your new ManagedPolicies before.
const policyNames = ['KMSLambdaPolicy'];
policyNames.forEach(policyName => {
const importedPolicy = iam.ManagedPolicy.fromManagedPolicyName(this, `${role.roleName}-${policyName}`, policyName)
role.addManagedPolicy(importedPolicy)
});