Azure Cost Control
💰 Shelvera Azure Cost Control
Generate copy-ready Ubuntu commands for Dev + QA Azure cost-control automation. Use this page to produce the cron entries, manual start/stop commands, enforcement enable/disable commands, bash aliases and log cleanup configuration from one set of inputs.
1. Generate Commands​
Show advanced disable files, locks and log filenames
/opt/shelvera/automation/azure/enforce-dev-qa-stopped-azure.sh/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-cron.logsudo mkdir -p "/opt/shelvera/automation/azure"
sudo mkdir -p "/opt/shelvera/automation/azure/logs"
sudo chown -R "$USER":"$USER" "/opt/shelvera/automation/azure"
chmod +x "/opt/shelvera/automation/azure/enforce-dev-qa-stopped-azure.sh" "/opt/shelvera/automation/azure/start-dev-qa-azure.sh" "/opt/shelvera/automation/azure/stop-dev-qa-azure.sh"/usr/bin/flock -n "/tmp/shelvera-enforce-dev-qa-stopped.lock" "/opt/shelvera/automation/azure/enforce-dev-qa-stopped-azure.sh" 2>&1 | \
tee -a "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-manual.log"/usr/bin/flock -n "/tmp/shelvera-start-dev-qa.lock" "/opt/shelvera/automation/azure/start-dev-qa-azure.sh" 2>&1 | \
tee -a "/opt/shelvera/automation/azure/logs/start-dev-qa-manual.log"/usr/bin/flock -n "/tmp/shelvera-stop-dev-qa.lock" "/opt/shelvera/automation/azure/stop-dev-qa-azure.sh" 2>&1 | \
tee -a "/opt/shelvera/automation/azure/logs/stop-dev-qa-manual.log"touch "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped"rm -f "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped"if [[ -f "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped" ]]; then
echo "ENFORCEMENT DISABLED"
else
echo "ENFORCEMENT ENABLED"
fiif [[ -f "/opt/shelvera/automation/azure/.disable-start-dev-qa" ]]; then
echo "START JOB DISABLED"
else
echo "START JOB ENABLED"
fiif [[ -f "/opt/shelvera/automation/azure/.disable-stop-dev-qa" ]]; then
echo "STOP JOB DISABLED"
else
echo "STOP JOB ENABLED"
fiTZ="America/New_York" date "+%Y-%m-%d %H:%M:%S.%3N %Z"# Shelvera Azure cost-control enforcement
*/15 * * * * /usr/bin/flock -n "/tmp/shelvera-enforce-dev-qa-stopped.lock" "/opt/shelvera/automation/azure/enforce-dev-qa-stopped-azure.sh" >> "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-cron.log" 2>&1
# Optional daily Dev + QA start job
0 19 * * * /usr/bin/flock -n "/tmp/shelvera-start-dev-qa.lock" "/opt/shelvera/automation/azure/start-dev-qa-azure.sh" >> "/opt/shelvera/automation/azure/logs/start-dev-qa-cron.log" 2>&1
# Optional daily Dev + QA stop job
0 23 * * * /usr/bin/flock -n "/tmp/shelvera-stop-dev-qa.lock" "/opt/shelvera/automation/azure/stop-dev-qa-azure.sh" >> "/opt/shelvera/automation/azure/logs/stop-dev-qa-cron.log" 2>&1TZ="America/New_York" bash -c 'now=$(date +%s); next=$(( ((now / 900) + 1) * 900 )); date -d "@$next" "+Next 15-minute cron run: %Y-%m-%d %H:%M:%S %Z"'crontab -e
crontab -l
sudo systemctl status cron
sudo systemctl start cron
sudo systemctl enable cron
sudo systemctl restart cronalias status-devqa-enforcement='{ echo ""; echo "===== $(date "+%Y-%m-%d %H:%M:%S.%3N %Z") | STATUS | enforce-dev-qa-stopped ====="; if [[ -f "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped" ]]; then echo "ENFORCEMENT DISABLED"; else echo "ENFORCEMENT ENABLED"; fi; } 2>&1 | tee -a "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-control.log"'
alias disable-devqa-enforcement='{ echo ""; echo "===== $(date "+%Y-%m-%d %H:%M:%S.%3N %Z") | DISABLE | enforce-dev-qa-stopped ====="; touch "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped"; echo "Disable file created: /opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped"; echo "ENFORCEMENT DISABLED"; } 2>&1 | tee -a "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-control.log"'
alias enable-devqa-enforcement='{ echo ""; echo "===== $(date "+%Y-%m-%d %H:%M:%S.%3N %Z") | ENABLE | enforce-dev-qa-stopped ====="; rm -f "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped"; echo "Disable file removed: /opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped"; echo "ENFORCEMENT ENABLED"; } 2>&1 | tee -a "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-control.log"'
alias start-devqa-azure='{ echo ""; echo "===== $(date "+%Y-%m-%d %H:%M:%S.%3N %Z") | MANUAL START | start-dev-qa-azure ====="; /usr/bin/flock -n "/tmp/shelvera-start-dev-qa.lock" "/opt/shelvera/automation/azure/start-dev-qa-azure.sh"; echo "===== $(date "+%Y-%m-%d %H:%M:%S.%3N %Z") | END MANUAL START | start-dev-qa-azure ====="; } 2>&1 | tee -a "/opt/shelvera/automation/azure/logs/start-dev-qa-manual.log"'
alias stop-devqa-azure='{ echo ""; echo "===== $(date "+%Y-%m-%d %H:%M:%S.%3N %Z") | MANUAL STOP | stop-dev-qa-azure ====="; /usr/bin/flock -n "/tmp/shelvera-stop-dev-qa.lock" "/opt/shelvera/automation/azure/stop-dev-qa-azure.sh"; echo "===== $(date "+%Y-%m-%d %H:%M:%S.%3N %Z") | END MANUAL STOP | stop-dev-qa-azure ====="; } 2>&1 | tee -a "/opt/shelvera/automation/azure/logs/stop-dev-qa-manual.log"'
alias watch-devqa-enforcement-log='tail -f "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-cron.log"'source ~/.bashrc
status-devqa-enforcement
disable-devqa-enforcement
enable-devqa-enforcement
start-devqa-azure
stop-devqa-azure
watch-devqa-enforcement-logtail -100 "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-cron.log"tail -f "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-cron.log"tail -100 "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-manual.log"tail -100 "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-control.log"tail -100 "/opt/shelvera/automation/azure/logs/start-dev-qa-cron.log"tail -100 "/opt/shelvera/automation/azure/logs/stop-dev-qa-cron.log"tail -100 "/opt/shelvera/automation/azure/logs/start-dev-qa-manual.log"tail -100 "/opt/shelvera/automation/azure/logs/stop-dev-qa-manual.log"Show start/stop job enable-disable commands
touch "/opt/shelvera/automation/azure/.disable-start-dev-qa"rm -f "/opt/shelvera/automation/azure/.disable-start-dev-qa"touch "/opt/shelvera/automation/azure/.disable-stop-dev-qa"rm -f "/opt/shelvera/automation/azure/.disable-stop-dev-qa"Show optional logrotate configuration
sudo nano /etc/logrotate.d/shelvera-azure-automation/opt/shelvera/automation/azure/logs/*.log {
size 10M
rotate 14
compress
missingok
notifempty
copytruncate
}sudo logrotate -d /etc/logrotate.d/shelvera-azure-automation2. Recommended Daily Workflow​
Before starting Dev + QA manually, run
disable-devqa-enforcement.Confirm status with
status-devqa-enforcement.Start Dev + QA with
start-devqa-azure.Complete your testing or development work.
Stop Dev + QA with
stop-devqa-azureif you want immediate cleanup.Re-enable the safety net with
enable-devqa-enforcement.Watch the next run using
watch-devqa-enforcement-log.
Use the aliases for daily work and keep the full generated commands on this page as the source of truth. The aliases are short, readable and still write control logs so you can audit what happened later.
3. Safety Rules​
Keep
flockin every cron and manual command to avoid overlapping Azure start/stop operations.Do not leave enforcement disabled after work unless that is intentional.
Review daily start/stop cron entries carefully so they do not fight the 15-minute enforcement job.
Prefer
tail -fwhile testing new cron entries so failures are visible immediately.Use logrotate instead of manually deleting active logs. The generated logrotate config keeps archives and safely truncates active files.
If the 15-minute enforcement job is enabled, it can stop Dev + QA shortly after a scheduled start. Use the scheduled start job only when your start script or your operating procedure intentionally handles the work window.
4. Parameter Guide​
| Input on this page | Generated output | Purpose |
|---|---|---|
| Automation Root Folder | Script paths and disable-file paths | Base folder for Shelvera Azure automation scripts. |
| Logs Folder | All log paths | Central location for cron, manual and control logs. |
| Timezone | TZ=... date helpers | Shows current time and next cron run in your preferred timezone. |
| Enforcement Script | Manual run and enforcement cron | Script that checks/stops Dev + QA resources. |
| Manual Start Script | Manual start command and optional start cron | Starts Dev + QA Azure resources. |
| Manual Stop Script | Manual stop command and optional stop cron | Stops Dev + QA Azure resources. |
| Disable Files | touch / rm -f commands | Turns enforcement, start job or stop job on/off. |
| Lock Files | /usr/bin/flock -n ... | Prevents duplicate concurrent script runs. |
| Enforce Every N Minutes | */N * * * * | Controls the cost-control enforcement cadence. |
| Start/Stop Hour and Minute | Daily cron entries | Generates optional daily start and stop jobs. |
| Tail Lines | tail -N commands | Controls how much history to show when viewing logs. |
| Logrotate Size / Archives | /etc/logrotate.d/... config | Rotates logs by size and removes archives beyond the retention count. |
5. Alias Catalog​
| Alias | Purpose |
|---|---|
status-devqa-enforcement | Shows whether 15-minute enforcement is currently enabled. |
disable-devqa-enforcement | Creates the enforcement disable file and writes a control log entry. |
enable-devqa-enforcement | Removes the enforcement disable file and writes a control log entry. |
start-devqa-azure | Starts Dev + QA manually with screen output and log capture. |
stop-devqa-azure | Stops Dev + QA manually with screen output and log capture. |
watch-devqa-enforcement-log | Live tails the enforcement cron log. |
6. Cron Meaning Reference​
| Cron expression | Meaning |
|---|---|
*/15 * * * * | Every 15 minutes. |
0 19 * * * | Every day at 7:00 PM server-local cron time. |
0 23 * * * | Every day at 11:00 PM server-local cron time. |
Cron uses the server's cron timezone unless you explicitly configure a timezone
for the cron environment. The generated TZ=America/New_York date ... commands
are helper commands for checking time; they do not change cron's own timezone.
7. Log Cleanup Recommendation​
The best long-term cleanup approach is logrotate by size for this automation:
Rotate when a log crosses a size threshold such as
10M.Keep a fixed number of compressed archives, such as
14.Use
copytruncatebecause shell scripts and cron append to simple log files.Avoid deleting active logs manually while a script may be writing to them.
The optional logrotate generator above creates a ready-to-paste config for:
/etc/logrotate.d/shelvera-azure-automation