皆様、お世話になっております。鈴木と申します。
今回はAWS CloudFormationを使用してRDSを作成していきたいと思います。
1.目次
2.要件
- エンジンをMySQLにて作成
- AWS Secrets Managerでパスワードを取得・管理
- マルチAZ配置
- プライベートサブネットに属しているEC2からのみのアクセスを許可(プロテクトサブネットに配置)
3.RDSについて
AWS RDS (Relational Database Service) は、AWSが提供するフルマネージドのリレーショナルデータベースサービスです。RDSを使用すると、データベースのセットアップ、運用、スケーリングが簡単に行え、アプリケーションのデータ管理を効率的にサポートします。
主な特徴として5つ挙げられます。
- フルマネージド
データベースのハードウェアやソフトウェアの管理、パッチ適用、バックアップ、復元など、運用に関わる多くの作業を AWS が代行します。 - 高可用性と耐障害性:
マルチAZ (アベイラビリティゾーン) 配置を利用することで、データベースの高可用性を確保し、障害発生時のデータ損失を防ぎます。 - スケーラビリティ:
インスタンスのサイズやストレージを動的にスケールアップまたはスケールダウンでき、トラフィックやデータの増減に対応します。 - セキュリティ:
データベースインスタンスは VPC (Virtual Private Cloud) 内に配置され、セキュリティグループやネットワークアクセス制御リストでアクセスを制御します。また、AWS Secrets Manager と連携して、データベースの認証情報を安全に管理できます。 - コスト効率:
使用した分だけを支払う従量課金制で、必要に応じてリソースを柔軟に利用できます。
主なエンジンとしては下記のものが挙げられます。
データベースエンジン | 概要 |
---|---|
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.構成図
- プライベートサブネットに属するEC2からのアクセスのみに設定
→セキュリティグループはこちらで作成済みです。
こちらでEC2ソース指定のMySQL(3306)のものを作成しております。 - マルチAZ配置にしてフェールオーバーできるように設定
- パスワードを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
下記のように作成できていることを確認
7-2.サブネットグループ
こちらも作成できていることを確認。
おそらく先に作成しないとインスタンス作成時にエラーが出ます。。
2つのサブネットを指定できており、マルチAZにする準備が出来ました。
7-3.RDSインスタンス
こちらも作成がでいていることを確認しました。
vpcも指定のものになっており、マルチAZにもなっております。
※現状は使用しないので一時的に停止しております。
7-4 EC2インスタンスとの疎通
現状はまだEC2は設置していないので下記にてテスト実施予定です。
【CloudFormation】AWSマルチAZ3層アーキテクチャの構築_EC2
8.感想
CloudFormationでのRDSの作成にあたって先にSecrets Managerを作成、それからサブネットグループを作成しないとエラーが起きていたため作成順序については気をつける必要があると感じました。