functionalone / serverless-iam-roles-per-function Goto Github PK
View Code? Open in Web Editor NEWServerless Plugin for easily defining IAM roles per function via the use of iamRoleStatements at the function level.
License: MIT License
Serverless Plugin for easily defining IAM roles per function via the use of iamRoleStatements at the function level.
License: MIT License
Hi ya, ran into another error as I try to integrate this plugin into the demo app I'm building for my course, which has API, Kinesis and SNS functions.
As you can see in this commit, I'm moving everything over to per-function roles, but when I run sls deploy
I get an error from CloudFormation saying An error occurred: RetryDashnotifyDashuserLambdaFunction - The provided execution role does not have permissions to callPublish on SNS.
I have looked at the CF template SLS generates, and the role does include the sns:Publish
permission.
If I do the following then it works:
iamRoleStatements
so they use the default IamRoleLambdaExecution
role that SLS generates, but leave all the other functions with their per-function IAM rolesiamRoleStatements
Based on the above, it feels like there's some race condition with creating these SNS functions, but I can't quite put my finger on what yet. Thoughts?
It it supported to just use the iamRoleStatementsName
config and not customize the roles in any way?
Hey!
Could you please update the version of the lodash dependency?
The current version is vulnerable to Prototype Pollution.
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10744
Thanks in advance,
Maurice
Hello,
So, I got the error that the auto-generated IAM-Role-Statements-Name was too long so I made my own. I took good care to make this a unique name indicating the region, the name of the stack etc. It seems that changing the name is nontrivial and ends up putting the stack in a weird place.
So my question is, is there a way to manipulate the maximum length of the unique role name so that I don't have to worry about it since the permissions are for this lambda function only?
Thanks,
Steven
The title pretty much says it all. Would be great because we maintain all of our roles in a separate system and we want to keep our serverless.yml as short as possible
Hi,
Great idea for plugin - however I'm having issue where default name role is used for the stack
The following is what I got
provider:
name: aws
runtime: nodejs8.10
provider:
region: eu-west-1
iamRoleStatementsName: SLSCloudRole-dev-abc
Based on the above I would assume default role name created to be SLSCloudRole-dev-abc
however I get sls-stackname-dev-eu-west-1-lambdaRole
Have tried also with the details below on provider
level but result is the same
iamRoleStatementsName: SLSCloudRole-dev-abc
iamRoleStatements: []
Any hints ?
I want to ensure that a function is able to access two queues in SQS. I am not sure how to structure the YAML. I have tried the following, neither of which worked.
v1_postEntitlement:
handler: src/entitlements/v1_postEntitlement.handler
iamRoleStatements:
- Effect: Allow
Action:
- sqs:SendMessage
Resource:
- arn:aws:sqs:us-east-1:xxxxxxxxxxxxxx:LicenseUpdateSerivce.fifo
- Effect: Allow
Action:
- sqs:SendMessage
Resource:
- arn:aws:sqs:us-east-1:xxxxxxxxxxxxxx:LoggingQueue
events:
- http:
path: vw/v1/entitlement
method: post
and..
v1_postEntitlement:
handler: src/entitlements/v1_postEntitlement.handler
iamRoleStatements:
- Effect: Allow
Action:
- sqs:SendMessage
Resource:
- arn:aws:sqs:us-east-1:xxxxxxxxxxxxxx:LoggingQueue
- arn:aws:sqs:us-east-1:xxxxxxxxxxxxxx:LicenseUpdateSerivce.fifo
events:
- http:
path: vw/v1/entitlement
method: post
I am planning to have the lambda authorizer generate a dynamic policy and assume a role based on the policy for tenant segregation. We already use serverless-iam-roles-per-function to limit lambda's access to AWS resources.
How does this sit with the dynamic policy generated to assume the role and thus limit access to S3 and dynamo (using leading keys and prefixes).
Should I remove dynamo from the IAM statement for the functions completely and let that be added through the dynamically generated policy or something else?
> serverless deploy --verbose
Serverless: Configuration warning at 'functions.import': unrecognized property 'iamRoleStatementsInherit'
Serverless:
Serverless: Learn more about configuration validation here: http://slss.io/configuration-validation
Serverless:
serverless -v
Framework Core: 2.11.1
Plugin: 4.1.2
SDK: 2.3.2
Components: 3.3.0
"devDependencies": {
"serverless-iam-roles-per-function": "^2.0.2"
},
serverless.yml
plugins:
- serverless-iam-roles-per-function # Define IAM roles per function
...
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.IMPORTER_DYNAMODB_TABLE}"
...
functions:
import:
handler: handlers/import.handler
iamRoleStatementsInherit: true
iamRoleStatements:
- Effect: "Allow"
Action:
- s3:GetObject
- s3:PutObject
Resource:
- Fn::Join:
- ""
- - !GetAtt ImporterS3Bucket.Arn
- "/*"
Serverless just released a new version of the npm package (https://github.com/serverless/serverless/releases/tag/v2.5.0) and the plugin started to fail with following error:
Error & stack trace
Type Error ---------------------------------------------
TypeError: this.awsPackagePlugin.validateStatements is not a function
at ServerlessIamPerFunctionPlugin.validateStatements (/home/circleci/repo/node_modules/serverless-iam-roles-per-function/dist/lib/index.js:49:31)
at ServerlessIamPerFunctionPlugin.createRoleForFunction (/home/circleci/repo/node_modules/serverless-iam-roles-per-function/dist/lib/index.js:189:14)
at ServerlessIamPerFunctionPlugin.createRolesPerFunction (/home/circleci/repo/node_modules/serverless-iam-roles-per-function/dist/lib/index.js:284:18)
at /snapshot/serverless/lib/classes/PluginManager.js:510:55
From previous event:
at PluginManager.invoke (/snapshot/serverless/lib/classes/PluginManager.js:510:22)
at /snapshot/serverless/lib/classes/PluginManager.js:545:24
From previous event:
at PluginManager.run (/snapshot/serverless/lib/classes/PluginManager.js:545:8)
at /snapshot/serverless/lib/Serverless.js:168:33
From previous event:
at Serverless.run (/snapshot/serverless/lib/Serverless.js:155:74)
at /snapshot/serverless/scripts/serverless.js:50:26
at processImmediate (internal/timers.js:456:21)
at process.topLevelDomainCallback (domain.js:137:15)
From previous event:
at Object.<anonymous> (/snapshot/serverless/scripts/serverless.js:50:4)
at Module._compile (pkg/prelude/bootstrap.js:1320:22)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1156:10)
at Module.load (internal/modules/cjs/loader.js:984:32)
at Function.Module._load (internal/modules/cjs/loader.js:877:14)
at Module.require (internal/modules/cjs/loader.js:1024:19)
at Module.require (pkg/prelude/bootstrap.js:1225:31)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (/snapshot/serverless/bin/serverless.js:47:1)
at Module._compile (pkg/prelude/bootstrap.js:1320:22)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1156:10)
at Module.load (internal/modules/cjs/loader.js:984:32)
at Function.Module._load (internal/modules/cjs/loader.js:877:14)
at Function.Module.runMain (pkg/prelude/bootstrap.js:1375:12)
at internal/main/run_main_module.js:17:47
I found a PR, which caused this error: serverless/serverless#8297
Basically, the method, which was used to validate the iam statements, was removed from serverless
package at all, so there should be a different way to validate the statements in order to align with the new versions of serverless
.
Hi,
Just a quick feature request - custom role names for each function. The serverless role names generated from the default lambda role seem to have so much in them sometimes when we deploy a longer stage name the build fails :-(. Would be good to be able to shorten them a bit!
Cheers for the plugin, it’s helped us a lot so far...don’t know why it isn’t a core feature of serverless! :)
service: service
provider:
name: aws
runtime: nodejs10.x
tracing:
lambda: true
plugins:
- serverless-iam-roles-per-function
custom:
serverless-iam-roles-per-function:
defaultInherit: true
functions:
a:
handler: handler.a
b:
handler: handler.b
iamRoleStatements:
- Effect: Allow
Action: some:Action
Resource: someResource
function a
will have X-Ray
working as expected, but not function b
Hi,
I found an issue, or at least I got an issue. Let's say my functions are working in us-east-1, and I have a function with this :
iamRoleStatements:
- Effect: "Allow"
Action:
- lambda:InvokeFunction
Resource:
- arn:aws:lambda:us-east-1:###
- arn:aws:lambda:eu-west-1:###
The resources when doing serverless package or deploy, will become :${AWS::Region}, and thus, my IAM ROLE will be able to invoke on Resource :
- arn:aws:lambda:us-east-1:###
- arn:aws:lambda:us-east-1:###
It is then not working properly. How can I deal with this issue ? Do I miss a parameter or something ?
I had to roll back to the iamRoleStatements in my provider and stop using the plugin.
Thanks !
For some reason starting today when I deploy, the -lambdaRole
at the end of the roles is no longer being removed automatically, so many of my functions are hitting the 64 character limit.
I have a feeling it might be because it's showing my environment now as NodeJS 10.10.0 because I haven't changed anything else. The weird thing is my node is set to 8.10.0 in provider
so not exactly sure what's going on.
If there is not exported name with the iam role created the plugin serverless-split-stacks
and serverless-nested -stacks
will failed to create the log stack appart from the api stack
Rather than forcing the IAM role name to be <service-name>-<stage>-<function-name>-<region>-lambdaRole
, can it be defined something like this?
custom:
serverless-iam-roles-per-function:
iamRoleNamePrefix: prefix
iamRoleNameSuffix: suffix
# iam role name becomes `prefix-<function-name>-suffix`
By design the default global role is created to maintain backwards compatibility. If all functions in the project use a per-function role and the default role is not being used by an external resource, then the role is really not needed. This feature will add a plugin option named: skipCreateDefaultRole
. The default for this option is false. If set to true then the global default role of the project will not be created.
Hi,
We started seeing a failure like this in one of our serverless deploys, which installs the latest serverless-iam-roles-per-function
plugin as part of the deploy. The error went away when we pinned back to 1.0.4
, i.e. with sls plugin install -n [email protected]
. Here's the error from the CloudFormation console:
11:42:18 UTC-0400 CREATE_FAILED AWS::IAM::Role DbDashoverflowDashguardIamRoleLambdaExecution ARN arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole is not valid. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: InvalidInput; Request ID: 8777cbd2-...)
Physical ID:Project-prod4-seq-over-guard
Our serverless template looks roughly like this (chunks of the template are redacted, but it seems to be enough to repro the issue):
---
service: 'Monitoring-${env:STACK_PREFIX}'
provider:
name: aws
runtime: python3.7
stage: production
region: ${env:AWS_DEFAULT_REGION}
custom:
pythonRequirements:
fileName: ../../requirements.txt
dockerizePip: non-linux
plugins:
- serverless-iam-roles-per-function
- serverless-python-requirements
functions:
db-overflow-guard:
handler: myfunc.lambda_handler
memorySize: 256
description: production monitoring
timeout: 30
environment:
STACK_PREFIX: '${env:STACK_PREFIX}'
vpc:
subnetIds:
- Fn::ImportValue: !Sub "${env:STACK_PREFIX}-PrivateSubnetOne"
- Fn::ImportValue: !Sub "${env:STACK_PREFIX}-PrivateSubnetTwo"
securityGroupIds:
- Fn::GetAtt: ServerlessSecurityGroup.GroupId
iamRoleStatementsInherit: true
iamRoleStatementsName: ${env:STACK_PREFIX}-seq-over-guard
iamRoleStatements:
- Effect: "Allow"
Action:
- "secretsmanager:GetSecretValue"
Resource:
- !Join
- ':'
- - "arn:aws:secretsmanager"
- !Ref AWS::Region
- !Ref AWS::AccountId
- !Join
- '/'
- - "secret:Project/${env:STACK_PREFIX}"
- "DBPass*"
events:
- schedule: rate(12 hours)
# you can add CloudFormation resource templates here
resources:
Description: Serverless functions for production monitoring
Resources:
ServerlessSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: SG for Lambda, RDS will allow access
VpcId:
Fn::ImportValue: !Sub "${env:STACK_PREFIX}-VPC"
Tags:
- Key: Name
Value: Security Group for Serverless Application
...
@glicht Hello please publish newly merged fixes
Similar to how the managed VPC execution policy is added to a function's role if running in a VPC, a kms:Decrypt
statement should be added automatically to the function specific policy if awsKmsKeyArn
is set.
Tested this both when awsKmsKeyArn
was set within function blocks as well as parent service block. In both cases kms:Decrypt
was not added. To compare, I did see the additional kms statement in the default lambda role created by serverless. To get around this, I enabled inheritance, and added the necessary statement under the provider block. Let me know if you need any more info, thank you for the work on this plugin!
Running serverless 1.30.0
and serverless-iam-roles-per-function 1.0.4
I have the setup of 2 lambdas and separate IAM role statements defined for both, these new roles get generated. What i noticed is there is actually 3 IAM roles generated for the lambdas, one of which i am assuming is the lambda default IAM role that serverless creates. This IAM role is unused in the generated CFT.
Not sure if this can be fixed but thought it was worth pointing out`
Hi 👋 , Serverless Framework core team here!
We're working on the v3 beta version right now. The v3 will include a redesigned CLI output:
You can try the v3 beta with: npm i serverless@pre-3
To help plugins integrate with that new design (and build a great user experience), we've added new APIs for plugins:
Any feedback is appreciated! If you want to update the plugin to use these new APIs, feel free to ping me if you have any questions!
If you don't have time to update the plugin, let me know, we can send a pull request!
(sorry, wanted to be more extensive but on a rush)
It seems using this plugin together with serverless event/sqs will break event/sqs because the function will not receive the required roles to Receive/Delete message:
CloudFormation - CREATE_FAILED - AWS::Lambda::EventSourceMapping - somenameEventSourceMappingSQSSomefn
Serverless: Operation failed!
An error occurred:
somenameEventSourceMappingSQSomefn - The provided execution role does not have permissions to call DeleteMessage on SQS (Service: AWSLambda; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: a4241910-6139-11e9-9650-af67fae496c2).
I got it working again after adding:
iamRoleStatements:
- Effect: 'Allow'
Action:
- 'sqs:*'
Resource: 'arn of the sqs event used in this fn'
to all functions that have
events:
- sqs:
[...]
Unless this issue is specific to SQS event, I'd guess this would happen to any other kind of event that requires special roles that aren't being set anymore because of how this plugin overrides them
Hi,
Not sure if it's an issue or not but I though I would ask anyway. In my case, for some reason, two roles are being created. One if the default role that is created by the serverless platform itself I believe, and the other is the role that I defined in my configuration. Lambda seems to be using the correct role though.
For example this is my serverless config and the role that has been defined is the gmailread-role which is being created successfully as well as it's getting associated with the function as well. However I also do observe, gmailread-default-us-east-1-lambdaRole is also being created, that is not being used by the function and has the policy to create and put log streams.
Is this by design, or is the default role being created by the serverless platform itself or am I missing something ?
In my serverless.yml I have a function that looks like this:
example_function:
handler: handler.doStuff
iamRoleStatementsInherit: true
iamRoleStatements:
- Effect: "Allow"
Action:
- s3:PutObject
Resource: arn:aws:s3:::bucket1/*
- Effect: "Allow"
Action:
- s3:PutObject
Resource: arn:aws:s3:::bucket2/*
events:
- http:
path: doStuff/{id}
method: get
cors: true
request:
parameters:
paths:
id: true
And plugins section like so:
plugins:
- serverless-webpack
- serverless-prune-plugin
- serverless-iam-roles-per-function
After running SLS_DEBUG=* sls deploy
, the output looks like:
Serverless: Invoke webpack:package
Serverless: Package lock found - Using locked versions
Serverless: Packing external modules: source-map-support@^0.5.5, aws-sdk@^2.233.1, babel-runtime@^6.26.0, request@^2.85.0, moment-timezone@^0.5.16, redis@^2.8.0
Serverless: Packaging service...
Type Error ---------------------------------------------
Cannot read property 'Properties' of undefined
For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
Stack Trace --------------------------------------------
TypeError: Cannot read property 'Properties' of undefined
at ServerlessIamPerFunctionPlugin.createRoleForFunction (/Users/patneedham/.../node_modules/serverless-iam-roles-per-function/dist/lib/index.js:146:25)
at ServerlessIamPerFunctionPlugin.createRolesPerFunction (/Users/patneedham/.../node_modules/serverless-iam-roles-per-function/dist/lib/index.js:220:18)
at BbPromise.reduce (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:372:55)
From previous event:
at PluginManager.invoke (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:372:22)
at PluginManager.spawn (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:390:17)
at Deploy.BbPromise.bind.then.then (/usr/local/lib/node_modules/serverless/lib/plugins/deploy/deploy.js:123:50)
From previous event:
at Object.before:deploy:deploy [as hook] (/usr/local/lib/node_modules/serverless/lib/plugins/deploy/deploy.js:113:10)
at BbPromise.reduce (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:372:55)
From previous event:
at PluginManager.invoke (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:372:22)
at PluginManager.run (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:403:17)
at variables.populateService.then (/usr/local/lib/node_modules/serverless/lib/Serverless.js:102:33)
at runCallback (timers.js:757:18)
at tryOnImmediate (timers.js:718:5)
at processImmediate [as _immediateCallback] (timers.js:698:5)
at process.topLevelDomainCallback (domain.js:101:23)
From previous event:
at Serverless.run (/usr/local/lib/node_modules/serverless/lib/Serverless.js:89:74)
at serverless.init.then (/usr/local/lib/node_modules/serverless/bin/serverless:42:50)
at <anonymous>
Get Support --------------------------------------------
Docs: docs.serverless.com
Bugs: github.com/serverless/serverless/issues
Forums: forum.serverless.com
Chat: gitter.im/serverless/serverless
Your Environment Information -----------------------------
OS: darwin
Node Version: 9.6.1
Serverless Version: 1.26.1
Line 151 of dist/lib/index.js
is
functionIamRole.Properties.Policies[0].PolicyDocument.Statement = policyStatements;
functionIamRole
is being defined a few lines before as
const functionIamRole = lodash_1.default.cloneDeep(globalIamRole);
I added some console.log
statements to see the value of globalRoleName
(it is IamRoleLambdaExecution) and the keys inside this.serverless.service.provider.compiledCloudFormationTemplate.Resources
, which is:
[ 'ServerlessDeploymentBucket',
'GetUnderscoreitemUnderscorecurrentUnderscorepriceLogGroup',
'SetUnderscoreitemUnderscorecurrentUnderscorepriceLogGroup',
'GetUnderscorerestaurantUnderscoreitemsLogGroup',
'SetUnderscorerestaurantUnderscoreitemsLogGroup',
'GetUnderscoreitemUnderscorepriceUnderscorehistoryLogGroup',
'SetUnderscoreitemUnderscorepriceUnderscorehistoryLogGroup',
'SaveUnderscorepriceUnderscorehistoriesLogGroup',
'MigrateUnderscorefromUnderscorefirebaseLogGroup',
'GetUnderscoreitemUnderscorecurrentUnderscorepriceLambdaFunction',
'GetUnderscoreitemUnderscorecurrentUnderscorepriceLambdaVersionPJd606YxdqlYrJY7maZxj7odx9UyOqdZBkIjXh2IrQ',
'SetUnderscoreitemUnderscorecurrentUnderscorepriceLambdaFunction',
'SetUnderscoreitemUnderscorecurrentUnderscorepriceLambdaVersionKY2N6rkRD6JWHIz3bi3WJUQg8iuVtEQgnBB0dLHAEx4',
'GetUnderscorerestaurantUnderscoreitemsLambdaFunction',
'GetUnderscorerestaurantUnderscoreitemsLambdaVersioncgZ0uIwf3U6MtYcx0WLUQzerNSpaYsgpZ9veQuhQ',
'SetUnderscorerestaurantUnderscoreitemsLambdaFunction',
'SetUnderscorerestaurantUnderscoreitemsLambdaVersion4sXQxEOWZfrjXBgMK9RycnkkNQWOenqFQq9l8lY',
'GetUnderscoreitemUnderscorepriceUnderscorehistoryLambdaFunction',
'GetUnderscoreitemUnderscorepriceUnderscorehistoryLambdaVersion8nFoEKThFPH9v2SUt9gTb2495K5tRdTPFVGbfK3lWIg',
'SetUnderscoreitemUnderscorepriceUnderscorehistoryLambdaFunction',
'SetUnderscoreitemUnderscorepriceUnderscorehistoryLambdaVersionOvpjQc0zsuXM5heiI5KWmL2ShLq3INL4Bmg69Lw9Qo',
'SaveUnderscorepriceUnderscorehistoriesLambdaFunction',
'SaveUnderscorepriceUnderscorehistoriesLambdaVersion8VqpFN3TuXXebCfp4F1WoIkqBDt1hgh6fyegyLDlO1Q',
'MigrateUnderscorefromUnderscorefirebaseLambdaFunction',
'MigrateUnderscorefromUnderscorefirebaseLambdaVersionTThMQo8dCKgLGj3WhpLka7w0zpSMfBBxvpBhv75WEO8' ]
which explains why globalIamRole
and subsequently functionIamRole
ended up as null
. The question is, why did that property not appear as a key inside the Resources
object? Does the stack trace I provided give any clues as to what might have gone wrong?
I tried adding
custom:
serverless-iam-roles-per-function:
defaultInherit: true
to serverless.yml
but ended up with the same result.
service: multibook-service-${self:custom.clientName}
package:
individually: true # Create an optimized package for our functions
include:
- "../libs/**" # Adds shared extensions
plugins:
- serverless-dynamodb-local # Development
- serverless-offline # Development
- serverless-iam-roles-per-function # Define IAM roles per function
- serverless-deployment-bucket # Create and configure the custom Serverless deployment bucket.
custom: ${file(../serverless.common.yml):custom}
provider:
name: aws
lambdaHashingVersion: 20201221
runtime: nodejs14.x
stage: ${self:custom.stage}
region: ${self:custom.region}
profile: ${self:custom.stages.${self:provider.stage}.profile}
# Deployment Bucket Configuration shared across stacks
# Does not work when importing from serverless.common.yml
deploymentBucket:
name: ${self:custom.artifactsBucketName}
serverSideEncryption: AES256
tags: # Tags that will be added to each of the deployment resources
CLIENT_NAME: ${self:custom.clientName}
stackTags: # Optional CF stack tags
CLIENT_NAME: ${self:custom.clientName}
tracing:
apiGateway: true
lambda: true
environment:
MULTIBOOKS_DYNAMODB_TABLE: ${self:custom.dynamodbTables.MULTIBOOKS_DYNAMODB_TABLE}
USERS_DYNAMODB_TABLE: ${self:custom.dynamodbTables.USERS_DYNAMODB_TABLE}
RELEASES_DYNAMODB_TABLE: ${self:custom.dynamodbTables.RELEASES_DYNAMODB_TABLE}
iamRoleStatements:
- ${file(../serverless.common.yml):lambdaPolicyXRay}
- Effect: Allow
Action:
- dynamodb:Query
Resource: !Sub "arn:aws:dynamodb:${self:provider.region}:${AWS::AccountId}:table/${self:provider.environment.MULTIBOOKS_DYNAMODB_TABLE}/index/*"
functions:
currentUserList:
handler: handlers/currentUser/list.handler
# iamRoleStatementsInherit: true <-- i still have to explicitly declare it to make it inherit
iamRoleStatements:
- Effect: "Allow"
Action:
- dynamodb:GetItem
Resource:
- !Sub "arn:aws:dynamodb:${self:provider.region}:${AWS::AccountId}:table/${self:provider.environment.USERS_DYNAMODB_TABLE}"
- !Sub "arn:aws:dynamodb:${self:provider.region}:${AWS::AccountId}:table/${self:provider.environment.RELEASES_DYNAMODB_TABLE}"
custom:
serverless-iam-roles-per-function: # Not working
defaultInherit: true
"serverless-iam-roles-per-function": "^3.1.0",
serverless --version
Framework Core: 2.25.2
Plugin: 4.4.3
SDK: 2.3.2
Components: 3.7.0
Edit:
provider
and more details to serverless.yml
serverless framework
and plugin versionHello!
I would like to have PermissionsBoundary property so i could limit what the roles are able to create. What do you guys think?
Hi guys,
It seems that you should add the logs:CreateLogGroup permission as in the AWSLambdaBasicExecutionRole policy so that Lambda does not complain about it:
Servless Framework had the same issue: serverless/serverless#6241.
Note that this is not a blocker as Lambda can still write logs in CloudWatch but it might an issue later on?
Serverless starts showing deprecation warning messages:
Serverless: Deprecation warning: Starting with version 3.0.0, following property will be replaced:
"provider.iamRoleStatements" -> "provider.iam.role.statements"
More Info: https://www.serverless.com/framework/docs/deprecations/#PROVIDER_IAM_SETTINGS
Migrating to the new property is not possible, because custom.serverless-iam-roles-per-function.defaultInherit
only looks for provider.iamRoleStatements
.
See https://github.com/functionalone/serverless-iam-roles-per-function/blob/master/src/lib/index.ts#L347
Im trying to enable Lambda Insights. Insights needs CloudWatchLambdaInsightsExecutionRolePolicy
, but it gets overridden even with iamRoleStatementsInherit
flag. defaultInherit
does not work as well.
....
provider: {
name: 'aws',
runtime: 'nodejs12.x',
region: 'eu-west-2',
iamManagedPolicies: ["arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy"],
},
functions: {
getSessions: {
handler: 'build/getSessions.handler',
timeout: 15,
package: {
include: ['build/getSessions*'],
},
events: [
{
httpApi: {
method: 'get',
path: '/sessions',
authorizer: {
name: 'customAuthorizer'
},
},
},
],
iamRoleStatementsInherit: true,
iamRoleStatements: [
{
Effect: 'Allow',
Action: ['ssm:GetParameters*'],
Resource: {
"Fn::Sub":'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${self:custom.stage}/*'
}
},
{
Effect: 'Allow',
Action: ['kms:Decrypt'],
Resource: {
"Fn::Sub":'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/CMK'
}
},
],
layers: [
`arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:14`
]
},
I use this in multiple modules, but for some reason it isn't working in a new module and I can't figure out why. Here's my serverless.yml file
service:
name: ${self:custom.provider.service}-device-notification-handler
plugins:
- serverless-export-env
- serverless-iam-roles-per-function
- serverless-webpack
- serverless-offline
package:
individually: true
exclude:
- node_modules/**
provider:
name: aws
runtime: nodejs12.x
region: ${self:custom.provider.regions.${self:custom.stage}}
profile: ${self:custom.provider.profile}
stage: dev
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
functions:
helloWorld:
handler: src/hello.main
iamRoleStatementsName: hello-world-lambdaRole
iamRoleStatements:
- Effect: "Allow"
Action:
- dynamodb:GetItem
Resource: "*"
And when I run it I get the following error:
An error occurred: IamRoleLambdaExecution - 1 validation error detected: Value 'smartwater-device-notification-handler-dev-ca-central-1-lambdaRole' at 'roleName' failed to satisfy constraint: Member must have length less than or equal to 64
And here's my package.json dependencies:
"serverless": "^1.60.4",
"serverless-iam-roles-per-function": "^2.0.2"
There are:
next
)Given that 3.0.2 and 3.1.0 appear in the changelog and have tags in github I assumed these would be released already, but I might be misunderstanding the intent/flow of the changelog/github tags/npm version?
Please add a way to add tags to the IAM role for the lambda.
Hi,
I ran into the issue after integrating 'serverless-iam-roles-per-function' plugin and I'm moving everything over to per-function roles, but when I run sls deploy I get an error from CloudFormation saying that
ServerlessError: An error occurred: ProcessESDataLoadEventLambdaFunction - The provided execution role does not have permissions to call PutTraceSegments on XRAY (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: 1d48ba9f-4e02-42df-8587-fe4b872d2161).
However, i see CF has below details auto generated.
`***********************************************************
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords"
],
"Resource": [
"*"
]
}
`
`
Below is my lambda function looks like after moving roles per function:
lamdbafuncitonexample:
handler: src/functions/handler
tags: ${self:custom.tags}
description: Process event received from changed sqs queue
iamRoleStatementsName:
Fn::Join:
- '-'
- - ${self:custom.Prefix}
- 'lamdbafuncitonexample'
iamRoleStatements:
- Effect: 'Allow'
Action:
- 'sns:Publish'
Resource: ${self:custom.resources.topic}
- Effect: 'Allow'
Action:
- 'secretsmanager:GetSecretValue'
Resource:
Fn::Join:
- ':'
- - 'arn:aws:secretsmanager'
- Ref: AWS::Region
- Ref: AWS::AccountId
- secret
- 'credential-'
- Effect: 'Allow'
Action:
- 'secretsmanager:GetSecretValue'
Resource:
Fn::Join:
- ':'
- - 'arn:aws:secretsmanager'
- Ref: AWS::Region
- Ref: AWS::AccountId
- secret
- 'credential-**'
events:
- sqs:
arn: ${self:custom.resources.SQS}`
I have the following serverless.yml (snippet)
iam:
role:
name: ${self:provider.stage}-${self:service.name}-default-role
statements:
- Effect: Allow
Action:
- ssm:GetParameter
- ssm:GetParameters
Resource:
- !Sub "arn:aws:ssm:${self:provider.region}:${AWS::AccountId}:parameter/${self:provider.stage}/*"
And when trying to deploy I get:
ERROR: Global Role Name is not in expected format. Got name: "test-rest-ra-gui-apis-default-role"
This used to work up until some time ago (maybe I updated serverless or the plugin inadvertently)
Looking at the source code it's doing:
const roleName = this.serverless.providers.aws.naming.getRoleName();
const fnJoin = roleName['Fn::Join'];
And checking some things on fnJoin
, which puzzles me because I didn't find in the documentation any reference to it
Any clues?
Thanks
I think it would be great if we could preserve the default permissions required to hook the lambda up to the specified event sources. This would reduce config bloat as well as ease migrating from global statements; currently an update with the missing permissions will cause the Lambda's to silently disable.
I'm open to looking into this if I get the opportunity. I'm not sure how much work is involved as I'm not familiar with how serverless composes/exposes these statements on the backend..
All lambdas get a default role associated with stack rather than the custom one per lambda. Copied example code.
Using serverless 2.0.0.
I just tried the plugin and got that error:
Serverless Error ---------------------------------------
Serverless plugin "serverless-iam-roles-per-function" initialization errored: Cannot find module 'serverless/lib/plugins/aws/package/lib/mergeIamTemplates'
Get Support --------------------------------------------
Docs: docs.serverless.com
Bugs: github.com/serverless/serverless/issues
Forums: forum.serverless.com
Chat: gitter.im/serverless/serverless
Your Environment Information -----------------------------
OS: linux
Node Version: 8.4.0
Serverless Version: 1.26.0
I have defined it in my serverless.yml:
plugins:
- serverless-webpack
- serverless-pseudo-parameters
- serverless-iam-roles-per-function
# ...
functions:
api:
handler: lambda.apiHandler
iamRoleStatements:
-
Effect: 'Allow'
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- ec2:CreateNetworkInterface
- ec2:DescribeNetworkInterfaces
- ec2:DeleteNetworkInterface
- sns:Publish
Resource: '*'
Hello,
Any idea if this would conflict with serverless-plugin-split-stacks? I'm getting an error The following resource(s) failed to create: [MyFunctionIamRoleLambdaExecution].
This is using the following:
MyFunction:
handler: index.handler
iamRoleStatements:
- Effect: 'Allow'
Action:
- 'lambda:InvokeFunction'
Resource: '*'
Thank you
I cannot use the intrinsic function to GetAtt of an Output in a nested stack like this:
Resource: Fn::GetAtt: [DynamoDbNestedStack, Outputs.DynamoDbTableUsersExport]
It results in the following error:
incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line...
How can I use correctly the intrinsic functions with this plugin?
Hi there,
I have the following config in Serverless.yml for a lambda:
asyncSyncProductsDb:
handler: functions/asyncSyncProductsDb/asyncSyncProductsDb.main
timeout: 300
memorySize: 2048
events:
//eventbridge event source
iamRoleStatements:
- Effect: Allow
Action:
- ssm:GetParameters
- ses:SendEmail
Resource:
- '*'
Now I want to temporarily disable creation of the log group, in order to later re-enable & recreate it in a nested stack using serverless-plugin-split-stacks
custom config. However when I add disableLogs: true
as per the docs I get an error:
asyncSyncProductsDb:
handler: functions/asyncSyncProductsDb/asyncSyncProductsDb.main
disableLogs: true
timeout: 300
memorySize: 2048
events:
//eventbridge event source
iamRoleStatements:
- Effect: Allow
Action:
- ssm:GetParameters
- ses:SendEmail
Resource:
- '*'
Serverless Error ----------------------------------------
serverless-iam-roles-per-function: ERROR: Function Resource is not in expected format. For function name: asyncSyncProductsDb
The plugin is throwing this error even though my lambda config is fine.
If I comment out the iamRoleStatements
then it works fine and deletes the log group, ostensibly because this plugin does not process the lambda config.
Any ideas on fixes or workarounds? I need to do this to about 30 lambdas :-)
In my serverless.yml file I have two imported functions:
functions:
- ${file(./test.json)}
- ${file(./test.yml)}
Both are identical (different function names) but the function referenced in test.json only gets the global iamRole, while the .yml creates a role as expected.
//// test.json
{
"convert": {
"handler": "test.handler",
"iamRoleStatements:": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": [
"arn:aws:s3:::${cf:S3Stack-${self:custom.stage}.bucket}/*" ]
}
]
}
}
I can't find any logical explanation for this, but would like to hear if this is fixable - i am one of those people who prefer json over yml :)
I'm using the plugin as described, but no role gets created and I can't query my index...
I get no errors
functions:
create-widget:
handler: Moveable.Widget.Settings::Settings.Handler::CreateWidget
package:
artifact: bin/Release/netcoreapp3.1/settings.zip
environment:
SETTINGS_HASH_INDEX_NAME: ${file(../Infrastructure/database.yml):custom.settingsHashIndexName}
events:
- http:
path: widgets
method: post
cors: true
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
Resource:
- 'Fn::Join':
- '/'
-
- 'Fn::ImportValue': ${self:provider.stage}-SettingsTable
- '/index/IX_Hash'
When using the new structure for IAM statements (provider.iam.role.statements
), I'm not seeing those statements cascade down to my function-level IAM roles. If I change my serverless config back to provider.iamRoleStatements
it works. Here are the package versions:
> npm ls | grep serverless
├── @serverless/[email protected]
├─┬ [email protected]
│ ├─┬ @serverless/[email protected]
│ │ ├─┬ @serverless/[email protected]
│ │ ├─┬ @serverless/[email protected]
│ │ │ ├─┬ @serverless/[email protected]
│ │ │ ├── @serverless/[email protected] deduped
│ │ ├─┬ @serverless/[email protected]
│ ├─┬ @serverless/[email protected]
│ │ ├─┬ @serverless/[email protected]
│ │ ├─┬ @serverless/[email protected]
│ │ │ ├─┬ @serverless/[email protected]
│ │ ├── @serverless/[email protected] deduped
│ ├─┬ @serverless/[email protected]
│ │ ├─┬ @serverless/[email protected]
│ │ ├── @serverless/[email protected] deduped
│ │ ├── @serverless/[email protected] deduped
│ ├─┬ @serverless/[email protected]
├─┬ [email protected]
├─┬ [email protected]
├─┬ [email protected]
├── [email protected]
Could you add support for managed polices in a simmilar way to how they are handled at global level.
iamManagedPolicies:
Issue description:
Plugin adds sns:Publish
permission in case if function has onError
definition and doesn't take into account that it might be SQS resource arn
Steps to reproduce:
onError
property mapped to SQS resource:functions:
function_name_here:
handler: functions/function_name_here/index.handler
iamRoleStatementsName: "function_name_here_lambda_role"
iamRoleStatements:
- ${file(../../function_name_here.yml)}
onError:
Fn::GetAtt: [QueueNameDeadLetterQueue, Arn]
Resources:
QueueNameDeadLetterQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: "SomeNameDeadLetterQueue"
sls deploy
Expected result:
No useless permissions should be added
Current result:
Useless permissions added:
{
"Action": [
"sns:Publish"
],
"Resource": "arn:aws:sqs:{region_here}:{accountId_here}:SomeNameDeadLetterQueue",
"Effect": "Allow"
}
Background:
Serverless added support for DQL setup with onError
function property here. However it has some strange concurrency issue described in docs. But still community has some workarounds and moreover, it's hard to reproduce it (that's why it's not fixed yet), so that most people (like me) use it as is without any issues.
TBD:
As possible solution I recommend to delete additional policy definitions in case if onError
property set in function definition.
In case if we want to keep backward compatibility we may add configuration property like addOnErrorPolicy: boolean
.
Looking forward for your comments,
Thanks in advance.
Hello,
Thank you for this great plugin!
I have the following serverless.yml
:
functions:
firstFunction:
handler: functions/firstFunction.handler
secondFunction:
handler: functions/secondFunction.handler
iamRoleStatements:
- Effect: Allow
Action: sns:Publish
Resource: '*'
thirdFunction:
handler: functions/thirdFunction.handler
vpc:
securityGroupIds:
- sg-xxxxxx
subnetIds:
- subnet-xxxx
- subnet-xxxxx
firstFunction
and thirdFunction
get the global role, so they both have VPC policy and permission to write in all logs.
I tried adding iamRoleStatements: []
but it doesn't work due to the early return here https://github.com/functionalone/serverless-iam-roles-per-function/blob/master/src/lib/index.ts#L149.
Any specific reason for this early return in createRoleForFunction
? I took a quick look at the code and it seems that this can be safely removed?
Error: schema is invalid: data.properties['custom'].properties['serverless-iam-roles-per-function'].properties['iamGlobalPermissionsBoundary'] should be object,boolean
function definition
functions:
add_tabs:
handler: handler.add_tabs
description: add tabs to an existing template
iamRoleStatements:
- Effect: 'Allow'
Action:
- ssm:GetParameters
Resource: '*'
using sls framework 1.8.3, plugin v3.1.0
I attempted to fill in this to quell the error, but to no avail.
custom:
serverless-iam-roles-per-function:
iamGlobalPermissionsBoundary: false
Just tried this one a project with some Kinesis functions, and as soon as these Kinesis functions are given per function IAM roles, the functions broke as the new role doesn't have the couple of permissions that the Serverless framework injects.
You can see it in the console as something like this:
PROBLEM: User: arn:aws:sts::xxx:assumed-role/big-mouth-dev-notify-restaurant-us-east-1-lambdaRole/awslambda_783_20180222015150438 is not authorized to perform: kinesis:DescribeStream on resource: arn:aws:kinesis:us-east-1:xxx:stream/order-events
I have tried setting default inherit to true
but no vail.
It looks like the default role has these permissions:
"kinesis:GetRecords",
"kinesis:GetShardIterator",
"kinesis:DescribeStream",
"kinesis:ListStreams"
so I'd have thought inheriting the default role would have done the trick, but unfortunately not :-/
I haven't drilled into the difference in the CF template too much, but it seems that the serverless framework injects additional permissions (above) when it sees functions with Kinesis subscription.
Given:
custom:
kmsKeyArn: "arn:aws:kms:${self:provider.region}:*:alias/my-application-${env:ENVIRONMENT}-kms"
functions:
hello:
handler: handler.hello
events:
- schedule: rate(1 minute)
iamRoleStatements:
- Effect: "Allow"
Action:
- kms:Decrypt
Resource: "${self:custom:kmsKeyArn}"
Results in:
An error occurred: HelloIamRoleLambdaExecution - Syntax errors in policy. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: 13134b80-fd51-11e8-86e9-6f039a192bc0).
But If I use it directly works perfectly:
functions:
hello:
handler: handler.hello
events:
- schedule: rate(1 minute)
iamRoleStatements:
- Effect: "Allow"
Action:
- kms:Decrypt
Resource: "arn:aws:kms:${self:provider.region}:*:alias/my-application-${env:ENVIRONMENT}-kms"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.