Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Latest js variable resolution changes #9186

Open
esteveslima opened this issue Mar 27, 2021 · 14 comments
Open

Latest js variable resolution changes #9186

esteveslima opened this issue Mar 27, 2021 · 14 comments
Assignees
Labels

Comments

@esteveslima
Copy link

Hi!

It appears that the latest releases(2.31.0) changed the variables resolution for .js files, no longer recognizing custom parameters from the CLI. This restriction change not mentioned in documentation yet.
Now, for example, when I run "sls print --service foo" the "service" option is no longer received at the "options" parameter, causing my current configuration to break due to the undefined value.

I'd like to know if there's still a way to get those custom CLI options(in serverless configuration "build time") and, in case not, ask for a workaround for this feature if possible(maybe a simple flag in serverless config file root, retrieving the previous functionality). I believe it could be a useful feature for a monorepo structure and important for my use-case.

Thanks very much for your help and time!

@medikoo
Copy link
Contributor

medikoo commented Mar 29, 2021

@esteveslima thanks for report. We're leaning towards recognizing only command defined options, as in future we plan to report with an error unrecognized options, It's to prevent accidental typos to sneak in (many popular CLI tools do same).

Have you considered relying on environment variables instead?

@medikoo
Copy link
Contributor

medikoo commented Mar 29, 2021

Also note, that if you didn't set variablesResolutionMode in your config, nothing should change for you (but deprecation warnings will be shown)

@esteveslima
Copy link
Author

Thanks for the reply!

I want to keep deprecation warnings solved in my projects. Was hoping that there is a better way than running "export service=foo && sls deploy" everytime(maybe can find a better way using npm scripts tho).

Is there a conventional(better) approach to monorepo using the framework?

@medikoo
Copy link
Contributor

medikoo commented Mar 29, 2021

Was hoping that there is a better way than running "export service=foo && sls deploy"

I believe you can run it as simply as:

service=foo sls deploy

It's even shorter than:

sls deploy --service foo

@medikoo
Copy link
Contributor

medikoo commented Mar 29, 2021

Is there a conventional(better) approach to monorepo using the framework?

We're thinking it through, please check: #9095 and please comment if you think we missed something.

@esteveslima
Copy link
Author

Thank you @medikoo! Following this discussion approach, I've managed to rebuild my project to work using npm workspaces with an exclusive package for serverless definitions. This way I can import a bunch of pre built boilerplates and plug into my serverless.js properties(This may be a hacky way to avoid deprecation warning/error, please let me know if this solution may lead into problems in the future).

Besides this, wouldn't be handy having the options(not the custom ones this time) available in case of conditional properties? Having the "stage" in the env variables for example, a function could be conditionally deployed using something like:
...(process.env.stage === 'prod') && { functionX }

@medikoo
Copy link
Contributor

medikoo commented Apr 9, 2021

This may be a hacky way to avoid deprecation warning/error, please let me know if this solution may lead into problems in the future

If there are no deprecations presented, you should be safe :) Otherwise track #9095 for more details on how we plan to coin multi-service repo problem. Very soon we will provide there details

Besides this, wouldn't be handy having the options(not the custom ones this time) available in case of conditional properties?

Can you provide more details? At least I don't fully understand example you've presented

@esteveslima
Copy link
Author

I was trying to find a way to conditionally deploy certain resources(e.g. functions) based on stage. Using js it would be possible using a simple condition, if the options were available at environment variables "before" build.

module.exports = {
	functions: {
		functionA: {
			handler: '...',
			events: [ http: {...} ]
		},
		...(process.env.stage === 'prod') && { functionB: {
			handler: '...',
			events: [ s3: {...} ]
		}}
	}
}

Although this seems to be the easiest way to avoid code replication for "different" stacks, it doesn't look very good. The ideal solution I believe would be something like:

module.exports = {
	functions: {
		functionA: {
			handler: '...',
			events: [ http: {...} ]
		},
		functionB: {
			conditions: {
			     stage: 'prod',
			     ...
			},
			handler: '...',
			events: [ s3: {...} ]
		}
	}
}

I tried to use the 'condition' property, but the deployment is completely blocked instead of removing the single function.

module.exports = {
	resources: {
	    Conditions: {
	      IsProd: {
		'Fn::Equals': [
		  '${self:provider.stage}',
		  'prod',
		],
	      },
	    },
	},
	functions: {
		functionA: {
			handler: '...',
			events: [ http: {...} ]
		},
		functionB: {
			conditions: 'IsProd',
			handler: '...',
			events: [ s3: {...} ]
		}
	}
}

This feature would be useful to be resolved from the framework side(maybe with warnings of unmatched conditions).

@medikoo
Copy link
Contributor

medikoo commented Apr 12, 2021

Technically you can resolve stage by using JS function as:

module.exports = async ({ options, resolveConfigurationProperty }) => {
  let stage = options.stage;
  if (!stage) {
    stage = await resolveConfigurationProperty(['provider', 'stage']);
    if (!stage) stage = 'dev'; // Framework default
  }
  return {
    functions: {
      ...(stage === 'prod') && { functionB: { } }
    }
  }
}

Obviously it's pretty verbose to resolve stage as above, therefore we have a plan to introduce sls:stage #6031 and also we plan to provide access to variable source resolvers with #9112

Would that solve this problem for you?

@esteveslima
Copy link
Author

Yes, this solution works for me, thank you! (in fact it is similar to the previous working setup I had before changing my entire structure).
I was just hoping it would be possible to do this in a more natural way, without relying on intermediary scripts, ending up splitting my stack config in fewer files.

@medikoo
Copy link
Contributor

medikoo commented Apr 22, 2021

I was just hoping it would be possible to do this in a more natural way, without relying on intermediary scripts, ending up splitting my stack config in fewer files.

How about going this route:

custom:
  functions:
    prod:
      prodFunct1:
        handler: ..
      prodFunct2:
        handler: ..
    dev:
      devFunct1:
        handler: ..
      devFunct2:
        handler: ..

functions: ${self:custom.functions${sls:stage}}

And if you want to make just some functions conditional then I believe !merge which we're implementing now (#8037) will help:

functions: !merge
  - anyStageFunc1:
      handler: ...
    anyStageFunc2:
      handler: ...
  - ${self:custom.functions${sls:stage}}

@rdsedmundo
Copy link
Contributor

rdsedmundo commented May 13, 2021

@medikoo somewhat related to this issue, I think it's still useful to pass the serverless object downstream. I was wanting to access serverless.cli.consoleLog for emitting a warn on my file resolver and on the new mode we don't have access to it anymore.

@medikoo
Copy link
Contributor

medikoo commented May 13, 2021

I was wanting to access serverless.cli.consoleLog

@rdsedmundo great thanks for input. For that simply use @serverless/utils/log. With #1720 it'll be additionally improved as it'll provide log levels and eventual custom namespaces

@medikoo
Copy link
Contributor

medikoo commented Aug 10, 2021

@esteveslima We're discussing support for arbitrary CLI options here: #9817 Any feedback is highly welcome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants