👏

AWS学びなおし(+TF)_RDS Proxy

2025/02/27に公開

AWS RDS Proxyは、Amazon Relational Database Service (RDS) の可用性、拡張性、セキュリティを向上させるフルマネージド型のデータベースプロキシサービスです。アプリケーションとRDSインスタンスの間に入り、以下の主な機能を提供します。

主な機能とメリット:

  • 接続プーリング: データベース接続を再利用可能なプールとして管理し、アプリケーションからの新しい接続要求に対して、プール内の既存の接続を効率的に割り当てます。これにより、データベースへの過剰な接続負荷を軽減し、接続確立のオーバーヘッドを削減します。
  • 接続多重化: 複数のアプリケーション接続を少数のデータベース接続に多重化します。これにより、データベースが処理する必要のある同時接続数を減らし、データベースのパフォーマンスと安定性を向上させます。特に、多数のクライアントからの断続的な接続が多いサーバーレス環境やマイクロサービスアーキテクチャにおいて有効です。
  • フェイルオーバーの透過性: RDSインスタンスでフェイルオーバーが発生した場合、RDS Proxyは自動的に新しいプライマリインスタンスへの接続を確立し、アプリケーションは透過的にフェイルオーバーを処理できます。アプリケーション側での再接続ロジックの実装や、フェイルオーバーによるサービス停止時間を最小限に抑えることができます。
  • 認証情報の管理: データベースの認証情報をRDS Proxyで集中管理し、アプリケーションコードや設定ファイルに認証情報を埋め込む必要性を減らします。AWS Secrets Managerと連携することで、認証情報を安全に管理し、ローテーションも容易に行えます。
  • セキュリティの強化: RDS Proxyは、アプリケーションからのすべてのデータベースアクセスを仲介するため、セキュリティポリシーの適用や監査を一元的に行うことができます。IAM認証と連携することで、きめ細かいアクセス制御を実現できます。

なぜRDS Proxyが必要なのか?

従来のアプリケーションアーキテクチャでは、アプリケーションがデータベースに直接接続するのが一般的でした。しかし、特にクラウドネイティブなアプリケーションでは、以下のような課題が顕在化してきました。

  • 接続数の制限: RDSインスタンスには、同時接続数の上限があります。アプリケーションのスケールアウトや、一時的なトラフィックの急増によって、接続数が上限を超え、データベースへの接続エラーやパフォーマンス低下が発生する可能性があります。
  • 接続確立のオーバーヘッド: アプリケーションが新しいリクエストごとにデータベース接続を確立・切断する場合、接続確立のオーバーヘッドが無視できなくなります。特に、リクエスト処理時間が短いサーバーレス関数などでは、このオーバーヘッドがパフォーマンスに大きな影響を与える可能性があります。
  • フェイルオーバー時の影響: RDSインスタンスでフェイルオーバーが発生した場合、アプリケーションは自身で再接続処理を実装する必要があります。再接続処理が適切に行われない場合、サービス停止時間が長くなる可能性があります。
  • 認証情報の管理の煩雑さ: 複数のアプリケーションでデータベースを利用する場合、それぞれのアプリケーションで認証情報を管理する必要があり、管理が煩雑になり、セキュリティリスクも高まります。

RDS Proxyは、これらの課題を解決し、よりスケーラブルで可用性が高く、安全なデータベースアクセスを実現します。

RDS Proxyの仕組み:

  1. アプリケーションはRDS Proxyのエンドポイントに接続: アプリケーションは、RDSインスタンスのエンドポイントではなく、RDS Proxyのエンドポイントに接続します。
  2. RDS Proxyは接続プールを管理: RDS Proxyは、バックエンドのRDSインスタンスへの接続プールを維持します。
  3. 接続の再利用と多重化: アプリケーションからの接続要求に対して、プール内の既存の接続を再利用したり、複数のアプリケーション接続を少数のデータベース接続に多重化したりします。
  4. 透過的なフェイルオーバー: RDSインスタンスでフェイルオーバーが発生した場合、RDS Proxyは自動的に新しいプライマリインスタンスへの接続を確立し、アプリケーションには透過的にフェイルオーバーが行われます。
  5. 認証とセキュリティ: RDS Proxyは、IAM認証やSecrets Managerとの連携により、安全な認証情報の管理とアクセス制御を実現します。

RDS Proxyが適しているワークロード:

  • サーバーレスアプリケーション (AWS Lambda, API Gateway): 接続数の急増や断続的な接続が発生しやすいサーバーレス環境において、接続プーリングと多重化の効果が特に大きいです。
  • マイクロサービスアーキテクチャ: 多数のマイクロサービスがデータベースにアクセスする場合、接続管理の複雑さを軽減し、データベース負荷を分散できます。
  • 接続数が変動しやすいアプリケーション: トラフィックの変動が大きく、接続数が予測しにくいアプリケーションにおいて、接続プーリングによりデータベースの安定性を向上させることができます。
  • 高可用性を要求されるアプリケーション: フェイルオーバーの透過性により、アプリケーションの可用性を向上させることができます。

RDS Proxyの制約事項:

  • 追加のレイテンシ: RDS Proxyを経由することで、わずかながらレイテンシが増加する可能性があります。ただし、通常は数ミリ秒程度であり、多くのアプリケーションでは許容範囲内です。
  • コスト: RDS Proxyの利用料金が発生します。ただし、接続効率の向上やデータベースリソースの最適化により、トータルコストを削減できる場合もあります。
  • 機能制限: RDS Proxyは、すべてのデータベース機能をサポートしているわけではありません。特定の拡張機能やプロトコルを使用している場合は、RDS Proxyの対応状況を確認する必要があります。(通常、一般的なSQL操作には問題ありません。)
  • 初期設定の複雑さ: RDS Proxyの初期設定には、VPC、セキュリティグループ、IAMロールなどの設定が必要であり、多少の学習コストがかかる場合があります。(TerraformなどのIaCツールを利用することで、設定を自動化し、簡素化できます。)

【実務レベルの内容と重要事項】

RDS Proxyを実務で利用する上で、以下の点が重要になります。

パフォーマンス:

  • レイテンシ: 前述の通り、RDS Proxyによるレイテンシは通常わずかですが、アプリケーションの要件によっては許容できない場合があります。特に、非常に低レイテンシを要求されるアプリケーションでは、RDS Proxyの導入前にパフォーマンステストを実施し、影響を確認する必要があります。
  • スケーラビリティ: RDS Proxy自身もスケールアウトしますが、極端に高いスループットを要求される場合は、RDS Proxyのキャパシティがボトルネックになる可能性も考慮する必要があります。AWSのドキュメントやベストプラクティスを参照し、適切なRDS Proxyのサイズを選択し、必要に応じてスケールアップ/アウトを検討してください。
  • 接続プールの設定: RDS Proxyの接続プールの設定 (最大接続数、アイドルタイムアウトなど) は、アプリケーションのワークロードに合わせて適切にチューニングする必要があります。設定が不適切な場合、パフォーマンスの低下や接続エラーが発生する可能性があります。CloudWatchメトリクスを監視しながら、最適な設定を見つけることが重要です。

セキュリティ:

  • IAM認証: RDS Proxyへのアクセス制御には、IAM認証を必ず利用するようにしてください。IAMロールを適切に設定し、必要最小限の権限を付与することが重要です。
  • Secrets Manager連携: データベースの認証情報は、Secrets Managerで安全に管理し、RDS ProxyからSecrets Manager経由で取得するように設定してください。アプリケーションコードや設定ファイルに認証情報を埋め込むことは避けるべきです。
  • VPCとセキュリティグループ: RDS ProxyとRDSインスタンスは、同じVPC内のプライベートサブネットに配置し、セキュリティグループを設定して、不要なアクセスを制限してください。

可用性と信頼性:

  • Multi-AZ構成: RDS Proxy自体は可用性の高いサービスとして設計されていますが、RDSインスタンスもMulti-AZ構成にすることで、より高い可用性を実現できます。
  • フェイルオーバーテスト: RDSインスタンスのフェイルオーバーテストを実施し、RDS Proxyが正常にフェイルオーバーを処理し、アプリケーションへの影響を最小限に抑えられることを確認してください。
  • モニタリング: RDS ProxyとRDSインスタンスのCloudWatchメトリクスを継続的に監視し、異常を早期に検知できるようにアラームを設定してください。特に、接続数、レイテンシ、エラー率などのメトリクスは重要です。
  • ログ: RDS Proxyのアクセスログとエラーログを有効化し、必要に応じてCloudWatch Logsに出力するように設定してください。ログは、問題発生時のトラブルシューティングに役立ちます。

運用:

  • TerraformなどのIaCツール: RDS Proxyの構築、設定、管理は、TerraformなどのIaC (Infrastructure as Code) ツールを利用して自動化することを強く推奨します。手動での設定は、ミスが発生しやすく、再現性も低いため、実運用には不向きです。
  • Blue/Greenデプロイ: RDS Proxyの設定変更やバージョンアップを行う場合は、Blue/Greenデプロイなどの手法を用いて、サービス停止時間を最小限に抑えることを検討してください。
  • バックアップとリストア: RDS Proxyの設定は、Terraformなどのコードで管理されているため、基本的にはコードをバックアップしておけばリストアは容易です。ただし、Secrets Managerで管理している認証情報のバックアップも忘れずに行うようにしてください。

その他:

  • コスト最適化: RDS Proxyの利用料金は、接続数や処理量に応じて変動します。不要なRDS Proxyは削除したり、適切なサイズを選択したりすることで、コストを最適化できます。また、RDS Proxyによる接続効率の向上により、RDSインスタンスのサイズを削減できる可能性もあります。
  • ドキュメントとサポート: AWSの公式ドキュメントを熟読し、RDS Proxyの機能、制限事項、ベストプラクティスを理解することが重要です。不明な点や問題が発生した場合は、AWSサポートに問い合わせることも検討してください。

【実務でどの程度使用されるのか】

RDS Proxyは、特に近年、実務での利用が急速に拡大しています。

利用が拡大している背景:

  • サーバーレスアーキテクチャの普及: AWS Lambdaなどのサーバーレス環境でのデータベース接続管理の課題を解決する有効な手段として、RDS Proxyの認知度が高まっています。
  • マイクロサービスアーキテクチャの普及: 多数のマイクロサービスからのデータベースアクセスを効率的に管理するニーズが高まっています。
  • クラウドネイティブアプリケーションの増加: スケーラビリティ、可用性、セキュリティを重視するクラウドネイティブアプリケーションにおいて、RDS Proxyのメリットが重視されるようになっています。
  • マネージドサービスの利便性: RDS Proxyはフルマネージドサービスであるため、運用管理の負荷が低く、導入しやすいという利点があります。

実際の利用状況:

  • 新規プロジェクトでの採用: 新規に開発されるサーバーレスアプリケーションやマイクロサービスアーキテクチャを採用するプロジェクトでは、RDS Proxyが積極的に採用されるケースが増えています。
  • 既存システムの移行: 既存のアプリケーションをクラウドに移行する際に、データベース接続管理の課題を解決するためにRDS Proxyを導入するケースもあります。
  • 大規模システムでの利用: 大規模なトラフィックを処理するシステムや、高い可用性を要求されるシステムにおいて、RDS Proxyがデータベースの安定性とパフォーマンス向上に貢献しています。

ただし、RDS Proxyは万能ではありません:

  • シンプルなアプリケーション: 接続数が少なく、パフォーマンス要件が厳しくないシンプルなアプリケーションでは、必ずしもRDS Proxyが必要とは限りません。RDS Proxyを導入することで、わずかながら複雑性とコストが増加するため、費用対効果を慎重に検討する必要があります。
  • 特定の機能に依存するアプリケーション: RDS Proxyがサポートしていないデータベース機能に依存するアプリケーションでは、RDS Proxyを導入できない場合があります。

結論:

RDS Proxyは、多くの実務環境で非常に有用なサービスであり、特にサーバーレス、マイクロサービス、クラウドネイティブアプリケーションにおいては、デファクトスタンダードとなりつつあります。新規プロジェクトや既存システムの移行において、RDS Proxyの導入を積極的に検討する価値は十分にあります。ただし、アプリケーションの要件や特性を考慮し、費用対効果を慎重に評価した上で、導入を判断することが重要です。

【terraformのコードで記述する場合の基本的内容と実務レベルの内容】

TerraformでRDS Proxyを記述する場合の基本と実務レベルの内容を解説します。

基本的な記述:

resource "aws_rds_proxy" "example" {
  name                   = "example-proxy"
  engine_family          = "MYSQL" # または "POSTGRESQL"
  role_arn               = aws_iam_role.rds_proxy_role.arn
  vpc_subnet_ids         = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id]
  vpc_security_group_ids = [aws_security_group.rds_proxy_sg.id]

  auth {
    auth_scheme = "SECRETS"
    secret_arn  = aws_secretsmanager_secret_version.db_credentials.arn
  }

  default_target_group_config {
    connection_pool_idle_ttl                  = 300 # 秒
    connection_borrow_timeout                 = 120 # 秒
    max_connections_percent                   = 100 # RDSインスタンスの最大接続数のパーセント
    max_idle_connections_percent              = 50  # RDSインスタンスの最大接続数のパーセント
  }

  tags = {
    Name        = "example-proxy"
    Environment = "Production"
  }
}

resource "aws_iam_role" "rds_proxy_role" {
  name = "rds-proxy-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "rds.amazonaws.com"
        }
      },
    ]
  })
}

resource "aws_iam_policy" "rds_proxy_policy" {
  name = "rds-proxy-policy"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "secretsmanager:GetSecretValue",
          "secretsmanager:DescribeSecret",
        ],
        Effect   = "Allow",
        Resource = [aws_secretsmanager_secret.db_secret.arn],
      },
      {
        Action = [
          "rds-db:connect",
        ],
        Effect   = "Allow",
        Resource = ["arn:aws:rds-db:*:*:dbuser:*/proxy-*"], # RDSインスタンスへの接続許可 (リソースARNは適宜変更)
      },
    ]
  })
}

resource "aws_iam_role_policy_attachment" "rds_proxy_policy_attachment" {
  role_arn   = aws_iam_role.rds_proxy_role.arn
  policy_arn = aws_iam_policy.rds_proxy_policy.arn
}


resource "aws_secretsmanager_secret" "db_secret" {
  name                    = "rds-proxy-db-credentials"
  recovery_window_in_days = 7
}

resource "aws_secretsmanager_secret_version" "db_credentials" {
  secret_id     = aws_secretsmanager_secret.db_secret.id
  secret_string = jsonencode({
    username = "dbuser"
    password = "dbpassword" # Secrets Managerで自動生成などを推奨
  })
}

resource "aws_subnet" "private_subnet_1" {
  # ... (VPCとサブネットの設定) ...
}

resource "aws_subnet" "private_subnet_2" {
  # ... (VPCとサブネットの設定) ...
}

resource "aws_security_group" "rds_proxy_sg" {
  # ... (セキュリティグループの設定) ...
}

コード解説 (基本):

  • aws_rds_proxy リソース: RDS Proxyの主要な設定を記述します。

    • name: RDS Proxyの名前。
    • engine_family: データベースエンジン (MYSQLまたはPOSTGRESQL)。
    • role_arn: RDS ProxyがSecrets ManagerやRDSにアクセスするためのIAMロールのARN。
    • vpc_subnet_ids, vpc_security_group_ids: RDS Proxyを配置するVPCのサブネットとセキュリティグループ。プライベートサブネットに配置することを推奨します。
    • auth ブロック: 認証設定。
      • auth_scheme = "SECRETS": Secrets Managerを利用した認証方式。
      • secret_arn: Secrets ManagerのシークレットバージョンのARN。
    • default_target_group_config ブロック: デフォルトターゲットグループ (RDSインスタンス) の接続プーリング設定。
      • connection_pool_idle_ttl: アイドル状態の接続を維持する時間 (秒)。
      • connection_borrow_timeout: アプリケーションが接続を借りるのを待つ最大時間 (秒)。
      • max_connections_percent: RDSインスタンスの最大接続数に対する、プロキシが許可する最大接続数の割合。
      • max_idle_connections_percent: RDSインスタンスの最大接続数に対する、プロキシが維持するアイドル接続数の最大割合。
    • tags: RDS Proxyに付与するタグ (Name, Environmentなど)。リソース管理やコスト管理に役立ちます。
  • aws_iam_role (rds_proxy_role): RDS ProxyがAssumeRoleするためのIAMロール。rds.amazonaws.com サービスプリンシパルからのAssumeRoleを許可します。

  • aws_iam_policy (rds_proxy_policy): RDS Proxyに必要な権限を付与するIAMポリシー。

    • secretsmanager:GetSecretValue, secretsmanager:DescribeSecret: Secrets Managerからデータベースの認証情報を取得するための権限。
    • rds-db:connect: RDSインスタンスへの接続を許可する権限。リソースARNは、接続先のRDSインスタンスに合わせて適切に設定する必要があります。arn:aws:rds-db:*:*:dbuser:*/proxy-* は、RDS Proxyからの接続を許可する一般的な設定例です。
  • aws_iam_role_policy_attachment: IAMロールとIAMポリシーを関連付けます。

  • aws_secretsmanager_secret, aws_secretsmanager_secret_version: Secrets Managerでデータベースの認証情報を安全に管理します。secret_string には、JSON形式で usernamepassword を記述します。passwordはハードコードせず、Secrets Managerの自動生成機能などを利用することを強く推奨します。

  • aws_subnet, aws_security_group: VPC、サブネット、セキュリティグループは、RDS Proxyを配置するネットワーク環境に合わせて適切に設定してください。プライベートサブネットと、必要なポートのみを許可するセキュリティグループを設定することが重要です。

実務レベルの記述:

実務レベルでは、上記の基本構成に加えて、以下の点を考慮する必要があります。

  • モジュール化: RDS Proxyの設定をTerraformモジュールとして作成し、再利用性を高めることを推奨します。モジュール化により、複数の環境 (開発環境、本番環境など) で同じ設定を簡単に使い回すことができ、コードの可読性、保守性も向上します。
  • 変数 (Variables) の活用: 環境ごとに異なる設定値 (VPC ID、サブネット ID、セキュリティグループ ID、RDSインスタンス名など) は、Terraformの変数として定義し、terraform.tfvars ファイルや環境変数で値を渡すようにします。これにより、設定の柔軟性と再利用性が向上します。
  • Outputs の活用: RDS Proxyのエンドポイント (proxy_endpoint) などの重要な情報は、Terraformの Outputs として出力し、アプリケーションや他のインフラリソースから参照できるようにします。
  • 詳細な接続プーリング設定: default_target_group_config ブロックでは、より詳細な接続プーリング設定を行うことができます。
    • session_pinning_filters: セッションピンニングのフィルタを設定できます。デフォルトでは、["AUTH_STATEMENTS", "SCHEMA_CHANGE"] が設定されており、認証ステートメントやスキーマ変更ステートメントを実行するセッションはピンニングされます。
    • init_query: プロキシが新しいデータベース接続を確立する際に実行するSQLクエリを設定できます。セッションの初期化処理などに利用できます。
  • ロギング設定: RDS Proxyのログ設定 (アクセスログ、エラーログ) をTerraformで管理することも可能です。CloudWatch Logsへの出力設定などを記述できます。 (Terraformのリソースでは直接的なロギング設定は提供されていません。AWS Management ConsoleまたはAWS CLI/SDKでの設定が必要です。)
  • モニタリングとアラーム: CloudWatchメトリクスを監視し、異常を検知するためのCloudWatchアラームをTerraformで設定することも重要です。aws_cloudwatch_metric_alarm リソースなどを利用して、接続数、レイテンシ、エラー率などのメトリクスを監視するアラームを作成します。
  • Secrets Manager のパスワード自動生成: aws_secretsmanager_secret リソースの generate_secret_string 引数を利用して、Secrets Managerにパスワードを自動生成させることを推奨します。これにより、よりセキュアなパスワード管理が可能になります。
  • IAM Role の最小権限設定: aws_iam_policy (rds_proxy_policy) で定義するIAMポリシーは、RDS Proxyに必要な最小限の権限に絞り込むことが重要です。ワイルドカード (*) の使用は避け、具体的なリソースARNを指定するようにしてください。
  • 環境分離: 開発環境、ステージング環境、本番環境などでRDS Proxyを構築する場合は、Terraformのワークスペースやモジュール、変数などを活用して、環境間の設定を分離し、管理しやすいように構成することを推奨します。

実務レベルのTerraformコード例 (モジュール化、変数、Outputs を活用):

# modules/rds_proxy/main.tf
resource "aws_rds_proxy" "this" {
  name                   = var.proxy_name
  engine_family          = var.engine_family
  role_arn               = aws_iam_role.rds_proxy_role.arn
  vpc_subnet_ids         = var.vpc_subnet_ids
  vpc_security_group_ids = var.vpc_security_group_ids

  auth {
    auth_scheme = "SECRETS"
    secret_arn  = aws_secretsmanager_secret_version.db_credentials.arn
  }

  default_target_group_config {
    connection_pool_idle_ttl                  = var.connection_pool_idle_ttl
    connection_borrow_timeout                 = var.connection_borrow_timeout
    max_connections_percent                   = var.max_connections_percent
    max_idle_connections_percent              = var.max_idle_connections_percent
  }

  tags = merge(var.tags, { Name = var.proxy_name })
}

resource "aws_iam_role" "rds_proxy_role" {
  name = "${var.proxy_name}-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "rds.amazonaws.com"
        }
      },
    ]
  })
}

resource "aws_iam_policy" "rds_proxy_policy" {
  name = "${var.proxy_name}-policy"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "secretsmanager:GetSecretValue",
          "secretsmanager:DescribeSecret",
        ],
        Effect   = "Allow",
        Resource = [var.secrets_manager_secret_arn],
      },
      {
        Action = [
          "rds-db:connect",
        ],
        Effect   = "Allow",
        Resource = [var.rds_instance_arn], # 変数でRDSインスタンスARNを受け取る
      },
    ]
  })
}

resource "aws_iam_role_policy_attachment" "rds_proxy_policy_attachment" {
  role_arn   = aws_iam_role.rds_proxy_role.arn
  policy_arn = aws_iam_policy.rds_proxy_policy.arn
}


data "aws_secretsmanager_secret" "db_secret" {
  arn = var.secrets_manager_secret_arn
}

data "aws_secretsmanager_secret_version" "db_credentials" {
  secret_id = data.aws_secretsmanager_secret.db_secret.id
}


output "proxy_endpoint" {
  value       = aws_rds_proxy.this.endpoint
  description = "RDS Proxy endpoint"
}
# modules/rds_proxy/variables.tf
variable "proxy_name" {
  type        = string
  description = "RDS Proxy name"
}

variable "engine_family" {
  type        = string
  description = "Database engine family (MYSQL or POSTGRESQL)"
  validation {
    condition     = contains(["MYSQL", "POSTGRESQL"], upper(var.engine_family))
    error_message = "Engine family must be either MYSQL or POSTGRESQL."
  }
}

variable "role_arn" {
  type        = string
  description = "IAM role ARN for RDS Proxy"
}

variable "vpc_subnet_ids" {
  type        = list(string)
  description = "List of VPC subnet IDs for RDS Proxy"
}

variable "vpc_security_group_ids" {
  type        = list(string)
  description = "List of VPC security group IDs for RDS Proxy"
}

variable "secrets_manager_secret_arn" {
  type        = string
  description = "ARN of Secrets Manager secret for database credentials"
}

variable "rds_instance_arn" {
  type        = string
  description = "ARN of the RDS instance"
}


variable "connection_pool_idle_ttl" {
  type        = number
  default     = 300
  description = "Connection pool idle TTL (seconds)"
}

variable "connection_borrow_timeout" {
  type        = number
  default     = 120
  description = "Connection borrow timeout (seconds)"
}

variable "max_connections_percent" {
  type        = number
  default     = 100
  description = "Maximum connections percent for connection pooling"
}

variable "max_idle_connections_percent" {
  type        = number
  default     = 50
  description = "Maximum idle connections percent for connection pooling"
}


variable "tags" {
  type        = map(string)
  default     = {}
  description = "Tags to apply to the RDS Proxy"
}
# main.tf (モジュール呼び出しの例)
module "rds_proxy_module" {
  source = "./modules/rds_proxy"

  proxy_name                = "my-app-proxy"
  engine_family           = "MYSQL"
  vpc_subnet_ids          = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id]
  vpc_security_group_ids  = [aws_security_group.rds_proxy_sg.id]
  secrets_manager_secret_arn = aws_secretsmanager_secret.db_secret.arn
  rds_instance_arn         = aws_db_instance.mydb.arn # 接続先のRDSインスタンスARNを指定

  tags = {
    Environment = "Production"
    Team        = "WebApp"
  }
}

# ... (VPC, Subnet, Security Group, Secrets Manager, RDS Instance などのリソース定義) ...

output "rds_proxy_endpoint" {
  value = module.rds_proxy_module.proxy_endpoint
}

実務レベルのコード解説:

  • モジュール化: RDS Proxyの設定を modules/rds_proxy ディレクトリにモジュールとして分離しました。これにより、コードの再利用性と可読性が向上します。
  • 変数 (Variables): モジュール内で使用する設定値は、variables.tf ファイルで変数として定義し、var. プレフィックスで参照するようにしました。これにより、設定の柔軟性が向上します。
  • Outputs: モジュールの outputs.tf ファイルで、RDS Proxyのエンドポイント (proxy_endpoint) を出力するようにしました。
  • merge 関数: tags 変数と固定の Name タグを merge 関数で結合することで、柔軟なタグ設定を可能にしました。
  • validation ブロック: engine_family 変数に validation ブロックを追加し、許可された値 (MYSQLまたはPOSTGRESQL) のみを設定できるように制約を設けました。
  • データソース (data): Secrets Manager シークレットの値を取得するために、data "aws_secretsmanager_secret"data "aws_secretsmanager_secret_version" を使用しました。これにより、シークレットの値を直接参照せず、ARNのみをパラメータとして渡すことができます。
  • RDSインスタンスARNの変数化: IAMポリシー (aws_iam_policy.rds_proxy_policy) で許可するRDSインスタンスのリソースARNを、変数 (var.rds_instance_arn) で受け取るように変更しました。これにより、モジュールを異なるRDSインスタンスに適用する場合に、変数の値を変更するだけで対応できます。

これらの実務レベルのTerraformコード例を参考に、ご自身の環境に合わせてRDS Proxyの設定を自動化し、効率的なインフラ管理を実現してください。

Discussion