Lambda 환경 변수 완전 가이드: DB 엔드포인트 주입부터 KMS 암호화까지
Lambda 함수에 데이터베이스 엔드포인트를 하드코딩했다가 코드 리포지토리에 그대로 노출된 경험이 한 번쯤은 있을 것이다. Lambda 환경 변수는 이 문제를 해결하는 가장 직접적인 방법이지만, KMS 암호화 옵션을 잘못 이해하면 오히려 보안 감사에서 지적을 받는다.
TL;DR — Lambda 환경 변수 핵심 요약
| 항목 | 내용 |
|---|---|
| 환경 변수 설정 방법 | 콘솔, CLI, IaC 모두 지원. 런타임에 OS 환경 변수로 주입됨 |
| 기본 암호화 | 저장 시 AWS 관리형 키(aws/lambda)로 자동 암호화 |
| KMS 고객 관리형 키(CMK) | 별도 KMS 키 지정 시 추가 제어 가능. 함수 실행 역할에 kms:Decrypt 필요 |
| 전송 중 암호화 | 콘솔 헬퍼 암호화 사용 시 배포 전 클라이언트 측 암호화 적용 |
| 민감 정보 대안 | Secrets Manager 또는 SSM Parameter Store(SecureString) 권장 |
Lambda 환경 변수가 동작하는 방식
Lambda는 함수 배포 패키지와 환경 변수를 분리해서 관리한다. 환경 변수는 함수 설정의 일부로 저장되고, 실행 환경(Execution Environment)이 초기화될 때 프로세스의 OS 환경 변수로 주입된다. 코드에서는 process.env.DB_ENDPOINT(Node.js), os.environ['DB_ENDPOINT'](Python) 처럼 일반 환경 변수와 동일하게 읽는다.
저장 계층에서 Lambda는 기본적으로 AWS 관리형 KMS 키(aws/lambda)를 사용해 환경 변수를 암호화한다. 이 키는 AWS가 소유하고 관리하므로 별도 비용이 발생하지 않지만, 키 정책 제어나 감사 로그 분리는 불가능하다. 고객 관리형 키(CMK)를 지정하면 키 정책으로 접근을 제어하고 CloudTrail에서 복호화 이벤트를 추적할 수 있다.
(환경 변수 + KMS Key ARN) LS->>KMS: GenerateDataKey 요청 KMS-->>LS: 암호화된 데이터 키 반환 LS->>LS: 환경 변수 암호화 후 저장 Note over EE,Code: 콜드 스타트 발생 시 LS->>KMS: Decrypt 요청 (데이터 키 복호화) KMS-->>LS: 복호화된 데이터 키 반환 LS->>EE: 환경 변수 복호화 후 주입 EE->>Code: os.environ / process.env 로 접근 Code-->>EE: 값 읽기 완료 (추가 KMS 호출 없음)
- 배포/설정 단계: 환경 변수는 KMS 키로 암호화되어 Lambda 서비스 스토리지에 저장된다.
- 콜드 스타트: 실행 환경 초기화 시 Lambda 서비스가 KMS를 호출해 복호화한 뒤 프로세스 환경에 주입한다.
- 함수 코드: 런타임에서 OS 환경 변수로 읽는다. 추가 API 호출 없음.
- 웜 실행: 이미 초기화된 실행 환경을 재사용하므로 KMS 호출이 발생하지 않는다.
환경 변수 설정 — CLI로 직접 적용하기
콘솔보다 CLI가 더 명확하다. 함수를 처음 생성하거나 기존 함수에 환경 변수를 추가/수정할 때 모두 update-function-configuration을 사용한다.
1단계: 환경 변수 설정 (기본 AWS 관리형 키)
aws lambda update-function-configuration \
--function-name my-api-function \
--environment 'Variables={DB_ENDPOINT=mydb.cluster-xxxx.us-east-1.rds.amazonaws.com,DB_PORT=5432,ENV=production}' \
--region us-east-1
--environment 파라미터는 기존 환경 변수 전체를 교체한다. 일부만 수정하려면 현재 값을 먼저 조회한 뒤 전체를 다시 전달해야 한다. 이 점을 놓치면 기존 변수가 조용히 삭제된다.
2단계: 설정 확인
aws lambda get-function-configuration \
--function-name my-api-function \
--region us-east-1 \
--query 'Environment'
KMS 고객 관리형 키로 환경 변수 암호화하기
규정 준수 요구사항이나 키 접근 감사가 필요한 경우 CMK를 사용한다. 설정 순서가 중요하다 — IAM 권한을 먼저 부여하지 않으면 함수 업데이트 자체가 실패한다.
kms:Decrypt 권한 추가"]; C --> D{"권한 적용 확인
iam simulate-principal-policy"}; D -- "허용됨" --> E["함수에 KMS Key ARN 연결
update-function-configuration"]; D -- "거부됨" --> F["SCP / 권한 경계 확인"]; F --> C; E --> G["환경 변수 설정"]; G --> H["get-function-configuration으로
KMSKeyArn 확인"];
- KMS 키 생성: Lambda 전용 CMK를 만든다. 키 정책에서 Lambda 실행 역할을 사용자(User)로 등록해야 한다.
- 실행 역할 권한 부여:
kms:Decrypt권한이 없으면 콜드 스타트 시 함수가 환경 변수를 읽지 못하고 실패한다. - 함수에 KMS 키 연결:
--kms-key-arn으로 지정한다.
1단계: KMS 키 생성
aws kms create-key \
--description 'Lambda environment variable encryption key' \
--key-usage ENCRYPT_DECRYPT \
--region us-east-1
반환된 KeyMetadata.KeyId를 기록해둔다. 이후 단계에서 ARN 형태로 사용한다.
2단계: KMS 키 별칭 생성 (선택, 관리 편의)
aws kms create-alias \
--alias-name alias/lambda-env-key \
--target-key-id <KeyId> \
--region us-east-1
3단계: Lambda 실행 역할에 KMS 권한 추가
실행 역할이 kms:Decrypt를 호출할 수 없으면 콜드 스타트 시 환경 변수 복호화에 실패한다. 에러 메시지가 직관적이지 않아서 처음에는 코드 문제로 오해하기 쉽다.
🔽 IAM 인라인 정책 JSON 보기
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowLambdaKMSDecrypt",
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": "arn:aws:kms:us-east-1:123456789012:key/<your-key-id>"
}
]
}
aws iam put-role-policy \
--role-name my-lambda-execution-role \
--policy-name LambdaKMSDecryptPolicy \
--policy-document file://kms-decrypt-policy.json
4단계: CMK를 사용하도록 함수 업데이트
aws lambda update-function-configuration \
--function-name my-api-function \
--kms-key-arn arn:aws:kms:us-east-1:123456789012:key/<your-key-id> \
--environment 'Variables={DB_ENDPOINT=mydb.cluster-xxxx.us-east-1.rds.amazonaws.com,DB_PORT=5432,ENV=production}' \
--region us-east-1
5단계: 암호화 키 적용 확인
aws lambda get-function-configuration \
--function-name my-api-function \
--region us-east-1 \
--query '{KMSKeyArn: KMSKeyArn, Environment: Environment.Variables}'
함수 코드에서 환경 변수 읽기
런타임에서는 복호화가 이미 완료된 상태로 주입되므로 별도 KMS API 호출 없이 읽으면 된다.
Python
import os
import psycopg2
def handler(event, context):
db_endpoint = os.environ['DB_ENDPOINT']
db_port = int(os.environ.get('DB_PORT', '5432'))
# 연결 로직
conn = psycopg2.connect(
host=db_endpoint,
port=db_port,
database=os.environ['DB_NAME'],
user=os.environ['DB_USER'],
password=os.environ['DB_PASSWORD']
)
return {'statusCode': 200}
Node.js
exports.handler = async (event) => {
const dbEndpoint = process.env.DB_ENDPOINT;
const dbPort = process.env.DB_PORT || '5432';
// 연결 로직
return { statusCode: 200 };
};
실제 운영에서 마주치는 문제: 잘못된 KMS 권한 진단
증상은 이렇다. 함수 코드와 환경 변수 설정은 정상인데, 특정 시간대에 간헐적으로 Runtime.ImportModuleError 또는 초기화 타임아웃이 발생한다. CloudWatch Logs에는 환경 변수 관련 에러가 아닌 모듈 로드 실패처럼 보인다.
처음에는 레이어 버전 충돌이나 패키지 누락으로 오해한다. 실제 원인은 콜드 스타트 시 KMS 복호화 실패였다. 실행 역할의 kms:Decrypt 권한이 특정 키 ARN에만 허용되어 있었는데, 키 별칭으로 참조하는 다른 환경의 함수가 같은 역할을 공유하면서 권한 범위가 맞지 않았다.
진단 순서는 다음과 같다.
1단계: 함수에 연결된 KMS 키 ARN 확인
aws lambda get-function-configuration \
--function-name my-api-function \
--region us-east-1 \
--query 'KMSKeyArn'
2단계: 실행 역할의 KMS 권한 시뮬레이션
IAM Policy Simulator를 CLI로 실행해 실제 권한 평가 결과를 확인한다. 콘솔에서 보이는 정책과 실제 평가 결과가 다를 수 있다 — SCP나 권한 경계가 개입하면 Allow로 보이는 정책이 실제로는 차단된다.
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:role/my-lambda-execution-role \
--action-names kms:Decrypt \
--resource-arns arn:aws:kms:us-east-1:123456789012:key/<your-key-id> \
--region us-east-1
3단계: CloudTrail에서 KMS 복호화 이벤트 확인
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=Decrypt \
--start-time 2024-01-15T00:00:00Z \
--end-time 2024-01-15T01:00:00Z \
--region us-east-1 \
--query 'Events[?contains(CloudTrailEvent, `my-api-function`)].{Time:EventTime,Result:CloudTrailEvent}'
CloudTrail에 AccessDenied로 기록된 Decrypt 이벤트가 보이면 권한 문제가 확정된다. 이 로그가 없다면 KMS 키 자체가 잘못 지정된 것이다.
환경 변수 vs. Secrets Manager — 언제 무엇을 쓸까
환경 변수에 데이터베이스 비밀번호를 넣는 것은 편리하지만, 보안 요구사항이 높아지면 한계가 있다. 환경 변수는 함수 설정을 읽을 수 있는 IAM 권한이 있으면 평문으로 노출된다. lambda:GetFunctionConfiguration 권한을 가진 사람은 누구나 값을 볼 수 있다.
| 기준 | 환경 변수 + CMK | Secrets Manager | SSM Parameter Store (SecureString) |
|---|---|---|---|
| 자동 교체(Rotation) | 미지원 | 지원 (Lambda 기반) | 미지원 (수동) |
| 접근 감사 | CloudTrail KMS 이벤트 | CloudTrail Secrets Manager 이벤트 | CloudTrail SSM 이벤트 |
| 런타임 API 호출 | 불필요 (주입됨) | 필요 (SDK 호출) | 필요 (SDK 호출) |
| 비용 | KMS 키 비용만 | 시크릿당 월 요금 발생 | 표준 파라미터 무료, 고급 유료 |
| 적합한 용도 | 비민감 설정값, 엔드포인트 | DB 비밀번호, API 키 | 설정값, 비밀번호 (비용 민감) |
환경 변수는 '어디에 연결하는가'를 담기 좋고, Secrets Manager는 '어떻게 인증하는가'를 담기 좋다. DB 엔드포인트는 환경 변수, DB 비밀번호는 Secrets Manager — 이 조합이 실용적인 기준선이다.
Terraform으로 환경 변수와 KMS 암호화 구성하기
CLI로 설정하면 상태 관리가 어렵다. 프로덕션에서는 IaC로 관리하는 것이 기본이다.
🔽 Terraform 구성 예시 보기
resource "aws_kms_key" "lambda_env_key" {
description = "Lambda environment variable encryption key"
deletion_window_in_days = 7
enable_key_rotation = true
}
resource "aws_kms_alias" "lambda_env_key_alias" {
name = "alias/lambda-env-key"
target_key_id = aws_kms_key.lambda_env_key.key_id
}
resource "aws_iam_role_policy" "lambda_kms_decrypt" {
name = "LambdaKMSDecryptPolicy"
role = aws_iam_role.lambda_exec.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["kms:Decrypt"]
Resource = aws_kms_key.lambda_env_key.arn
}
]
})
}
resource "aws_lambda_function" "my_api_function" {
function_name = "my-api-function"
role = aws_iam_role.lambda_exec.arn
handler = "index.handler"
runtime = "python3.12"
filename = "function.zip"
kms_key_arn = aws_kms_key.lambda_env_key.arn
environment {
variables = {
DB_ENDPOINT = "mydb.cluster-xxxx.us-east-1.rds.amazonaws.com"
DB_PORT = "5432"
ENV = "production"
}
}
}
Lambda 환경 변수 운영 체크리스트
- 민감하지 않은 설정값(엔드포인트, 포트, 리전)은 환경 변수로 관리
- 비밀번호, API 키 등 민감 정보는 Secrets Manager 또는 SSM SecureString 사용
- CMK 사용 시 실행 역할에
kms:Decrypt권한 확인 필수 --environment파라미터는 전체 교체 방식임을 인지하고 기존 값 보존 여부 확인- 키 로테이션 활성화 (
enable_key_rotation = true) - CloudTrail에서 KMS Decrypt 이벤트 모니터링 설정
- 환경별(dev/staging/prod) 함수에 별도 KMS 키 사용 권장
마무리 및 다음 단계
Lambda 환경 변수는 설정값 주입의 가장 간단한 방법이지만, KMS 암호화 설정과 IAM 권한 모델을 정확히 이해하지 않으면 운영 중 예상치 못한 장애로 이어진다. DB 엔드포인트처럼 민감도가 낮은 설정은 환경 변수 + CMK 조합으로 충분하고, 비밀번호처럼 교체가 필요한 자격증명은 Secrets Manager로 분리하는 것이 실용적인 기준선이다.
다음 단계로 AWS Lambda 환경 변수 공식 문서와 Lambda와 Secrets Manager 통합 가이드를 참고하라.
용어 정리 (Glossary)
| 용어 | 설명 |
|---|---|
| 실행 환경 (Execution Environment) | Lambda 함수가 실행되는 격리된 런타임 환경. 콜드 스타트 시 초기화되고 웜 상태에서 재사용됨 |
| 고객 관리형 키 (CMK) | 사용자가 AWS KMS에서 직접 생성하고 관리하는 암호화 키. 키 정책과 감사 로그를 직접 제어 가능 |
| 콜드 스타트 (Cold Start) | 새 실행 환경이 초기화되는 과정. 환경 변수 복호화가 이 시점에 발생함 |
| kms:Decrypt | KMS로 암호화된 데이터를 복호화하는 IAM 액션. Lambda 실행 역할에 반드시 필요 |
| Secrets Manager | 자격증명 저장, 자동 교체, 접근 감사를 제공하는 AWS 관리형 비밀 관리 서비스 |
댓글
댓글 쓰기