I am using the following configuration to deploy a couple lambda functions to different stages prod
and dev
on AWS. Both stages should be protected with an api key which is stored in SSM.
serverless.yml
service: my-service
frameworkVersion: "3"
provider:
name: aws
runtime: nodejs16.x
region: eu-central-1
apiGateway:
apiKeys:
- name: my-apikey
value: ${ssm:my-apikey}
functions:
v1_myfunc:
handler: src/api/myfunc/get_func.get
events:
- http:
path: /v1/myfunc
method: get
private: true
plugins:
- serverless-esbuild
- serverless-offline
- serverless-dotenv-plugin
My deployment scripts look like this:
package.json
"scripts": {
"deploy:dev": "serverless deploy --stage dev",
"deploy:prod": "serverless deploy --stage prod"
}
The problem:
When I deploy one of the stages then everything works fine. But if I deploy the other one afterwards, I always get the following error (in this case I deployed prod first, and then dev):
Deploying my-service to stage dev (eu-central-1)
✖ Stack my-service-dev failed to deploy (46s)
Environment: darwin, node 16.15.0, framework 3.23.0, plugin 6.2.2, SDK 4.3.2
Credentials: Local, "default" profile
Error:
Invalid API Key identifier specified
error Command failed with exit code 1.
Looking into AWS console, I noticed that the generated api key has the same id for both stacks (dev and prod). So, I'm guessing this is where the problem is: Both stacks sharing the same api key instance.
So, I tried to fix this by setting different api key names for each stage:
- name: my-apikey-${self:provider.stage}
value: ${ssm:my-apikey}
But this doesn't solve the problem, as I'm still getting this error:
Invalid API Key identifier specified
Question: How do I have to change my serverless.yml
config to fix the issue?
The api key values for both stages need to be different:
service: my-service
frameworkVersion: "3"
provider:
name: aws
runtime: nodejs16.x
region: eu-central-1
apiGateway:
apiKeys:
${self:custom.apiTest.${sls:stage}}
functions:
v1_myfunc:
handler: src/api/myfunc/get_func.get
events:
- http:
path: /v1/myfunc
method: get
private: true
plugins:
- serverless-esbuild
- serverless-offline
- serverless-dotenv-plugin
custom:
apiTest:
dev:
- name: api-key-dev
value: 123 # Needs to be different vs prod!
prod:
- name: api-key-prod
value: 456 # Needs to be different vs dev!