Skip to content

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) with the CertifyClouds image imported
  • [ ] Two subnets in your VNet (one for the application, one for PostgreSQL)

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:

Fully-managed with auto-scaling, health probes, and load balancing. Cost: ~$60-100/month.

./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 and cheaper. Direct private IP, no load balancer. Cost: ~$40-60/month.

./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 tier only)
./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

  1. Login: Use the admin credentials displayed at the end of deployment
  2. Username: admin (or as configured)
  3. Password: The generated password from deployment output
  4. Change Password: Immediately change the admin password after first login
  5. Settings > Subscriptions: Add your Azure subscription IDs
  6. Test Connection: Verify CertifyClouds can access Azure
  7. Discovery: Run your first scan
  8. Compliance: Review security posture
  9. 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:

SMTP_HOST=<YOUR_SMTP_HOST>
SMTP_PORT=<YOUR_SMTP_PORT>
SMTP_USERNAME=<YOUR_SMTP_USERNAME>
SMTP_PASSWORD=<YOUR_SMTP_PASSWORD>
SMTP_FROM_EMAIL=alerts@yourcompany.com
SENDGRID_API_KEY=<YOUR_SENDGRID_API_KEY>
SMTP_FROM_EMAIL=alerts@yourcompany.com

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:

# 1. Import new version to ACR
az acr import --name YOUR_ACR \
  --source <PROVIDED_SOURCE_IMAGE>:v3.1.0 \
  --image certifyclouds:v3.1.0 \
  --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:v3.1.0

# 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 v3.1.0

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

  1. Restore PostgreSQL to a new server or point-in-time
  2. Update connection string in Container App/ACI environment variables
  3. 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

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:

  1. Configure a generic webhook in CertifyClouds
  2. Point to your SIEM's HTTP event collector
  3. Map fields as needed in your SIEM

Support