[Spring Boot] AWS Secret Manager를 이용하여 프로퍼티를 관리하자

모지리 개발자·2022년 9월 8일
3
post-thumbnail

Intro

기존에 중요한 키 값들을(api키, db계정,암호) application.yml 혹은 env 파일을 따로 만들어서 그 안에 두고 주입시켜서 사용하여 프로젝트를 진행했었습니다. 하지만 이렇게 사용하게 되면 Github repository에 키값들을 그대로 올리는 것보다야 괜찮겠지만 유지보수 측면에서 큰 단점이 있습니다. 값이 추가되거나 변경될 때 서버에 개별적으로 접속해서 직접 다 변경해줘야 되기 때문이죠

그래서 이번 글에서는 Secret Manager 에 대한 설명Spring Boot에서의 사용방법에 대해 설명해보겠습니다.

AWS Secret Manager란?

AWS Secrets Manager는 애플리케이션, 서비스 및 IT 리소스에 대한 액세스를 보호하는 데 도움이 되는 보안 정보 관리 서비스입니다. 이 서비스를 사용하면 수명 주기 동안 데이터베이스 자격 증명, API 키 및 기타 보안 정보를 손쉽게 교체, 관리 및 검색할 수 있습니다. Secrets Manager를 사용하면 AWS 클라우드, 타사 서비스 및 온프레미스에 있는 리소스에 액세스하는 데 사용되는 보안 정보를 보호하고 관리할 수 있습니다. -- aws 홈페이지

이름 그대로 AWS에서 제공해주는 비밀 값 관리 서비스 입니다.

왜 Secret Manager를 선택했을까?

외부에서 보안 프로퍼티를 주입하는 방법에 대해 찾아보았고 다양한 방법이 있는 것을 알게되었습니다.
크게 고려했던 3가지의 툴에 대해 간단히 비교해보겠습니다.

AWS Secret ManagerAWS Parameter StoreGithub Actions Secret
장점강력하고 안전한 비밀번호 생성무료무료
Profile을 나눠 관리 가능사용 방법이 간단하고 관리 용이새로운 툴 도입 필요 X(빠르게 구현 가능)
AWS 다양한 서비스와 긴밀한 통합 가능
단점유료cross region replication 지원 X단일 디렉토리 (유지보수 어려움)

외부에서 보안 프로퍼티를 주입하는데에는 다양한 방법이 있지만 우선 Secret Manager가 유료라고는 하지만 보안 정보당 월 0.40 USD로 부담되지 않는 가격이기도 하고 유지보수와 안정성 측면에서 더 유리하다고 판단하여 AWS Secret Manager를 선택했습니다.

사용방법

2가지 사용방법에 대해 모두 언급해 보려고 합니다.

  1. Amazon RDS 데이터베이스에 대한 자격증명
  2. 다른 유형의 보안 암호

우선 로그인 후 Secret Manager 링크에 접속합니다.
우측의 새 보안 암호 저장 버튼을 클릭하게 되면 아래와 같은 화면을 보게됩니다.

Amazon RDS 데이터베이스에 대한 자격증명

Amazon RDS를 생성하는 방법은 이글의 주제가 아니므로 링크만 첨부하고 넘어가겠습니다. Amazon RDS 인스턴스 생성

사용자 이름 : DB username
암호 : DB password
입력하시면 됩니다.

데이터베이스 탭에서 원하는 데이터베이스를 선택한 후 다음 버튼을 누르시면 아래와 같은 사진을 볼 수 있게되고 보안암호 네이밍은 원하시는대로 하면 됩니다.

보안암호 이름은 prod/AppBeta/Postgresql 이라고 생성해봤습니다.
그리고 다음 버튼을 누르시면 교체구성 - 선택사항이라는 화면이 나오는데

Secrets Manager는 일정에 따라 보안 암호를 자동으로 교체할 수 있습니다. 보안 암호를 교체하기 위해 Secrets Manager는 Lambda 함수를 사용하여 보안 암호와 데이터베이스 또는 서비스의 자격 증명을 업데이트합니다. 교체는 오랫동안 자격 증명을 변경하지 않고 유지할 때의 위험을 줄입니다. Secrets Manager에서 이 보안 암호를 검색하는 사용자 및 애플리케이션은 교체가 완료되는 즉시 최신 버전을 가져옵니다.

이러한 기능을 가능하게 해주는 메뉴입니다. 이번 글에서는 사용하지않으므르 다음, 저장 버튼 눌러 생성해보겠습니다.

AWS RDS에 대한 보안암호가 생성되었습니다!

다른 유형의 보안 암호

다른 유형의 보안암호 탭을 눌러줍니다

키와 값을 넣어줍니다.

그리고 다음버튼을 눌러준다음에 RDS에 대한 보안암호 이름를 생성했던 것과 마찬가지로 보안암호 이름을 생성해줍니다.

보안암호 이름을 적어줍니다. 다음을 누르고 저장해보겠습니다.

전에 만들었던 RDS에 대한 보안암호, 다른 유형의 보안암호에 대해 2개가 생성된 것을 볼 수 있습니다!

AWS 설정

서버에서 secret manager에 접속하기 위해서는 SecretsManagerReadWrite 권한이 필수적으로 필요합니다.
아래와 같이 권한을 추가해주세요 권한추가 방법

그 후 아래와 같이 액세스 키 를 만들어봅시다.

주의사항 : 만들 때 access-key와 secret-key는 보안상 중요하므로 외부에 노출되어서는 안됩니다! 또 기억할 자신이 없으시다면 다른 곳에 메모해두시거나 파일로도 다운받을 수 있으니 따로 보관해주세용

AWS CLI 설치, 계정정보 등록

AWS Command Line Interface(AWS CLI)는 명령줄 셸의 명령을 사용하여 AWS 서비스와 상호 작용할 수 있는 오픈 소스 도구입니다. 최소한의 구성으로 AWS CLI를 사용하면 터미널 프로그램에 있는 명령 프롬프트에서 브라우저 기반 AWS Management Console에서 제공하는 것과 동일한 기능을 구현하는 명령을 실행할 수 있습니다.

AWS CLI 설치 방법

설치가 끝나면 터미널에 접속하여 계정정보를 입력해줍니다.

$ aws configure
AWS Access Key ID [None]: 발급 받은 Access Key 
AWS Secret Access Key [None]: 발급 받은 Secret Access Key 
Default region name [None]: us-west-2 
Default output format [None]: json

Spring Boot에서 사용하기

의존성 추가하기

// AWS Secret Manager
	implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.3'
	implementation 'org.springframework.cloud:spring-cloud-starter-aws-secrets-manager-config:2.2.6.RELEASE'
	implementation 'com.amazonaws.secretsmanager:aws-secretsmanager-jdbc:1.0.8'

AWS RDS 연결하기

application.yml 기존코드

spring:
  datasource:
    url: ${db.url}
    hikari:
      username: ${db.username}
      password: ${db.password}

application.yml 변경된 코드

spring:
  datasource:
    url: jdbc-secretsmanager:postgresql://{db.url}
    username: prod/AppBeta/Postgresql
    driver-class-name: com.amazonaws.secretsmanager.sql.AWSSecretsManagerPostgreSQLDriver

username 부분에는 RDB에 대한 보안암호 명을 작성하면됩니다.
보이는 것과 같이 DB접속할 때 사용하던 정보를 숨길 수 있습니다.

다른 유형의 보안 암호 연결하기

bootstrap.yml

aws:
  secretsmanager:
    name: test3 #프로젝트 이름(위에서 /secret/test3 이라고 설정함) 
cloud:
  aws:
    region:
      static: ap-northeast-2

bootstrap.yml 은 Spring Boot App 기동 시 applicaition.yml 보다 먼저 로드된다!

이제 테스트 해봅시다.
test


@Slf4j
@Transactional
@AutoConfigureMockMvc
@SpringBootTest
public class MallApplicationTests {

	@Value("${changhwan.test}")
	private String test;

	@Test
	public void getTest() {
		System.out.println(">>>" + test);
	}

원하는대로 결과가 나오는 것을 볼 수 있습니다.

마주친 문제

SecretManager를 통해 DB를 접속하다보니 URL값을 url: jdbc-secretsmanager:postgresql://{db.url} 과 같이 고정해야했습니다. 하지만 팀에서는 log를 더 자세하게 확인하기 위해서 url: jdbc:log4jdbc:postgresql://{db.url} 과 같이 log4jdbc를 사용하기를 원했습니다.

-> 그래서 결국 DB username과 DB password도 Secret Manger의 다른 유형의 보안암호로 연결하여 사용하였습니다.(좋은 방법 있으면 알려주세요...)

결론

이렇게 Secret Manager와 Spring Boot를 연동해봤습니다. 보안프로퍼티는 비즈니스에도 직접적으로 타격을 줄 수 있는 중요한 정보이기 때문에 잘 관리하는 것이 중요합니다.

제가 잘못이해하고 있거나 잘못 작성한 부분이 있다면 지적, 비판, 피드백 뭐든 해주시면 감사하겠습니다!

profile
항상 부족하다 생각하며 발전하겠습니다.

0개의 댓글