This repository provides both local development and Azure production deployment for MinIO object storage with Keycloak SSO authentication, Coraza WAF protection, and opkssh SSH certificate authentication.
For local testing and development:
cd docker-compose
./setup-local.shSee docker-compose/README.md for complete local development documentation.
For production deployment to Azure:
terraform init
terraform plan
terraform applySee Terraform Usage below for details.
.
βββ docker-compose/ # Local development environment
β βββ README.md # Complete local dev documentation
β βββ setup-local.sh # Automated local setup
β βββ ... # Docker Compose configuration
β
βββ main.tf # Terraform Azure deployment
βββ variables.tf # Terraform variables
βββ outputs.tf # Terraform outputs
βββ README.md # This file
graph TD
subgraph "Client Access"
Client[External Traffic<br/>HTTPS: 443, 8443, 8444<br/>IP Restricted]
end
subgraph "Azure Virtual Network"
subgraph "Application Gateway Subnet"
AppGW[Azure Application Gateway<br/>SSL Termination<br/>Load Balancing]
end
subgraph "Container Instances Subnet"
subgraph "WAF Layer"
WAF[Coraza WAF<br/>Caddy Reverse Proxy<br/>:8080, :8081, :8082]
end
subgraph "Application Services"
MinIO[MinIO Object Storage<br/>UI: :9001<br/>API: :9000]
Keycloak[Keycloak<br/>OIDC Provider<br/>:8083]
end
subgraph "Data Layer"
DB[(MariaDB<br/>:3306)]
MinIOStorage[(Azure File Share<br/>MinIO Data)]
KeycloakStorage[(Azure File Share<br/>Keycloak Data)]
DBStorage[(Azure File Share<br/>MariaDB Data)]
end
end
end
Client --> AppGW
AppGW --> WAF
WAF -->|:8080/:8081| MinIO
WAF -->|:8082| Keycloak
MinIO --> MinIOStorage
MinIO -.OIDC Auth.-> Keycloak
Keycloak --> DB
Keycloak --> KeycloakStorage
DB --> DBStorage
style Client fill:#e3f2fd
style AppGW fill:#fff3e0
style WAF fill:#ff9800
style MinIO fill:#2196f3
style Keycloak fill:#4caf50
style DB fill:#607d8b
style MinIOStorage fill:#b0bec5
style KeycloakStorage fill:#b0bec5
style DBStorage fill:#b0bec5
- MinIO: S3-compatible object storage with OIDC authentication
- Keycloak: Enterprise identity and access management
- MariaDB: Database backend for Keycloak
- Coraza WAF: OWASP Core Rule Set protection with rate limiting
- Application Gateway: SSL termination, load balancing, IP restrictions (ports 443/8443/8444)
- Network Security Group: IP-based access control
- Azure File Shares: Persistent storage for MinIO, MariaDB, and Keycloak data
- Virtual Network: Network isolation with dedicated subnets
- Key Vault: Secure certificate storage
- opkssh: SSH certificate-based authentication using OIDC (local development only)
- Azure Subscription
- Terraform >= 1.0
- Azure CLI (logged in)
Create a terraform.tfvars file from the example:
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your valuesMinimum required variables:
resource_group_name = "minio-production"
public_url_domain_name = "minio-prod"
minio_root_password = "your-secure-password"
keycloak_admin_password = "your-keycloak-admin-password"
allowed_ip_addresses = "203.0.113.0/32,198.51.100.0/24"See terraform.tfvars.example for all available options.
terraform init
terraform plan
terraform applyAfter deployment, Terraform provides:
- console_url: MinIO web console URL
- s3_api_url: MinIO S3 API endpoint
- keycloak_url: Keycloak admin console
- fqdn: Fully qualified domain name
- mc_alias_command: MinIO client configuration command
- certificate_download_command: Download self-signed certificate
https://your-domain.azurecontainer.io/
Login with:
- Root credentials: Configured via
minio_root_userandminio_root_password - SSO: Click "Login with SSO" for Keycloak authentication
https://your-domain.azurecontainer.io:8443/
https://your-domain.azurecontainer.io:8444/
Default realm: minio_realm
- Admin user:
admin(password fromkeycloak_admin_password) - Test user:
testuser/[email protected]
# Get the setup command from Terraform output
terraform output -raw mc_alias_command
# Or manually configure
mc alias set myminio https://your-fqdn.azurecontainer.io:8443 minioadmin your-password
# Download certificate if needed
terraform output -raw certificate_pem > minio-cert.pem- OWASP Core Rule Set v4
- SQL injection prevention
- XSS protection
- Command injection blocking
- Path traversal prevention
- Rate limiting per source IP
- Audit logging
- IP Restrictions: NSG rules limit access to specified IPs
- SSL Termination: Azure Application Gateway encrypts all traffic
- Network Isolation: Dedicated VNet with subnet segmentation
- Internal Communication: Container-to-container traffic stays within group
- Certificate Storage: Azure Key Vault for SSL certificates
- No Direct Access: MinIO/Keycloak ports not exposed externally
- Application Gateway: SSL termination, load balancing (ports 443, 8443, 8444)
- Virtual Network: Network isolation with Application Gateway + Container Instance subnets
- Network Security Group: IP-based access restrictions
- Container Group: Hosts MinIO, Keycloak, MariaDB, and Coraza WAF
- Storage Account: Persistent storage backend
- Storage Shares: Separate shares for MinIO, MariaDB, and Keycloak data
- Key Vault: Secure certificate storage
- Log Analytics Workspace: Monitoring and diagnostics
- docker-compose/README.md - Complete local development guide
- README-coraza.md - Coraza WAF container documentation
- Terraform Variables - Complete variable reference below
| Name | Version |
|---|---|
| azurerm | 4.36.0 |
| random | ~> 3.1 |
No modules.
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| allowed_ip_addresses | Comma-separated list of IP addresses that will be allowed to access the MinIO service in CIDR format. Example: '203.0.113.0/32' for a single IP or '10.10.10.2/32,192.168.1.0/24' for multiple IPs. | string |
"10.10.10.2/32" |
no |
| coraza_waf_image | Coraza WAF container image | string |
"ghcr.io/meshcloud/minio_azure_container_app/coraza-caddy:caddy-2.8-coraza-v2.0.0" |
no |
| keycloak_admin_password | Keycloak admin password | string |
n/a | yes |
| keycloak_admin_user | Keycloak admin username | string |
"admin" |
no |
| keycloak_test_user_email | Keycloak test user email | string |
"[email protected]" |
no |
| keycloak_test_user_password | Keycloak test user password | string |
"password" |
no |
| keycloak_test_user_username | Keycloak test user username | string |
"testuser" |
no |
| location | Azure region for deployment | string |
"germanywestcentral" |
no |
| mariadb_database | MariaDB database name for Keycloak | string |
"mariadb" |
no |
| mariadb_user | MariaDB username | string |
"keycloak" |
no |
| minio_image | MinIO container image | string |
"quay.io/minio/minio:RELEASE.2025-04-22T22-12-26Z" |
no |
| minio_root_password | MinIO root password for admin access | string |
n/a | yes |
| minio_root_user | MinIO root username for admin access | string |
"minioadmin" |
no |
| nginx_image | Nginx container image | string |
"mcr.microsoft.com/azurelinux/base/nginx:1.25" |
no |
| opkssh_redirect_uris | OpenPubkey SSH client redirect URIs for local development | list(string) |
[ |
no |
| public_url_domain_name | Domain name for the public URL (e.g., 'miniotest' creates 'miniotest.westeurope.azurecontainer.io') | string |
n/a | yes |
| resource_group_name | Name of the Resource Group where you want to deploy MinIO | string |
n/a | yes |
| storage_account_name | Storage Account Name prefix (random suffix will be added for global uniqueness) | string |
"miniostorage" |
no |
| storage_share_size | Storage space needed in GBs (minimum 1GB, maximum 5120GB/5TB) | number |
100 |
no |
| Name | Description |
|---|---|
| certificate_download_command | Command to download certificate locally |
| certificate_pem | Self-signed certificate in PEM format (public cert) |
| console_url | MinIO Web Console URL |
| fqdn | Fully qualified domain name |
| keycloak_client_secret | Generated Keycloak OIDC client secret for MinIO |
| keycloak_url | Keycloak admin console URL |
| mc_alias_command | MinIO client setup command |
| public_ip | Public IP address |
| s3_api_url | MinIO S3 API endpoint |
| storage_account_name | Azure Storage Account name |