メインコンテンツまでスキップ

RDS: マネージドPostgreSQLの設計判断とセキュリティグループチェーンの完成

前章で、Tasuku は Fargate 上でコンテナを起動する実行基盤を手に入れました。ただし、起動したタスクはまだ何のデータも扱っていません。タスク管理 SaaS である以上、タスクの内容やユーザー情報をどこかに保存する場所が必要です。この章では、その保存先となるマネージドデータベース、RDS for PostgreSQL を構築します。第4章4.7 節で予告したセキュリティグループのチェーンも、この章で完成します。

9.1. マネージドデータベースの責任分界​

RDS (Relational Database Service) は、PostgreSQL をはじめとするリレーショナルデータベースエンジンをマネージドサービスとして提供する仕組みです。第1章で予告した通り、Tasuku はこの RDS で PostgreSQL を動かします。

もう 1 つの選択肢が、EC2 インスタンスに自分で PostgreSQL をインストールして運用する方法です。この方法では、OS のパッチ適用、PostgreSQL 自体のマイナーバージョンアップ、バックアップの取得と保管、障害発生時の切り替えを、すべて自分で構築し維持する必要があります。RDS はこれらの管理作業を代行し、バックアップの取得・ソフトウェアパッチの適用・障害の自動検知と復旧を AWS 側が担います。1 同期セカンダリインスタンスへのフェイルオーバーによる高可用性も、RDS が提供する仕組みの 1 つです。1 Tasuku の規模でこれらの運用を自前で構築する理由はないため、RDS を選びます。

RDS が代行しないのは、テーブル設計・クエリの書き方・アクセス制御・インスタンスサイズの選定です。この章で扱うのは主にインスタンスサイズの選定 (9.4 節) とアクセス制御 (9.5 節・9.7 節) です。テーブル設計とクエリは Tasuku のアプリケーションコードの範疇のため、第1章1.3 節の境界宣言通りこの連載では扱いません。

9.2. PostgreSQLのバージョン選定​

PostgreSQL にはメジャーバージョンが複数あり、RDS では執筆時点でバージョン 18 から 14 までが現行サポート対象です。2 各メジャーバージョンには、RDS 上での標準サポート終了日が設定されています。2 2022 年にリリースされたバージョン 14 は 2027 年 2 月に標準サポートが終了し、2024 年にリリースされたバージョン 17 は 2030 年 2 月まで続きます。2

この章では PostgreSQL 17 を採用します。執筆時点 (2026 年 7 月) で RDS へのリリースから 1 年半ほどが経ち、標準サポート終了まで 4 年近くの猶予があります。最新のバージョン 18 はリリースからまだ日が浅く、実績が薄いバージョンです。バージョン選定に AWS の公式な推奨基準があるわけではなく、これはこの連載での執筆判断です。

9.3. サブネットグループ: private-dataサブネットの再利用​

RDS インスタンスを VPC 内に配置するには、DBサブネットグループを用意する必要があります。DB サブネットグループは、RDS インスタンスをどのサブネットに置くかを指定する入れ物で、最低でも 2 つのアベイラビリティゾーンにまたがるサブネットを含まなければなりません。3 満たさない場合、RDS インスタンスの作成自体がエラーになります。3

第4章で作成した private-data サブネット (2 つのアベイラビリティゾーンにまたがる10.0.20.0/24・10.0.21.0/24) は、最初から RDS 用として設計されており、この 2AZ 要件をそのまま満たします。この章では新しいサブネットを作らず、このサブネットグループをそのまま使います。

9.4. インスタンスクラス、ストレージ、Multi-AZ​

RDS のインスタンスクラスには、汎用・メモリ最適化・バーストパフォーマンスなど複数の系統があります。4 この章ではdb.t4g.microを採用します。

db.t4g は Arm ベースの AWS Graviton2 プロセッサで動くバーストパフォーマンス系のインスタンスクラスで、4 PostgreSQL 17 を含む現行のすべてのバージョンをサポートします。5 第8章の Fargate で cpu・memory を最小構成 (256・512MiB) から始めたのと同じ考え方で、db.t4g.micro から始めます。

T インスタンス (db.t2・t3・t4g) について、「開発・テスト環境専用で本番では非推奨」という注意書きを見かけることがあります。これは Aurora 向けのガイドに明記されている内容です。6 Aurora 以外の標準的な RDS のガイドでは、この注意書きは db.t2 にのみ付いており、db.t3・db.t4g には付いていません。7 Tasuku が使うのは Aurora でなく標準の RDS のため、db.t4g.micro を本番環境の出発点として使うことに支障はありません。

db.t4g.micro のメモリは 1GiB です。8 Tasuku の想定規模 (数十テナント、同時アクセス数百ユーザー程度、第8章8.2 節) でこれが十分かどうかは、実際に apply して負荷をかけてみるまでわかりません。Fargate は第 10 章の Auto Scaling でタスクの数を負荷に応じて動的に調整しますが、cpu・memory の値自体は第 8 章の決め打ちのまま連載を通じて見直しません。RDS のインスタンスクラスも同様に、見直す章はこの連載の計画にありません。実運用で不足が見えたときにインスタンスクラスの変更で対応する前提の値だと理解してください。

ストレージにはgp3を使い、サイズは最小値の 20GiB とします。9 暗号化は作成時に有効にします。RDS インスタンスの暗号化は、作成後の既存インスタンスに追加できません。10 暗号化されたスナップショットのコピーを作り、そこから新しいインスタンスを復元するしかありません。10 最初から有効にしておけば、この作り直しを避けられます。

最後に、Multi-AZを有効にします。第4章で、1 つのアベイラビリティゾーンが利用不可になってもサービスを継続する構成にすると決めています。RDS だけシングル AZ のままでは、この前提がデータベースの層で崩れます。Multi-AZ を有効にすると、RDS は別のアベイラビリティゾーンに同期レプリカのスタンバイインスタンスを自動的に用意し、障害発生時にフェイルオーバーします。11 この方式は「Multi-AZ DB instance デプロイメント」と呼ばれ、11 読み取り可能なスタンバイを 2 台持つ別方式の「Multi-AZ DB cluster デプロイメント」とは違い、12 インスタンスクラスに制限がありません。12 db.t4g.micro のまま Multi-AZ 化できるのはこのためです。

ここでも常時課金が増えます

Multi-AZ を有効にすると、スタンバイインスタンス分の課金が加わります。第4章の NAT Gateway 二重化と同じ判断です。具体的な料金はAWSの料金ページで確認してください。

9.5. マスターパスワードとSecrets Manager統合​

RDS インスタンスにはマスターユーザーが必要です。このパスワードの管理方法には、Terraform のコードに直接書く方法と、AWS Secrets Manager に管理を委ねる方法があります。この章では後者を使います。

manage_master_user_passwordを有効にすると、RDS がパスワードを生成し、Secrets Manager 上のシークレットとしてライフサイクル全体を管理します。13 シークレットは既定で 7 日ごとに自動的にローテーションされます。14 生成されたシークレットには、少なくともユーザー名とパスワードのキーが含まれることを、AWS 公式ドキュメントの例から確認できます。15 接続先のホスト名・ポート番号・データベース名は、シークレットの中身に頼らず Terraform の outputs から取得する設計にします。

この統合の有効化に必要な権限は、カスタムの KMS キーを使わない場合、kms:DescribeKey・secretsmanager:CreateSecret・secretsmanager:TagResourceの 3 つです。16 第3章で設定した terraform 実行者の権限にはPowerUserAccessが含まれています。このポリシーが除外するのはiam:*・organizations:*・account:*の 3 つの名前空間だけで、17 上の 3 つの権限はいずれもこの除外に該当しません。第8章8.5 節で ECR の実行ロール権限に自前のポリシーが必要になったのとは違い、この統合には追加の IAM ポリシーが要りません。

9.6. パラメータグループ​

PostgreSQL のエンジン設定 (パラメータ) を変更するには、専用のDBパラメータグループを作成する必要があります。パラメータグループは、対応するエンジンとメジャーバージョンの組み合わせ (family) を 1 つ持ちます。18 この章ではpostgres17という family でパラメータグループを新設します。

最初に検討したのは、SSL 接続を強制するrds.force_sslパラメータを明示的に 1 へ変更することでした。ただし、PostgreSQL 15 以降ではこのパラメータの既定値がすでに 1 (オン) です。19 Tasuku が採用する PostgreSQL 17 でも同様のため、変更する必要はありません。パラメータグループでは変更でなく、9.9 節の動作確認で既定値どおり有効になっていることを確かめます。

パラメータグループで実際に変更するのはlog_min_duration_statementです。このパラメータは既定では設定されておらず、20 値をミリ秒単位で指定すると、それ以上かかった SQL 文をログに記録します。1000 (1 秒) を設定し、遅いクエリを検知できるようにします。このパラメータが即座に反映されるか、DB インスタンスの再起動を要するかを明記した一次情報は見つかりませんでした。9.9 節の動作確認で反映を確認し、反映されていなければ再起動が必要になる場合があります。

9.7. セキュリティグループ: チェーンの完成​

第4章4.7 節のセキュリティグループチェーンの図では、RDS 用の SG が「ECS タスク用 SG のみ」からの ingress を許可する形で予告されていました。ここでその通りに作り、第6章の ALB、第8章の ECS タスクに続いて、この連載 3 つ目の明示的な SG を新設します。

ingress は、第8章で作った ECS タスク用 SG からの 5432 番のみを許可します。PostgreSQL の既定ポートです。

egress は一切定義しません。RDS インスタンス自身が外部への接続元として動作しない限り、egress のルールは実質的に意味を持ちません。21 加えて、AWS は VPC 内に新しいセキュリティグループを作ると、既定で egress の全許可ルールを自動的に追加します。22 Terraform のaws_security_groupリソースは、egress を明示的に指定しない場合、この自動生成されたルールを検出して削除します。23 つまり、egress のルールを 1 つも書かなければ、最終的な状態は egress が 1 件もない全 egress 拒否になります。第6章の ALB 用 SG の「意図的に空」も、同じ仕組みの上に成立しています。

最後に、第8章で作った ECS タスク用 SG に、RDS 用 SG への 5432 番 egress を追加します。第 8 章時点の egress は 443 番のみだったため、この章でセキュリティグループチェーンが完成します。

9.8. Terraform実装​

ここまでの内容をrds.tfという新しいファイルに書きます。DB 名・マスターユーザー名にはname_prefixをそのまま使えません。PostgreSQL のdb_nameは 1〜63 文字の英数字とアンダースコアのみ、master_usernameは 1〜16 文字の英数字とアンダースコアのみで、いずれもハイフンを含められないためです。24 db_nameにはname_prefixのハイフンをアンダースコアに変換した値を使い、master_usernameにはvar.project(既定値tasuku、ハイフンを含まない)からこの変換を経由せず直接組み立てた値を使います。なお、db_nameを指定しても、それとは別にpostgresという名前の既定データベースが常に作成されます。24 Tasuku 用のデータベースだけが存在するわけではありません。

locals {
db_identifier_safe = replace(local.name_prefix, "-", "_")
}

resource "aws_db_subnet_group" "main" {
name = "${local.name_prefix}-db-subnet-group"
description = "RDS用サブネットグループ。第4章のprivate-dataサブネット (2AZ) を使用"
subnet_ids = [for k in local.private_data_subnet_keys : aws_subnet.this[k].id]

tags = {
Name = "${local.name_prefix}-db-subnet-group"
}
}

9.7 節で決めたセキュリティグループのチェーンです。

resource "aws_security_group" "rds" {
name = "${local.name_prefix}-rds-sg"
description = "RDS用SG。ECSタスク用SGからのingressのみ許可"
vpc_id = aws_vpc.main.id

tags = {
Name = "${local.name_prefix}-rds-sg"
}
}

resource "aws_vpc_security_group_ingress_rule" "rds_from_ecs_tasks" {
security_group_id = aws_security_group.rds.id

referenced_security_group_id = aws_security_group.ecs_tasks.id
from_port = 5432
to_port = 5432
ip_protocol = "tcp"

description = "ECSタスク用SG (第8章) からのPostgreSQL接続のみ許可"
}

resource "aws_vpc_security_group_egress_rule" "ecs_tasks_to_rds" {
security_group_id = aws_security_group.ecs_tasks.id

referenced_security_group_id = aws_security_group.rds.id
from_port = 5432
to_port = 5432
ip_protocol = "tcp"

description = "RDS用SGへのPostgreSQL接続 (run-taskでのpsql疎通確認、第10章のアプリ本体でも使用)"
}

9.6 節のパラメータグループです。

resource "aws_db_parameter_group" "postgres17" {
name = "${local.name_prefix}-postgres17"
family = "postgres17"
description = "Tasuku用PostgreSQL 17パラメータグループ。スロークエリログ (1秒以上) を有効化"

parameter {
name = "log_min_duration_statement"
value = "1000"
}

tags = {
Name = "${local.name_prefix}-postgres17"
}
}

RDS インスタンス本体です。9.4 節・9.5 節で決めた設計をまとめて反映します。

resource "aws_db_instance" "main" {
identifier = "${local.name_prefix}-db"
engine = "postgres"
engine_version = "17"
instance_class = "db.t4g.micro"

allocated_storage = 20
storage_type = "gp3"
storage_encrypted = true

db_name = local.db_identifier_safe
username = "${var.project}_admin"

manage_master_user_password = true

db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.rds.id]
parameter_group_name = aws_db_parameter_group.postgres17.name

multi_az = true

backup_retention_period = 7
deletion_protection = true

# 固定identifierのfinal_snapshot_identifierはdestroy再実行時に名前衝突するため、
# 最終スナップショットは作らない (deletion_protectionで誤操作防止は別途担保)
skip_final_snapshot = true

tags = {
Name = "${local.name_prefix}-db"
}
}

backup_retention_periodは明示的に 7 を指定しています。Terraform でこの引数を省略すると既定値は 0 (自動バックアップ無効) になり、25 AWS の API・CLI 経由の既定値である 1 日とも、コンソール経由で作成した場合の既定値である 7 日とも異なります。25 コンソールの既定値と同じ 7 日を明示しました。deletion_protectionも既定は false のため、26 本番運用を想定して true にしています。

skip_final_snapshotは true にし、削除時の最終スナップショットを作りません。27 false にするとfinal_snapshot_identifierで指定した名前のスナップショットが作成されますが、27 固定の文字列をこの値に使うと、destroy してから同じコードでもう一度 apply・destroy したときに、前回作成済みの同名スナップショットと衝突します。誤操作からの保護はdeletion_protectionがすでに担っているため、この章ではシンプルに true を選びます。

最後に、動作確認で使う psql クライアント同梱の専用タスク定義を追加します。Tasuku のアプリイメージはまだ存在しないため、第8章の hello-world と同じく、Docker 公式のpostgresイメージで代用します。28 実行ロール・タスクロール・クラスタ・ロググループは第 8 章のものを再利用し、ログストリームの prefix だけ変えます。

resource "aws_ecs_task_definition" "psql_check" {
family = "${local.name_prefix}-psql-check"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 256
memory = 512
execution_role_arn = aws_iam_role.ecs_task_execution.arn
task_role_arn = aws_iam_role.ecs_task.arn

runtime_platform {
operating_system_family = "LINUX"
cpu_architecture = "X86_64"
}

container_definitions = jsonencode([
{
name = "psql-check"
image = "${aws_ecr_repository.app.repository_url}:psql-check"
essential = true

logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group" = aws_cloudwatch_log_group.app.name
"awslogs-region" = var.region
"awslogs-stream-prefix" = "psql-check"
}
}
}
])

tags = {
Name = "${local.name_prefix}-psql-check"
}
}

後続の章が参照する値をoutputs.tfに追加します。

output "rds_endpoint" {
description = "RDSインスタンスの接続エンドポイント (address:port形式、第10章のアプリ接続文字列で参照)"
value = aws_db_instance.main.endpoint
}

output "rds_address" {
description = "RDSインスタンスのホスト名のみ (ポート番号を含まない、run-taskのpsql接続コマンドで参照)"
value = aws_db_instance.main.address
}

output "rds_db_name" {
description = "RDSインスタンスの初期データベース名 (第10章のアプリ接続文字列で参照)"
value = aws_db_instance.main.db_name
}

output "rds_master_user_secret_arn" {
description = "マスターパスワードを管理するSecrets ManagerシークレットのARN (run-task疎通確認・第10章のアプリでの参照用)"
value = aws_db_instance.main.master_user_secret[0].secret_arn
}

output "rds_port" {
description = "RDSインスタンスのポート番号"
value = aws_db_instance.main.port
}

output "rds_security_group_id" {
description = "RDS用SGのID (第10章で参照する可能性あり)"
value = aws_security_group.rds.id
}

output "psql_check_task_definition_arn" {
description = "psql疎通確認用タスク定義のARN (run-taskで参照)"
value = aws_ecs_task_definition.psql_check.arn
}

9.9. 動作確認​

terraform fmt -check -recursive -diffとterraform validateを実行し、構文とプロバイダスキーマの整合を確認します。この章の検証も validate までで、planやapplyは対象に含めません。

実際に apply して確認する場合の手順です。まず、postgres:17-alpineイメージを Docker Hub から pull して ECR へ再ホストします。第8章8.9 節の hello-world と同じ手順です。

aws ecr get-login-password --region ap-northeast-1 \
| docker login --username AWS --password-stdin <account-id>.dkr.ecr.ap-northeast-1.amazonaws.com
docker pull postgres:17-alpine
docker tag postgres:17-alpine <account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/tasuku-dev-app:psql-check
docker push <account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/tasuku-dev-app:psql-check

次に、Secrets Manager からマスターパスワードを取得します。JSON からパスワードだけを取り出すためjqコマンドを使います。事前にインストールしておいてください。

PGPASSWORD=$(aws secretsmanager get-secret-value \
--secret-id <rds_master_user_secret_arnの値> \
--query SecretString --output text | jq -r .password)

取得したパスワードをコンテナの環境変数に注入し、run-taskで psql の単発タスクを起動します。--network-configurationのsubnets・securityGroupsは、第8章8.9 節と同じく明示します。省略すると VPC の既定セキュリティグループが使われてしまい、第4章で全閉鎖したその SG では疎通できません。接続先のホスト名にはrds_endpointではなくrds_addressを使います。rds_endpointはポート番号を含むaddress:port形式のため、そのままではpsqlの-hオプションに渡せません。

aws ecs run-task \
--cluster tasuku-dev-cluster \
--task-definition tasuku-dev-psql-check \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[<private-appサブネットID>],securityGroups=[<ecs_tasks SGのID>],assignPublicIp=DISABLED}" \
--overrides "{\"containerOverrides\":[{\"name\":\"psql-check\",\"environment\":[{\"name\":\"PGPASSWORD\",\"value\":\"$PGPASSWORD\"}],\"command\":[\"psql\",\"-h\",\"<rds_addressの値>\",\"-U\",\"tasuku_admin\",\"-d\",\"tasuku_dev\",\"-c\",\"SELECT version(); SHOW rds.force_ssl; SHOW log_min_duration_statement;\"]}]}"

検証は 2 段階です。まずaws ecs describe-tasksでlastStatusがSTOPPEDになり、containers[].exitCodeが0であることを確認します。タスクが正常に終了しただけでは、実際に PostgreSQL へ接続できたかはわかりません。続けてaws logs tail /ecs/tasuku-dev-appを実行します。CloudWatch Logs に記録されたSELECT version()の実際の出力、rds.force_sslがonであること、log_min_duration_statementが1000であることを確認します。この 2 段階を経て、初めて疎通確認が完了したと言えます。

この章の RDS インスタンスも、これまでと同じ検証水準です。実際に AWS へ apply してこの手順を実行した結果は保証しません。

本章のまとめ​

  • RDS はバックアップ・パッチ適用・障害検知と復旧を AWS 側が代行するマネージドサービスで、Tasuku はテーブル設計・アクセス制御・インスタンスサイズの選定を担います
  • PostgreSQL 17 を採用しました。標準サポート終了まで 4 年近くの猶予があり、最新バージョンほど実績が浅くないという執筆判断です
  • インスタンスクラスは db.t4g.micro から始めます。「T インスタンスは開発・テスト専用」という注意書きは Aurora 向けのガイダンスで、標準 RDS には同じ制約がないことを確認しました
  • ストレージは gp3・20GiB・暗号化有効、Multi-AZ も有効にし、第4章で決めたアベイラビリティゾーン障害への耐性をデータベースの層まで一貫させました
  • deletion_protectionを有効にして誤操作による削除を防ぎ、skip_final_snapshotは true にして固定文字列の識別子による名前衝突を避けました
  • マスターパスワードは Secrets Manager 統合 (manage_master_user_password) に任せ、第 8 章のような追加 IAM ポリシーは不要でした
  • パラメータグループでは、PostgreSQL 15 以降で既定オンのrds.force_sslを変更せず、log_min_duration_statementのみ明示的に変更しました
  • RDS 用 SG を新設し、第4章で予告された ALB→ECS→RDS のセキュリティグループチェーンを完成させました
  • 動作確認は、psql クライアント同梱のタスクによる run-task で行い、exitCode と CloudWatch Logs の実際の出力の両方を確認する 2 段階の検証にしました

次に読む​

Footnotes​

  1. 出典: What is Amazon Relational Database Service (Amazon RDS)?。RDS がバックアップ・ソフトウェアパッチ適用・障害の自動検知とリカバリを管理し、プライマリ DB インスタンスと同期セカンダリ DB インスタンスによる高可用性を提供するとしています。 ↩ ↩2

  2. 出典: Release calendars for Amazon RDS for PostgreSQL。PostgreSQL 各メジャーバージョンの RDS リリース日・標準サポート終了日を示す表を掲載しています。 ↩ ↩2 ↩3

  3. 出典: Working with a DB instance in a VPC、およびDBSubnetGroupDoesNotCoverEnoughAZs。DB サブネットグループは最低 2 つのアベイラビリティゾーンにまたがるサブネットを含む必要があり、満たさない場合は例外が発生するとしています。 ↩ ↩2

  4. 出典: DB instance class types。db.t4g が AWS Graviton2 プロセッサで動くバーストパフォーマンス系のインスタンスクラスであるとしています。 ↩ ↩2

  5. 出典: Supported DB engines for DB instance classes。db.t4g.micro が PostgreSQL 17・16・15・14・13 の全バージョンをサポートするとしています。 ↩

  6. 出典: DB instance class types (Aurora User Guide)。db.t3 について「開発・テストサーバーなど、本番以外のサーバーでの利用のみを推奨する」との注記があります。 ↩

  7. 出典: DB instance class types (Amazon RDS User Guide)。同様の注記は db.t2 にのみ付いており、db.t3・db.t4g の説明文には付いていません。 ↩

  8. 出典: Hardware specifications for DB instance classes。db.t4g.micro のメモリが 1GiB であることを示す表を掲載しています。 ↩

  9. 出典: CreateDBInstanceRequest.allocatedStorage。RDS for PostgreSQL の gp2・gp3 ストレージは 20〜65536 (GiB) の整数という制約を示しています。 ↩

  10. 出典: WKLD.09 Encrypt Amazon RDS databases。暗号化は作成時にのみ有効にでき、既存の暗号化なしインスタンスを暗号化するには新しい暗号化インスタンスを作成してデータを移行する必要があるとしています。 ↩ ↩2

  11. 出典: Multi-AZ DB instance deployments for Amazon RDS。スタンバイ DB インスタンス 1 台による高可用性の仕組みで、すべての Amazon RDS に適用されるとしています。 ↩ ↩2

  12. 出典: Multi-AZ DB cluster deployments for Amazon RDS。読み取り可能なスタンバイ 2 台による別方式で、db.m5d・db.r6gd 等の特定インスタンスクラスに限定されるとしています。 ↩ ↩2

  13. 出典: terraform MCP (hashicorp/aws provider v6.53.0、aws_db_instance)。manage_master_user_passwordを有効にすると RDS が Secrets Manager でマスターパスワードを生成・管理するとしています。 ↩

  14. 出典: Password management with Amazon RDS and AWS Secrets Manager。シークレットは既定で 7 日ごとに自動的にローテーションされるとしています。 ↩

  15. 出典: Get a secret or secret value from Secrets Manager。CloudFormation の動的参照サンプルから、シークレットの JSON 内にusername・passwordのキーが存在することが確認できます。 ↩

  16. 出典: 同上「Permissions required for Secrets Manager integration」。カスタム KMS キー不使用時に必要な権限をkms:DescribeKey・secretsmanager:CreateSecret・secretsmanager:TagResourceの 3 つとしています。 ↩

  17. 出典: PowerUserAccess。iam:*・organizations:*・account:*をNotActionで除外し、それ以外の全アクションを Resource "*"で許可するポリシー文書を示しています。 ↩

  18. 出典: New-RDSDBClusterParameterGroup Cmdlet。DB パラメータグループの family 名はエンジンとメジャーバージョンの組み合わせに対応し、RDS for PostgreSQL ではpostgres13のような形式を取るとしています。 ↩

  19. 出典: Using SSL with a PostgreSQL DB instance。rds.force_sslの既定値は PostgreSQL 15 以降で 1 (オン)、14 以前は 0 (オフ) だとしています。 ↩

  20. 出典: Turning on query logging for your RDS for PostgreSQL DB instance。log_min_duration_statementは既定では設定されておらず、有効にすると最適化されていないクエリの発見に役立つとしています。 ↩

  21. 出典: Controlling access with security groups。アウトバウンドのトラフィックルールは、DB インスタンス自身がクライアントとして動作する場合を除き適用されないとしています。 ↩

  22. 出典: Security group rules。新規作成したセキュリティグループには、既定ですべてのアウトバウンドトラフィックを許可するルールが 1 つ付くとしています。 ↩

  23. 出典: terraform MCP (hashicorp/aws provider v6.53.0、aws_security_group)。「NOTE on Egress rules」として、Terraform は新規セキュリティグループ作成時にこの既定の ALL 許可ルールを検出して削除するとしています。 ↩

  24. 出典: CreateDBInstanceRequest.dbName、およびmasterUsername。いずれも英数字とアンダースコアのみで先頭は英字という制約を示しています。 ↩ ↩2

  25. 出典: terraform MCP (hashicorp/aws provider v6.53.0)、およびBackup retention period。Terraform の既定値は 0、AWS API・CLI の既定値は 1 日、コンソールの既定値は 7 日と、3 者が異なるとしています。 ↩ ↩2

  26. 出典: terraform MCP (hashicorp/aws provider v6.53.0)。deletion_protectionの既定値は false だとしています。 ↩

  27. 出典: terraform MCP (hashicorp/aws provider v6.53.0、aws_db_instance)。skip_final_snapshotを true にすると最終スナップショットを作成せず、false の場合はfinal_snapshot_identifierの値でスナップショットを作成するとしています。 ↩ ↩2

  28. 出典: postgres - Official Image。イメージに psql クライアントが同梱されているとしています。 ↩