secretmanager에 redshift 패스워드 넣기

Twoeyes·2024년 7월 31일

AWS

목록 보기
3/4

Lambda에서 Redshift를 사용하는데, Redshift의 계정 정보를 환경변수에 넣어두었다. 하지만 계정 정보를 환경변수에 넣어놓는건 하책이니 더 좋은 방법을 생각해보자.

  1. Secret Manager에 넣어놓고 권한 분리를 진행한다.(특정 계정과, 특정 Lambda에서만 Secret Manager 항목에 접근하도록 권한 정리)

  2. Secret Manager에 KMS'까지' 엮어서 or Secret Manager'만' 사용해 암호화 / 복호화

2번은 사실 큰 의미가 없어보인다. Secret manager의 열람 권한을 획득한다면 사실상 다 털린 것이라 무방하게 여겨져서 그냥 1번으로 진행했다.

일단 무작정 Secret Manager를 생성했다.

목적: Lambda에서 Secret Manager를 호출하여 확인이 가능한지 알고자 SNS를 통해 password를 메일 발송.

무작정 Lambda도 생성했다.

Lambda에서 SecretManager를 호출하려면 권한이 필요하다.

{
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret"
            ],
            "Resource": "arn:aws:secretsmanager:ap-northeast-2:XXXXXXXXXXXX:secret:test-ymw-*"
        },

→ 그 다음은 SNS 생성

주제 생성

구독 생성

Lambda에서 SNS를 쓰려면 권한이 필요하다.

{
            "Effect": "Allow",
            "Action": [
                "sns:Publish"
            ],
            "Resource": [
                "arn:aws:sns:ap-northeast-2:XXXXXXXXXXXXX:test-secret-lambda-ymw"
            ]
        },

1. IAM 권한

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret"
            ],
            "Resource": "arn:aws:secretsmanager:ap-northeast-2:006533451623:secret:test-ymw-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:Publish"
            ],
            "Resource": [
                "arn:aws:sns:ap-northeast-2:006533451623:test-secret-lambda-ymw"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DeleteNetworkInterface"
            ],
            "Resource": "*"
        }
    ]
}

2. Lambda에 IAM 권한 연결하고, 코드 넣기

import json
import boto3
from botocore.exceptions import ClientError

# AWS Secrets Manager 클라이언트 생성
secrets_manager = boto3.client('secretsmanager', endpoint_url='https://vpce-XXXXXX33ffe0b2-xXXXXXX.secretsmanager.ap-northeast-2.vpce.amazonaws.com')

# Amazon SNS 클라이언트 생성
sns = boto3.client('sns', region_name='ap-northeast-2', endpoint_url='https://vpce-XXXXXXXXXXXXXXe-dkXXXXXl.sns.ap-northeast-2.vpce.amazonaws.com')

def lambda_handler(event, context):
    # Secrets Manager에서 비밀번호 가져오기
    try:
        get_secret_value_response = secrets_manager.get_secret_value(
            SecretId='test-ymw'
        )
    except ClientError as e:
        raise e

    # 비밀번호 추출
    secret = get_secret_value_response['SecretString']
    redshift_password = json.loads(secret)['redshift_password']

    # SNS 주제에 메시지 전송
    sns_topic_arn = 'arn:aws:sns:ap-northeast-2:XXXXXXXXXXX:test-secret-lambda-ymw'
    message = f'Redshift 데이터베이스 비밀번호: {redshift_password}'

    try:
        response = sns.publish(TopicArn=sns_topic_arn,Message=message,Subject='오늘 5퇴는 철회하라 <결사 반대>')
    except ClientError as e:
        raise e

    return {
        'statusCode': 200,
        'body': json.dumps(f'메시지가 SNS 주제 {secret} / {redshift_password} / {message} 에 성공적으로 전송되었습니다.')
    }

3. SNS 메일로 구성해서 패스워드 보내보기

여긴 쉬우니 패스

4. VPC 엔드포인트 사용해보기

VPC에 속한 Lambda가 사용되려면 VPC Endpoint or Nat Gateway 가 필요하다.
VPC에 속하게되면, VPC 뿐만아니라 Subnet도 가지게되며, 내부서비스만 이용가능하게 되는데, 그에따라 AWS의 SAAS는 사용 못하게 된다.
하지만 목적은 Lambda에서 Secretmanager와 sns를 쓰는게 목적이므로 VPC Endpoint를 생성하였다.

서비스를 선택해야한다. ↓

참고로 SNS와 Secret Manager 두 서비스를 이용할 계획이므로 2개의 VPC 엔드포인트가 필요하다.

+ VPC 엔드포인트에 대한 요금 정보

VPC EndPoint를 생성하다보면 가용 영역을 설정하게 되는데, 가용 영역 갯수당 한개의 ENI가 부여된다. 요금은 ENI 기준으로 부과되므로 *ENI 갯수 의 요금이 부과된다.

profile
아 배고파

0개의 댓글