AWS RDS Proxy 설정
RDS Proxy 서비스가 필요했던 것은 아니고 RDS 관련해서 알아보다가 Proxy 서비스가 있다는 것을 알게된 김에 어떻게 사용하는 건지 간단하게 세팅하고 테스트를 진행해봤다.
Amazon RDS Proxy를 사용하면 애플리케이션이 데이터베이스 연결을 풀링하고 공유하도록 허용하여 확장 기능을 향상할 수 있습니다. RDS Proxy는 애플리케이션 연결을 유지하면서 예비 DB 인스턴스에 자동으로 연결하여 데이터베이스 장애에 대한 애플리케이션의 복원력을 높입니다. RDS 프록시를 사용하면 데이터베이스에 대해 AWS Identity and Access Management (IAM) 인증을 사용하고 AWS Secrets Manager에 자격 증명을 안전하게 저장합니다.
고가용성 측면과 Connection Pool 관점에서 보면 좋은 서비스인데 현재는 뭔가 사용하기에 애매한 느낌이 없지않아 있다. 자료 등을 찾아보면 Lambda 등의 서버리스 환경에서 사용하면 좋다는데.. 이건 좀 더 체크해볼 필요가 있을 것 같다.
RDS Proxy 는 DB 인스턴스와 연결 정보를 AWS Secret Manager 에 저장하고 연결할 때 이 정보를 이용한다. 그래서 Proxy 생성 전에 먼저 연결정보를 저장해야 한다.
사용자 이름 / 암호는 DB 인스턴스에 연결할 때 사용하는 정보를 입력한다. 다음으로 RDS Proxy 에서 위에서 생성한 암호 정보에 접근할 때 사용되는 IAM 정책을 생성해야 한다. 정책은 아래와 같다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": [
"arn:aws:secretsmanager:ap-northeast-2:<account_id>:secret:<secret_id>"
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:ap-northeast-2:<account_id>:key/<key_id>",
"Condition": {
"StringEquals": {
"kms:ViaService": "secretsmanager.ap-northeast-2.amazonaws.com"
}
}
}
]
}
<secret_id>
는 위에서 생성한 보안암호에 확인되는 값을 변경한다. <account_id>
역시 바로 확인이 가능하다. <key_id>
는 조금 어려울 수 있는데 KMS 에 등록된 값으로 미리 확인해놓지 않았다면 아래와 같이 확인할 수 있다. 보안암호 생성 때 DefaultEncryptionKey
를 선택했을 때 사용할 수 있는 key_id 이다.
이미지에서 aws/secretsmanager
키 ID를 사용한다. 이제 RDS Proxy 를 생성한다.
Proxy 생성 때 이름 등의 정보를 입력하면 바로 생성이 가능하다. 여기서는 EC2에서 IAM 인증을 사용하여 Proxy 에 접속하는 것을 생각했기 때문에 추가로 전송 계층 보안필요
항목과 IAM 인증
을 활성화 한다. 이제 RDS Proxy 에 접속 때 사용할 정책을 설정해야 한다. 일반적으로 EC2 에서 접속할 것으로 생각해서 아래와 같이 생성했고 해당 정책을 EC2 인스턴스프로파일로 적용해서 사용했다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:ap-northeast-2:<account_id>:dbuser:prx-xxxxxx01847576d56/<username>"
]
}
]
}
rds-db:connect
라는 사용되는 게 특이하다. prx-xxxxxx01847576d56
부분은 Proxy ID 정보이다. 생성 후 입력하면 된다. <username>
이라는 부분이 있는데 이 부분은 *
와 같이 설정할 수도 있다. 좀 더 확인을 해봐야겠지만 이 username 부분에 dbuser 와 같이 입력을 하면 Proxy 에 접속할 때 해당 username 만 접근이 가능해지는 듯 하다. Proxy 에 접속하면 RDS Proxy 에서 SecretsManager 에 접근하여 DB 접속정보를 가져오고 이 정보로 DB 에 접속하게 된다. 사실 이 부분 때문에 RDS Proxy 에 대해서 알아보게 된 것이었는데 프로그램 소스 코드에서 DB 접속 정보를 숨길 수 있기 때문이다. 그런데 결국은 이 부분때문에 고려를 하지 않게 되기도 했다.
생성된 Proxy 에 접속해보자. 먼저 TLS 보안전송을 사용했기 때문에 인증서가 필요하다. 관련 내용은 이 문서에서 확인할 수 있으며 인증서는 https://www.amazontrust.com/repository/AmazonRootCA1.pem 를 다운로드하면 된다. 쉘 상에서 msyql 명령을 사용하여 RDS Proxy 에 접속한다.
RDSHOST="rds-proxy-test.proxy-cdfdfuzq0haly1.ap-northeast-2.rds.amazonaws.com"
TOKEN="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 3306 --region ap-northeast-2 --username dbuser )"
mysql --host=$RDSHOST --port=3306 --ssl-ca=/home/ec2-user/AmazonRootCA1.pem --enable-cleartext-plugin --user=dbuser --password=$TOKEN
RDS Proxy 에 접속하기 위해서는 TOKEN 을 사용해야 하는데 IAM 인증을 사용하도록 했기 때문이다. IAM 인증을 사용하지 않으면 기존 DB 연결정보를 이용해 바로 접속이 가능하다. --enable-cleartext-plugin
는 TLS 접속을 위한 옵션이다. 토큰은 생성 후 15분간 유효하다. 만약 PHP 등에서 RDS Proxy 접속을 위해 매번 토큰을 생성하도록 한다면 토큰 생성에 딜레이가 있기 때문에 그만큼 퍼포먼스가 떨어지게 된다. 이걸 피하기 위해서는 토큰을 관리하는 기능을 만들고 주기적으로 토큰을 재 생성해야 하면 프로그램에서는 이 토큰을 사용하도록 기존 코드를 사용해야할 필요성이 있다. RSX Proxy 접속을 위한 코드는 여기에서 확인할 수 있다.