TIL - 20260807

juni·2026년 8월 7일

TIL

목록 보기
425/468

0807 인프라/DevOps 운영 심화 (6/N): 환경변수, Secret 관리와 AWS SSM


✅ 1. 환경변수란 무엇인가?

  • 환경변수(Environment Variable)는 애플리케이션 코드 밖에서 실행 환경에 따라 달라지는 값을 주입하는 방식입니다.
  • 데이터베이스 주소, API 주소, 암호화 키, JWT Secret, 외부 서비스 키, 실행 모드 같은 값이 대표적입니다.
  • 환경변수를 쓰는 이유는 같은 코드라도 로컬, 개발, 스테이징, 운영 환경에서 다른 설정으로 실행하기 위해서입니다.
같은 코드
  ↓
로컬 환경변수
  ↓
로컬 DB / 로컬 API 사용

같은 코드
  ↓
운영 환경변수
  ↓
운영 DB / 운영 API 사용

➕ 1-1. 환경변수가 필요한 이유

  • 코드에 민감한 값을 직접 넣지 않기 위해 필요합니다.
  • 로컬/스테이징/운영 설정을 분리할 수 있습니다.
  • 배포 환경에 따라 API 주소와 DB 주소를 다르게 쓸 수 있습니다.
  • Secret을 Git에 커밋하지 않고 관리할 수 있습니다.
  • 새 Mac, CI/CD, 서버 환경에서 설정을 재현하기 쉬워집니다.
코드:
비즈니스 로직

환경변수:
환경별 설정값

Secret Manager/SSM:
민감한 환경변수 저장소

✅ 2. 환경변수와 Secret의 차이

  • 모든 환경변수가 Secret은 아닙니다.
  • 외부에 공개되어도 큰 문제가 없는 설정값도 있고, 절대 노출되면 안 되는 민감값도 있습니다.
구분예시노출 위험
일반 환경변수NODE_ENV, PROJECT_NAME, PUBLIC_API_URL낮음
공개 프론트 환경변수VITE_API_BASE_URL브라우저에 노출됨
SecretDATABASE_URL, JWT_SECRET, AWS_SECRET_ACCESS_KEY높음
암호화 키AES_KEY, COOKIE_SECRET_KEY, SALT_KEY매우 높음

➕ 2-1. Secret 예시

DATABASE_URL
REDIS_URL
JWT_SECRET
ACCESS_TOKEN_SECRET
REFRESH_TOKEN_SECRET
COOKIE_SECRET_KEY
AES_KEY
SALT_KEY
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
KAKAO_CLIENT_SECRET
ALIMTALK_API_KEY
PAYMENT_SECRET_KEY

➕ 2-2. Secret 관리 원칙

코드에 직접 작성하지 않기
Git에 커밋하지 않기
프론트엔드 빌드에 포함하지 않기
개발/운영 값을 분리하기
필요한 사람/서비스만 접근하기
노출 의심 시 즉시 교체하기
  • Secret은 한 번 노출되면 “다시 숨기는 것”이 아니라 “폐기하고 교체하는 것”이 원칙입니다.
  • 특히 운영 DB, AWS 키, JWT Secret은 유출 시 피해가 큽니다.

✅ 3. .env 파일이란 무엇인가?

  • .env 파일은 로컬 개발에서 환경변수를 쉽게 관리하기 위해 많이 사용합니다.
  • Node.js/NestJS/Vite 프로젝트에서 자주 쓰입니다.
  • 하지만 .env는 편한 만큼 Git에 커밋하면 매우 위험합니다.
NODE_ENV=development
DATABASE_URL=postgresql://together:password@localhost:5432/together
JWT_SECRET=local_jwt_secret
REDIS_URL=redis://localhost:6379

➕ 3-1. .env 사용 기준

로컬 개발:
.env.local 또는 .env 사용 가능

운영 서버:
파일로 둘 수도 있지만 권한 관리 필요

CI/CD:
GitHub Secrets 또는 SSM에서 주입

프론트:
VITE_ / NEXT_PUBLIC_ 변수는 노출된다고 생각

➕ 3-2. .gitignore 필수

.env
.env.*
!.env.example
  • .env.example은 커밋해도 됩니다.
  • 실제 값이 아니라 필요한 변수 이름과 예시만 담아야 합니다.

✅ 4. .env.example 관리

  • .env.example은 새 환경을 세팅할 때 필요한 변수 목록을 알려주는 문서 역할을 합니다.
  • 실제 Secret 없이 구조만 남깁니다.
NODE_ENV=development
PROJECT_NAME=togethermall

DATABASE_URL=postgresql://USER:PASSWORD@localhost:5432/DB_NAME?schema=public
SHADOW_DATABASE_URL=postgresql://USER:PASSWORD@localhost:5432/SHADOW_DB_NAME?schema=public
REDIS_URL=redis://localhost:6379

COOKIE_SECRET_KEY=change_me
AES_KEY=change_me
SALT_KEY=change_me
ACCESS_TOKEN_SECRET=change_me
REFRESH_TOKEN_SECRET=change_me

➕ 4-1. 좋은 .env.example 기준

필요한 변수 모두 포함
실제 운영값 없음
로컬 실행 기준 주석 포함
프론트/백엔드 변수 구분
최신 상태 유지

➕ 4-2. 나쁜 .env.example

운영 DB 주소 포함
실제 토큰 포함
오래된 변수 방치
필수 변수 누락
로컬/운영 값이 섞임
  • .env.example이 최신이면 새 Mac 세팅과 AI 자동화 작업이 훨씬 쉬워집니다.
  • 반대로 오래된 .env.example은 세팅 오류를 만듭니다.

✅ 5. 프론트엔드 환경변수 주의점

  • 프론트엔드 환경변수는 백엔드 Secret과 완전히 다르게 생각해야 합니다.
  • Vite의 VITE_, Next.js의 NEXT_PUBLIC_ 값은 브라우저 번들에 포함됩니다.
  • 사용자가 DevTools로 확인할 수 있다고 봐야 합니다.

➕ 5-1. Vite 예시

VITE_API_BASE_URL=https://api.example.com
VITE_PUBLIC_ASSET_URL=https://cdn.example.com
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;

➕ 5-2. 프론트에 넣으면 안 되는 값

DATABASE_URL
JWT_SECRET
COOKIE_SECRET_KEY
AES_KEY
SALT_KEY
AWS_SECRET_ACCESS_KEY
ALIMTALK_API_KEY
PAYMENT_SECRET_KEY
관리자 전용 Secret

➕ 5-3. 프론트에 넣어도 되는 값

공개 API Base URL
공개 CDN URL
서비스 이름
공개용 feature flag
Sentry DSN 같은 공개 client key
지도 public client key
  • 프론트 환경변수는 “숨겨지는 값”이 아닙니다.
  • Secret은 반드시 백엔드에서만 사용해야 합니다.

✅ 6. 백엔드 환경변수 관리 기준

  • 백엔드는 DB, 인증, 암호화, 외부 API Secret을 다루기 때문에 환경변수 관리가 훨씬 중요합니다.

➕ 6-1. 백엔드 환경변수 예시

NODE_ENV=production
PORT=3000

DATABASE_URL=postgresql://user:password@rds-host:5432/together
REDIS_URL=redis://redis-host:6379

COOKIE_SECRET_KEY=...
AES_KEY=...
SALT_KEY=...
ACCESS_TOKEN_SECRET=...
REFRESH_TOKEN_SECRET=...

AWS_REGION=ap-northeast-2
S3_BUCKET_NAME=...

➕ 6-2. 관리 기준

필수 변수 검증
운영/개발 값 분리
Secret은 SSM/Secrets Manager 사용 검토
로그에 env 값 출력 금지
env 변경 시 재시작/재배포 기준 정리
  • 백엔드 환경변수는 애플리케이션 시작 시 검증하는 것이 좋습니다.
  • 누락된 환경변수를 늦게 발견하면 운영 장애로 이어질 수 있습니다.

✅ 7. 환경변수 검증

  • 환경변수는 앱 시작 시 검증해야 합니다.
  • 값이 없거나 형식이 틀리면 서버를 바로 실패시키는 것이 낫습니다.
  • 잘못된 값으로 어중간하게 실행되면 장애 원인을 찾기 어렵습니다.

➕ 7-1. zod 검증 예시

import { z } from 'zod';

const envSchema = z.object({
  NODE_ENV: z.enum(['development', 'test', 'production']),
  DATABASE_URL: z.string().url(),
  COOKIE_SECRET_KEY: z.string().min(32),
  ACCESS_TOKEN_SECRET: z.string().min(32),
  REFRESH_TOKEN_SECRET: z.string().min(32),
});

export const env = envSchema.parse(process.env);

➕ 7-2. 검증하면 좋은 항목

필수값 존재 여부
URL 형식
숫자 범위
NODE_ENV 허용값
Secret 길이
운영에서 localhost 금지
운영에서 insecure 설정 금지

➕ 7-3. 운영에서 막아야 할 값

DATABASE_URL=localhost
REDIS_URL=localhost
COOKIE_SECURE=false
NODE_ENV=development
API_BASE_URL=http://
  • 운영 환경에서 localhost가 들어가면 치명적인 오류가 날 수 있습니다.
  • 배포 전 env 검증은 방어선 역할을 합니다.

✅ 8. AWS SSM Parameter Store란 무엇인가?

  • AWS SSM Parameter Store는 AWS Systems Manager의 기능 중 하나로, 환경변수나 설정값을 안전하게 저장하고 읽을 수 있는 서비스입니다.
  • 로컬 .env 파일 대신 SSM에 값을 저장하고, 애플리케이션 실행 시 가져와 사용할 수 있습니다.
  • 민감한 값은 SecureString으로 저장해 KMS 암호화를 적용할 수 있습니다.
AWS SSM Parameter Store
  ↓
/togethermall/development/DATABASE_URL
/togethermall/production/DATABASE_URL
/togethermall/production/JWT_SECRET
  ↓
앱 실행 시 읽기

➕ 8-1. SSM의 장점

  • Secret을 Git에 두지 않을 수 있습니다.
  • 환경별 값을 경로로 분리할 수 있습니다.
  • IAM 권한으로 접근 제어할 수 있습니다.
  • AWS CLI, SDK, GitHub Actions에서 읽을 수 있습니다.
  • 로컬 개발 환경도 .env 없이 구성할 수 있습니다.

➕ 8-2. SSM에 적합한 값

DATABASE_URL
REDIS_URL
JWT Secret
Cookie Secret
AES/SALT Key
외부 API Key
프로젝트별 환경 설정
배포용 설정값
  • SSM은 “운영 Secret을 안전하게 보관하는 곳”이자 “환경별 설정의 기준 저장소”가 될 수 있습니다.

✅ 9. SSM Parameter 타입

타입설명사용 예시
String일반 문자열NODE_ENV, PROJECT_NAME
StringList쉼표 구분 목록허용 origin 목록
SecureString암호화된 문자열DATABASE_URL, JWT_SECRET

➕ 9-1. String

값이 민감하지 않은 일반 설정

예:
/togethermall/development/NODE_ENV
/togethermall/development/PROJECT_NAME

➕ 9-2. SecureString

민감한 Secret

예:
/togethermall/production/DATABASE_URL
/togethermall/production/ACCESS_TOKEN_SECRET
/togethermall/production/COOKIE_SECRET_KEY

➕ 9-3. 기준

공개되어도 큰 문제 없는 값:
String

유출되면 위험한 값:
SecureString

목록 형태:
StringList 또는 JSON String
  • 헷갈리면 Secret 성격의 값은 SecureString으로 저장하는 것이 안전합니다.

✅ 10. SSM 경로 설계

  • SSM은 경로 구조를 잘 잡는 것이 중요합니다.
  • 프로젝트명, 환경명, 앱 이름을 기준으로 나누면 관리하기 쉽습니다.

➕ 10-1. 기본 구조

/togethermall/development/back/DATABASE_URL
/togethermall/development/back/COOKIE_SECRET_KEY
/togethermall/development/front/VITE_API_BASE_URL
/togethermall/development/admin/VITE_API_BASE_URL

/togethermall/production/back/DATABASE_URL
/togethermall/production/back/COOKIE_SECRET_KEY
/togethermall/production/front/VITE_API_BASE_URL
/togethermall/production/admin/VITE_API_BASE_URL

➕ 10-2. 경로 기준

/프로젝트명/환경명/앱이름/변수명

➕ 10-3. 예시

/togethermall/local/back/DATABASE_URL
/togethermall/development/back/DATABASE_URL
/togethermall/staging/back/DATABASE_URL
/togethermall/production/back/DATABASE_URL
  • 운영과 개발 경로가 섞이면 위험합니다.
  • 경로만 봐도 어떤 프로젝트, 어떤 환경, 어떤 앱 값인지 알 수 있어야 합니다.

✅ 11. AWS CLI로 SSM 값 저장

  • AWS CLI를 사용해 SSM Parameter를 저장할 수 있습니다.

➕ 11-1. String 저장

aws ssm put-parameter \
  --name "/togethermall/development/back/NODE_ENV" \
  --value "development" \
  --type "String" \
  --overwrite \
  --region ap-northeast-2

➕ 11-2. SecureString 저장

aws ssm put-parameter \
  --name "/togethermall/development/back/DATABASE_URL" \
  --value "postgresql://user:password@localhost:5432/together?schema=public" \
  --type "SecureString" \
  --overwrite \
  --region ap-northeast-2

➕ 11-3. 주의

터미널 히스토리에 Secret이 남을 수 있음
스크립트에 실제 Secret 하드코딩 금지
공유 화면에서 명령어 노출 주의
운영값 입력 전 profile/region 확인
  • CLI로 Secret을 직접 입력하면 shell history에 남을 수 있습니다.
  • 민감한 값은 입력 방식과 기록 관리도 신경 써야 합니다.

✅ 12. AWS CLI로 SSM 값 읽기

➕ 12-1. 단일 값 읽기

aws ssm get-parameter \
  --name "/togethermall/development/back/DATABASE_URL" \
  --with-decryption \
  --region ap-northeast-2

➕ 12-2. 경로 기준으로 여러 값 읽기

aws ssm get-parameters-by-path \
  --path "/togethermall/development/back" \
  --with-decryption \
  --recursive \
  --region ap-northeast-2

➕ 12-3. 값만 출력

aws ssm get-parameter \
  --name "/togethermall/development/back/DATABASE_URL" \
  --with-decryption \
  --query "Parameter.Value" \
  --output text \
  --region ap-northeast-2
  • SecureString은 --with-decryption이 있어야 실제 값을 읽을 수 있습니다.
  • 읽기 권한이 없으면 AccessDenied가 발생합니다.

✅ 13. SSM 값을 .env로 생성하는 방식

  • 로컬 개발에서는 SSM에서 값을 읽어 .env.local 파일을 생성하는 스크립트를 만들 수 있습니다.
  • 이렇게 하면 실제 Secret을 Git에 두지 않고도 로컬 실행이 쉬워집니다.

➕ 13-1. 흐름

AWS SSO 로그인
  ↓
SSM 값 읽기
  ↓
.env.local 생성
  ↓
npm run dev

➕ 13-2. 예시 스크립트 개념

aws ssm get-parameters-by-path \
  --path "/togethermall/development/back" \
  --with-decryption \
  --recursive \
  --region ap-northeast-2

➕ 13-3. 주의

생성된 .env.local은 Git 커밋 금지
파일 권한 확인
운영 SSM 경로로 잘못 생성하지 않기
기존 .env 덮어쓰기 전 확인
  • SSM을 쓰더라도 최종적으로 로컬에 .env.local이 생성되면 그 파일은 Secret 파일입니다.
  • 반드시 .gitignore에 포함되어야 합니다.

✅ 14. 앱 실행 시 SSM에서 직접 읽기

  • 서버 실행 시 AWS SDK로 SSM 값을 직접 읽는 방식도 가능합니다.
  • 하지만 애플리케이션 시작 속도, 장애 지점, IAM 권한을 고려해야 합니다.

➕ 14-1. 구조

앱 시작
  ↓
AWS SDK로 SSM Parameter 읽기
  ↓
env config 구성
  ↓
서버 실행

➕ 14-2. 장점

서버에 .env 파일을 두지 않아도 됨
SSM 값 변경 관리 가능
IAM Role 기반 접근 가능

➕ 14-3. 단점

앱 시작 시 AWS 의존성 증가
SSM 장애/권한 오류 시 앱 시작 실패
로컬 실행 복잡도 증가
캐싱 전략 필요
  • 초기에는 배포 시 SSM 값을 읽어 환경변수로 주입하는 방식이 더 단순할 수 있습니다.
  • 운영 서버가 AWS 안에 있다면 IAM Role 기반 접근을 고려할 수 있습니다.

✅ 15. GitHub Actions에서 SSM 사용

  • GitHub Actions 배포 과정에서 SSM 값을 읽어 빌드 또는 배포에 사용할 수 있습니다.
  • 단, 프론트 빌드에 들어가는 값은 결국 브라우저에 노출됩니다.

➕ 15-1. SSM에서 프론트 env 읽기

- name: Load frontend env from SSM
  run: |
    echo "VITE_API_BASE_URL=$(aws ssm get-parameter \
      --name /togethermall/production/front/VITE_API_BASE_URL \
      --query Parameter.Value \
      --output text)" >> $GITHUB_ENV

➕ 15-2. SecureString 읽기

- name: Load backend secret from SSM
  run: |
    echo "DATABASE_URL=$(aws ssm get-parameter \
      --name /togethermall/production/back/DATABASE_URL \
      --with-decryption \
      --query Parameter.Value \
      --output text)" >> $GITHUB_ENV

➕ 15-3. 주의

로그에 값 출력 금지
set -x 사용 금지
프론트 env와 backend secret 구분
GitHub Actions IAM 권한 최소화
운영 SSM 경로 접근은 production workflow로 제한
  • GitHub Actions 로그에 Secret이 찍히면 안 됩니다.
  • 배포용 IAM은 필요한 SSM 경로만 읽을 수 있어야 합니다.

✅ 16. AWS SSO와 로컬 개발

  • 로컬에서 AWS SSM을 읽으려면 AWS CLI 인증이 필요합니다.
  • 회사 AWS는 가능하면 Access Key를 개인 Mac에 오래 저장하기보다 AWS SSO를 사용하는 것이 안전합니다.

➕ 16-1. SSO 로그인

aws sso login --profile togethermall-dev

➕ 16-2. profile 사용

AWS_PROFILE=togethermall-dev aws ssm get-parameters-by-path \
  --path "/togethermall/development/back" \
  --with-decryption \
  --recursive \
  --region ap-northeast-2

➕ 16-3. 주의

profile 이름 명확히 구분
운영 profile과 개발 profile 분리
터미널 prompt에 profile 표시 고려
SSO 세션 만료 시 재로그인 필요
  • 개발용 profile과 운영용 profile은 반드시 구분해야 합니다.
  • 운영 profile로 로컬 개발 스크립트를 돌리는 실수를 막아야 합니다.

✅ 17. IAM 권한 최소화

  • SSM을 제대로 쓰려면 IAM 권한 설계가 중요합니다.
  • 모든 SSM 값을 읽을 수 있게 하면 위험합니다.
  • 프로젝트와 환경별로 필요한 경로만 읽도록 제한해야 합니다.

➕ 17-1. 개발용 권한 예시

허용:
ssm:GetParameter
ssm:GetParameters
ssm:GetParametersByPath

경로:
arn:aws:ssm:ap-northeast-2:ACCOUNT_ID:parameter/togethermall/development/*

➕ 17-2. 운영용 권한

운영 배포 role:
production 경로 읽기 가능

일반 개발자:
production Secret 읽기 제한

GitHub Actions:
필요한 production 경로만 읽기 가능

➕ 17-3. 원칙

필요한 프로젝트만
필요한 환경만
필요한 경로만
필요한 액션만
  • Secret 관리에서 가장 중요한 원칙은 최소 권한입니다.
  • 접근 권한이 넓을수록 유출 시 피해 범위도 커집니다.

✅ 18. SSM과 KMS

  • SSM SecureString은 KMS를 사용해 암호화할 수 있습니다.
  • 기본 AWS managed key를 사용할 수도 있고, 직접 만든 KMS key를 사용할 수도 있습니다.

➕ 18-1. KMS가 필요한 이유

SecureString 암호화
복호화 권한 제어
키 사용 감사
환경별 key 분리 가능

➕ 18-2. 주의

SSM 읽기 권한만으로 부족할 수 있음
SecureString 복호화에는 kms:Decrypt 필요
KMS key 정책 확인 필요
운영 key 접근 권한 최소화
  • AccessDenied가 발생하면 SSM 권한뿐 아니라 KMS 권한도 확인해야 합니다.
  • SecureString을 읽을 때는 ssm:GetParameter와 kms:Decrypt가 모두 필요할 수 있습니다.

✅ 19. AWS Secrets Manager와 SSM 차이

  • AWS에는 Secrets Manager도 있습니다.
  • 둘 다 Secret 저장에 사용할 수 있지만 목적과 비용, 기능이 다릅니다.
구분SSM Parameter StoreSecrets Manager
용도설정값/Secret 저장Secret 전문 관리
비용상대적으로 저렴/기본 사용 쉬움비용 더 발생 가능
Rotation직접 구성 필요자동 Rotation 기능 강함
구조경로 기반 ParameterSecret 단위
사용 예환경변수, 앱 설정DB password, API Secret rotation

➕ 19-1. SSM이 적합한 경우

환경변수 관리
로컬/개발/운영 설정 분리
간단한 Secret 저장
경로 기반 관리

➕ 19-2. Secrets Manager가 적합한 경우

정기적 Secret rotation 필요
DB credential 자동 교체
보안 요구가 높은 운영 Secret
Secret version 관리가 중요
  • 1인 개발/중소 규모 프로젝트에서는 SSM Parameter Store부터 시작해도 충분한 경우가 많습니다.
  • DB 비밀번호 자동 rotation까지 필요해지면 Secrets Manager를 검토하면 됩니다.

✅ 20. Secret Rotation

  • Secret Rotation은 Secret을 주기적으로 교체하는 작업입니다.
  • 보안 사고가 있었거나 키가 오래됐거나 접근자가 바뀌었다면 교체해야 합니다.

➕ 20-1. 교체해야 하는 상황

Secret이 Git에 올라감
터미널/로그/스크린샷에 노출됨
PC 감염 또는 탈취 의심
퇴사자/외부 작업자 접근 이력
키가 너무 오래됨
권한 범위가 과도함

➕ 20-2. 교체 순서

1. 새 Secret 생성
2. SSM/환경변수 업데이트
3. 앱 재시작/재배포
4. 정상 동작 확인
5. 기존 Secret 폐기
6. 로그/문서/권한 정리

➕ 20-3. 주의

JWT Secret 교체 시 기존 토큰 무효화 가능
DB password 교체 시 연결 중단 가능
외부 API key 교체 시 callback 설정 확인
운영 배포 시간 고려
  • Secret 교체는 단순 변경이 아닙니다.
  • 어떤 사용자가 영향을 받는지, 기존 세션이 끊기는지 확인해야 합니다.

✅ 21. 로컬 개발에서 Secret 노출 줄이기

  • 로컬 개발 장비는 항상 안전하다고 보면 안 됩니다.
  • 브라우저, 터미널, 메모앱, 스크린샷, 로그, AI 도구를 통해 Secret이 노출될 수 있습니다.

➕ 21-1. 주의할 곳

.env 파일
터미널 history
console.log
에러 로그
스크린샷
메모앱
Notion 문서
AI 프롬프트
Git 커밋
GitHub issue/PR

➕ 21-2. 방지 방법

.env는 Git 제외
Secret은 문서에 붙여넣지 않기
AI에게 실제 Secret 제공 금지
터미널 공유 전 마스킹
로그에 process.env 출력 금지
운영 Secret 로컬 저장 최소화
  • 특히 AI에게 에러 분석을 맡길 때 .env 전체를 붙여넣으면 안 됩니다.
  • 필요한 값은 ****로 마스킹하고 구조만 알려주면 됩니다.

✅ 22. Secret 스캔

  • Git에 Secret이 들어가는 것을 막기 위해 secret scanning 도구를 사용할 수 있습니다.
  • GitHub 자체 secret scanning, gitleaks 같은 도구가 대표적입니다.

➕ 22-1. gitleaks 예시

brew install gitleaks
gitleaks detect --source .

➕ 22-2. 사용 시점

커밋 전
배포 전
공개 레포 전환 전
보안 사고 후 점검

➕ 22-3. 주의

도구가 모든 Secret을 잡지는 못함
오탐 가능
잡힌 Secret은 삭제가 아니라 폐기/교체 필요
Git history에 남은 Secret도 위험
  • 이미 Git history에 들어간 Secret은 파일에서 지우는 것만으로 끝나지 않습니다.
  • 외부에 노출됐을 가능성이 있으면 교체해야 합니다.

✅ 23. 운영 서버에서 환경변수 주입 방식

  • 운영 서버에서 환경변수를 주입하는 방식은 여러 가지가 있습니다.
방식설명장점주의
.env 파일서버 파일로 저장단순함파일 권한/백업 주의
systemd EnvironmentFilesystemd 서비스에 주입서버 프로세스 관리와 연결파일 관리 필요
Docker Compose env_file컨테이너 실행 시 주입컨테이너 운영에 편함env 파일 보안
SSM에서 배포 시 생성배포 과정에서 env 생성Git 제외 가능스크립트 관리 필요
앱 시작 시 SSM 직접 읽기앱이 직접 SSM 호출env 파일 감소시작 의존성 증가

➕ 23-1. PM2 기준

PM2 ecosystem.config.js에 env 설정 가능
단, Secret을 파일에 직접 넣으면 파일 보안 필요

➕ 23-2. Docker Compose 기준

services:
  backend:
    image: togethermall-api
    env_file:
      - .env.production

➕ 23-3. 추천 기준

초기:
서버 .env.production + 파일 권한 관리

개선:
SSM에서 배포 시 .env 생성

더 개선:
IAM Role 기반 SSM 직접 읽기 또는 ECS/Parameter Store 연동
  • 지금 단계에서는 복잡한 Secret 운영보다 “Git에 안 올리고, 접근 권한을 줄이고, 환경별로 분리하는 것”이 우선입니다.

✅ 24. 환경변수 변경과 재시작

  • 환경변수를 바꿨다고 실행 중인 앱에 바로 반영되는 것은 아닙니다.
  • 대부분의 Node.js 앱은 시작 시점에 환경변수를 읽습니다.
  • 따라서 env 변경 후 앱 재시작이 필요합니다.

➕ 24-1. PM2 재시작

pm2 restart togethermall-api --update-env

➕ 24-2. Docker Compose 재시작

docker compose up -d --force-recreate backend

➕ 24-3. 주의

환경변수 변경 후 재시작 필요
프론트 env 변경은 재빌드 필요
백엔드 env 변경은 재시작 필요
DB 연결값 변경은 health check 필요
Secret 변경은 기존 세션 영향 확인
  • 프론트와 백엔드는 env 반영 방식이 다릅니다.
  • 프론트는 재빌드, 백엔드는 재시작이 기본입니다.

✅ 25. 환경별 분리 기준

  • 로컬, 개발, 스테이징, 운영 환경의 Secret은 분리해야 합니다.

➕ 25-1. 환경별 목적

local:
개인 Mac 개발

development:
개발 서버 또는 내부 테스트

staging:
운영 배포 전 검증

production:
실제 고객/운영자 사용

➕ 25-2. 절대 섞이면 안 되는 것

로컬에서 운영 DB 사용
개발 서버에서 운영 알림톡 발송
스테이징에서 운영 고객 데이터 수정
프론트 운영 빌드에 개발 API URL 포함
운영 서버가 development NODE_ENV로 실행

➕ 25-3. 환경명 명확화

DATABASE_URL_LOCAL
DATABASE_URL_STAGING
DATABASE_URL_PRODUCTION

또는 SSM 경로:
/togethermall/local/back/DATABASE_URL
/togethermall/staging/back/DATABASE_URL
/togethermall/production/back/DATABASE_URL
  • 환경 이름은 귀찮아도 명확하게 붙여야 합니다.
  • 모호한 이름은 사고로 이어집니다.

✅ 26. AI에게 환경변수/SSM 문제를 물어볼 때 좋은 질문법

  • 환경변수 문제는 앱 종류, 실행 위치, env 주입 방식, 오류 메시지, 실제 값의 마스킹된 형태를 알려줘야 정확히 분석할 수 있습니다.
  • 절대 실제 Secret을 그대로 붙여넣으면 안 됩니다.

➕ 26-1. 좋은 질문 예시

NestJS + Prisma 백엔드에서 AWS SSM Parameter Store로 환경변수를 관리하려고 해.

상황:
1. 로컬은 Mac + OrbStack PostgreSQL 사용
2. 개발 SSM 경로는 /togethermall/development/back/*
3. 운영 SSM 경로는 /togethermall/production/back/*
4. DATABASE_URL, COOKIE_SECRET_KEY, ACCESS_TOKEN_SECRET은 SecureString
5. AWS SSO profile은 togethermall-dev 사용
6. 백엔드는 로컬 Node에서 npm run dev로 실행
7. SSM에서 값을 읽어 .env.local을 생성하는 스크립트를 만들고 싶음
8. 실제 Secret 값은 아래처럼 마스킹함
   - DATABASE_URL=postgresql://****:****@localhost:5432/together
   - ACCESS_TOKEN_SECRET=****
9. 현재 에러는 AccessDenied 또는 Missing env임

요청:
- SSM 경로 설계 점검
- 필요한 IAM 권한
- AWS CLI 확인 명령어
- .env.local 생성 흐름
- zod env validation 예시
- 운영값과 개발값을 헷갈리지 않기 위한 체크리스트
- Secret 노출 방지 기준
을 정리해줘.

➕ 26-2. AI 답변 검증 기준

  1. 실제 Secret을 요구하지 않는가?
  2. 프론트 env와 백엔드 Secret을 구분하는가?
  3. SSM String과 SecureString 차이를 설명하는가?
  4. --with-decryption 필요성을 언급하는가?
  5. IAM과 KMS 권한을 함께 확인하는가?
  6. 운영/개발 SSM 경로 분리를 강조하는가?
  7. env 변경 후 재시작/재빌드 차이를 설명하는가?
  8. Git history에 노출된 Secret은 교체해야 한다고 말하는가?

✅ 27. 실무 체크리스트

➕ 27-1. 환경변수 체크리스트

  1. .env가 .gitignore에 포함되어 있는가?
  2. .env.example이 최신인가?
  3. 로컬/개발/스테이징/운영 값이 분리되어 있는가?
  4. 프론트 env에 Secret이 들어가지 않았는가?
  5. 운영 env에 localhost가 들어가지 않았는가?
  6. 필수 env 검증 로직이 있는가?
  7. env 변경 후 재시작/재빌드 기준이 문서화되어 있는가?
  8. 로그에 env 전체를 출력하지 않는가?

➕ 27-2. SSM 체크리스트

  1. SSM 경로가 /프로젝트/환경/앱/변수명 기준으로 정리되어 있는가?
  2. Secret 값은 SecureString으로 저장되어 있는가?
  3. 개발/운영 SSM 경로가 분리되어 있는가?
  4. --with-decryption이 필요한 값이 구분되어 있는가?
  5. IAM 권한이 필요한 경로로 제한되어 있는가?
  6. KMS Decrypt 권한이 필요한 경우 설정되어 있는가?
  7. GitHub Actions에서 필요한 SSM 경로만 읽는가?
  8. SSM 값 변경 이력과 영향 범위를 기록하는가?

➕ 27-3. Secret 보안 체크리스트

  1. Secret을 코드에 직접 작성하지 않았는가?
  2. Secret을 AI 프롬프트에 그대로 넣지 않았는가?
  3. Secret이 터미널/로그/스크린샷에 노출되지 않았는가?
  4. Git history에 Secret이 들어간 적 없는가?
  5. gitleaks 등으로 공개 전 스캔했는가?
  6. 노출 의심 Secret은 폐기/교체했는가?
  7. AWS 키는 최소 권한으로 발급했는가?
  8. 운영 Secret 접근자를 최소화했는가?

➕ 27-4. 운영 분리 체크리스트

  1. 로컬에서 운영 DB를 쓰지 않는가?
  2. 개발 서버에서 운영 알림톡/SMS가 발송되지 않는가?
  3. 스테이징과 운영 API URL이 분리되어 있는가?
  4. 운영 배포 workflow와 개발 workflow가 분리되어 있는가?
  5. AWS profile 이름이 명확한가?
  6. 운영 명령어 실행 전 profile/region/account를 확인하는가?
  7. production SSM 접근 권한이 제한되어 있는가?
  8. 운영 Secret 변경 시 롤백/재시작 계획이 있는가?

📌 요약

  • 환경변수는 코드 밖에서 실행 환경별 설정값을 주입하는 방식이며, 로컬/개발/스테이징/운영 환경을 분리하는 핵심 도구입니다.
  • 모든 환경변수가 Secret은 아니지만, DATABASE_URL, JWT_SECRET, COOKIE_SECRET_KEY, AES_KEY, AWS_SECRET_ACCESS_KEY 같은 값은 유출되면 치명적이므로 별도로 안전하게 관리해야 합니다.
  • .env 파일은 로컬 개발에서는 편하지만 Git에 커밋하면 위험하므로 반드시 .gitignore에 포함하고, 실제 값 없는 .env.example만 커밋해야 합니다.
  • 프론트엔드의 VITE_, NEXT_PUBLIC_ 환경변수는 브라우저에 노출된다고 봐야 하며, Secret은 절대 넣으면 안 됩니다.
  • 백엔드는 앱 시작 시 환경변수를 검증해야 하며, 운영 환경에서 localhost, NODE_ENV=development, COOKIE_SECURE=false 같은 위험한 값이 들어가지 않게 막아야 합니다.
  • AWS SSM Parameter Store는 환경변수와 Secret을 경로 기반으로 저장하고 IAM 권한으로 접근 제어할 수 있는 서비스입니다.
  • SSM에서는 일반 설정은 String, 민감한 Secret은 SecureString으로 저장하고, SecureString을 읽을 때는 --with-decryption과 KMS 권한이 필요할 수 있습니다.
  • SSM 경로는 /프로젝트명/환경명/앱이름/변수명처럼 설계하면 개발/운영 값을 분리하기 쉽습니다.
  • GitHub Actions에서 SSM 값을 읽을 수 있지만, 로그에 Secret이 출력되지 않게 주의하고, 배포용 IAM 권한은 필요한 SSM 경로와 AWS 작업으로 제한해야 합니다.
  • Secret이 노출됐거나 노출이 의심되면 파일에서 지우는 것으로 끝나지 않고 반드시 폐기/교체해야 합니다.
  • 프론트 env 변경은 재빌드가 필요하고, 백엔드 env 변경은 앱 재시작이 필요합니다.
  • AI에게 환경변수 문제를 물어볼 때는 실제 Secret을 그대로 붙여넣지 말고, 경로 구조와 마스킹된 형태, 오류 메시지, 실행 환경만 제공해야 합니다.

0개의 댓글