- Shell 100%
| .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 | ||
| 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.
🚀 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
CI/CD Run
- Define the variables below as Secrets or Variables in your CI/CD settings.
- The pipeline runner simply executes
./install.sh.
Note: The script uses pipefail and nounset. It will exit immediately if any API call fails or if any required variable is missing from the environment.
🛠 Runner Requirements
The machine/container running this script (Runner host) must have:
- bash: Shell environment.
- jq: Command-line JSON processor (
sudo apt install jq). - ssh/scp: Standard OpenSSH tools.
- Access: Outbound HTTPS access to DigitalOcean and Cloudflare APIs.
🛠 Prerequisites
Important
SSH Key Requirements:
- DigitalOcean: You must upload your SSH Public Key to your DigitalOcean account before running this script. The
$SSH_KEY_DO_IDmust match the Name or Fingerprint in your DO dashboard.- Runner Access: The runner must have access to the corresponding Private Key (
$SSH_KEY_PRIVATE_KEY).- Projects: The target
$PROJECT_NAMEmust already exist in your DigitalOcean account.
1. Required Variables
Authentication & SSH
| Variable | Description |
|---|---|
$SSH_KEY_PRIVATE_KEY |
Path to the private key (e.g., ~/.ssh/id_rsa). |
$DIGITALOCEAN_TOKEN |
Your DigitalOcean Personal Access Token. |
$CF_TOKEN |
Cloudflare API Token (DNS edit permissions). |
Infrastructure (DigitalOcean)
| Variable | Description |
|---|---|
$DROPLET_NAME |
The name to be assigned to the VM. |
$PROJECT_NAME |
The existing DO Project name to assign the VM to. |
$SSH_KEY_DO_ID |
The name of the pre-loaded SSH key in your DO account. |
$REGION |
The region to deploy in (e.g., nyc, ams). |
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. |
2. Orchestration Logic
What install.sh does:
- Pre-flight Check: Verifies
jqis installed and all required variables are present. - Provisions VM: Resolves Project Name to UUID, creates the droplet with Keycloak metadata tags, and assigns it to the Project.
- Configures DNS: Points your Cloudflare domain to the new VM IP (Proxied: OFF).
- Remote Config: SSHs into the VM using the specified private key to:
- Run system
dist-upgradeand kernel tuning. - Install Wazuh (All-in-one).
- Generate Let's Encrypt certificates.
- Configure Keycloak OpenID SSO integration.
- Run system
- Finalize: The VM reboots to apply all changes.
3. Local Development Template (sample.env)
If running locally, create a .env file with these contents:
# --- SSH_PRIVATE_KEY Config ---
export SSH_KEY_PRIVATE_KEY="~/.ssh/id_rsa"
# --- DigitalOcean Config ---
export DROPLET_NAME="wazuh-01"
export DIGITALOCEAN_TOKEN="your_do_token_here"
export PROJECT_NAME="Production"
export SSH_KEY_DO_ID="my-ssh-key-name"
export REGION="nyc"
# --- Cloudflare Config ---
export FQDN="wazuh.example.com"
export CF_ZONE_ID="your_zone_id_here"
export CF_TOKEN="your_cloudflare_api_token"
export COMMENT="Wazuh-SSO-Deployment"
# --- Keycloak Config ---
export KEYCLOAK_URL="[https://sso.example.com/auth](https://sso.example.com/auth)"
export KEYCLOAK_REALM="master"
export APP_NAME="wazuh-dashboard"
export KEYCLOAK_USER="admin"
export KEYCLOAK_PASSWORD="your_admin_password"
🚀 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
1. Environment Variables (Pipe set)
| Variable | Description |
|---|---|
$DROPLET_NAME |
Generated by CI. Must use dashes - instead of underscores _. |
$FQDN |
Generated by CI. Must be a valid DNS hostname (no underscores). |
$DOMAIN |
The base domain used to anchor the dynamic FQDN. |
🗑 Teardown / Cleanup
If you need to decommission a deployment, ensure the $DROPLET_NAME and $FQDN of the target instance are set in your environment, then run:
chmod +x destroy.sh
./destroy.sh