serverless: BREAKING - [1.3.0] IAM role name is to long if service + stage is more than 37 characters

This is a Bug Report

Description

  • What went wrong?

Deployment failed due to having an IAM role that was to long (over 64 characters):

sls deploy                    
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3 (274 B)...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.......Serverless: Deployment failed!
 
  Serverless Error ---------------------------------------
 
     An error occurred while provisioning your stack: IamRoleLambdaExecution
     - 1 validation error detected: Value 'this-string-is-one-character-over-stage-ap-southeast-2-lambdaRole'
     at 'roleName' failed to satisfy constraint: Member must
     have length less than or equal to 64.
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
 
  Your Environment Information -----------------------------
     OS:                 darwin
     Node Version:       6.9.1
     Serverless Version: 1.3.0
 
  • What did you expect should have happened?

Should have deployed successfully. v1.2.1 still deploys successfully with a role name of this-string-is-one-characte-IamRoleLambdaExecution-123456ABCDEFG

I don’t know if going back to what it was is the answer (I’m not sure what the purpose behind the changes was) but that be sufficient for me.

  • What was the config you used?
service: this-string-is-one-character-over
provider:
  name: aws
  runtime: nodejs4.3
  region: ap-southeast-2
  stage: stage
functions:
  'helloworld':
    events:
      - http: GET helloworld
    handler: handler.handler
  • What stacktrace or error message from your provider did you see?

An error occurred while provisioning your stack: IamRoleLambdaExecution - 1 validation error detected: Value ‘this-string-is-one-character-over-stage-ap-southeast-2-lambdaRole’ at ‘roleName’ failed to satisfy constraint: Member must have length less than or equal to 64.

Similar or dependent issues:

N/A

Additional Data

  • Serverless Framework Version you’re using: v1.3.0
  • Operating System: darwin
  • Stack Trace: N/A
  • Provider Error messages:

An error occurred while provisioning your stack: IamRoleLambdaExecution - 1 validation error detected: Value ‘this-string-is-one-character-over-stage-ap-southeast-2-lambdaRole’ at ‘roleName’ failed to satisfy constraint: Member must have length less than or equal to 64.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 17
  • Comments: 21 (8 by maintainers)

Most upvoted comments

Our solution was to create a role in IAM first before deployment and then add that role to the serverless.yml:

service: really-long-service-name-that-will-break-sls-deploy
provider:
  name: aws
  runtime: nodejs4.3
  region: ap-southeast-2
  stage: prod
  role: 'arn:aws:iam::123456789012:role/name-of-role'

Same issue 😦 Letting specify RoleName would be awesome, similar to stackName and name of the function

Is it possible to just get the possibility to override it instead? Using the same cloud formation syntax, something like :

    RoleName: my-custom-role-name
    - Effect: "Allow"
      Action:
        - ssm:Describe*
        - ssm:Get*
        - ssm:List*```

We’re hitting this issue as we’re doing branch deploys so the stage names varies in length. Is there any (easy) way to override the generated role name? I’d really like to avoid adding the custom role definition etc.?

Just hit on this issue ):

If you are going to revisit, then why not keep the issue open?

Maybe in v2 we can have naming strategies like using small hash algorithms to still keep predictability and whatnot.

I am facing a similar issue with functionNames:

ServerlessError: An error occurred: UpdateCustomerProjectDefaultPaymentSourceLambdaFunction - 1 validation error detected: Value 'biggggproject-billing-staging-updateCustomerProjectDefaultPaymentSource' at 'functionName' failed to satisfy constraint: Member must have length less than or equal to 64 (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException;

My function name is: updateCustomerProjectDefaultPaymentSource. I solved using a short name.

Is there a way to validate that thing before deployment? Could be in serverless deploy --noDeploy command

Here’s a workaround solution, similar to the idea of manually creating an IAM role suggested by @mymattcarroll . You can have the resources section of your serverless template create the role, then reference that role in your function, like this:

functions:
  my-func:
    handler: foo.lambda_handler
    role: MyRole
    ...

resources:
  Resources:
    MyRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: "hooray-short-role-name"
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
              Action: sts:AssumeRole
        Policies:
          - PolicyName: my-role-base-policy
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow
                  Action:
                    - "logs:CreateLogStream"
                    - "logs:CreateLogGroup"
                    - "logs:PutLogEvents"
                    - "logs:PutRetentionPolicy"
                    - "cloudwatch:PutMetricData"
                  Resource: "*"
                - Effect: "Allow"
                  Action:
                    - "ec2:CreateNetworkInterface"
                    - "ec2:DescribeNetworkInterfaces"
                    - "ec2:DeleteNetworkInterface"
                  Resource: "*"
                - Effect: "Allow"
                  Action:
                    - "s3:PutObject"
                  Resource: !Join
                    - ""
                    - - "arn:aws:s3:::"
                      - !Ref ServerlessDeploymentBucket

The tricky part is getting all the permissions that Serverless would normally be creating for you automatically - above are basic CloudWatch logging perms, plus the ec2:CreateNetworkInterface etc. permissions you need if your Lambda is tied to a VPC (i.e. has the vpc: property defined) .

We’re hitting the same issue here:

An error occurred while provisioning your stack: IamRoleLambdaExecution
     - 1 validation error detected: Value 'bandlab-captain-hook-featureupgradeserv-ap-northeast-1-lambdaRole'
     at 'roleName' failed to satisfy constraint: Member must
     have length less than or equal to 64.

We’re doing feature branch deployments (😊) which could lead/will to longer stage names.

But the problem relies within the RoleName which is optional. @pmuens If I’m not mistaken, this should not impact logical resource ids.

https://github.com/functionalone/serverless-iam-roles-per-function Serverless Plugin for easily defining IAM roles per function via the use of iamRoleStatements at the function level.

Sometimes, we need to rely upon predictable RoleName values. In particular, I need to rely on them in order to give cross-account rights to lambdas within creating a circular deployment dependency.

It’s nasty but with a static name, I:

  1. deploy the service offering a resource and a role to access that resource (explicitly declared so that I can use RoleName)
  2. deploy a service with a lambda that will use that resource and its role (explicitly declared so that I can use RoleName)
  3. deploy an update to the first service to provide a trust relationship between the first service’s role and the second service’s role

If the roles are given new names during each deploy this would be impossible. Note there is more to it (such as Fn::ImportValueing the ARNs for use in TemporaryCredentials) but that’s the core of the use case. There are also risks with using RoleName as documented but we can deal with those too.

I was considering writing up a separate issue. Does that seem appropriate or does this concern fit here?

Resources:
  Logical ID:
    Type: Resource type
    Properties:
      Set of properties

In our case the Logic Resource Id is IamRoleLambdaExecution.

But this will still be a breaking change, right? Because the value will be generated by AWS if we leave this blank and people might rely on the predictable value…

You are right that it would be a problem if people would rely on a predictable RoleName.

Options would be:

  1. Length checks on service name + stage
  2. Deprecation warning for next release(s)

Personally I would go for option two as I don’t want to deal with stack, service and/or stage name length validations.

The idea of having such a name is predictability. We designed the resource logical ids in a way that you as a framework user can overwrite / modify them with the help of the resources section which gives you the full power of doing everything you want to do (basically everything which can be done with CloudFormation can also be done with the framework).