Installation Guide¶
This guide walks you through deploying CertifyClouds in your Azure environment.
Prerequisites¶
Before you begin, ensure you have:
- [ ] Azure subscription with Owner or Contributor role
- [ ] Azure CLI installed and logged in (
az login) - [ ] A CertifyClouds license key (provided by CertifyClouds)
- [ ] Azure Container Registry (ACR) available for the CertifyClouds image
- [ ] CertifyClouds deployment package, including deployment scripts and registry import credentials
- [ ] Two delegated subnets in your VNet, or permission to create them during deployment
Step 1: Import the CertifyClouds Image to Your ACR¶
Contact CertifyClouds for registry credentials, then import the image to your ACR:
az acr import --name YOUR_ACR \
--source <PROVIDED_SOURCE_IMAGE> \
--image certifyclouds:latest \
--username <PROVIDED_USERNAME> \
--password <PROVIDED_TOKEN>
Step 2: Create Required Subnets¶
CertifyClouds requires two subnets in your VNet:
Application Subnet (Container Apps or ACI)¶
# For Container Apps (minimum /27)
az network vnet subnet create \
--resource-group <NETWORKING_RG> \
--vnet-name <VNET_NAME> \
--name snet-certifyclouds-cae \
--address-prefixes 10.0.1.0/27 \
--delegations Microsoft.App/environments \
--service-endpoints Microsoft.KeyVault Microsoft.ContainerRegistry
# For Container Instances (minimum /28)
az network vnet subnet create \
--resource-group <NETWORKING_RG> \
--vnet-name <VNET_NAME> \
--name snet-certifyclouds-aci \
--address-prefixes 10.0.1.0/28 \
--delegations Microsoft.ContainerInstance/containerGroups \
--service-endpoints Microsoft.KeyVault Microsoft.ContainerRegistry
PostgreSQL Subnet (minimum /28)¶
az network vnet subnet create \
--resource-group <NETWORKING_RG> \
--vnet-name <VNET_NAME> \
--name snet-certifyclouds-psql \
--address-prefixes 10.0.1.32/28 \
--delegations Microsoft.DBforPostgreSQL/flexibleServers
Step 3: Deploy CertifyClouds¶
Choose your deployment method:
Option A: Azure Container Apps (Recommended)¶
Fully managed with auto-scaling, health probes, and load balancing. Estimate cost using your Azure region, replica count, CPU/memory allocation, and database size.
./deploy-certifyclouds-cae.sh \
--name prd \
--location uksouth \
--acr-name YOUR_ACR \
--container-apps-subnet /subscriptions/YOUR_SUB/resourceGroups/YOUR_RG/providers/Microsoft.Network/virtualNetworks/YOUR_VNET/subnets/snet-certifyclouds-cae \
--postgres-subnet /subscriptions/YOUR_SUB/resourceGroups/YOUR_RG/providers/Microsoft.Network/virtualNetworks/YOUR_VNET/subnets/snet-certifyclouds-psql
Option B: Azure Container Instances¶
Simpler deployment model with direct private IP access. Estimate cost using your Azure region and CPU/memory allocation.
./deploy-certifyclouds-aci.sh \
--name prd \
--location uksouth \
--acr-name YOUR_ACR \
--aci-subnet /subscriptions/YOUR_SUB/resourceGroups/YOUR_RG/providers/Microsoft.Network/virtualNetworks/YOUR_VNET/subnets/snet-certifyclouds-aci \
--postgres-subnet /subscriptions/YOUR_SUB/resourceGroups/YOUR_RG/providers/Microsoft.Network/virtualNetworks/YOUR_VNET/subnets/snet-certifyclouds-psql
Deployment Output¶
On successful deployment, you'll see:
================================================================================
DEPLOYMENT COMPLETE!
================================================================================
Managed Identity Principal ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Use this Principal ID to grant Key Vault access:
./setup-certifyclouds-access.sh --principal-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --apply
Save the Principal ID - you'll need it for the next step.
Step 4: Configure Key Vault Permissions¶
Run the setup script with the Principal ID from deployment output:
# Check current permissions (dry run)
./setup-certifyclouds-access.sh --principal-id $PRINCIPAL_ID
# Apply permissions
./setup-certifyclouds-access.sh --principal-id $PRINCIPAL_ID --apply
# (Optional) Enable Rotation permissions (PRO + ENTERPRISE tiers)
./setup-certifyclouds-access.sh --principal-id $PRINCIPAL_ID --apply --pro
The script will:
- Discover all Key Vaults across your subscriptions
- Auto-detect RBAC vs Access Policy configuration
- Grant appropriate read (or write) permissions
- Add subnet to Key Vault firewall rules if needed
Step 5: Access the Application¶
CertifyClouds is deployed with internal-only ingress - it has no public IP address.
Access Methods¶
| Method | Description |
|---|---|
| VPN | Connect to your VNet via VPN Gateway |
| Azure Bastion | Use a jumpbox VM in the same VNet |
| ExpressRoute | Access from on-premises network |
| Peered VNet | Access from a VM in a peered VNet |
URLs¶
- Container Apps:
https://<INTERNAL_FQDN>(shown in deployment output) - ACI:
http://<PRIVATE_IP>:8080(shown in deployment output)
Step 6: First-Time Setup¶
- Login: Use the admin credentials displayed at the end of deployment
- Username:
admin(or as configured) - Password: The generated password from deployment output
- Change Password: Immediately change the admin password after first login
- Settings > Subscriptions: Add your Azure subscription IDs
- Test Connection: Verify CertifyClouds can access Azure
- Discovery: Run your first scan
- Compliance: Review security posture
- Alerts: Configure notification rules
Configuration Reference¶
Environment Variables¶
The deployment scripts configure these automatically. See Environment Setup for the complete reference.
| Variable | Description |
|---|---|
CERTIFYCLOUDS_LICENSE_KEY | Your license key (CC-XXXX-XXXX-XXXX) |
INITIAL_ADMIN_USERNAME | Initial admin username (default: admin) |
INITIAL_ADMIN_PASSWORD | Initial admin password (auto-generated if not set) |
SECRET_KEY | Encryption key for Sync credentials (auto-generated if not set) |
Email Configuration (for Alerts)¶
Configure email alerts by setting SMTP environment variables:
Resource Requirements¶
| Environment | Key Vaults | Secrets | CPU | Memory |
|---|---|---|---|---|
| Small | 1-10 | <500 | 1 vCPU | 2 GB |
| Medium | 10-50 | <2,000 | 2 vCPU | 4 GB |
| Large | 50-200 | <10,000 | 4 vCPU | 8 GB |
Updating CertifyClouds¶
When a new version is released, set VERSION to the target release and run:
VERSION=v1.4.14 # set to the target release tag
# 1. Import new version to ACR
az acr import --name YOUR_ACR \
--source <PROVIDED_SOURCE_IMAGE>:$VERSION \
--image certifyclouds:$VERSION \
--username <PROVIDED_USERNAME> \
--password <PROVIDED_TOKEN>
# 2a. For Container Apps - update image
az containerapp update \
--name cc-uks-prd \
--resource-group rg-cc-uks-prd \
--image YOUR_ACR.azurecr.io/certifyclouds:$VERSION
# 2b. For ACI - redeploy with new version
./deploy-certifyclouds-aci.sh \
--name prd \
--location uksouth \
--acr-name YOUR_ACR \
--aci-subnet /subscriptions/.../subnets/snet-certifyclouds-aci \
--postgres-subnet /subscriptions/.../subnets/snet-certifyclouds-psql \
--image-version $VERSION
The latest available version is surfaced in the dashboard's update banner (populated from the license server's heartbeat). Your deployment's current running version is shown at the bottom of the Settings page and at GET /api/system/version.
Architecture¶
CertifyClouds runs as a containerised application within your Azure VNet alongside a managed database. All components are private with no public IP exposure. The application uses Managed Identity to access Key Vaults across your subscriptions.
+------------------------------------------------------------------------+
| Your Azure Subscription |
| |
| +------------------------------------------------------------------+ |
| | Your Existing VNet | |
| | | |
| | +------------------------+ +-------------------------------+ | |
| | | Application Subnet | | Database Subnet | | |
| | | | | | | |
| | | +--------------------+ | | +---------------------------+ | | |
| | | | CertifyClouds |----| | Managed Database | | | |
| | | | (Container) | | | | (VNet integrated) | | | |
| | | | - Managed Identity | | | +---------------------------+ | | |
| | | +--------------------+ | +-------------------------------+ | |
| | +------------------------+ | |
| +------------------------------------------------------------------+ |
| |
| Key Vaults (various subscriptions) |
| - Accessed via Managed Identity |
+------------------------------------------------------------------------+
Backup & Recovery¶
What to Back Up¶
CertifyClouds stores all data in your PostgreSQL database. Back up the database regularly.
| Data | Location | Backup Method |
|---|---|---|
| Scan results | PostgreSQL | Azure Backup |
| Rotation history | PostgreSQL | Azure Backup |
| Alert rules | PostgreSQL | Azure Backup |
| Audit logs | PostgreSQL | Azure Backup |
| Configuration | Environment variables | Document/export |
Azure PostgreSQL Backup¶
Azure PostgreSQL Flexible Server includes automatic backups:
# Check backup configuration
az postgres flexible-server show \
--resource-group rg-cc-uks-prd \
--name psql-cc-uks-prd \
--query "backup"
# Create on-demand backup
az postgres flexible-server backup create \
--resource-group rg-cc-uks-prd \
--name psql-cc-uks-prd \
--backup-name manual-backup-$(date +%Y%m%d)
Recommended Settings:
- Retention: 7-35 days (based on compliance requirements)
- Geo-redundant backup: Enable for DR scenarios
- Point-in-time restore: Available for last 7 days by default
Recovery Procedure¶
- Restore PostgreSQL to a new server or point-in-time
- Update connection string in Container App/ACI environment variables
- Restart the application to connect to restored database
# Point-in-time restore
az postgres flexible-server restore \
--resource-group rg-cc-uks-prd \
--name psql-cc-uks-prd-restored \
--source-server psql-cc-uks-prd \
--restore-time "2026-02-20T10:00:00Z"
High Availability¶
Application Statelessness¶
CertifyClouds is stateless - all persistent data is stored in PostgreSQL. This means:
- Safe to run multiple replicas
- No session affinity required
- Can be restarted without data loss
Container Apps HA (Recommended)¶
Azure Container Apps provides built-in HA:
# Scale to multiple replicas
az containerapp update \
--name cc-uks-prd \
--resource-group rg-cc-uks-prd \
--min-replicas 2 \
--max-replicas 4
Benefits:
- Automatic load balancing
- Health probe-based failover
- Rolling updates with zero downtime
Database HA¶
Azure PostgreSQL Flexible Server HA options:
| Option | Description | Cost |
|---|---|---|
| Zone-redundant | Standby in different AZ | ~2x |
| Same-zone | Standby in same AZ | ~1.5x |
| None | Single instance | Base |
# Enable zone-redundant HA
az postgres flexible-server update \
--resource-group rg-cc-uks-prd \
--name psql-cc-uks-prd \
--high-availability ZoneRedundant
SIEM Integration¶
Log Sources¶
CertifyClouds generates logs that can be sent to your SIEM:
| Log Type | Content | Format |
|---|---|---|
| Application logs | All operations, errors | JSON (structured) |
| Audit logs | User actions, changes | Stored in PostgreSQL |
| Azure diagnostics | Container metrics, events | Azure Monitor format |
Azure Monitor Integration¶
Enable diagnostic settings to send logs to Log Analytics:
# Get Container App resource ID
RESOURCE_ID=$(az containerapp show \
--name cc-uks-prd \
--resource-group rg-cc-uks-prd \
--query id -o tsv)
# Create diagnostic setting
az monitor diagnostic-settings create \
--name certifyclouds-logs \
--resource $RESOURCE_ID \
--workspace /subscriptions/.../resourceGroups/.../providers/Microsoft.OperationalInsights/workspaces/YOUR_WORKSPACE \
--logs '[{"category": "ContainerAppConsoleLogs", "enabled": true}]'
Webhook to SIEM¶
Use CertifyClouds webhooks to send alerts to your SIEM:
- Configure a generic webhook in CertifyClouds
- Point to your SIEM's HTTP event collector
- Map fields as needed in your SIEM
Support¶
- Documentation: You're reading it!
- Email: support@certifyclouds.com