serverless / serverless-azure-functions

Serverless Azure Functions Plugin – Add Azure Functions support to the Serverless Framework
MIT License
266 stars 162 forks source link

Complete system declaration in serverless.yml #446

Closed erikerikson closed 4 years ago

erikerikson commented 4 years ago

This is a Feature Proposal

This may not be a feature request. Apologies in advance if it is not (please provide links to knowledge).

TL;DR: allow the declaration of arbitrary Azure resource types in the serverless.yml

I am transplanting my brain to Azure, having used Serverless in AWS primarily to deploy a complete declaration of the intended system resources in my cloud declaratively and succinctly using the advantages that the framework brings to the table (particularly the variable system). This avoids a lot of duplication and engineer overhead/management waste, synchronization, and confusion. It appears this is not currently supported but it would be very valuable if it were.

Description

Please add support for declaring arbitrary ARM resources in serverless.yml files.

Complete system declaration using the Serverless Framework. This provides a richer variable capability and a more friendly, consistent developer experience. The end result is the distillation of the system structure and bringing that to the forefront of engineer attention thus reducing cognitive load and the noise filtering requirements on your customers.

A minor example, your docs mention the following:

provider:
  stage: dev
  region: westus
  resourceGroup: myResourceGroup

You ask what happens if the same group is deployed to multiple stages and or regions. This isn't a concern if one follows framework best practices and you declare this as follows:

provider:
  stage: ${opts:stage, env:stage, 'dev'}
  region: ${opts:region, env:region, 'westus'}
  resourceGroup: ${self:provider.stage}-${self:provider.region}-myResourceGroup

Perhaps a name length issue arises but that is a solvable problem. This makes the knowledge explicit and enables individual engineers to deploy complete and nearly identical copies of production.

Example projects declaring more resources: https://github.com/serverless/examples/blob/master/aws-node-typescript-rest-api-with-dynamodb/serverless.yml https://github.com/serverless/examples/blob/master/aws-node-graphql-and-rds/serverless.yml or the more complex: https://github.com/Nordstrom/hello-retail

Note that particularly in the last project there was the opportunity to define shared configuration files, generate resource names according to consistent conventions, and consistently reference resources defined in separately deployable services. The services can be deployed identically in different regions and stages/environments and even deal with different versions of the same deployment in one region & stage to facilitate multi-version support.

service: my-service
provider:
  name: azure
...

plugins:
  - serverless-azure-functions

...
resources: 
 - type: "Microsoft.DocumentDB/databaseAccounts"
   apiVersion: "2020-03-01"
   name: ${env:accountName}
   location: ${env:location}
   properties: 
    enableFreeTier: true
    databaseAccountOfferType: Standard
    consistencyPolicy: 
     defaultConsistencyLevel: Session
 - type: "Microsoft.DocumentDB/databaseAccounts/sqlDatabases"
   apiVersion: "2020-03-01"
   name: ${env:accountName}/${env:databaseName}
   dependsOn: 
    - "[resourceId('Microsoft.DocumentDB/databaseAccounts', ${env:accountName}]"
   properties: 
    resource: 
     id: ${env:databaseName}
    options: 
     throughput: 400

I would suggest taking a look at the use of resources in the above links as a place for arbitrary template content. Using the array of objects convention already used in your templates seems appropriate.

Similar or dependent issues:

tbarlow12 commented 4 years ago

@erikerikson thanks for posting. The declaration you describe sounds an awful lot like an ARM template. The plugin does allow for the declaration of a custom ARM template like so:

...
provider:
  ...
  armTemplate:
    file: myTemplate.json

The file path is relative to the root path of your project.

erikerikson commented 4 years ago

Oh, perfect. That wasn't on https://www.serverless.com/framework/docs/providers/azure/guide/serverless.yml/.

Sorry for the noise and thank you for the tip!

tbarlow12 commented 4 years ago

@erikerikson no noise at all! Thanks for the callout. One thing that we are definitely lacking on is documentation...

erikerikson commented 4 years ago

Sorry, I'm looking at the code now in armService and it seems that the template content can only be provided as a separate ARM Template file as opposed to in the serverless.yml. Is that the current state of things?

erikerikson commented 4 years ago

If you would like to open this back up, I'm happy to add to the Azure serverless.yml docs.