- Shell 100%
| .ai/mcp | ||
| .idea | ||
| baseinstall.sh | ||
| cf-dns.sh | ||
| destroy.sh | ||
| digital-ocean-vm.sh | ||
| install.sh | ||
| letsencrypt.sh | ||
| manual install.md | ||
| opensearch_dashboards.yml | ||
| pipeline logic.txt | ||
| README.md | ||
| roles.yml | ||
| roles_mapping.yml | ||
| runner.sh | ||
| sample.env | ||
| ssoconfig.sh | ||
Wazuh & SSO Automated Deployment
This project orchestrates the end-to-end deployment of a Wazuh server on DigitalOcean. It automates VM provisioning, Cloudflare DNS configuration, SSL termination, and Keycloak SSO (OpenID) integration.
🛠 Prerequisites
- Keycloak: The Target
$KEYCLOAK_REALMmust be in place.- DigitalOcean: The target
$PROJECT_NAMEmust already exist in your DigitalOcean account.- Cloudflare: The target
$DOMAINmust already exist in your Cloudflare account.
Keycloak Users For App Access
Realm setup info
- The realm needs to have been inited by idhub
Users in the Realm
- Must have the attribute idhub-roles with the key of
wazuh-readonlyor the key ofwazuh-adminto be able to login at$FQDN
Required Variables
Authentication
| Variable | Description |
|---|---|
$DIGITALOCEAN_TOKEN |
Your DigitalOcean Personal Access Token. |
$CF_TOKEN |
Cloudflare API Token (DNS edit permissions). |
Infrastructure (DigitalOcean)
| Variable | Description |
|---|---|
$DROPLET_NAME |
Unique VM name (e.g., realm-app-abc12). No underscores. |
$FQDN |
The Full Qualified Domain Name. No underscores. |
$DOMAIN |
The base domain used to anchor the dynamic FQDN. |
$PROJECT_NAME |
The existing DO Project name to assign the VM to. |
$REGION |
The region to deploy in (e.g., nyc3, ams3). |
Networking & SSO
| Variable | Description |
|---|---|
$FQDN |
The Full Qualified Domain Name (e.g., wazuh.domain.com). |
$CF_ZONE_ID |
Your Cloudflare Zone ID. |
$KEYCLOAK_URL |
URL must include /auth and NO trailing slash. |
$APP_NAME |
The name of the client to be created in Keycloak. |
$KEYCLOAK_REALM |
The target Keycloak Realm. |
$KEYCLOAK_USER |
Keycloak Admin username. |
$KEYCLOAK_PASSWORD |
Keycloak Admin password. |
🛠 Runner Requirements
The machine or container running this script must have:
- bash: Shell environment.
- jq: Command-line JSON processor (
sudo apt install jq). - ssh/scp: Standard OpenSSH tools.
- ssh-keygen: To generate ephemeral deployment keys.
- Access: Outbound HTTPS access to DigitalOcean and Cloudflare APIs.
🔐 API Authorization & Scopes Requirements
This project requires granular API permissions. Follow the links below to generate tokens with the required custom scopes.
🔹 DigitalOcean Custom Scopes (23 Total)
Generate a Personal Access Token in the DigitalOcean Dashboard. Select "Custom Scopes" and verify the following 23 permissions:
| Category | Permissions | Purpose | Official Docs |
|---|---|---|---|
| Account | read |
Verify API connectivity. | Docs |
| Actions | read |
Monitor droplet creation progress. | Docs |
| Droplet | create, read, update, delete |
Full VM lifecycle management. | Docs |
| Firewall | create, read, update, delete |
Secure VM with Wazuh rules. | Docs |
| SSH Key | create, read, update, delete |
Manage ephemeral deployment keys. | Docs |
| Project | read, update |
Assigning droplets to specific projects. | Docs |
| Tag | create, read, delete |
Organizing resources by Realm/App. | Docs |
| Images | read |
Fetching the Ubuntu 24.04 base image. | Docs |
| Regions/Sizes | read |
Validating datacenter and plan availability. | Docs |
| Snapshots | read |
Backup validation. | Docs |
🔹 Cloudflare API Permissions
Generate a Custom Token in the Cloudflare Profile Dashboard.
| Permission Type | Level | Purpose | Official Docs |
|---|---|---|---|
| Zone / DNS | Edit |
Creating/Updating A records for the VM. | Docs |
| Zone / Zone | Read |
Looking up Zone IDs for your domain. | Docs |
🚀 Execution
The script is designed to be environment-agnostic. It will use variables from a .env file if sourced locally, or from the shell environment if running in a CI/CD pipeline.
Local Run
source .env./install.sh
Login into application
After install there will be an reboot of the new vm and can take about 5 min for it to load up.
Check that the users you want to use has the attribute of idhub-roles with the key of wazuh-readonly for readonly access or the key of wazuh-admin for admin access
Go to the FQDN that you set in the env and login into keycloak with an user that has the attribute set.
CI/CD Run
- Define the variables below as Secrets or Variables in your CI/CD settings.
- The pipeline runner executes
./install.sh.
Orchestration Logic
What install.sh does:
- Ephemeral Key Setup: Generates a temporary RSA key pair and uploads it to DigitalOcean.
- Pre-flight Check: Verifies tools and validates that hostnames contain no underscores.
- Provisions VM: Creates the droplet with metadata tags and assigns it to the Project.
- Configures DNS: Points Cloudflare to the new IP with a rich audit comment.
- Apt Backoff: Remote logic waits for background system locks to release before installing.
- Remote Config: SSHs into the VM using the ephemeral key to:
- Run system
dist-upgradeand install dependencies. - Install Wazuh (All-in-one) and generate Let's Encrypt certificates.
- Configure Keycloak OpenID SSO integration using
$DROPLET_NAMEas the client ID.
- Run system
- Cleanup & Finalize: Deletes the temporary key from DigitalOcean and the runner, then reboots the VM.
🚀 CI/CD Pipeline Flow
The pipeline is responsible for generating the dynamic identity. Note that underscores are not permitted in hostnames or tags; the pipeline logic must convert them to dashes.
Naming Logic Example:
If $KEYCLOAK_REALM is internal_sec and $APP_NAME is wazuh_prod:
- Sanitize:
internal-sec-wazuh-prod - Randomize:
internal-sec-wazuh-prod-a1b2c - FQDN:
internal-sec-wazuh-prod-a1b2c.yourdomain.com
🗑 Teardown / Cleanup
To decommission a deployment, ensure the $DROPLET_NAME and $FQDN are set in your environment, then run:
chmod +x destroy.sh
./destroy.sh