Split-Up / Include / Reference serverless.yml file?

The best way to structure a large project is with an API per functionality.

/users
/products
/payments
etc.

You will end up getting long deploy times if you do not structure in this way and you will end up hitting a hard limit of 200 resources per Cloudformation template.

Good luck

@Franky you can reference smaller yaml files with the ${file} variables https://serverless.com/framework/docs/providers/aws/guide/variables/#reference-variables-in-other-files

1 Like

@DavidWells thanks for the hint, i did overlook this little detail in the docs.

This doesn’t really answer the question. Yes, you can use ${file} to reference variables, but what about entire blocks of CloudFormation resources? E.g.:

resources:
  Resources:
    ${include(./database.yml)}
    ${include(./vpc.yml)}
2 Likes

yeah the ${file(./path/to/file.yml} can do exactly what you mention

1 Like

It doesn’t seem to work like this, unfortunately:

serverless.yml

service:
  name: pow

provider:
  name: aws
  runtime: nodejs8.10

resources:
  Resources:
    ${file(./part1.yml)}
    ${file(./part2.yml)}

part1.yml

Test1:
  Type: AWS::S3::Bucket
  Properties:
    BucketName: lkawjef-aa11

part2.yml

Test2:
  Type: AWS::S3::Bucket
  Properties:
    BucketName: lkawjef-aaz7zzz

Ah right right right. I remember now.

I was using serverless.js and this package https://github.com/blackflux/yaml-boost#deep-merge to deep merge them.

Here was the usage example https://github.com/blackflux/lambda-monitor/blob/master/serverless.js

Huh. I was kinda hoping for a built-in solution… too bad Serverless doesn’t have it.

I could also go this route which isn’t perfect, but better than what I have now:

    ### AppSync resolvers ###
    GetTrackResolver:
      Type: AWS::AppSync::Resolver
      Properties: ${file(./resolver-resources/get-track.yml)}
    GetTracksResolver:
      Type: AWS::AppSync::Resolver
      Properties: ${file(./resolver-resources/get-tracks.yml)}

Serverless variable refs want to be used in colon pairs, not free-floating in the middle of the YAML file. :wink:

@ffxsam check out https://github.com/Back9digital/b9-teesheet/blob/2de85a0cfd9d02dd848f779e09102c8cdd74e88d/serverless.yml#L162-L201

Whoa! Thanks, I’ll give this a shot when I get a chance!

I ran into this problem as well. The key here seems to be dropping the includes under “resources” (lowercase) starting each included file with “Resources” (uppercase):

serverless.yml

[ ... stuff ... ]

resources:
  - ${file(./dynamo.yml)}
  - ${file(./roles.yml)}

dynamo.yml

Resources:
  DynamoTableOne:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        [ ... stuff ... ]
  DynamoTableTwo:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        [ ... stuff ... ]

roles.yml

Resources:
  MyRole:
    Type: AWS::IAM::Role
    Properties:
        [ ... stuff ... ]
  MyOtherRole:
    Type: AWS::IAM::Role
    Properties:
        [ ... stuff ... ]
4 Likes

@DavidWells So I came back to this thread to look again at what you did that elicited a “whoa!” but it’s gone now. Any chance of throwing something into pastebin so it lives forever?

@cameroncf I’ll give this a try too, thanks!

@ffsam checkout https://github.com/AnomalyInnovations/serverless-stack-demo-api/blob/master/serverless.yml#L128-L137

and there tutorial series https://serverless-stack.com/

Got it, thanks! It’s essentially the same approach Cameron used.

Hello everybody -
Just willing to collaborate, Mr. @cameroncf approach worked for me.

I had a similar approach to setup the [ iamRoleStatements ] in a well organized and clean manner. Please see next the serverless.yml file lines:
iamRoleStatements:

  • ${file(dynamo_roles/i-am-role-TABLENAME-table.yml)}

  • ${file(dynamo_roles/i-am-role-TABLENAME-table.yml)}

and next a sample role in it’s yml file [ i-am-role-TABLENAME-table.yml ]
Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
- dynamodb:DescribeTable
Resource:
- “RESOURCE ARN USING REGION {opt:region, self:provider.region} and env variables {self:provider.environment.DYNAMODB_TABLE_VEHICLE_TYPE}”

@hamletrp @Franky
My idea is to use an external way to create a compiled YAML file
created by the inclusion of $include tag
try this https://github.com/javanile/yamlinc

@Franky @DavidWells
I had similar issues recently mostly when dealing with monorepo.
You can try plugin I recently published: https://github.com/KrysKruk/serverless-import-config-plugin .
It just import whole yaml files.

1 Like

Hi, It gives bad indentation of a mapping entryYAML where - ${file(./dynamo.xml)} with pointing at -

Hi. I had the same issue and this works for me.

serverless.yml

service:
  name: pow

provider:
  name: aws
  runtime: nodejs8.10

resources:
    ${file(./main-config.yml)}

main-config.yml

 - ${file(./part1.yml)}
 - ${file(./part2.yml)}
....

part1.yml

Resources:
  Test1:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: lkawjef-aa11

part2.yml

Resources:
  Test2:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: lkawjef-aaz7zzz