【CloudFormation】AWSマルチAZ3層アーキテクチャの構築_RDS

皆様、お世話になっております。鈴木と申します。
今回はAWS CloudFormationを使用してRDSを作成していきたいと思います。

1.目次

目次はこちら

2.要件

  • エンジンをMySQLにて作成
  • AWS Secrets Managerでパスワードを取得・管理
  • マルチAZ配置
  • プライベートサブネットに属しているEC2からのみのアクセスを許可(プロテクトサブネットに配置)

3.RDSについて

AWS RDS (Relational Database Service) は、AWSが提供するフルマネージドのリレーショナルデータベースサービスです。RDSを使用すると、データベースのセットアップ、運用、スケーリングが簡単に行え、アプリケーションのデータ管理を効率的にサポートします。

主な特徴として5つ挙げられます。

  1. フルマネージド
    データベースのハードウェアやソフトウェアの管理、パッチ適用、バックアップ、復元など、運用に関わる多くの作業を AWS が代行します。
  2. 高可用性と耐障害性:
    マルチAZ (アベイラビリティゾーン) 配置を利用することで、データベースの高可用性を確保し、障害発生時のデータ損失を防ぎます。
  3. スケーラビリティ:
    インスタンスのサイズやストレージを動的にスケールアップまたはスケールダウンでき、トラフィックやデータの増減に対応します。
  4. セキュリティ:
    データベースインスタンスは VPC (Virtual Private Cloud) 内に配置され、セキュリティグループやネットワークアクセス制御リストでアクセスを制御します。また、AWS Secrets Manager と連携して、データベースの認証情報を安全に管理できます。
  5. コスト効率:
    使用した分だけを支払う従量課金制で、必要に応じてリソースを柔軟に利用できます。

主なエンジンとしては下記のものが挙げられます。

データベースエンジン 概要
Amazon Aurora 高性能でスケーラブルな MySQL および PostgreSQL 互換のデータベース
MySQL オープンソースのリレーショナルデータベース
MariaDB MySQL のフォークで、高い互換性とパフォーマンスを提供
PostgreSQL 高度な機能を備えたオープンソースのリレーショナルデータベース
Oracle 商用データベースで高いパフォーマンスと機能性を提供
SQL Server Microsoft のリレーショナルデータベースで、豊富な管理機能を備えています

またユースケースの例としては、下記のケースが挙げられます。

  • ウェブアプリケーション: ユーザー情報やコンテンツの管理に使用
  • ビジネスアプリケーション: 売上データや顧客情報の保存
  • データ分析: 大量のデータを効率的に処理し、レポートや分析に利用

DynamoDB(NoSQL)との違い

下記は特徴の比較になります。

特徴 AWS RDS DynamoDB
タイプ リレーショナルデータベース(RDBMS) NoSQL データベース
データモデル テーブル、行、列 キーと値、ドキュメント(JSONなど)
スキーマ 固定スキーマ スキーマレス
クエリ言語 SQL PartiQL、またはAPIを使用したクエリ
トランザクション トランザクションサポート(ACID準拠) 部分的なトランザクションサポート
スケーラビリティ スケールアップ(インスタンスサイズ変更)、スケールアウト(レプリカ) 自動スケーリング(リクエスト単位)
高可用性 マルチAZ配置、リードレプリカ 自動複製、マルチリージョン配置(グローバルテーブル)
バックアップ 自動バックアップ、スナップショット バックアップとリストア、ポイントインタイムリカバリ
運用管理 フルマネージド(ハードウェア、ソフトウェア、パッチ管理など) フルマネージド(スケーリング、ハードウェア管理など)
コスト インスタンス料金、ストレージ、IOPS、データ転送など 読み取り・書き込みキャパシティ、ストレージ、データ転送など

続いてユースケースです。

ユースケース AWS RDS DynamoDB
トランザクション処理 高度なトランザクションサポートが必要な場合(例:金融システム) 部分的なトランザクションサポート、ACIDが必要な場合は不向き
複雑なクエリ SQL を用いた複雑なクエリや結合が必要な場合(例:データ分析) PartiQL またはシンプルなクエリが適している場合
リレーショナルデータ データの関係性や整合性が重要な場合(例:在庫管理、顧客データ) データの関係性が不要な場合(例:セッションデータ)
スケーラビリティ インスタンスのサイズ変更やリードレプリカでスケーリング(例:企業アプリケーション) 自動スケーリングが必要な場合(例:トラフィックの変動が激しいウェブサイト)
高可用性 マルチAZやリードレプリカで高可用性を確保(例:高可用性が求められるビジネスアプリ) グローバルテーブルや自動複製で高可用性を確保(例:グローバルなアプリケーション)
シンプルなキー-バリューストレージ シンプルなキー-バリューのストレージは不向き 高いパフォーマンスでキー-バリューのストレージが適している場合
スキーマレスデータ 固定スキーマが必要な場合(例:業務データベース) スキーマレスなデータで柔軟なデータモデルが必要な場合
コスト効率 インスタンスサイズやストレージ、IOPSに応じたコスト 読み取り・書き込みキャパシティに基づくコスト

簡単に言えばAWS RDSはSQLを使用したリレーショナルデータベースで、トランザクション処理や複雑なクエリに適しています。一方、DynamoDBはNoSQLデータベースで、スキーマレスなデータモデルと自動スケーリングによる高パフォーマンスを提供します。

4.構成図

file

  1. プライベートサブネットに属するEC2からのアクセスのみに設定
    セキュリティグループはこちらで作成済みです。
    こちらでEC2ソース指定のMySQL(3306)のものを作成しております。
  2. マルチAZ配置にしてフェールオーバーできるように設定
  3. パスワードをSecrets Manager経由で取得・運用

5.ソースコード

YAMLにて記載しております。
またファイルを3つに分けて作成しております。

5-1.Secrets Manager作成用

Resources:
  CloudFormationCreatedSecret:
    Type: 'AWS::SecretsManager::Secret' #デフォルトの定義
    Properties:
      Description: Simple secret created by AWS CloudFormation. #説明
      SecretString: '{"username": "ユーザー名", "password": "パスワード"}' #ユーザー名とパスワードは今回は指定するパターンで作成しております。

5-2.RDS サブネットグループ作成用

AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template to create a DB Subnet Group for RDS

Parameters:
  # DB Subnet Groupの名前を指定するパラメータ
  DBSubnetGroupName:
    Description: The name of the DB Subnet Group
    Type: String
    Default: naoki-db-subg

  # DB Subnet Groupを作成するVPCのIDを指定するパラメータ
  VPCId:
    Description: The VPC ID where the subnets are located
    Type: String
    Default: vpc-062d5b30de12cff6a

  # DB Subnet Groupに含めるサブネットのIDをカンマ区切りで指定するパラメータ
  SubnetIds:
    Description: The list of subnet IDs to include in the DB Subnet Group
    Type: CommaDelimitedList
    Default: subnet-06938606508b14fa2,subnet-0ed3deb02f824b0ae

Resources:
  # DB Subnet Groupの作成
  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: "DB Subnet Group for RDS" # 説明
      DBSubnetGroupName: !Ref DBSubnetGroupName # グループ名
      SubnetIds: !Ref SubnetIds #サブネットID
      Tags:
        - Key: Name
          Value: !Ref DBSubnetGroupName

Outputs:
  # DB Subnet Groupの名前を出力
  DBSubnetGroupName:
    Description: The name of the DB Subnet Group
    Value: !Ref DBSubnetGroupName

  # DB Subnet GroupのIDを出力
  DBSubnetGroupId:
    Description: The ID of the DB Subnet Group
    Value: !Ref DBSubnetGroup

5-3.RDSインスタンス作成用

AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template for creating an RDS instance with MySQL using an existing Secrets Manager secret for credentials

Parameters:
  # RDSインスタンスの識別子を指定するパラメータ
  DBInstanceIdentifier:
    Description: The DB instance identifier
    Type: String
    Default: naoki-rds-db

  # RDSインスタンスのマスターusernameを指定するパラメータ
  MasterUsername:
    Description: The master username for the DB instance
    Type: String
    Default: admin

  # 既存のSecrets ManagerシークレットのARNを指定するパラメータ
  SecretsManagerSecretArn:
    Description: The ARN of the existing Secrets Manager secret containing the master credentials
    Type: String
    Default: "シークレットマネージャーのARN"

  # RDSインスタンスを配置するVPCのIDを指定するパラメータ
  VPCId:
    Description: The VPC ID where the RDS instance will be deployed
    Type: String
    Default: vpc-062d5b30de12cff6a

  # 既存のDB Subnet Groupの名前を指定するパラメータ
  DBSubnetGroupName:
    Description: The name of the existing DB Subnet Group
    Type: String
    Default: naoki-db-subg

Resources:
  # RDSインスタンスの作成
  MyDBInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: !Ref DBInstanceIdentifier
      DBInstanceClass: db.t3.micro
      Engine: mysql
      EngineVersion: 8.0.35
      AllocatedStorage: 20
      StorageType: gp3
      MultiAZ: true
      MasterUsername: !Ref MasterUsername
      MasterUserPassword: !Sub "{{resolve:secretsmanager:${SecretsManagerSecretArn}:SecretString:password}}"
      DBSubnetGroupName: !Ref DBSubnetGroupName
      VPCSecurityGroups:
        - "sg-0f0fab14c0b720d0c"
      PubliclyAccessible: false
      BackupRetentionPeriod: 7
      PreferredBackupWindow: "20:00-21:00"
      Port: 3306
      DBName: mydatabase
      DeletionProtection: true
      CopyTagsToSnapshot: true
      Tags:
        - Key: Name
          Value: !Ref DBInstanceIdentifier

Outputs:
  # 作成したRDSインスタンスのエンドポイントアドレスを出力します
  RDSInstanceEndpoint:
    Description: The endpoint address of the RDS instance
    Value: !GetAtt MyDBInstance.Endpoint.Address

  # 作成したRDSインスタンスの識別子を出力します
  RDSInstanceIdentifier:
    Description: The identifier of the RDS instance
    Value: !Ref MyDBInstance

6.ソースコード詳細

6-1.Secrets Manager

使用するオプション 設定値 説明
Type AWS::SecretsManager::Secret デフォルトの定義
SecretString ‘{"username": "ユーザー名", "password": "パスワード"}’ ユーザー名とパスワード指定
今回は手動で設定
Resources:
  CloudFormationCreatedSecret:
    Type: 'AWS::SecretsManager::Secret' #デフォルトの定義
    Properties:
      Description: Simple secret created by AWS CloudFormation. #説明
      SecretString: '{"username": "ユーザー名", "password": "パスワード"}' #ユーザー名とパスワードは今回は指定するパターンで作成しております。

6-2.RDS サブネットグループ

初めにパラメータを指定します。
ここではサブネットグループの名前,VPC,サブネットを指定します。

使用するオプション 設定値 説明
Type AWS::RDS::DBSubnetGroup デフォルトの定義
DBSubnetGroupName Ref DBSubnetGroupName パラメータを指定(グループ名)
SubnetIds !Ref SubnetIds パラメータを指定(サブネットID)
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template to create a DB Subnet Group for RDS

Parameters:
  # DB Subnet Groupの名前を指定するパラメータ
  DBSubnetGroupName:
    Description: The name of the DB Subnet Group
    Type: String
    Default: naoki-db-subg

  # DB Subnet Groupを作成するVPCのIDを指定するパラメータ
  VPCId:
    Description: The VPC ID where the subnets are located
    Type: String
    Default: vpc-062d5b30de12cff6a

  # DB Subnet Groupに含めるサブネットのIDをカンマ区切りで指定するパラメータ
  SubnetIds:
    Description: The list of subnet IDs to include in the DB Subnet Group
    Type: CommaDelimitedList
    Default: subnet-06938606508b14fa2,subnet-0ed3deb02f824b0ae

Resources:
  # DB Subnet Groupの作成
  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: "DB Subnet Group for RDS" # 説明
      DBSubnetGroupName: !Ref DBSubnetGroupName # グループ名
      SubnetIds: !Ref SubnetIds #サブネットID
      Tags:
        - Key: Name
          Value: !Ref DBSubnetGroupName

Outputs:
  # DB Subnet Groupの名前を出力
  DBSubnetGroupName:
    Description: The name of the DB Subnet Group
    Value: !Ref DBSubnetGroupName

  # DB Subnet GroupのIDを出力
  DBSubnetGroupId:
    Description: The ID of the DB Subnet Group
    Value: !Ref DBSubnetGroup

6-3.RDSインスタンス作成用

Secrets Managerとセキュリティグループの構築完了後にRDSインスタンスを立ち上げます。
ここでも初めにパラメータを指定します。

使用するオプション 設定値 説明
Type AWS::RDS::DBInstance RDSのDBインスタンスを作成するリソースタイプです。
DBInstanceIdentifier !Ref DBInstanceIdentifier DBインスタンスの識別子です。
DBInstanceClass db.t3.micro DBインスタンスのクラスです。
Engine mysql データベースエンジンとしてMySQLを使用します。
EngineVersion 8.0.35 MySQLのバージョンを指定します。
AllocatedStorage 20 ストレージサイズ(GB単位)を指定します。
StorageType gp3 ストレージタイプとしてGeneral Purpose SSD (gp3)を使用します。
MultiAZ true 高可用性のためにMulti-AZ配置を有効にします。
MasterUsername !Ref MasterUsername DBインスタンスのマスターUsernameです。
MasterUserPassword !Sub "{{resolve:secretsmanager:${SecretsManagerSecretArn}:SecretString:password}}" Secrets Managerからマスターパスワードを取得します。
DBSubnetGroupName !Ref DBSubnetGroupName DB Subnet Groupの名前です。
VPCSecurityGroups – "sg-0f0fab14c0b720d0c" インスタンスに関連付けるセキュリティグループのIDです。
PubliclyAccessible false インターネットからのアクセスを無効にします。
BackupRetentionPeriod 7 バックアップの保持期間を指定します。
PreferredBackupWindow "20:00-21:00" バックアップウィンドウを指定します。
Port 3306 MySQLのデフォルトポート番号を指定します。
DBName mydatabase データベースの名前です。
DeletionProtection true インスタンスの削除保護を有効にします。
CopyTagsToSnapshot true スナップショットにタグをコピーします。
Tags Key: Name
Value: !Ref DBInstanceIdentifier
リソースにタグを設定します。
DBSubnetGroupName Ref DBSubnetGroupName パラメータを指定(グループ名)
SubnetIds !Ref SubnetIds パラメータを指定(サブネットID)
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template for creating an RDS instance with MySQL using an existing Secrets Manager secret for credentials

Parameters:
  # RDSインスタンスの識別子を指定するパラメータ
  DBInstanceIdentifier:
    Description: The DB instance identifier
    Type: String
    Default: naoki-rds-db

  # RDSインスタンスのマスターusernameを指定するパラメータ
  MasterUsername:
    Description: The master username for the DB instance
    Type: String
    Default: admin

  # 既存のSecrets ManagerシークレットのARNを指定するパラメータ
  SecretsManagerSecretArn:
    Description: The ARN of the existing Secrets Manager secret containing the master credentials
    Type: String
    Default: "シークレットマネージャーのARN"

  # RDSインスタンスを配置するVPCのIDを指定するパラメータ
  VPCId:
    Description: The VPC ID where the RDS instance will be deployed
    Type: String
    Default: vpc-062d5b30de12cff6a

  # 既存のDB Subnet Groupの名前を指定するパラメータ
  DBSubnetGroupName:
    Description: The name of the existing DB Subnet Group
    Type: String
    Default: naoki-db-subg

Resources:
  # RDSインスタンスの作成
  MyDBInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: !Ref DBInstanceIdentifier
      DBInstanceClass: db.t3.micro
      Engine: mysql
      EngineVersion: 8.0.35
      AllocatedStorage: 20
      StorageType: gp3
      MultiAZ: true
      MasterUsername: !Ref MasterUsername
      MasterUserPassword: !Sub "{{resolve:secretsmanager:${SecretsManagerSecretArn}:SecretString:password}}"
      DBSubnetGroupName: !Ref DBSubnetGroupName
      VPCSecurityGroups:
        - "sg-0f0fab14c0b720d0c"
      PubliclyAccessible: false
      BackupRetentionPeriod: 7
      PreferredBackupWindow: "20:00-21:00"
      Port: 3306
      DBName: mydatabase
      DeletionProtection: true
      CopyTagsToSnapshot: true
      Tags:
        - Key: Name
          Value: !Ref DBInstanceIdentifier

Outputs:
  # 作成したRDSインスタンスのエンドポイントアドレスを出力します
  RDSInstanceEndpoint:
    Description: The endpoint address of the RDS instance
    Value: !GetAtt MyDBInstance.Endpoint.Address

  # 作成したRDSインスタンスの識別子を出力します
  RDSInstanceIdentifier:
    Description: The identifier of the RDS instance
    Value: !Ref MyDBInstance

7.結果

7-1.Secrets Manager

下記のように作成できていることを確認
file

7-2.サブネットグループ

こちらも作成できていることを確認。
おそらく先に作成しないとインスタンス作成時にエラーが出ます。。
file

2つのサブネットを指定できており、マルチAZにする準備が出来ました。
file

7-3.RDSインスタンス

こちらも作成がでいていることを確認しました。
vpcも指定のものになっており、マルチAZにもなっております。
※現状は使用しないので一時的に停止しております。

file

7-4 EC2インスタンスとの疎通

現状はまだEC2は設置していないので下記にてテスト実施予定です。
【CloudFormation】AWSマルチAZ3層アーキテクチャの構築_EC2

8.感想

CloudFormationでのRDSの作成にあたって先にSecrets Managerを作成、それからサブネットグループを作成しないとエラーが起きていたため作成順序については気をつける必要があると感じました。

Last modified: 2024-07-31

Author