SecretsManager CloudFormation으로 작성해보기!
소개
안녕하세요! 클래스메소드 금상원 입니다. 이번 블로그에서는 SecretsManager를 CloudFormation을 이용하여 작성하는 방법에 대해 해보도록 하겠습니다.
콘솔 화면에서 SecretsManager작성 하는 방법에 대하여
SecretsManager작성하기
SecretString JSON 에 램덤으로 생산되는 패스워드를 가진 새로운 SecretsManager를 작성합니다.
이 정보에는 암호, 사용자 이름 및 암호와 같은 자격 증명 집합, OAuth 토큰 또는 Secrets Manager에서 암호화된 형식으로 정보를 저장 합니다.
RDSRotationSecret: Type: AWS::SecretsManager::Secret Properties: Description: "test rds instance secret" Name: "/aws/rds/cluster/test/keum" GenerateSecretString: SecretStringTemplate: '{"username": "admin"}' GenerateStringKey: "password" PasswordLength: 32 ExcludeCharacters: '"@/\'
GenerateSecretString : 비밀번호를 생성하고 SecretsManager에 저장하는 방법을 지정하는 구조입니다.
SecretStringTemplate : 생성된 문자열이 RDS와 일치되여야하는 부분이기때문에 RDS의 MasterUsername을 입력해줍니다.
GenerateStringKey : 키/값 쌍의 JSON 키 이름입니다. 여기서 값은 생성된 RDS의 비밀번호입니다.
PasswordLength : 비밀번호의 길이를 지정합니다.
ExcludeCharacters : 암호에 포함하지 않는 문자를 지정합니다. (문제가 되는 문자들을 주로 기입합니다.)
RDS와 연결하기
RDS와 생성한 SecretsManager를 연결하여 해당 RDS의 비밀번호를 관리 합니다.
SecretRDSInstanceAttachment: Type: AWS::SecretsManager::SecretTargetAttachment Properties: SecretId: !Ref RDSRotationSecret TargetId: !Ref RDSCluster TargetType: AWS::RDS::DBCluster
SecretId : 생성된 SecretsManager의 ID를 입력합니다. (!Ref를 사용하는 것을 추천합니다.)
TargetId : 연결할 서비스의 ID를 입력합니다. (!Ref나 !ImportValue를 사용하는 것을 추천합니다.)
TargetType : 연결할 서비스의 유형을 링크 에서 확인 후 입력합니다.
로테이션 작성하기
보안 암호에 대한 교체 일정 및 Lambda 교체 함수를 설정합니다.
MySecretRotationSchedule: Type: AWS::SecretsManager::RotationSchedule DependsOn: SecretRDSInstanceAttachment Properties: SecretId: !Ref RDSRotationSecret HostedRotationLambda: RotationType: "PostgreSQLSingleUser" RotationLambdaName: "SecretsManagerRotation" VpcSecurityGroupIds: !ImportValue SMSG VpcSubnetIds: "subnet-bb293dd2" RotationRules: Duration: "1h" ScheduleExpression: "cron(0 17 ? * FRI *)"
SecretId : 로테이션을 연결할 SecretsManager의 ID를 입력합니다. (!Ref를 사용하는 것을 추천합니다.)
HostedRotationLambda : Secrets Manager 교체 함수 템플릿 중 하나를 기반으로 새 Lambda 교체 함수를 생성합니다 .
RotationType : 회전 기능의 기반이 되는 회전 템플릿을 링크에서 확인한 후 입력 해주세요.
VpcSecurityGroupIds : 람다에 사용할 보안그룹ID을 입력합니다.
VpcSubnetIds : 람다를 배치할 Subnet의 ID를 입력합니다.
RotationRules : Secrets Manager에 대한 Rotation 구성을 정의하는 구조입니다.
Duration : Rotation을 실행하는 시간의 길이입니다. Secrets Manager는 이 기간 동안 언제든지 암호를 교체합니다.
ScheduleExpression : 암호 교체 일정을 정의합니다. 표현식은 cron()또는 rate() 사용합니다.
전체 코드
AWSTemplateFormatVersion: "2010-09-09" Description: "Secrets Manager with automatic rotation" Transform: "AWS::SecretsManager-2020-07-23" Parameters: USERNAME: Type: String Default: "keum" Description: user name DBNAME: Type: String Default: "test" Description: DB Name DBTYPE: Type: String Default: "db.r6g.large" Description: DB Instance Type ENGINE: Type: String Default: "aurora-postgresql" Description: DB Engine ENGINEVERSION: Type: String Default: "13.5" Description: DB Engine Version Resources: RDSRotationSecret: Type: AWS::SecretsManager::Secret Properties: Description: "test rds instance secret" Name: "/aws/rds/cluster/test-prd-db-rds-aurora-postgresql/okina" GenerateSecretString: SecretStringTemplate: '{"username": "keum"}' GenerateStringKey: "password" PasswordLength: 32 ExcludeCharacters: '"@/\' RDSClusterParameterGroup: Type: "AWS::RDS::DBClusterParameterGroup" Properties: Description: "DB Parameter Group for test-prd-db-rds-aurora-postgresql" Family: "aurora-postgresql13" Parameters: timezone : Asia/Tokyo client_encoding: UTF8 Tags: - Key: Name Value: "test-prd-db-rds-aurora-postgresql-cluster-dbparametergroup" DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: "DB Subnet Group on Isolated Subnets" DBSubnetGroupName: "test-prd-rds-sbng" SubnetIds: - !ImportValue PrivateSubnet-a #from subnet.yaml - !ImportValue PrivateSubnet-c #from subnet.yaml Tags: - Key: Name Value: "test-prd-rds-sbng" RDSCluster: Type: AWS::RDS::DBCluster Properties: DatabaseName: !Ref DBNAME Engine: !Ref ENGINE EngineMode: "provisioned" EngineVersion: !Ref ENGINEVERSION DBClusterIdentifier: "test-prd-db-rds-aurora-postgresql" MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref RDSRotationSecret, ':SecretString:username}}' ]] MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref RDSRotationSecret, ':SecretString:password}}' ]] DBSubnetGroupName: !Ref DBSubnetGroup Port: 5432 BackupRetentionPeriod: 7 CopyTagsToSnapshot: true PreferredBackupWindow: "16:00-16:30" PreferredMaintenanceWindow: "Fri:18:00-Fri:18:30" DeletionProtection: true EnableCloudwatchLogsExports: - postgresql VpcSecurityGroupIds: - !ImportValue RDSSG DBClusterParameterGroupName: !Ref RDSClusterParameterGroup StorageEncrypted: true RDSDBParameterGroup: Type: "AWS::RDS::DBParameterGroup" Properties: Description: "DB Parameter Group for test-prd-db-rds-aurora-postgresql" Family: "aurora-postgresql13" Tags: - Key: Name Value: "test-prd-db-rds-aurora-postgresql-dbparametergroup" RDSDBInstance: Type: "AWS::RDS::DBInstance" Properties: DBClusterIdentifier: !Ref RDSCluster DBInstanceClass: !Ref DBTYPE MultiAZ: false AvailabilityZone: "ap-northeast-1a" PubliclyAccessible: false EnablePerformanceInsights: true PerformanceInsightsRetentionPeriod: 7 AutoMinorVersionUpgrade: true PreferredMaintenanceWindow: "Fri:18:30-Fri:19:00" DBSubnetGroupName: !Ref DBSubnetGroup DBParameterGroupName: !Ref RDSDBParameterGroup Engine: !Ref ENGINE EngineVersion: !Ref ENGINEVERSION SecretRDSInstanceAttachment: Type: AWS::SecretsManager::SecretTargetAttachment Properties: SecretId: !Ref RDSRotationSecret TargetId: !Ref RDSCluster TargetType: AWS::RDS::DBCluster MySecretRotationSchedule: Type: AWS::SecretsManager::RotationSchedule DependsOn: SecretRDSInstanceAttachment Properties: SecretId: !Ref RDSRotationSecret HostedRotationLambda: RotationType: "PostgreSQLSingleUser" RotationLambdaName: "SecretsManagerRotation" VpcSecurityGroupIds: !ImportValue SMSG # from sg.yaml VpcSubnetIds: "subnet-bb293dd2" # ec2 subnet RotationRules: Duration: "1h" ScheduleExpression: "cron(0 17 ? * FRI *)"
마무리
이번 블로그에서는 CloudFormation을 이용하여 AWS ScretsManager를 작성하는 방법에 대해 알아보았습니다.
ScretsManager를 CloudFormation으로 작성 하실려는 분들에게 조금이나마 도움이 되었으면 좋겠습니다.
참고자료
본 블로그 게시글을 보시고 문의 사항이 있으신 분들은 클래스메소드코리아 (info@classmethod.kr)로 연락 주시면 빠른 시일 내 담당자가 회신 드릴 수 있도록 하겠습니다 !