TL;DR - for many cases in the backend where you're using Lambda functions and you want to set a variable to different values in your sandboxes, your main branch deployment, and sub branch deployments- secrets work exactly like you want env variables to work. So what if it's a public API key- call it a secret and load the values with ease using the secrets functionality. Feel free to stop reading, that's all there is to it.
If you're determined to use environment variables (they do actually have a few uses, and you can force them to work as the OP wants, and secrets cost money), as of July 2024, the environment variables "feature" of Amplify is useful for at least two things (that I've discovered):
- If you're using React, you can pull them into your frontend code. This can be useful for public API keys. This is described relatively clearly in the docs you referenced. If you're using Angular (like me), this doesn't work but there are easy workarounds.
- On your backend's CDK configuration, you can pass variables to Lambda functions or use them to configure your backend. In a Typescript setup, it's in
backend.ts
. Simple applications may just have a defineBackend
call here but anything beyond that will have CDK stacks.
For the backend CDK config, here are some examples. First, suppose you have an SNS Topic checkCodeTopic
that you want a Lambda function called checkCode
to publish to, you can pull the topic name into the Lambda's environment space:
const checkCodeTopic = new sns.Topic(logNotificationStack, "CheckCodeTopic", {
// parameters can go here
});
// let the checkCode function publish to this topic
checkCodeTopic.grantPublish(backend.checkCode.resources.lambda);
// pass this Topic's ARN to the checkCode function's environment, so it can find it
(backend.checkCode.resources.lambda as Function).addEnvironment("CHECK_CODE_TOPIC_ARN", checkCodeTopic.topicArn);
Now in your Lambda function you can do:
const CHECK_CODE_TOPIC_ARN = process.env.CHECK_CODE_TOPIC_ARN;
That's one of the most useful uses of environment variables IMHO.
For configuring your backend, suppose you want to read an environment variable and enable deletion protection on your user pool or DynamoDB tables:
const deletionProtection = process.env.DELETION_PROTECTION;
if (deletionProtection === 'enabled') {
console.log("ENABLING deletion protection on resources");
// protect user pool
const { cfnUserPool } = backend.auth.resources.cfnResources
cfnUserPool.deletionProtection = "ACTIVE";
...
You use the Amplify Console to set DELETION_PROTECTION for your branch deployments. This is super helpful because you probably want deletion protection for your prod resources, you likely want it for your dev deployment so you know what happens on an upgrade before you try it on prod, and you probably do NOT want it on your sandbox. For your sandbox, you set an environment variable on your terminal like normal export DELETION_PROTECTION=enabled
(for macOS/linux) then run npx ampx sandbox
and it'll use that environment variable to configure your backend.
Tying this all together, if you really want to pass environment variables to your Lambdas and you don't want to do it the easy way with secrets, you just put those two concepts together in your backend.ts
. For example, let's say you're using Stripe and you want to pass your public API key in a env variable called STRIPE_PUBLISHABLE_KEY
into a Lambda called createStripeSession
(put your secret API key in the Amplify secrets box):
// pass environment variables into the Lambda functions that need them
(backend.createStripeSession.resources.lambda as Function).addEnvironment("STRIPE_PUBLISHABLE_KEY", process.env.STRIPE_PUBLISHABLE_KEY ?? 'NO KEY DEFINED');
Again, here you'll populate those in the Amplify Console for branch deployments and your terminal for sandbox deployments. You pull it into your Lambda function the same as above:
const STRIPE_PUBLISHABLE_KEY = process.env.STRIPE_PUBLISHABLE_KEY;
Honestly though, the downside is that for your sandboxes you have to define these every time you make a new terminal window. You restart VSCode for an update- export them all over again. You restart your computer, all over again. With secrets, you set them once and done and no need for this little hack in backend.ts
. Of course, secrets cost $0.40 per month, so there's that.