アプリ用の PostgreSQL データベースを作成する

AWSBeginner
オンラインで実践に進む

はじめに

注文アプリが顧客の注文を保存するには、リレーショナルデータベースが必要です。このラボでは Amazon RDS でプライベートな PostgreSQL データベースを作成し、標準 SQL クライアントで接続して、アプリに新しいエンドポイントを設定します。

前の VPC と EC2 コースで扱うサブネット、セキュリティグループ、アプリ接続の知識を前提とします。ネットワーク、アプリ、設定済み AWS CLI は提供されます。個人の AWS アカウントは不要です。最後にデータベースを削除します。

認定試験との関連

このラボは、次の試験テーマについて入門的な実践練習を提供します。

アプリ用データベースを作成する

このステップでは、準備済みのデータベースネットワーク内にプライベート PostgreSQL インスタンスを作成します。

Amazon RDS はリレーショナルデータベースのインスタンスを管理します。PostgreSQL はテーブルを保存し SQL を実行するデータベースエンジンです。AWS CLI は RDS リソースを管理し、SQL クライアントはエンジンに接続してデータを操作します。RDS インスタンスの作成とテーブルの検索は別の操作です。

AWS Management Console はサービスの探索やリソース確認に役立ちます。CLI は正確な照会、繰り返せる操作、自動化に適していますが、構文の習得には練習が必要です。このコースでは準備済みの Terminal と AWS View を使います。AWS View はラボのリソースとアプリの結果を表示する画面で、AWS Management Console とは別です。

作業ディレクトリに移動し、提供された接続設定を読み込みます。

cd /home/labex/project
source database.env

DB_SECURITY_GROUP_ID はデータベースに用意されたネットワークアクセスルールを示します。PGSERVICEFILE と PGPASSFILE は、通常の接続ファイルとパスワードファイルの場所を PostgreSQL クライアントに知らせます。パスワードファイルは非公開に保ち、内容を表示する必要はありません。

準備済みの DB サブネットグループ を確認します。

aws rds \
  describe-db-subnet-groups \
  --db-subnet-group-name orders-subnets \
  --query 'DBSubnetGroups[].{Name:DBSubnetGroupName,VPC:VpcId,Subnets:Subnets[].SubnetIdentifier}'

DB サブネットグループは、RDS の配置に使用できる VPC サブネットを指定します。このグループには 2 つのアベイラビリティーゾーンのプライベートなデータベースサブネットが含まれます。サブネットが 2 つあるだけで Multi-AZ 配置が有効になるわけではありません。

インスタンスを作成します。

aws rds \
  create-db-instance \
  --db-instance-identifier orders-db \
  --db-instance-class db.t3.micro \
  --engine postgres \
  --engine-version 16.15 \
  --allocated-storage 20 \
  --master-username orders_admin \
  --master-user-password "$(cat db-password.txt)" \
  --db-name orders \
  --db-subnet-group-name orders-subnets \
  --vpc-security-group-ids "$DB_SECURITY_GROUP_ID" \
  --no-publicly-accessible \
  --backup-retention-period 0 \
  --query 'DBInstance.{Identifier:DBInstanceIdentifier,Status:DBInstanceStatus,Engine:Engine}'

インスタンス識別子 orders-db は RDS リソース名、データベース名 orders はその中の PostgreSQL データベース名です。db.t3.micro はインスタンスクラスを、20 は GiB 単位の要求ストレージ容量を指定します。プライベートアクセスによりアプリ接続を準備済みネットワーク内に保ちます。この短い演習では自動バックアップの保持を無効にし、後のラボで手動スナップショットを学びます。

$(cat db-password.txt) は準備済みのパスワードを表示せずに渡します。パスワードをメモやスクリーンショットに貼り付けないでください。

利用可能になるまで待ち、接続エンドポイントを確認します。

aws rds \
  wait db-instance-available \
  --db-instance-identifier orders-db
aws rds \
  describe-db-instances \
  --db-instance-identifier orders-db \
  --query 'DBInstances[0].{Identifier:DBInstanceIdentifier,Database:DBName,Status:DBInstanceStatus,Endpoint:Endpoint}'

データベース orders、状態 available、PostgreSQL ポート 5432 が表示されるはずです。エンドポイント はクライアントがこのインスタンスを選ぶためのアドレスです。AWS View にはプライマリデータベース orders-db が表示されます。注文テーブルはまだ作成されていません。

SQL クライアントとアプリを接続する

このステップではエンジンをテストし、アプリの接続先をそのエンドポイントに設定します。

psql は PostgreSQL の標準コマンドラインクライアントです。準備済みの orders-db サービスには、作成したインスタンスの接続情報が保存されます。サービス名は便利なクライアント設定項目であり、AWS リソースではありません。

エンジンを照会します。

プライベート PostgreSQL 接続には到達可能なエンドポイントと許可されたポートが必要

概念図:プライベート PostgreSQL 接続には到達可能なエンドポイントと許可されたポートが必要。

psql \
  "service=orders-db" \
  --command 'SELECT current_database(), current_user;'

データベース orders とユーザー orders_admin が返るはずです。この結果は RDS リソースのメタデータではなく、データベース接続から得られます。RDS がデータベースホストを管理するため、アプリはホストへの SSH ではなくデータベースプロトコルで接続します。

RDS からエンドポイントを取得します。--query が 1 つのフィールドを選び、--output text が単純な値を出力し、シェルの $(...) がそれを DB_ENDPOINT に保存します。

DB_ENDPOINT=$(aws rds \
  describe-db-instances \
  --db-instance-identifier orders-db \
  --query 'DBInstances[0].Endpoint.Address' \
  --output text)

提供されたアプリ設定を確認します。

cat app-config.json

read_host は照会用、write_host は変更用のデータベースを選びます。今は両方ともプライマリを使用します。password_file は、この JSON にパスワードを直接埋め込まず、非公開ファイルを参照します。

JSON 編集ツール jq で両方のホスト項目を設定します。新しいファイルに書き込み、編集が成功したら元の設定を置き換えます。

jq \
  --arg host "$DB_ENDPOINT" \
  '.read_host = $host | .write_host = $host' \
  app-config.json > app-config.new
mv app-config.new app-config.json

アプリの接続をテストします。

curl \
  --silent \
  --show-error \
  --fail \
  http://127.0.0.1:8080/application/connection

database は orders、user は orders_admin、read_only は false になるはずです。プライマリは書き込めますが、このラボでは接続だけを確立します。注文テーブルがないため AWS View の注文一覧はまだ利用できません。次のラボでテーブルを作成します。 AWS View の PostgreSQL プライマリ接続

例ではアプリがプライマリの orders データベースに接続し、ネイティブな RDS エンドポイントが表示されています。注文テーブルはまだありません。リソース識別子は環境によって異なります。

AWS Console: RDS

公式 Console の例:Connectivity & security の Endpoint と Port は CLI の Endpoint.Address と Endpoint.Port に対応します。公式例は MySQL の 3306 ですが、このラボでは PostgreSQL の 5432 と自分のコマンドが返すエンドポイントを使用します。例のホスト名やポートをコピーしないでください。AWS にサインインせず Terminal と AWS View で続けます。

Source: AWS RDS guide.

データベースインスタンスを削除する

このステップでは、準備済みのアプリとネットワークを保持し、短期間の演習用データベースを削除します。

最終スナップショットを残さずインスタンスを削除します。

aws rds \
  delete-db-instance \
  --db-instance-identifier orders-db \
  --skip-final-snapshot \
  --query 'DBInstance.DBInstanceIdentifier'

--skip-final-snapshot は復元用コピーを保存せず、演習のデータベースを破棄します。重要なデータでは、インスタンス削除前にバックアップの保持方法を決めてください。

削除完了を待ち、リソース一覧を確認します。

aws rds \
  wait db-instance-deleted \
  --db-instance-identifier orders-db
aws rds \
  describe-db-instances \
  --query 'DBInstances[].DBInstanceIdentifier'

結果は [] になるはずです。AWS View にはデータベースが表示されなくなります。アプリの古いエンドポイントにはデータベースがないため、削除後の接続失敗は想定どおりです。提供されたサブネットグループ、セキュリティグループ、アプリファイルは保持してください。

まとめ

プライベートな RDS PostgreSQL インスタンスを作成し、リソース識別子とデータベース名の違いを理解して、エンドポイントを確認しました。psql でエンジンを照会し、アプリを同じプライマリに接続した後、準備済みネットワークを保持してインスタンスを削除しました。

次のラボでは注文テーブルを作成し、SQL で顧客の注文を保存、検索します。