Dissecting Serverless Stacks (II)

This content is more than 4 years old and the cloud moves fast so some information may be slightly out of date.

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.

Similar Posts You Might Enjoy

Dissecting Serverless Stacks (IV)

Dissecting Serverless Stacks (IV) After we figured out how to implement a sls command line option to switch between the usual behaviour and a way to conditionally omit IAM in our deployments, we will get deeper into it and build a small hack on how we could hand over all artefacts of our project to somebody who does not even know SLS at all. - by Thomas Heinen

Dissecting Serverless Stacks (III)

Dissecting Serverless Stacks (III) The third post of this series showed how to make IAM statements an external file, so we can deploy that one but still work with the sls command. It still involved commenting out things in the configuration, so this post will show how to solve that issue. - by Thomas Heinen

Dissecting Serverless Stacks (I)

Dissecting Serverless Stacks (I) This post establishes the base for a small series on how to create Serverless based Lambdas which can be deployed in environments without IAM privileges or where the sls command cannot be used at all. - by Thomas Heinen