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.
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.
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
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
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.
ENV['SECRET'] # 1A2B3C4D5E6F
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_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.