Learn how to securely manage and inject environmental variables into your AWS Lambda functions using Terraform for efficient and scalable deployments.
Managing environment variables for your AWS Lambda functions is crucial for configuring behavior and accessing external resources. Terraform provides flexible ways to define and manage these variables, ensuring secure and dynamic configurations. This article explores various methods for setting environment variables in your Lambda functions using Terraform, ranging from simple in-line declarations to leveraging AWS Secrets Manager for sensitive data and dynamically generating values.
Directly within the aws_lambda_function
resource:
resource "aws_lambda_function" "example" {
# ... other configurations ...
environment {
variables = {
KEY1 = "VALUE1"
KEY2 = "VALUE2"
}
}
}
Referencing variables defined elsewhere:
variable "lambda_environment" {
default = {
KEY1 = "VALUE1"
KEY2 = "VALUE2"
}
}
resource "aws_lambda_function" "example" {
# ... other configurations ...
environment {
variables = var.lambda_environment
}
}
Using AWS Secrets Manager (for sensitive data):
Dynamically generating environment variables:
locals {
accounts = [
{ name = "account1", number = "123456789012" },
{ name = "account2", number = "987654321012" }
]
environment_variables = {
for account in local.accounts :
"ACCOUNT_${account.name}_NUMBER" => account.number
}
}
resource "aws_lambda_function" "example" {
# ... other configurations ...
environment {
variables = local.environment_variables
}
}
This example creates environment variables like ACCOUNT_account1_NUMBER
and ACCOUNT_account2_NUMBER
.
Important Considerations:
The code demonstrates various methods to set environment variables for AWS Lambda functions using Terraform. It showcases setting variables directly, referencing them from elsewhere, using AWS Secrets Manager for sensitive data, and dynamically generating them based on the Terraform workspace. The examples provide a starting point for configuring Lambda functions with different environment setups while emphasizing security and best practices.
1. Directly within the aws_lambda_function
resource:
resource "aws_lambda_function" "example" {
function_name = "my-lambda-function"
runtime = "nodejs16.x"
handler = "index.handler"
# ... other configurations ...
environment {
variables = {
LOG_LEVEL = "INFO"
API_ENDPOINT = "https://api.example.com"
}
}
}
2. Referencing variables defined elsewhere:
variable "lambda_environment" {
type = map(string)
default = {
LOG_LEVEL = "INFO"
API_ENDPOINT = "https://api.example.com"
}
}
resource "aws_lambda_function" "example" {
function_name = "my-lambda-function"
runtime = "nodejs16.x"
handler = "index.handler"
# ... other configurations ...
environment {
variables = var.lambda_environment
}
}
3. Using AWS Secrets Manager (for sensitive data):
# Create a Secrets Manager secret
resource "aws_secretsmanager_secret" "example" {
name = "my-lambda-secret"
}
resource "aws_secretsmanager_secret_version" "example" {
secret_id = aws_secretsmanager_secret.example.id
secret_string = jsonencode({
API_KEY = "your_api_key"
})
}
# Grant Lambda function permission to access the secret
data "aws_iam_policy_document" "lambda_secrets_policy" {
statement {
actions = ["secretsmanager:GetSecretValue"]
resources = [aws_secretsmanager_secret.example.arn]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy_attachment" "lambda_secrets_attachment" {
role = aws_iam_role.lambda_role.name
policy_arn = data.aws_iam_policy_document.lambda_secrets_policy.arn
}
# Reference the secret in your Lambda function code
# (example in Node.js)
const AWS = require('aws-sdk');
const client = new AWS.SecretsManager();
exports.handler = async (event) => {
const data = await client.getSecretValue({ SecretId: 'my-lambda-secret' }).promise();
const secret = JSON.parse(data.SecretString);
// Access the API key
console.log(secret.API_KEY);
// ... your lambda function logic ...
};
4. Dynamically generating environment variables:
locals {
stages = {
dev = {
db_name = "dev_database"
}
prod = {
db_name = "prod_database"
}
}
environment_variables = {
DB_NAME = local.stages[terraform.workspace].db_name
}
}
resource "aws_lambda_function" "example" {
function_name = "my-lambda-function"
runtime = "nodejs16.x"
handler = "index.handler"
# ... other configurations ...
environment {
variables = local.environment_variables
}
}
This example dynamically sets the DB_NAME
environment variable based on the current Terraform workspace.
Remember:
your_api_key
with your actual values.General:
Security:
Best Practices:
Alternatives to Secrets Manager:
Debugging:
terraform output
to display the values of dynamically generated environment variables for verification.This document outlines various methods for setting environment variables in AWS Lambda functions using Terraform.
| Method | Description
By employing these techniques, you can effectively manage and secure your AWS Lambda environment variables, leading to more robust and adaptable serverless applications. Remember to prioritize security, especially when handling sensitive data, and leverage Terraform's capabilities for dynamic and organized configurations. By adhering to best practices and exploring the available tools and services, you can streamline your Lambda development workflow and ensure your applications are secure, scalable, and maintainable.