Upgrade to Pro — share decks privately, control downloads, hide ads and more …

From 1 to 101 Lambda Functions in Production: Evolving a Serverless Architecture - Node Congress 2021

From 1 to 101 Lambda Functions in Production: Evolving a Serverless Architecture - Node Congress 2021

Building a serverless function or an API is easy. However, things get a bit more complicated as your application grows. What works for a few functions often don't work for hundreds of functions. As your application grows, you'll need to evolve your architecture, deployment, monitoring, and many other things. This talk is a case study of an evolution of the serverless startup's architecture. We started with a single Lambda function in early 2018 and evolved our application through multiple stages and architectures. At the moment application uses GraphQL and more than 100 Lambda functions and serves millions of requests. We faced and solved many issues during the last three years, learned many things, and managed to keep our infrastructure costs low.

Slobodan Stojanović

February 19, 2021
Tweet

More Decks by Slobodan Stojanović

Other Decks in Programming

Transcript

  1. In 2016 we decided to build a leave tracking system

    To solve our own leave tracking problem
  2. In 2016 we decided to build a leave tracking system

    2017 To solve our own leave tracking problem
  3. In 2016 we decided to build a leave tracking system

    2017 2018 To solve our own leave tracking problem
  4. The idea was simple: - track leave requests and number

    of remaining days - use some SSO, so we do not n!d to remember more passwords - connect to Slack so that we can have the info in Slack - connect to the calendar so we can subscribe to events
  5. - startups - sma" companies - schools - non-profits -

    teams from enterprises - government organizations - churches
  6. Slobodan Stojanović CTO @ Cloud Horizon & CTO @ Vacation

    Tracker co-author of Serverless Applications with Node.js book AWS Serverless Hero https://slobodan.me
  7. s e r v e r l e s s

    low xpensive
  8. s e r v e r l e s s

    low xpensive endor lock-in
  9. s e r v e r l e s s

    low xpensive endor lock-in
  10. Serverless because: - Sma" team without devops experience - AUTO

    SCALABLE - Cheap - Fast to build a prototype - Secure
  11. - Quick and independent deployments - Easy to understand and

    maintain - Easy to onboard new people - Cheap Benefits:
  12. - Everything is in IaaC CloudFormation - Replaced Node.js server

    with serverless services - Added TypeScript - Replaced MongoDB with DynamoDB Things we changed:
  13. - Storing state not events - Wasting time on less

    important things - Hard to onboard new developers - Many new services Downsides:
  14. - Storing state not events - Wasting time on less

    important things - Hard to onboard new developers - Many new services - Developers don't like YAML :) Downsides:
  15. - Ana created a location and moved John and Mike

    - Ana assigned Mike as an approver - Ana assigned a leave policy (20 PTO days per year) - John requested a leave, Ana approved - Ro"over, some unused days were transferred to the next year - Ana changed John's working w!k - Mike added some past leaves for John - Alex transferred John to another location with different policy - …
  16. - Fu"y Managed GraphQL - Less code - Better control

    - A" benefits from the previous architecture - Monorepo Benefits:
  17. Current team - 4 developers (a" fu" stack, one new)

    - 1 Marketing - 1 Customer support - 1 Product manager - Some fr!lance support (marketing + design)
  18. @slobodan_ describe('DynamoDB repository', () => { describe('unit', () => {

    ... }) describe('integration', () => { beforeAll(() => { // Create test DB }) afterAll(() => { // Destroy test DB }) // Tests }) })
  19. @slobodan_ beforeAll(async () => { const params = { ...

    } await dynamoDb.createTable(params).promise() await dynamoDb.waitFor('tableExists', { TableName: tableName }).promise() })
  20. @slobodan_ afterAll(async () => { await dynamoDb.deleteTable({ TableName: tableName }).promise()

    await dynamoDb.waitFor('tableNotExists', { TableName: tableName }).promise() })
  21. @slobodan_ • Evolve your architecture with your product • Pick

    a good architecture, it helps you to keep your migration and onboarding costs low • Think about onboarding new team members • Hexagonal architecture is a nice fit for serverless apps • CQRS is also A nice fit for serverless apps and excellent fit for Vacation Tracker • Test your integrations (and app in general) • Testing is not enough, you'll need monitoring and error tracking