26

I realize it's pretty new but I don't see any examples in any language how you would specify a role for the lambda created with the AWS CDK.

I was attempting to do this

const cdk       = require('@aws-cdk/cdk');
const lambda    = require('@aws-cdk/aws-lambda');
const iam       = require('@aws-cdk/aws-iam');

const path      = require('path');

class MyStack extends cdk.Stack {
    constructor (parent, id, props) {
            super(parent, id, props);

            //
            // Create a lambda...
            const fn = new lambda.Function(this, 'MyFunction-cdktest', {
                runtime: lambda.Runtime.NodeJS810,
                handler: 'index.handler',
                code: lambda.Code.directory( path.join( __dirname, 'lambda')),
                role: iam.RoleName('lambda_basic_execution')
            });

    }
}

class MyApp extends cdk.App {
        constructor (argv) {
                super(argv);

                new MyStack(this, 'hello-cdk');
        }
}

console.log(new MyApp(process.argv).run());

in order to try and specify an existing IAM role for the function but that doesn't seem to be correct syntax. I also would be ok with ( or maybe even prefer ) to generate the custom role on the fly specific to this lambda but I didn't see any examples on how to do that either.

Does anyone have any insight on how to accomplish this?

Ivan Kluzak
  • 655
  • 2
  • 7
  • 11

6 Answers6

33

A Lambda already comes with an execution role, and it already has the basic execution permissions. If you want to add additional permissions to the role it has, do something like the following:

import * as iam from '@aws-cdk/aws-iam';

lambda.addToRolePolicy(new iam.PolicyStatement()
   .addResource('arn:aws:....')
   .addAction('s3:GetThing'));

Or better yet, use one of the convenience functions for permissions on some resources:

bucket.grantRead(lambda.role);
Mohamed Ali JAMAOUI
  • 14,275
  • 14
  • 73
  • 117
rix0rrr
  • 9,856
  • 5
  • 45
  • 48
23

Even though the lambda comes with an IAM role, you can create a custom role for the lambda. You just have to make sure to assign correct minimum required permissions to it.

You can create a role like this:

    const customRole = new Role(this, 'customRole', {
                    roleName: 'customRole',
                    assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
                    managedPolicies: [
                        ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaVPCAccessExecutionRole"),
                        ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")
                    ]
                })

If the lambda does not need to be in a VPC you can skip AWSLambdaVPCAccessExecutionRole.

And to assign this role to the lambda function:

const lambda = new lambda.Function(this, 'lambda', {
                runtime:....,
                code:...,
                role: customRole,
                handler:....,
                memorySize:...,
                timeout:....,
                vpc:...,
                environment: {
                   ....
                }
            });
user2803056
  • 377
  • 4
  • 12
14

The accepted answer by @rix0rrr doesn't work any more. Seems CDK get some updates. Currently version is

"@aws-cdk/core": "^1.1.0"

Updated code:

    import iam = require("@aws-cdk/aws-iam");

    const statement = new iam.PolicyStatement();
    statement.addActions("lambda:InvokeFunction");
    statement.addResources("*");

    lambda.addToRolePolicy(statement); 
Bill
  • 2,494
  • 5
  • 26
  • 61
11

Bill's answer works, but here's another way:

import iam = require("@aws-cdk/aws-iam");

lambda.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: [ 'lambda:InvokeFunction' ],
  resources: [ '*' ]
}));
Tanvir
  • 1,453
  • 2
  • 16
  • 32
  • If you came here looking to do add a policy, you may (like me) not know exactly what the `actions` array should be filled with. You can get a list of these by going to the IAM console > Policies > [Click on a Policy] > Policy Summary. Also, you can generate policies (with actions) from CloudWatch Logs. In IAM console > Roles > [Select a Role] > Permissions > Button(Generate Policy). Be sure to pick a time period representing usage. – Andrew Philips Jul 03 '21 at 01:53
  • Above "Policy Summary" to see the actions should have been "Json" – Andrew Philips Jul 03 '21 at 02:04
3

I came across a similar situation, and found an answer like


import * as lambda from '@aws-cdk/aws-lambda';

import iam = require("@aws-cdk/aws-iam");

      // define lambda fucntion
        const lambdaFunction = new lambda.Function(this, 'my-lambda', {
            code: this.lambdaCode,
            functionName: 'athena-gateway',
            handler: 'index.handler',
            runtime: lambda.Runtime.NODEJS_12_X,
            timeout: Duration.minutes(14)
        });

        // provide athena,s3 access to lambda function
        const athenaAccessPolicy = new iam.PolicyStatement({
            effect: iam.Effect.ALLOW,
            actions: [
                "s3:*",
                "athena:*"                            ]

        });
        athenaAccessPolicy.addAllResources();
        lambdaFunction.addToRolePolicy(athenaAccessPolicy)

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
1

I didn't managed to add role during lambda creation, but next code gives to lambda access to external role, created in another CDK:

lambdaFn.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: [ "sts:AssumeRole" ],
  resources: [externalRoleArn]
}))
Artem Sky
  • 11
  • 1