Dissecting Serverless Stacks (II)

Thumbnail

Dissecting Serverless Stacks (II)

With the output of the last post of this series, we established the base to be able to deliver a Serverless application independent of its needed IAM privileges. So let’s see how this will work out.

Last time, we just converted IAM statements from neat Serverless YAML syntax into the beloved bulky CloudFormation style. The goal or this week is to extract this into something that can be deployed independently.

Externalizing IAM

Serverless offers the possibility to use contents of files, either in a variable style of ${file(../config.json):attribute} or as a whole file. So let’s do the latter in our serverless.yml

service: fancy

provider:
  name: aws
  runtime: ruby2.5
  region: eu-west-1

package:
  exclude:
    - package*.json
    - node_modules/**

functions:
  fancy:
    description: Our fancy example Lambda
    handler: src/handler.main
    role: fancyRole
    
resources:
  - ${file(iam.yml)}

Simply putting the whole contents into this new file iam.yml will then work, just as the previous solution. We will have to do two small adjustments though: First off, we want to deploy the IAM part independently, so we cannot just reference the new role by role: fancyRole which only works within the same file. To decouple this, we already gave the role a fixed name in our last post (which usually asks for trouble on updates). Luckily, we can reference a role via its ARN as well. As we will need some CloudFormation variables for this and the serverless variable syntax produces conflicts, I like using the serverless-pseudo-parameters plugin for this. After including it, we can use ${} for serverless and #{} for AWS-type replacements.

# ... unchanged parts above ...

plugins:
  - serverless-pseudo-parameters

functions:
  fancy:
    description: Our fancy example Lambda
    handler: src/handler.main
    role: arn:aws:iam::#{AWS::AccountId}:role/fancyRole

resources:
  - ${file(iam.yml)}
  - Description: ${self:functions.fancy.description}

One final point in the snippet above is that the Description of our main SLS stack would be overwritten by any inside the potentially independent IAM stack. That’s the reason for the second resources statement, which just pulls in the Lambda description again. This kind of lookup syntax works across your whole serverless.yml configuration.

This way, we have a really independent IAM stack. But while we can deploy the IAM one on its own, we cannot use sls deploy later on because it will still include IAM. Basically, we would need to comment out that resources part and then could go ahead in our usual development cycle.

In the next post, I will show how we can create a user-defined flag, so we can omit the IAM sub-stack on demand.