Environment Configuration & Secrets
Most Rails applications require over a dozen environment variables to configure itself along with other popular gems used. Most notable is ActiveRecord's DATABASE_URL
. There are numerous ways to configure environment variables ranging from "quick and dirty" by adding secrets to your git repo (⚠️) all the way to a strict "separation of config" from code using countless methods to achieve a proper Twelve-Factor application. We want to cover a few topics that may help you pick and choose what works best for you.
Configuration
You can add simple configurations to your all of your function's environment using SAM's global section. Configurations like these are ones that you feel safe comitting to your git repo.
Globals:
Environment:
Variables:
SOME_SERVICE_URL: https://prod.some-service.com/api
If you deploy to multiple environments, you can even have these be dynamic by leveraging CloudFormation's mappings. Here is an example that builds on our RailsEnv
parameter.
Mappings:
SomeService:
staging:
Url: https://staging.some-service.com/api
production:
Url: https://prod.some-service.com/api
# ...
Globals:
Environment:
Variables:
SOME_SERVICE_URL: !FindInMap [SomeService, !Ref RailsEnv, Url]
Secrets with Crypteia
The Crypteia package is Rust Lambda Extension for any Runtime/Container to preload SSM Parameters as secure environment variables. It takes advantages of LD_PRELOAD
to seamlessly fetch values from SSM when a process starts and then injects them as natively accesible Ruby ENV
variables. Our Quick Start guide's cookiecutter includes Crypteia already for you via a Docker COPY
command into the Lambda Extension /opt
directory.
FROM ruby:3.2-bullseye
COPY /opt /opt
Usage is simply done by adding variables to your SAM template and accessing the values fetched from SSM like any other environment variable. Please read the Crypteia's documentation for full details on how to add IAM Permissions to read SSM Parameters.
Globals:
Environment:
Variables:
SECRET: x-crypteia-ssm:/myapp/SECRET
ENV['SECRET'] # 1A2B3C4D5E6F
About SECRET_KEY_BASE
Our cookiecutter project disabled Rails encrypted credentials in favor of a more simple SECRET_KEY_BASE
setting. The starter project places a temporary value for this environment variable in the config/initializers/secret_key_base.rb
file. Please remove the ENV['SECRET_KEY_BASE'] = '0123...'
line and use Crypteia as described above.
Modern IAM Role Usage
If your application uses other AWS resources like EventBridge or S3, you may be using environment variables like AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
. Avoid this pattern. Instead, please add explicit IAM policies within your template.yaml
file. They will be attached to your Lambda's Execution Role and inherently give your Lambda the needed permissions. AWS is constantly making IAM permissions more approachable. There are two high level interfaces within SAM to connect your application to cloud resources. Newest first:
- AWS SAM Connectors: Are an AWS SAM abstract resource type, identified as
AWS::Serverless::Connector
, that can be defined in your AWS SAM templates to grant Read and Write access of data and events from a supported AWS resource to another. - AWS SAM Policy Templates: Are pre-defined sets of permissions that you can add to your AWS SAM templates to manage access and permissions between your AWS Lambda functions, AWS Step Functions state machines and the resources they interact with.
If needed, you can use the lower level Policies
property of your AWS::Serverless::Function
resource to attach any inline policies to your application's IAM Role.