Search code examples
amazon-web-serviceslambdaserverless

Disable sls plugin on production (different plugins per stage?)


I've got a problem with serverless-offline plugin. I want it to be only accessible when developing locally (dev stage), but not on any other stage

My serverless.yml looks like this:

service: foo
provider:
  # ...
  stage: dev

plugins:
  - serverless-offline

custom:
  stage: "${opt:stage, self:provider.stage}"
  # ...

And it works fine (on my local machine)

I've tried this solution (passing plugins as custom variables), but it doesn't work

service: foo
provider:
  # ...
  stage: dev

custom:
  stage: "${opt:stage, self:provider.stage}"
  plugins:
    dev:
      - serverless-offline
  # ...

plugins: ${self:custom.plugins.${self:custom.stage}}

When running sls offline start it gives me an error Serverless command "offline" not found


I've included serverless-offline as devDependencies (package.json) - on production when plugin is included in serverless.yml it gives an error Serverless command "offline" not found

How to solve this kind of problem (now I have to comment it out before deploy)?


Solution

  • https://forum.serverless.com/t/separate-plugins-for-different-environments/2043/7 states that you cannot make plugins work dynamically.

    Plugins are loaded before the serverless.yml is parsed, so you can't have dynamic variables that include or exclude plugins based on stage.

    I ended up writing a small script to remove the plugins property from the configuration file. Our configuration is in JSON, not YAML, but you can use the yamljs package to parse and write YAML files. That way you can keep the configuration file intact in your version control system, and only have it modified during build time.

    It's not elegant because it deletes all the plugins instead of a specific one, but it works. It's also easy to adapt if you just need to remove a specific plugin.

    I've put this code in a file called remove-serverless-offline.js.

    const jsonfile = require('jsonfile');
    const file = './serverless.json';
    jsonfile.readFile(file, function(err, obj){
    
      if(!obj.hasOwnProperty('plugins')){
    
        console.log('serverless.json: could not find serverless-offline in plugin list.');
        return;
      }
    
      delete obj.plugins;
    
      jsonfile.writeFile(file, obj, {spaces: 4}, function(err){
    
        console.error(err);
      });
    
      console.log('serverless.json: removed serverless-offline from plugin list.')
    });
    

    In my package.json under scripts, I've added this:

    "remove-serverless-offline": "node remove-serverless-offline.js",
    

    In the buildspec.yml, it's then a matter of adding this line to the pre_build commands.

    - npm run remove-serverless-offline