Reproducibly Setting Production Environment Variables for AWS Lambda Apps
Tags: aws, serverless, awslambda, devops
Published: 2020-03-27 16:26:59

---
title: Reproducibly Setting Production Environment Variables for AWS Lambda Apps
published: true
date: 2020-03-27 16:21:11 UTC
tags: aws, serverless, awslambda, devops
canonical_url: https://avdi.codes/reproducibly-setting-production-environment-variables-for-aws-lambda-apps/
cover_image: https://i2.wp.com/avdi.codes/wp-content/uploads/2020/03/dreamstime_m_86423817.jpg?zoom=2&resize=1000%2C750&ssl=1
---

The problem with infinitely flexible building blocks is that there are always a half-dozen well-documented ways to do things wrong.

I wanted my AWS Lambda app (I refuse to call it a “function” because it isn’t) to get the third-party API keys it needs from environment variables. Not from hardcoded strings or config files.

The most immediately accessible way to set up env vars for a Lambda is [via the AWS console](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html). But that’s not a reproducible, versionable workflow I can capture in my project.

Searching for info on setting up environment variables in a SAM-based AWS Lambda app turns up a lot of results. It seems you can set variables in the SAM config in `template.yaml`.

```
Resources:
  HelloWorldFunction:
   Type: AWS::Serverless::Function
   Properties:
     CodeUri: hello\_world/
     Handler: app.lambda\_handler
     Runtime: python3.7
     Environment:
       Variables:
         API\_KEY: 12345...
​
```

More usefully, you can define env vars that apply to all of your functions by putting them in the globals section that normally lives at the top of `template.yaml`

```
Globals:
  Function:
    # ...
   Environment:
     Variables:
       API\_KEY: 12345...
```

Which is all great, except that I explicitly _don’t_ want these variable values to apply universally, and I don’t want them to be checked-in to my repo. I just want to set them for my production deployment.

My searching next took me down the rabbit hole of [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html). But that’s _way_ too heavyweight a solution for what I want to do.

Finally, I realized that I could probably set env vars via the `aws` CLI (not `sam`). Like everything to do with AWS, the command isn’t particularly intuitive, but here’s what I cam up with:

```
aws --region us-east-1 lambda update-function-configuration \
    --function-name myapp-MyFunction-1234ABCD \
    --environment "Variables={API\_KEY=12345}"
```

Some points to note:

1. Nothing worked until I explicitly set the `–region`
2. Environment variables are part of a “function configuration”
3. The function name for a SAM-managed app is the full name that SAM invents, including the app name, the function name, and some ID garbage at the end.
4. You can’t just set environment variables directly; that would be too easy. You need to pass `Variables={...}`, where the contents of the curly braces are `key=value` pairs delimited by commas.

This gives me a documentable, reproducible template for setting API key environment variables in just the production deployment. Which is what I wanted.