この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
소개
안녕하세요! 클래스메소드 금상원 입니다. 이번 블로그에서는 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)로 연락 주시면 빠른 시일 내 담당자가 회신 드릴 수 있도록 하겠습니다 !