serverless: Unable to deploy a packaged service (This command can only be run in a Serverless service directory)

This is a Bug Report

Description

  • What went wrong? I have created a vanilla aws-nodejs service. Then packaged and tried to deploy the artifacts outwith the source folder.

  • What did you expect should have happened? The stack should have been deployed to AWS

  • What was the config you used?

These are the steps to reproduce the issue from scratch

serverless create --template aws-nodejs --path hello-world
cd hello-world
serverless package --package artifacts
cd ..
serverless deploy --package hello-world/artifacts

The following error shows

  This command can only be run in a Serverless service directory
  • What stacktrace or error message from your provider did you see?
Error: This command can only be run in a Serverless service directory
    at getServerlessConfigFile.then (/usr/local/lib/node_modules/serverless/lib/plugins/lib/validate.js:20:23)
From previous event:
    at Deploy.validate (/usr/local/lib/node_modules/serverless/lib/plugins/lib/validate.js:12:51)

I’ve looked at the source file in the stack trace gerServerlessConfigFile.js

and it seems to be looking for one of the standard config files

const jsonPath = path.join(servicePath, 'serverless.json');
  const ymlPath = path.join(servicePath, 'serverless.yml');
  const yamlPath = path.join(servicePath, 'serverless.yaml');
  const jsPath = path.join(servicePath, 'serverless.js');

  return BbPromise.props({
    json: fileExists(jsonPath),
    yml: fileExists(ymlPath),
    yaml: fileExists(yamlPath),
    js: fileExists(jsPath),

If I understand this correctly, the point of generating a package was not to rely on having access to the serverless config in source. So I’d say that there is something with the way the deploy --package command

Similar or dependent issues:

Additional Data

  • Serverless Framework Version you’re using: 1.26.0
  • Operating System: MacOs and Linux

thanks very much,

Jaume

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 3
  • Comments: 21 (3 by maintainers)

Commits related to this issue

Most upvoted comments

Fair enough, but there’s something that I’m not fully understanding here. I’ve come across this issue as I was configuring my CD pipelines.

When I submit my serverless service to a git repo, I have a build pipeline that creates an output folder. This output folder is then stored in my artifacts repository, as an immutable bundle.

The release pipeline is then automatically triggered, retrieves the artifact, and deploys its contents to a specific environment.

As a temporary workaround, I am adding the serverless.yml to my output folder and that deploys fine. However, it seems that this serverless.yml is being used to re-generate the cloudformation files. If that’s the case, this behaviour would break the “immutability” of the artifact.

All summed up, is that my expectation was that the package command would indeed create a package, with all the resources that are required for an independent deployment.

If the existence of the serverless.yml doesn’t re-generate the CF config, then I’d suggest that the package command should also copy the config. (just like I do with my workaround)

Otherwise, if the config file does regenerate the CF files, it means that we are ignoring the ones that were already available package. So the deploy --package path-to-folder command should be then amended to execute the CF stack directly.

Am I making sense at all?

Running into this here as well. The desire is to create a universal/immutable package that can then be versioned and appropriately sent out vs the reality that each stage effectively is a mini pipeline unto itself (I’m rebuilding each time). Obviously workable, but less than ideal.

Could you then accept a feature request to make generated packages immutable? IMO the current implementation breaks one of the core tenets of Continuous Delivery, by having to regenerate the CF files when performing a release.

Essentially, the task would need the following:

  • To include in the package output all source code and its required dependencies
  • Make the deploy command skip any build/generation phase and deploy the CF directly to the provider.

Thanks

For what it is worth, our workaround was switching to SAM. 🤷

@ahmed-abdulmoniem There is a suggested workaround from @bishwash-devops on Medium, but even that requires a complete npm environment with serverless and all plugins installed. It seems like there needs to be a serious conversation of hardening serverless for CI/CD pipelines that is ongoing.

@jsancho the root problem of your deploy invocation here is, that is must be executed with a CWD set to the service directory. That’s why it bails out with This command can only be run in a Serverless service directory. This behavior is unrelated to the package/deploy but is a requirement of Serverless itself. The CWD for the Serverless invocation has to be the directory where your serverless.yml is located.

It seems like there needs to be a serious conversation of hardening serverless for CI/CD pipelines that is ongoing.

I couldn’t agree more with you @Lanakire .

It was almost a year ago that I reported this issue.

I’m currently using the following workarounds

  • add serverless.yml to the artifact produced by sls package
  • add commands to install sls plugins that are required at deploy time, such as serverless-iam-roles-per-function
  • introduce the sls deploy --force flag because sometimes deployments are unexpectedly skipped

I have also been recently disappointed that all our CD deployments to AWS lambda broke after upgrading to latest version of the framework. The issue has been that sls package is now creating a zip file, whereas it used to simply create a folder that I then packaged myself with the workarounds above.

Ideally, I would have preferred to keep backwards compatibility, or failing that, to be able to use a flag to keep the old behaviour.

As much as a I appreciate that the framework is pushing forward with new features, such as coming out with support for WebSockets straight after the re:Invent announcements.

It is a tad disappointing to not see an interest in getting some more of the basics right. This is my personal take, but I cannot possibly think of a fast-moving and reliable development effort these days without first-class support for CI/CD practices.

I’d be more than happy to discuss this further and help out as much as I possibly can.

@defaultbr I couldn’t agree with you on deploy command reading yml file from zip. Deploy simply reads serverless.yml in that folder where you run deploy command. So you need to extract the zip and run deploy command inside the extracted directory