amplify-hosting
amplify-hosting copied to clipboard
Next.js SSR mode - Environment Variables not being carried over to the created Lambda Functions
Before opening, please confirm:
- [X] I have checked to see if my question is addressed in the FAQ.
- [X] I have searched for duplicate or closed issues.
- [X] I have read the guide for submitting bug reports.
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
App Id
d36aqre3ndgr2h
Region
us-east-1
Amplify Console feature
Environment variables
Describe the bug
When I set environment variables in the Amplify app, they are NOT being carried through to the Lambda functions that are automatically created for my Next.js SSR website.
Even if I set the environment variables later on the Lambda functions that are created, they get wiped out the next time I do a build.
Here's a link to my repo: https://github.com/agility/agilitycms-nextjs-ssr-starter
Expected behavior
I expected the environment variables to propagate from the Amplify settings to the Lambda functions that are created.
Reproduction steps
- Create a new Next.js site on Amplify site using this repo: https://github.com/agility/agilitycms-nextjs-ssr-starter
- Set the environment variables as needed (let me know if you need this information specifically)
- Push a change to the main branch
- The Environment variables are NOT on the Lambda functions.
- The code in the Lambda functions that uses process.env.VARIABLE_NAME doesn't work
Build Settings
No response
Additional information
No response
hey @joelvarty did you find any solution? I am having the same problem
hey @joelvarty did you find any solution? I am having the same problem
Nope. I think this is an actual bug in the Next.js SSR Logic with Amplify
Hi, yes this is a bug and we are working on a fix. As a temporary workaround you can manually add the environment variable to your SSR Lambda function in the Lambda Console. Sorry you are facing this issue; we will follow up when this is fixed. Thanks!
@Athena96 thanks for the workaround, however, after a redeploy all lambda functions are published as a new version without the env. variables, is there a way to prevent that from happening?
On each push to my branches I'm losing the data and the app starts crashing.
Thanks
Same issue here. The only solution I can think of in the meantime is to use secrets manager or ssm parameter store
@bajcmartinez You could try this in the meantime:
Go to AWS Console->Systems Manager->Parameter store
Create your environment variables. If you have different stages, you should be using different accounts anyway so the keys shouldn't clash
import AWS from 'aws-sdk'
var ssm = new AWS.SSM()
export default async (req: NextApiRequest, res: NextApiResponse) => {
var MY_TABLE;
ssm.getParamter({ Name: 'MY_TABLE' }, (err, data) => {
MY_TABLE = data.Parameter?.Value!
})
...
}
While not an ideal solution, it is perhaps futureproofed if you needed to reuse environment variables across different apps. Although the Amplify team will fix this in a few hours I hope. Perhaps best not to refactor large parts of code if it is to be fixed tomorrow or something.
Would be nice to have an ETA here, in the meanwhile I moved my config to parameter store as pointed out by @joekendal, however, it is not ideal as the parameter key name is "hardcoded" and it is not environment independent.
I can survive with it for now, but I can see this being a major issue for some others, it is very inconvinient.
Additionally, what would be the best way to give those lambda functions a policy to read from parameter store?
They have a custom role created by amplify, but there's no cloud formation template for it.
I did it manually for now
@bajcmartinez yeah I haven't opted for that solution myself. Waiting for an update here. Will have to just deploy the API lambdas separately using CDK or something as opposed to Next.js /api/ route feature.
The problem is even more deep, even if I try to add the env variables manually I cannot deploy those functions as the CloudFront edge run environment does not support lambda environment variables as described here: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html#edge-function-restrictions-all
The problem is even more deep, even if I try to add the env variables manually I cannot deploy those functions as the CloudFront edge run environment does not support lambda environment variables as described here: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html#edge-function-restrictions-all
I'm very confused then @Athena96 declares this is a bug and not a feature. But it seems it is in fact a feature and not a bug. Vercel uses Lambda@Edge and enables the user to provide environment variables. So they must be doing something during build time to make that available to process.env behind the scenes
Hi @Athena96 has there been any movement on this?
This is a really big issue.
Same issue here.
Hi all! We have added support for Environment variables for Next.js SSR apps. Follow these steps to enable:
- Add your desired environment variable in the Amplify Console like normal (steps)
- Update (or create) your
next.config.jsfile with the environment variable you added in the Amplify Console. E.g if you created an environment variable namedMY_ENV_VARin the console in step 1) above, then you would add the following:
module.exports = {
env: {
MY_ENV_VAR: process.env.MY_ENV_VAR
}
};
- Now after your next build you will be able to reference your environment variable (
process.env.MY_ENV_VAR) in your SSR lambdas!
Thank you, and please let us know if you have any additional questions!
This is great news @Athena96, will try it today. Thanks so much, have a great weekend!
I was just thinking, nextjs has public and private env variables, some that get sent to the client start with NEXT_PUBLIC_, how are they treated now? will env. variables treated the same way? meaning non-public like SECRET_ENV_VAR, will that one remain for API and SSR ONLY?
Hi all! We have added support for Environment variables for Next.js SSR apps. Follow these steps to enable:
- Add your desired environment variable in the Amplify Console like normal (steps)
- Update (or create) your
next.config.jsfile with the environment variable you added in the Amplify Console. E.g if you created an environment variable namedMY_ENV_VARin the console in step 1) above, then you would add the following:module.exports = { env: { MY_ENV_VAR: process.env.MY_ENV_VAR } };
- Now after your next build you will be able to reference your environment variable (
process.env.MY_ENV_VAR) in your SSR lambdas!Thank you, and please let us know if you have any additional questions!
I appreciate this @Athena96! However... is there any reason not to simply create ALL the environment vars that are defined in Amplify on the Lambda functions? That way we don't need to have the extra config.
The reason this is important to us is that we build starter templates that run in a TON of cloud environments, and having to put vendor-specific config in there seems out of place.
@Athena96 I'm having issues now with my production build. It's not taking the env. overrides and always picking the default sets for the variables.
Could you please confirm this? Or is there anything else I should fix?
e.g.: In my app I have the following settings:

And it's always using the test...... URL
I was just thinking, nextjs has public and private env variables, some that get sent to the client start with NEXT_PUBLIC_, how are they treated now? will env. variables treated the same way? meaning non-public like SECRET_ENV_VAR, will that one remain for API and SSR ONLY?
Hi @bajcmartinez currently we do not make a distinction between the Next public/private env vars. They are all treated the same way.
@Athena96 I'm having issues now with my production build. It's not taking the env. overrides and always picking the default sets for the variables.
Could you please confirm this? Or is there anything else I should fix?
e.g.: In my app I have the following settings:
And it's always using the test...... URL
@bajcmartinez yes this is a bug and we are working on a fix. I will follow up when it is deployed. As a workaround you can create separate env vars for the different values.
@Athena96 I'm having issues now with my production build. It's not taking the env. overrides and always picking the default sets for the variables. Could you please confirm this? Or is there anything else I should fix? e.g.: In my app I have the following settings:
And it's always using the test...... URL
@bajcmartinez yes this is a bug and we are working on a fix. I will follow up when it is deployed. As a workaround you can create separate env vars for the different values.
Hi @Athena96 I'm trying to follow your work around. I understand creating separate variables for different environments (e.g. API_URL_DEV vs API_URL_QA). My quesiton still stands at build time how would the application know which one to point to ? Is there a default variable from Amplify that can be used to know which ("env" or branch) is being built.
@Athena96 I'm having issues now with my production build. It's not taking the env. overrides and always picking the default sets for the variables. Could you please confirm this? Or is there anything else I should fix? e.g.: In my app I have the following settings:
And it's always using the test...... URL
@bajcmartinez yes this is a bug and we are working on a fix. I will follow up when it is deployed. As a workaround you can create separate env vars for the different values.
Hi @Athena96 I'm trying to follow your work around. I understand creating separate variables for different environments (e.g. API_URL_DEV vs API_URL_QA). My quesiton still stands at build time how would the application know which one to point to ? Is there a default variable from Amplify that can be used to know which ("env" or branch) is being built.
Hi All who are looking for a work around. AWS Amplify makes the branch you're building available in an envrionment variable (process.env.AWS_BRANCH). Using this env var I'm able to point to the correct url I want to use pending that branch build.
const baseURL = { develop: process.env.BASE_URL_DEV, qa: process.env.BASE_URL_QA, }[process.env.AWS_BRANCH || 'develop']
If there are other feature branches you can add them as options in the object, if a variable is not available for the AWS_BRANCH being built it will default to the develop option.
Hi all! We have added support for Environment variables for Next.js SSR apps. Follow these steps to enable:
- Add your desired environment variable in the Amplify Console like normal (steps)
- Update (or create) your
next.config.jsfile with the environment variable you added in the Amplify Console. E.g if you created an environment variable namedMY_ENV_VARin the console in step 1) above, then you would add the following:module.exports = { env: { MY_ENV_VAR: process.env.MY_ENV_VAR } };
- Now after your next build you will be able to reference your environment variable (
process.env.MY_ENV_VAR) in your SSR lambdas!Thank you, and please let us know if you have any additional questions!
This should probably be documented on the Amplify Docs here: https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html#access-env-vars
If someone else did all of the above and is hopeless as I was:
- Delete the app from amplify
- Create it again through the wizard (connect repo)
- Declare the environment variables on the wizard
My guess is there was some cache somewhere and my changes on the next.config.js were not getting picked up 🤷
@Athena96
This does not work for us. Here is our next.config.js:
module.exports = {
env: {
MG_API_KEY: process.env.MG_API_KEY,
},
webpack: (config, { isServer }) => {
// Fixes npm packages that depend on `ws` module
if (!isServer) {
config.node = {
ws: "empty",
};
}
return config;
},
};
The MG_API_KEY variable is still undefined in the Lambda function.
Hi all! We have added support for Environment variables for Next.js SSR apps. Follow these steps to enable:
- Add your desired environment variable in the Amplify Console like normal (steps)
- Update (or create) your
next.config.jsfile with the environment variable you added in the Amplify Console. E.g if you created an environment variable namedMY_ENV_VARin the console in step 1) above, then you would add the following:module.exports = { env: { MY_ENV_VAR: process.env.MY_ENV_VAR } };
- Now after your next build you will be able to reference your environment variable (
process.env.MY_ENV_VAR) in your SSR lambdas!Thank you, and please let us know if you have any additional questions!
Solved for me!! Thanks!
This is not a nice solution for CDK users. How can we import environment variables from CDK? SST offers a CDK stack for Next.js with environment variables https://docs.serverless-stack.com/constructs/NextjsSite
@joekendal, you would follow the same approach as the environment variable set up with the AWS CLI or CDK. The only difference is that the variable names also need to be referenced in the next.config.js, but that reference is to the var name that you set with the CDK/CLI above.
So, step 1 above can be handled by CDK.
AWS_BRANCH
Even though this workaround works, it's a bad practice, you'll be exposing keys to all the environments