Serverless deployed environment variables do not update - node.js

The app is a nodejs app deployed to AWS Lambda using Serverless. I have the production environment variables stored in .env-prod.json
serverless.yml:
custom:
stage: ${opt:stage, self:provider.stage}
service: my-backend
provider:
name: aws
runtime: nodejs14.x
stage: prod
region: us-east-1
memorySize: 128
functions:
app:
handler: index.handler
environment: ${file(./.env-${self:custom.stage}.json)}
events:
- http:
path: /
method: ANY
cors: true
- http:
path: /{proxy+}
method: ANY
cors: true
.env-prod.json:
{
"ENVIRONMENT": "prod",
"TEST1": "abc",
"TEST2": "abc2"
}
For the first serverless deploy I had only TEST1 var present and this deployed successfully. Now, after I added TEST2 var, then run serverless deploy, it does not deploy the new variable or any change to a variable, only code and code changes. In order to change or add a new var, I have to go to the AWS console UI and do it there.
Is there some special way to re-deploy the variables? I have tried the force option which had no effect.

I fixed this issue changing ${self:custom.stage} to ${opt:stage, self:provider.stage, 'dev'}
I hope it will work for your case. Tks

Related

Accessing environment configs defined in serverless.yaml in standalone nodejs script

I have recently started working on a project in which we are using serverless framework. We are using docker to make dev environment easier to setup.
As part of this docker setup we have created a script that creates S3 buckets & tables among other things. We were earlier defining environment variables in the docker-compose file and were accessing them in our nodejs app. For purposes of deployment to other environments our devops team defined a few environment variables in the serverless.yaml file resulting in environment configs being present at two places. We are now planning to move all the environment configs defined in our docker-compose file to serverless.yaml. This works well for our lambdas functions as they are able to read these configs, but it doesn't work for the standalone setup script that we have written.
I tried using this plugin(serverless-scriptable-plugin) in an attempt to be able to read these env variables but still unable to do so.
Here is my serverless.yaml file
service:
name: my-service
frameworkVersion: '2'
configValidationMode: error
provider:
name: aws
runtime: nodejs14.x
region: 'us-east-1'
profile: ${env:PROFILE, 'dev'}
stackName: stack-${self:provider.profile}
apiName: ${self:custom.environment_prefix}-${self:service.name}-my-api
environment: ${self:custom.environment_variables.${self:provider.profile}}
plugins:
- serverless-webpack
- serverless-scriptable-plugin
- serverless-offline-sqs
- serverless-offline
functions:
myMethod:
handler: handler.myHandler
name: ${self:custom.environment_prefix}-${self:service.name}-myHandler
events:
- sqs:
arn:
Fn::GetAtt:
- MyQueue
- Arn
resources:
Resources:
MyQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:custom.queuename}
Tags:
- Key: product
Value: common
- Key: service
Value: common
- Key: function
Value: ${self:service.name}
- Key: region
Value: ${env:REGION}
package:
individually: true
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
serverless-offline:
host: 0.0.0.0
port: 3000
serverless-offline-sqs:
apiVersion: '2012-11-05'
endpoint: http://sqs:9324
region: ${self:provider.region}
accessKeyId: root
secretAccessKey: root
skipCacheInvalidation: false
localstack:
stages:
- local
lambda:
mountCode: true
debug: true
environment_prefixes:
staging: staging
production: production
dev: dev
environment_prefix: ${self:custom.environment_prefixes.${self:provider.profile}}
queuename: 'myQueue'
environment_variables:
dev:
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
BUCKET_NAME: my-bucket
S3_URL: http://localstack:4566
SLS_DEBUG: '*'
scriptable:
commands:
setup: node /app/dockerEntrypoint.js
In my DockerFile I try executing script using sls setup CMD. I initially thought using sls command might expose these environment variables defined in serverless.yaml file but it doesn't seem to happen.
Is there any other way this can be achieved? I am trying to access these variables using process.env which works for lambdas but not for my standalone script. Thanks!
There's not a good way to get access to these environment variables if you're running the lambda code as a script.
The Serverless Framework injects these variables into the Lambda function runtime configuration via CloudFormation.
It does not insert/update the raw serverless.yml file, nor does it somehow intercept calls to process.env via the node process.
You'll could use the scriptable plugin to run after package, and then export each variable into your local docker environment. But that seems pretty heavy for the variables in your env.
Instead, you might consider something like dotenv, which will load variables from a .env file into your environment.
There is a serverless-dotenv plugin you could use, and then your script could also call dotenv before running.

How to access SSM Parameter Store from SAM lambda local in node

I have a lambda with node and for local deployment I am using SAM CLI. This lambda requires some parameters in the SSM parameter store to be able to connect to the DB.
I configured the AWS_ACCES_KEY_ID and AWS_SECRET_ACCESS_KEY, as environment variables, in addition to the region. When executing the local lamda, I do not get any error, as it goes to aws, but it does not bring me anything. It is not a code issue, because if I deploy it already in aws it works without problem. I don't know if I need to do another configuration for it to work.
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
ciencuadras-appraisal-request
Sample SAM Template for ciencuadras-appraisal-request
Parameters:
Stage:
Type: String
Default: dev
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
ApiDeployment:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Stage
RequestAppraisalFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: dist/
Handler: main.handler
Runtime: nodejs14.x
Environment:
Variables:
AWS_REGION: 'us-east-1'
Events:
RequestAppraisal:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /sendemail-new-appraisal
Method: post
RestApiId: !Ref ApiDeployment
Thanks
Currently there is no possibility to access Parameter Store variables from Sam Local as you can read up here.
Instead, you can use --env-vars option on SAM CLI to pass values to
the running function.
You can still use SSM in your template and pass --env-vars when invoking the function locally, for example:
template.yaml
MyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: dist/
Handler: main.handler
Runtime: nodejs14.x
Environment:
Variables:
API_KEY: !Sub '{{resolve:ssm:API_KEY:1}}'
env.json:
{
"Parameters": {
"API_KEY": "123"
}
}
pass env.json when invoking the function:
sam local invoke --env-vars env.json MyFunction
Note: If you are running API locally too, you can do:
sam local start-api --env-vars env.json

FUNCTION_ERROR_INIT_FAILURE AWS lambda

I recently added the cool lambda feature - provisioned concurrency.
After a few successful deployments, I now face this issue
Serverless Error ---------------------------------------
ServerlessError: An error occurred:
GraphqlPrivateProvConcLambdaAlias - Provisioned Concurrency
configuration failed to be applied. Reason:
FUNCTION_ERROR_INIT_FAILURE.
at C:\Users\theod\AppData\Roaming\npm\node_modules\serverless\lib\plugins\aws\lib\monitorStack.js:125:33
From previous event:
at AwsDeploy.monitorStack (C:\Users\theod\AppData\Roaming\npm\node_modules\serverless\lib\plugins\aws\lib\monitorStack.js:28:12)
at C:\Users\theod\AppData\Roaming\npm\node_modules\serverless\lib\plugins\aws\lib\updateStack.js:107:28
From previous event:
at AwsDeploy.update
here's my sample serverless.yml file
service: backend-api
parameters:
region: ap-southeast-2
path: &path /
provider:
name: aws
runtime: nodejs12.x
stage: ${env:STAGE, 'staging'}
region: ap-southeast-2
versionFunctions: true
plugins:
- serverless-webpack
- serverless-pseudo-parameters
- serverless-prune-plugin
# - serverless-offline-scheduler
- serverless-offline
functions:
# GRAPHQL APIs
graphqlPrivate:
handler: src/graphql/private/index.handler
memorySize: 256
timeout: 30
name: ${self:service}-gqlPrivate-${self:provider.stage}
vpc: ${file(./serverless/vpc.yml)}
events:
- http:
path: /graphql/private
method: ANY
cors: true
authorizer:
arn: arn:aws:cognito-idp:#{AWS::Region}:#{AWS::AccountId}:userpool/${self:custom.cognitoArns.private.${self:provider.stage}}
provisionedConcurrency: 10
package:
individually: true
custom:
webpack:
keepOutputDirectory: true
serializedCompile: true
webpackConfig: 'webpack.config.js'
packager: 'npm'
stage: ${opt:stage, self:provider.stage}
prune:
automatic: true
number: 1
anybody able to resolve this issue?
Your Environment Information ---------------------------
Operating System: win32
Node Version: 12.11.0
Framework Version: 1.61.3
Plugin Version: 3.2.7
SDK Version: 2.3.0
Components Core Version: 1.1.2
Components CLI Version: 1.4.0
FUNCTION_ERROR_INIT_FAILURE plainly means there's something wrong with the function's handler/code that i'm trying to deploy, w/c is why provisioned lambdas can't start up/initialize.
The way to resolve this, is to test w/o provisioned concurrency option first.
Once you are able to push your lambda, error(s) will surely flow into your CW logs.
The best way though, is to test your lambda locally(using serverless-offline plugin or serverless invoke), if it works properly.
You can also package your app, and invoke it with serverless cli to detect issues on packaging.
In my case, there is a runtime error where my code bundle is looking for a require that is not part of bundle.
This is undocumented on AWS lambda as of now(Jan 29, 2020)

How to set up environment variables when using aws-serverless-express

I am using aws-serverless-express for deploying an express api on aws lambda. I followed the aws-serverless-express repository example (https://github.com/awslabs/aws-serverless-express/tree/master/examples/basic-starter) to deploy the api and it works, but now I don't know how to set up environment variables in express code then after the express deployment I can see and edit those environment variables on lambda console. I didn't find any documentation about this.
In the repository you mentioned, the cloudformation.yaml file has the function definition called YOUR_SERVERLESS_EXPRESS_LAMBDA_FUNCTION_NAME. you can define an attribute called Environment under that. see the example below.
YOUR_SERVERLESS_EXPRESS_LAMBDA_FUNCTION_NAME:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./
Handler: lambda.handler
MemorySize: 1024
Role: !GetAtt LambdaExecutionRole.Arn
Runtime: nodejs8.10
Timeout: 30
Environment:
Variables:
SOME_VAR: value
Events:
ProxyApiRoot:
Type: Api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /
Method: ANY
ProxyApiGreedy:
Type: Api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /{proxy+}
Method: ANY

How to get same host on api gateway aws using serverless fraemwork in different service

I have to 2 service. I want to deploy it and get the same aws host.
1. This is first configuration serverless.yml
service: test
provider:
name: aws
runtime: nodejs8.10
stage: prod
region: ap-southeast-1
plugins:
- serverless-offline
functions:
bilangangenap:
handler: index.handler
events:
- http:
path: test/satu
method: post
timeout: 120
This is second configuration serverless.yml
service: test
provider:
name: aws
runtime: nodejs8.10
stage: prod
region: ap-southeast-1
plugins:
- serverless-offline
functions:
bilanganganjil:
handler: index.handler
events:
- http:
path: test/dua
method: post
timeout: 120
When I deploy first service, I got end point :
https://abcdefgh.execute-api.ap-southeast-1.amazonaws.com/prod/test/satu
And when I deploy second service, I got end point :
https://abcdefgh.execute-api.ap-southeast-1.amazonaws.com/prod/test/dua
But when I deploy second service, the first service will be deleted.
I want to use same host like : https://abcdefgh.execute-api.ap-southeast-1.amazonaws.com with different end point.

Resources