AWS CloudFormation으로 RDS 인스턴스 띄우기

태그
AWS CloudFormation
CloudFormation
  • AWS에서 제공하는 IaC 도구 입니다.
  • CloudFormation 템플릿으로 리소스들을 작성할 수 있습니다. 템플릿은 JSON, YAML로 작성할 수 있습니다.
  • 템플릿으로 생성된 결과물을 ‘스택’ 이라 칭합니다.
  • 생성된 스택은 롤백하거나 업데이트 할 수 있고, 스택을 중첩시켜서 여러 스택관의 의존관계를 나타내는 것도 가능합니다.
 
CloudFormation 템플릿의 기본 구조
Parameters: Tag: Type: "String" Resources: VPC: Type: "AWS::EC2::VPC" Properties: CidrBlock: "10.0.0.0/16" Tags: - Key: "Name" Value: !Ref "Tag" SubnetA: Type: "AWS::EC2::Subnet" Properties: AvailabilityZone: !Select - 0 - !GetAZs Ref: 'AWS::Region' VpcId: !Ref "VPC" CidrBlock: "10.0.0.0/24" Outputs: VpcId: Description: The VPC ID Value: !Ref VPC
  • Parameter
    • Template 으로 넘겨주는 입력 값
    • 예를 들면, DB의 Username과 Password를 설정해야한다고 가정해봅시다.
      • 계정 정보를 소스코드내 명시하는 건 좋지 않습니다.
      • 따라서 Template 으로 생성하는 단계에 입력 받아서 넘겨주는 역할을 수행해야하는데 이런 경우에 사용할 수 있습니다.
  • Resources
    • 실제로 생성될 AWS의 리소스를 나타냅니다.
    • 거의 모든 AWS 리소스에 대한 정보를 AWS 공식문서에서 확인할 수 있습니다.
  • Outputs
    • 템플릿으로 스택을 생성한 이후 나오는 출력 값을 정의합니다.
    • 주로 스택에서 생성한 어떤 리소스의 ARN이나 이름 값을 가져다 다른 스택의 Input Parameter 값으로 넘겨주거나 할 때 쓰이곤 합니다.
 
CloudFormation 실행하기/검증하기
작성한 CloudFormation의 구문 오류, 조건 검증하기. 단, 값 자체에 대한 유효성 검증은 하지 않기에, 생성시 오류가 나는 부분까지 잡아주진 않습니다.
 
Template 검증하기
aws cloudformation validate-template --template-body file:://./file.yaml
 
AWS CLI 로 실행하기
aws cloudformation create-stack --stack-name [StackName] --template-body file:://./file.yaml --parameters ParameterKey=dbUserName,ParameterValue=root ParameterKey=dbUserPassword,ParameterValue=1234
 
AWS 콘솔에서 실행하기
CloudFormation → 스택 생성 → 새 리소스 사용
notion imagenotion image
 
RDS를 생성하려면 어떤 리소스가 필요한가?
  • AWS::RDS::DBInstance (필수)
  • AWS::EC2::SecurityGroup (필수)
  • AWS::RDS::DBSubnetGroup (선택)
  • AWS::RDS::DBCluster (선택)
  • AWS::RDS::DBClusterParameterGroup (선택)
 
RDS를 CloudFormation으로 생성시 주의 할점
  • 콘솔에서 생성시에는 당연히 여기다가 제약이 없는 IaC 환경에서 실행하다보면 잦은 오류를 볼 수 있습니다.
  • DB 엔진 값은 아래는 Engine에 대한 리스트를 참조해서 맞는 DB를 넣읍시다. CloudFormation 뿐 아니라, Terraform 으로 생성할 때도 참고할 수 있습니다.
aurora-mysql (for Aurora MySQL DB instances) aurora-postgresql (for Aurora PostgreSQL DB instances) custom-oracle-ee (for RDS Custom for Oracle DB instances) custom-oracle-ee-cdb (for RDS Custom for Oracle DB instances) custom-sqlserver-ee (for RDS Custom for SQL Server DB instances) custom-sqlserver-se (for RDS Custom for SQL Server DB instances) custom-sqlserver-web (for RDS Custom for SQL Server DB instances) db2-ae db2-se mariadb mysql oracle-ee oracle-ee-cdb oracle-se2 oracle-se2-cdb postgres sqlserver-ee sqlserver-se sqlserver-ex sqlserver-web
  • 해당 DB에 대한 사용가능한 version은 CLI에서 확인할 수 있습니다.
    • aws rds describe-db-engine-versions --engine <db_engine>
  • 이 때 일부 DB의 경우 지원하는 인스턴스 클래스가 맞지 않을 수 있습니다. 예를 들면, aurora-mysql이나 aurora-postgresql은 생성가능한 인스턴스 클래스가 t3.medium 이상만 지원합니다. 그 미만의 인스턴스는 생성 불가합니다.
    • DBInstance 로 단일 구동하는 게 아닌 DBCluster 를 구동하는 경우에도 마찬가지로 제약이 있습니다.
  • DBCluster 를 생성하는 경우에 DBInstance 에는 DBName, MasterUserName, MasterPassword, VPCSecurityGroups, StorageSize, AllocatedStorage 등등 속성이 들어가면 안됩니다. DBInstance 가 아닌 DBCluster 내 들어가야할 정확히는 아래 속성들이 포함됩니다.
    • AllocatedStorage AutoMinorVersionUpgrade AvailabilityZone BackupRetentionPeriod CharacterSetName DBInstanceClass DBName DBParameterGroupName DBSecurityGroups DBSubnetGroupName Engine EngineVersion Iops LicenseModel MasterUsername MasterUserPassword MultiAZ OptionGroupName PreferredBackupWindow PreferredMaintenanceWindow
  • DBInstance 속성 중에는 지원하거나 권장되지 않는 설정들이 존재합니다. 실행시 ‘해당 리전에서는 지원하지 않는다’ 는 오류가 뜹니다. 주로 더 이상 사용 되지 않거나 Deprecated 된 속성들이 존재합니다.
    • DBSecurityGroups
  • DeletionPolicy 를 SnapShot으로 설정하는 것이 좋습니다. CloudFormation 으로 생성한 리소스의 경우 해당 스택을 삭제해버리면, DB의 데이터 역시 날아갑니다. 이 때 DeletionPolicy를 SnapShot으로 설정하면 스택 삭제전에 자동으로 스냅샷을 생성합니다.
    • 업데이트 하는 경우 역시 기존 데이터베이스 스냅샷을 가져와서 업데이트 할 수 있습니다. DBSnapshotIdentifier 속성을 지정하면 업데이트 할 때 기존 데이터베이스의 데이터를 그대로 가져올 수 있습니다. 그렇지 않으면, 데이터가 날라갑니다.
 
아래는 Cluster 1개와 Instance 1개인 RDS를 구성하는 예시입니다. 서브넷과 VPC는 이미 생성된 리소스를 참조하는 것을 가정했습니다.
AWSTemplateFormatVersion: 2010-09-09 Description: Set up rds dbUserPassword: NoEcho: true Type: String dbUserName: NoEcho: true Type: String DbSize: Type: String Default: db.t4g.medium DbStorageSize: Type: String Default: "20" DbName: Type: String Default: "my_database" Resources: EC2SecurityGroupForDatabase: Type: "AWS::EC2::SecurityGroup" Properties: GroupName: "my-rds-sg" GroupDescription: "security group for rds" VpcId: "vpc-09c07451beabe29da" SecurityGroupEgress: - IpProtocol: -1 FromPort: -1 ToPort: -1 CidrIp: 0.0.0.0/0 SecurityGroupIngress: - IpProtocol: tcp FromPort: 5432 ToPort: 5432 CidrIp: 0.0.0.0/0 PublicDatabaseSubnetGroup: Type: "AWS::RDS::DBSubnetGroup" Properties: DBSubnetGroupDescription: Subnet for rds DBSubnetGroupName: rds-subnet-group SubnetIds: - subnet-0a78a3b6a6e420b40 - subnet-01078402d182b8615 DatabaseCluster: Type: "AWS::RDS::DBCluster" Properties: MasterUsername: !Ref dbUserName MasterUserPassword: !Ref dbUserPassword AllocatedStorage: !Ref DbStorageSize Engine: postgres EngineVersion: 14.9 DBSubnetGroupName: !Ref PublicDatabaseSubnetGroup VpcSecurityGroupIds: - Ref: "EC2SecurityGroupForDatabase" DatabasePrimaryInstance: Type: "AWS::RDS::DBInstance" Properties: Engine: postgres EngineVersion: 14.9 DBClusterIdentifier: !Ref "DatabaseCluster" DBInstanceClass: !Ref DbSize PubliclyAccessible: false DeletionPolicy: Snapshot
 
서버리스 v2로 생성하려는 경우 DatabaseCluster로 생성해줘야 합니다.
AWSTemplateFormatVersion: 2010-09-09 Description: ServerlessV2 Cluster Parameters: MasterUsername: Type: String MasterUserPassword: Type: String NoEcho: true DBClusterIdentifier: Type: String EngineVersion: Type: String MinCapacity: Type: String MaxCapacity: Type: String Resources: RDSDBCluster: Type: 'AWS::RDS::DBCluster' Properties: Engine: aurora-mysql DBClusterIdentifier: !Ref DBClusterIdentifier EngineVersion: !Ref EngineVersion MasterUsername: !Ref MasterUsername MasterUserPassword: !Ref MasterUserPassword ServerlessV2ScalingConfiguration: MinCapacity: !Ref MinCapacity MaxCapacity: !Ref MaxCapacity RDSDBInstance: Type: 'AWS::RDS::DBInstance' Properties: Engine: aurora-mysql DBInstanceClass: db.serverless DBClusterIdentifier: !Ref RDSDBCluster
 

요약

📌
요약: ??