# PostgreSQL Tenant Module

This module creates a PostgreSQL database and user (tenant) on a VPS-hosted PostgreSQL instance using SSH tunneling for secure access.

## Features

- Creates SSH tunnel to VPS-hosted PostgreSQL
- Creates isolated database and user for tenant
- Generates secure random password
- Outputs connection details for application use
- Supports explicit dependencies via `wait_on`

## Requirements

- SSH access to VPS with key-based authentication
- PostgreSQL admin credentials
- `terraform-ssh-tunnel` module (automatically downloaded)
- `cyrilgdn/postgresql` provider (automatically configured)

## Usage

### Basic Example

```hcl
module "app_tenant" {
  source = "./quadlets/modules/postgres/tenant"

  tenant_name     = "myapp"
  admin_username  = "postgres"
  admin_password  = var.postgres_admin_password
  server_ip       = "203.0.113.10"
  ssh_user        = "fourlights"
  
  # Wait for PostgreSQL service to be ready
  wait_on = module.postgres.installed
}

# Use the connection details
output "app_db_connection" {
  value = {
    host     = module.app_tenant.host
    port     = module.app_tenant.port
    database = module.app_tenant.database
    username = module.app_tenant.username
    password = module.app_tenant.password
  }
  sensitive = true
}
```

### With Custom Port

```hcl
module "custom_tenant" {
  source = "./quadlets/modules/postgres/tenant"

  tenant_name     = "custom_app"
  admin_username  = "postgres"
  admin_password  = var.postgres_admin_password
  server_ip       = "203.0.113.10"
  target_port     = 5433  # Custom PostgreSQL port
  
  wait_on = module.postgres.installed
}
```

### Multiple Tenants

```hcl
module "tenant_1" {
  source = "./quadlets/modules/postgres/tenant"

  tenant_name     = "app1"
  admin_username  = "postgres"
  admin_password  = var.postgres_admin_password
  server_ip       = var.vps_ip
  
  wait_on = module.postgres.installed
}

module "tenant_2" {
  source = "./quadlets/modules/postgres/tenant"

  tenant_name     = "app2"
  admin_username  = "postgres"
  admin_password  = var.postgres_admin_password
  server_ip       = var.vps_ip
  
  wait_on = module.postgres.installed
}
```

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|----------|
| tenant_name | Name of the tenant (used for database name and username) | string | - | yes |
| admin_username | PostgreSQL admin username | string | "postgres" | no |
| admin_password | PostgreSQL admin password | string | - | yes |
| server_ip | VPS server IP address | string | - | yes |
| ssh_user | SSH user for connecting to VPS | string | "fourlights" | no |
| ssh_private_key_path | Path to SSH private key | string | "~/.ssh/id_rsa" | no |
| target_port | PostgreSQL port on VPS | number | 5432 | no |
| wait_on | Resources to wait on before creating tenant | any | null | no |

## Outputs

| Name | Description | Sensitive |
|------|-------------|-----------|
| host | PostgreSQL connection host (via SSH tunnel) | no |
| port | PostgreSQL connection port (via SSH tunnel) | no |
| database | Database name | no |
| username | Database username | no |
| password | Database password | yes |
| connection_string | Full PostgreSQL connection string | yes |
| installed | Installation complete flag | no |

## How It Works

1. **SSH Tunnel**: The module uses `terraform-ssh-tunnel` to create a secure SSH tunnel from your local machine to the VPS PostgreSQL instance
2. **Provider Configuration**: The PostgreSQL provider is configured to connect through the tunnel
3. **Resource Creation**: Creates a PostgreSQL role (user) and database with appropriate permissions
4. **Password Generation**: Generates a cryptographically secure random password
5. **Outputs**: Provides connection details for your application to use

## Notes

- The SSH tunnel is created dynamically when Terraform needs to connect
- Ensure your SSH agent is running and has the appropriate key loaded
- The database and user will have the same name as `tenant_name`
- The user is granted full privileges on their database
- Password is stored in Terraform state (sensitive)