애플리케이션 개발 시 데이터베이스 자격 증명이나 API 키 같은 민감한 정보를 코드에 직접 하드코딩하는 것은 보안상 매우 위험합니다. AWS에서는 이런 비밀 정보를 안전하게 보관하고 조회할 수 있는 AWS Secrets Manager 서비스를 제공하며, Python에서는 boto3 라이브러리를 통해 손쉽게 연동할 수 있습니다.
이 글에서는 boto3를 사용하여 AWS Secrets Manager에 저장된 비밀 값을 일반 텍스트(plain text) 형태로 가져오는 방법을 단계별로 살펴보겠습니다.
문제 상황
Python의 boto3 라이브러리를 사용해 AWS Secrets Manager에 저장된 비밀 키(secret key)를 프로그래밍 방식으로 조회하고 싶습니다.
해결 접근 방식 및 알고리즘
- 1단계: 예외 처리를 위해 boto3와 botocore.exceptions의 예외 클래스를 임포트합니다.
- 2단계: secret_stored_location(비밀 값이 저장된 위치)은 필수 파라미터입니다.
- 3단계: boto3를 사용해 AWS 세션(Session)을 생성합니다. 기본 프로파일에 region_name이 설정되어 있지 않다면, 세션 생성 시 반드시 region_name을 명시적으로 전달해야 합니다.
- 4단계: secretmanager 서비스를 위한 AWS 클라이언트를 생성합니다.
- 5단계: get_secret_value 메서드를 호출하고, secret_stored_location을 SecretId 인자로 전달합니다.
- 6단계: 호출이 성공하면 해당 위치에 저장된 비밀 값이 암호화되지 않은 일반 텍스트 형태로 반환됩니다.
- 7단계: 값을 조회하는 과정에서 오류가 발생할 경우를 대비해 일반 예외(generic exception)도 함께 처리합니다.
예제 코드
아래 코드를 사용하면 AWS Secrets Manager에서 일반 텍스트 형태의 비밀 값을 가져올 수 있습니다.
import boto3
from botocore.exceptions import ClientError
def get_secret_details(secret_stored_location):
session = boto3.session.Session()
s3_client = session.client('secretmanager')
try:
response = s3_client.get_secret_value(SecretId=secret_stored_location)
return response
except ClientError as e:
raise Exception("boto3 client error in get_secret_details: " + e.__str__())
except Exception as e:
raise Exception("Unexpected error in get_secret_details: " + e.__str__())
a = get_secret_details('/secrets/aws')
print(a['SecretString'])
실행 결과
{"aws.user":"SERVICE_USER","aws.accesskey":"I**************"}
추가 참고 사항
- 반환되는 응답 객체에는 SecretString 외에도 ARN, Name, VersionId, CreatedDate 등의 메타데이터가 포함되어 있습니다.
- 비밀 값이 바이너리 형태로 저장된 경우에는 SecretBinary 필드를 사용해야 하며, base64 디코딩이 필요합니다.
- 정상적인 호출을 위해서는 실행 주체(IAM 사용자 또는 역할)에게 secretsmanager:GetSecretValue 권한이 부여되어 있어야 합니다.
- 운영 환경에서는 예외 발생 시 로깅을 남기거나 재시도 로직을 추가하는 것이 좋습니다.