AWS Secrets Manager에서 RDS 데이터베이스에 대한 자격증명 사용법

GarionNachal·2025년 12월 11일

AWS

목록 보기
6/11
post-thumbnail

📋 목차

  1. AWS Secrets Manager란?
  2. RDS와 Secrets Manager 통합의 장점
  3. RDS 자격증명을 Secrets Manager에 저장하기
  4. 애플리케이션에서 자격증명 가져오기
  5. 자동 자격증명 로테이션 설정
  6. 보안 모범 사례

AWS Secrets Manager란?

AWS Secrets Manager는 데이터베이스 자격증명, API 키, OAuth 토큰 및 기타 비밀 정보의 전체 수명 주기를 중앙에서 관리할 수 있는 완전 관리형 서비스입니다. 하드코딩된 자격증명을 제거하고 보안을 강화하며 규정 준수를 간소화할 수 있습니다.

주요 기능

  • 🔐 중앙 집중식 비밀 관리: 모든 자격증명을 한 곳에서 관리
  • 🔄 자동 로테이션: 정기적으로 자격증명 자동 갱신
  • 🔑 암호화: AWS KMS를 사용한 저장 시 암호화
  • 📊 감사 로깅: CloudTrail을 통한 모든 액세스 추적
  • 🌐 다양한 통합: AWS 서비스와의 원활한 통합

AWS Secrets Manager 콘솔


RDS와 Secrets Manager 통합의 장점

Amazon RDS는 AWS Secrets Manager와의 네이티브 통합을 제공하여 데이터베이스 자격증명 관리를 더욱 안전하고 편리하게 만듭니다.

주요 이점

보안 강화

  • 코드나 구성 파일에 평문 비밀번호 저장 불필요
  • 암호화된 상태로 안전하게 보관
  • 세밀한 IAM 권한으로 액세스 제어

자동 로테이션

  • 수동 개입 없이 정기적으로 비밀번호 변경
  • 다운타임 없이 원활한 자격증명 업데이트
  • 보안 정책 준수 간소화

운영 효율성

  • 애플리케이션 재시작 없이 자격증명 업데이트
  • 중앙 집중식 관리로 복잡성 감소
  • 여러 환경에서 일관된 자격증명 관리

RDS 자격증명을 Secrets Manager에 저장하기

방법 1: RDS 인스턴스 생성 시 통합

RDS 데이터베이스를 처음 생성할 때 Secrets Manager와 직접 통합할 수 있습니다.

단계별 가이드

1단계: RDS 콘솔에서 데이터베이스 생성

AWS 콘솔에서 RDS 서비스로 이동:

RDS 콘솔 → Databases → Create database

2단계: 자격증명 설정에서 Secrets Manager 선택

Credential Settings 섹션에서:

  • ✅ "Manage master credentials in AWS Secrets Manager" 선택
  • 암호화 키 선택 (기본 KMS 키 또는 사용자 지정 키)

RDS Secrets Manager 통합

3단계: 데이터베이스 생성 완료

나머지 설정을 구성하고 데이터베이스를 생성하면, AWS가 자동으로:

  • Secrets Manager에 비밀 생성
  • RDS 인스턴스와 연결
  • 필요한 IAM 권한 설정

방법 2: 기존 RDS 인스턴스에 수동으로 비밀 저장

기존 RDS 데이터베이스의 자격증명을 Secrets Manager에 저장하려면:

AWS CLI 사용

aws secretsmanager create-secret \
    --name prod/myapp/database \
    --description "Production RDS MySQL credentials" \
    --secret-string '{
        "engine": "mysql",
        "host": "mydb.c9akciq32.us-east-1.rds.amazonaws.com",
        "username": "admin",
        "password": "MySecurePassword123!",
        "dbname": "myapplication",
        "port": 3306
    }' \
    --tags Key=Environment,Value=Production Key=Application,Value=MyApp

AWS SDK (Python Boto3) 사용

import boto3
import json

# Secrets Manager 클라이언트 생성
client = boto3.client('secretsmanager', region_name='us-east-1')

# 비밀 정보 구성
secret_data = {
    'engine': 'mysql',
    'host': 'mydb.c9akciq32.us-east-1.rds.amazonaws.com',
    'username': 'admin',
    'password': 'MySecurePassword123!',
    'dbname': 'myapplication',
    'port': 3306
}

# 비밀 생성
response = client.create_secret(
    Name='prod/myapp/database',
    Description='Production RDS MySQL credentials',
    SecretString=json.dumps(secret_data),
    Tags=[
        {'Key': 'Environment', 'Value': 'Production'},
        {'Key': 'Application', 'Value': 'MyApp'}
    ]
)

print(f"Secret ARN: {response['ARN']}")

애플리케이션에서 자격증명 가져오기

Secrets Manager에 저장된 자격증명을 애플리케이션에서 안전하게 가져와 사용하는 방법을 알아보겠습니다.

자격증명 로테이션 프로세스

Python 애플리케이션 예제

import boto3
import json
from botocore.exceptions import ClientError

def get_database_credentials(secret_name, region_name='us-east-1'):
    """
    AWS Secrets Manager에서 데이터베이스 자격증명을 가져옵니다.
    
    Args:
        secret_name: Secrets Manager의 비밀 이름
        region_name: AWS 리전
    
    Returns:
        dict: 데이터베이스 자격증명 정보
    """
    # Secrets Manager 클라이언트 생성
    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=region_name
    )
    
    try:
        # 비밀 값 가져오기
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
    except ClientError as e:
        # 에러 처리
        if e.response['Error']['Code'] == 'DecryptionFailureException':
            raise Exception("복호화 실패")
        elif e.response['Error']['Code'] == 'InternalServiceErrorException':
            raise Exception("내부 서비스 오류")
        elif e.response['Error']['Code'] == 'InvalidParameterException':
            raise Exception("잘못된 파라미터")
        elif e.response['Error']['Code'] == 'InvalidRequestException':
            raise Exception("잘못된 요청")
        elif e.response['Error']['Code'] == 'ResourceNotFoundException':
            raise Exception(f"비밀을 찾을 수 없습니다: {secret_name}")
    else:
        # SecretString 파싱
        if 'SecretString' in get_secret_value_response:
            secret = get_secret_value_response['SecretString']
            return json.loads(secret)
        else:
            raise Exception("SecretString이 없습니다")

# 사용 예제
credentials = get_database_credentials('prod/myapp/database')

# 데이터베이스 연결
import pymysql

connection = pymysql.connect(
    host=credentials['host'],
    user=credentials['username'],
    password=credentials['password'],
    database=credentials['dbname'],
    port=credentials['port']
)

print("데이터베이스 연결 성공!")

Node.js 애플리케이션 예제

const AWS = require('aws-sdk');

// Secrets Manager 클라이언트 생성
const client = new AWS.SecretsManager({
    region: 'us-east-1'
});

async function getDatabaseCredentials(secretName) {
    try {
        const data = await client.getSecretValue({ 
            SecretId: secretName 
        }).promise();
        
        if ('SecretString' in data) {
            return JSON.parse(data.SecretString);
        } else {
            // Binary secret 처리
            let buff = Buffer.from(data.SecretBinary, 'base64');
            return JSON.parse(buff.toString('ascii'));
        }
    } catch (err) {
        console.error('Error retrieving secret:', err);
        throw err;
    }
}

// 사용 예제
(async () => {
    const credentials = await getDatabaseCredentials('prod/myapp/database');
    
    const mysql = require('mysql2/promise');
    const connection = await mysql.createConnection({
        host: credentials.host,
        user: credentials.username,
        password: credentials.password,
        database: credentials.dbname,
        port: credentials.port
    });
    
    console.log('데이터베이스 연결 성공!');
})();

Java 애플리케이션 예제

import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.services.secretsmanager.model.*;
import com.google.gson.Gson;
import java.util.Map;

public class DatabaseCredentials {
    
    public static Map<String, String> getSecret(String secretName) {
        String region = "us-east-1";
        
        // Secrets Manager 클라이언트 생성
        AWSSecretsManager client = AWSSecretsManagerClientBuilder.standard()
            .withRegion(region)
            .build();
        
        String secret;
        GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest()
            .withSecretId(secretName);
        GetSecretValueResult getSecretValueResult = null;
        
        try {
            getSecretValueResult = client.getSecretValue(getSecretValueRequest);
        } catch (DecryptionFailureException e) {
            throw e;
        } catch (InternalServiceErrorException e) {
            throw e;
        } catch (InvalidParameterException e) {
            throw e;
        } catch (InvalidRequestException e) {
            throw e;
        } catch (ResourceNotFoundException e) {
            throw e;
        }
        
        if (getSecretValueResult.getSecretString() != null) {
            secret = getSecretValueResult.getSecretString();
            Gson gson = new Gson();
            return gson.fromJson(secret, Map.class);
        }
        
        return null;
    }
    
    public static void main(String[] args) {
        Map<String, String> credentials = getSecret("prod/myapp/database");
        System.out.println("Host: " + credentials.get("host"));
        System.out.println("Database: " + credentials.get("dbname"));
    }
}

자동 자격증명 로테이션 설정

정기적인 자격증명 로테이션은 보안 모범 사례입니다. Secrets Manager는 RDS 데이터베이스에 대한 자동 로테이션을 지원합니다.

로테이션 활성화 방법

AWS 콘솔 사용

1단계: Secrets Manager 콘솔로 이동

Secrets Manager → Secrets → 비밀 선택

2단계: 로테이션 구성

  • "Rotation configuration" 섹션에서 "Edit rotation" 클릭
  • "Enable automatic rotation" 활성화
  • 로테이션 일정 설정 (예: 30일마다)

3단계: Lambda 함수 선택

  • AWS가 제공하는 로테이션 Lambda 함수 사용
  • 또는 사용자 정의 Lambda 함수 생성

자격증명 로테이션 아키텍처

AWS CLI 사용

# 로테이션 활성화
aws secretsmanager rotate-secret \
    --secret-id prod/myapp/database \
    --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotation \
    --rotation-rules AutomaticallyAfterDays=30

로테이션 작동 방식

자동 로테이션은 다음 단계로 진행됩니다:

  1. CreateSecret: 새로운 비밀번호 생성 및 임시 저장
  2. SetSecret: RDS에서 새 비밀번호 설정
  3. TestSecret: 새 자격증명으로 연결 테스트
  4. FinishSecret: 새 버전을 현재 버전으로 표시

이 과정은 다운타임 없이 진행되며, 애플리케이션은 자동으로 새 자격증명을 사용하게 됩니다.


보안 모범 사례

AWS Secrets Manager와 RDS를 함께 사용할 때 다음 모범 사례를 따르세요:

1. 최소 권한 원칙 적용

IAM 정책을 사용하여 필요한 최소 권한만 부여:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue"
            ],
            "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/database-*"
        }
    ]
}

2. VPC 엔드포인트 사용

프라이빗 서브넷의 리소스가 인터넷을 거치지 않고 Secrets Manager에 액세스할 수 있도록 VPC 엔드포인트 구성:

aws ec2 create-vpc-endpoint \
    --vpc-id vpc-1234567890abcdef0 \
    --service-name com.amazonaws.us-east-1.secretsmanager \
    --route-table-ids rtb-1234567890abcdef0

3. 암호화 키 관리

사용자 지정 KMS 키를 사용하여 비밀 암호화:

# KMS 키 생성
aws kms create-key --description "Secrets Manager encryption key"

# 비밀 생성 시 KMS 키 지정
aws secretsmanager create-secret \
    --name prod/myapp/database \
    --kms-key-id arn:aws:kms:us-east-1:123456789012:key/abcd1234-a123-456a-a12b-a123b4cd56ef \
    --secret-string file://credentials.json

4. 태그를 사용한 리소스 관리

비밀에 태그를 추가하여 관리 및 비용 추적 간소화:

aws secretsmanager tag-resource \
    --secret-id prod/myapp/database \
    --tags Key=Environment,Value=Production Key=CostCenter,Value=Engineering

5. CloudTrail로 감사 로깅

모든 Secrets Manager API 호출을 CloudTrail로 모니터링:

# CloudWatch Logs로 이벤트 필터링
aws logs put-metric-filter \
    --log-group-name /aws/cloudtrail/my-trail \
    --filter-name SecretsManagerAccess \
    --filter-pattern '{ $.eventName = "GetSecretValue" }' \
    --metric-transformations metricName=SecretAccessCount,metricNamespace=CustomMetrics,metricValue=1

6. 정기적인 로테이션 구성

보안 정책에 따라 자격증명을 정기적으로 로테이션:

  • 프로덕션 환경: 30일마다
  • 개발/테스트 환경: 90일마다
  • 민감한 데이터: 7-14일마다

7. 비밀 버전 관리

여러 버전을 유지하여 롤백 가능성 확보:

# 이전 버전으로 롤백
client.update_secret_version_stage(
    SecretId='prod/myapp/database',
    VersionStage='AWSCURRENT',
    RemoveFromVersionId='current-version-id',
    MoveToVersionId='previous-version-id'
)

마치며

AWS Secrets Manager와 RDS의 통합은 데이터베이스 자격증명을 안전하게 관리하는 강력한 솔루션을 제공합니다. 자동 로테이션, 중앙 집중식 관리, 그리고 세밀한 액세스 제어를 통해 보안을 강화하고 운영 효율성을 높일 수 있습니다.

주요 포인트 요약

보안: 평문 자격증명 제거 및 암호화된 저장
자동화: 수동 개입 없는 자격증명 로테이션
통합: AWS 서비스와의 원활한 연동
감사: CloudTrail을 통한 완전한 추적성
효율성: 중앙 집중식 관리로 복잡성 감소

이제 여러분의 RDS 데이터베이스에 AWS Secrets Manager를 적용하여 보안과 운영 효율성을 모두 향상시켜 보세요!


참고 자료


Tags: #AWS #SecretsManager #RDS #보안 #자격증명관리 #클라우드보안 #DevSecOps

profile
AI를 꿈꾸는 BackEnd개발자

0개의 댓글