How to create multiple stages in serverless framwork - serverless-framework

i'm trying yo create multiple stages in serverless with no success.
Here is my serverless.yml:
service: some-cache-updater
provider:
name: aws
runtime: nodejs8.10
stage: dev
functions:
scheduledUpdater:
handler: handler.scheduledUpdater
timeout: 120
What i wish to add is a prod stage with a different timeout.
Can i do it in the same yml?
Any way an example or a reference will be helpful... thanks.

Use Serverless' $self reference interpolation which can include further interpolation.
Define a custom variable where necessary. You can also use a default value if the variable doesn't exist.
Example:
service: some-cache-updater
custom:
functimeout:
prod: 120
uat: 60
provider:
name: aws
runtime: nodejs8.10
stage: ${opt:stage, 'dev'}
functions:
scheduledUpdater:
handler: handler.scheduledUpdater
# Lookup stage key from custom.functimeout. If it doesn't exist
# default to 10
timeout: ${self:custom.functimeout.${self:provider.stage}, '10'}
Then, when you deploy you can pass the --stage prod or --stage uat argument. In this example, no setting the stage will default to dev

serverless.yml:
...
provider:
stage: ${opt:stage, 'dev'}
...
Command line:
sls deploy --stage prod
${opt:stage, 'dev'} takes the value passed from command line --stage option. In this case prod. If no option is passed dev is taken as default.
More info here:
https://serverless.com/framework/docs/providers/aws/guide/variables/#recursively-reference-properties

Related

Use pool name as variable from variable group for deployment task

This question came from fact that you can only use global variables for deployment:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/deployment-jobs?view=azure-devops#schema
Use only global level variables for defining a pool name. Stage/job level variables are not supported to define pool name.
But my config is a bit more complex. I do have main pipeline.yml with several stages. Stage's jobs defined in the template, so I have following structure:
# pipeline.yml (some cuts)
....
stages:
- stage: Build
displayName: Build all
jobs:
- template: ../templates/build.yml
parameters:
stage: 'DEV'
- stage: Dev
displayName: Deploy Dev
variables:
- group: GROUP-DEV
pool:
name: '$(env._global.agentPool)' # env._global.agentPool defined in in the variable group
jobs:
- template: ../templates/deployment.yml
parameters:
stage: 'DEV'
# other stages here ....
# templates/deployment.yml
parameters:
- name: stage
displayName: 'Stage'
type: string
jobs:
- deployment: Deploy${{ parameters.stage }}
displayName: Deploy ${{ parameters.stage }}
environment: ${{ parameters.stage }}
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: art_${{ parameters.stage }}
displayName: 'Download art_${{ parameters.stage }}'
# more steps here.....
Now the problem: with such config I got error:
##[error]Pipeline does not have permissions to use the referenced pool(s) . For authorization details, refer to https://aka.ms/yamlauthz.
which means we faced with limitation mentioned in the first quote (proof: https://developercommunity.visualstudio.com/t/pool-name-in-deployment-job-cannot-be-in-a-variabl/940174)
As soon as I change either pool name to hardcoded value or remove -deployment and use regular steps all works fine.
Question: with that, is there any chance to re-work templates to still use agent pool name from group variable? I need the -deployment task to reference environment.
What was tried already:
use pool name as param of the templates/deployment.yml and use pool inside steps. No luck, same story

Having a script run only when a manually triggered job fails in GitLab

I have the following script that pulls from a remote template. The remote template has the following stages: build, test, code_analysis, compliance, deploy.
The deploy step is manually triggered and executed AWS CLI to deploy a SAM project.
I want to add an additional step such that when the deploy step fails, it will execute a script to rollback the cloudformation stack to its last operational state.
I created a "cleanup-cloudformation-stack-failure" job and tried adding "extends: .deploy", but that didn't work.
I then added an additional stage called "cloudformation_stack_rollback" in the serverless-template.yml file and tried to use a mix of rules and when to get it to trigger on failure, but I'm getting errors flagged by GitLab's linter.
Does anyone know what I'm doing wrong?
include:
- remote: 'https://my-gitlab-server.com/ci-templates/-/raw/master/serverless-template.yml'
deploy-qas:
extends: .deploy
variables:
....
PARAMETER_OVERRIDES: "..."
environment: qas
only:
- qas
tags:
- serverless
cleanup-cloudformation-stack-failure:
variables:
STACK_NAME: $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME
stage: cloudformation_stack_rollback
rules:
- if: '$CI_JOB_MANUAL == true'
when: on_failure
script:
- aws cloudformation continue-update-rollback --stack-name ${STACK_NAME} --resources-to-skip ${STACK_NAME}
You forgot double quotes around true, however you can use Directed Asyclic Graphs to execute jobs conditionally
include:
- remote: 'https://my-gitlab-server.com/ci-templates/-/raw/master/serverless-template.yml'
deploy-qas:
extends: .deploy
variables:
....
PARAMETER_OVERRIDES: "..."
environment: qas
only:
- qas
tags:
- serverless
cleanup-cloudformation-stack-failure:
needs:
- deploy-qas
when: on_failure
variables:
STACK_NAME: $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME
stage: cloudformation_stack_rollback
script:
- aws cloudformation continue-update-rollback --stack-name ${STACK_NAME} --reso

Use gitlab environment(or branch) name in sources

Good day, all.
In serverless framework 'serverless.yml' i have a database variable.
environment:
DATABASE_NAME: ${'test-db'}
In Gitlab CI I try to replace the same database name with branch or environment name in serverless.yml file. serverless deploy command uses serverless.yml content to deploy resources.
i tried:
DATABASE_NAME: ${ CI_ENVIRONMENT_NAME }
DATABASE_NAME: ${ $CI_ENVIRONMENT_NAME }
.gitlab-ci.yml:
image: ~some-nodejs-image
stages:
- deploy
deploy_development:
stage: deploy
script:
- serverless deploy -v
environment:
name: development
only:
- develop
I think you are conflating bash syntax, with the variable syntax allowed in serverless.yml.
Try:
DATABASE_NAME: ${env:CI_ENVIRONMENT_NAME}

Fail to invoke step function using serverless framework ("stepf" is not a valid sub command)

After the installing of the serverless step function plugin
npm install -g serverless
npm install -g serverless-step-functions
... and successfully deploy the step function through
serverless deploy
... Then I try to run: serverless invoke stepf
serverless invoke stepf --name ${sf} --data '${OUTPUT}'
Serverless Error ---------------------------------------
"stepf" is not a valid sub command. Run "serverless invoke" to see a more helpful error message for this command.
... And I get "stepf" is not a valid sub command
Why can't use the functionality from the serverless-step-functions plugin to invoke a step function?
The invoke command is described on the serverless-step-functions git-hub page:
https://github.com/serverless-operations/serverless-step-functions#invoke
The used version of the plugin serverless-step-functions is 2.21.1
Edit
An important piece of information is that the invoke command was executed from a folder that did not contain a serverless.yml file
The invoke command was executed from a directory which did not have a serverless.yml file.
Adding this minimal yaml file activated the plugin
service: some-step-function
provider:
name: aws
region: eu-north-1
runtime: java11
timeout: 30
plugins:
- serverless-step-functions
But in order to run:
serverless invoke stepf --name ${sf} --data '${input}'
... the name parameter in invoke must be the name described in the serverless.yml file.
In the example below, the correct value for the name parameter is aStateMachine. I first did the uncorrected assumption that the name was the same as the name parameter under the state machine.
service: some-step-function
provider:
name: aws
region: eu-north-1
runtime: java11
timeout: 30
...
stepFunctions:
stateMachines:
aStateMachine:
name: thisIsNotTheName
plugins:
- serverless-step-functions
Amusing that you are in the same directory as the above serverless.yml file. A working invoke to a step function could look something like:
serverless invoke stepf --name aStateMachine --data '{}'
The above example explain the error message in the question.
It's however much more convenient to build a solution where the invoke command is executed from the directory where you have the serverless.yml file.

Serverless: deploy particular profile

In the serverless.yml, the deployment profiles are set like this
custom:
defaultStage: dev
profiles:
dev: b***2_dev
prod: b***2_prod
suku: b***2_suku
While the default deploy is dev, I would like to deploy the profile suku without changing the defaultStage.
What is the command for this? sls deploy --profile suku didn't work
On newest versions of serverless (currently 1.26.1), you can provide the argument --aws-profile
ex: sls --aws-profile suku deploy
https://serverless.com/framework/docs/providers/aws/guide/credentials#using-the-aws-profile-option
However, in your case, another option could be to use "per stage" profile:
service: new-service
provider:
name: aws
runtime: nodejs6.10
stage: ${opt:stage, self:custom.defaultStage}
profile: ${self:custom.profiles.${self:provider.stage}}
custom:
defaultStage: dev
profiles:
dev: devProfile
prod: prodProfile
https://serverless.com/framework/docs/providers/aws/guide/credentials#per-stage-profiles
The --profile argument is not currently supported. You can set the environment by setting the AWS_PROFILE environment variable as appropriate. To run a command using a particular profile other than the default one in the system settings, you can do:
On Linux & OSX:
AWS_PROFILE=suku sls deploy
On Windows:
cmd /C "set AWS_PROFILE=suku && sls deploy"
Ensure that your aws profile is setup in ~/.aws/credentials you can the run export AWS_PROFILE=selectedAccount. For the rest of your shell session selectedAccount will be your default profile. You can now run sls deploy and it will deploy to selectedAccount