Skip to main content

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​

# Anchor
Shelvera Azure Cost-Control Command Builder
Generate copy-ready Ubuntu/bash commands for Dev + QA Azure automation: manual start/stop, 15-minute cost-control enforcement, cron entries, aliases, log viewing and log cleanup.
Enforcement every 15 minutesTimezone: America/New_YorkStart 19:00 / Stop 23:00Ubuntu cron + bash aliases
Folders and Timezone
These values drive every generated script path, log path and time command.
Folder containing enforce/start/stop Azure automation scripts.
All generated log commands and aliases write to or read from this folder.
Used by the current-time and next-cron-run helper commands.
Script Names
Keep these defaults unless you renamed the shell scripts.
Stops Dev + QA Azure resources when enforcement is enabled.
Starts Dev + QA Azure resources for work/testing.
Stops Dev + QA Azure resources manually.
Schedule
The enforcement cron is the cost-control safety net. Daily start/stop entries are optional convenience jobs.
Creates */N cron syntax.
Used by tail commands.
24-hour format.
0-59.
24-hour format.
0-59.
Show advanced disable files, locks and log filenames
Disable Files
These files turn individual scheduled jobs on/off.
Lock Files
flock prevents duplicate concurrent executions.
Log Filenames
Only filenames are needed here because the Logs Folder is configured above.
Resolved paths from your inputs
Main script
/opt/shelvera/automation/azure/enforce-dev-qa-stopped-azure.sh
Disable file
/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped
Cron log
/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-cron.log
Prepare Folder Permissions
Run this after copying scripts into the automation folder, or use it to repair missing folders and executable permissions.
sudo 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"
Manual Enforcement Run
Runs the every-15-minute enforcement script manually with flock protection and manual logging.
/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"
Manual Start Dev + QA
Use this when you intentionally need Dev + QA running for work or testing.
/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"
Manual Stop Dev + QA
Use this to stop Dev + QA immediately without waiting for the next enforcement cycle.
/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"
Disable Enforcement
Create the disable file. The enforcement script should do nothing while this file exists.
touch "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped"
Enable Enforcement
Remove the disable file so the scheduled enforcement can resume.
rm -f "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped"
Check Enforcement Status
if [[ -f "/opt/shelvera/automation/azure/.disable-enforce-dev-qa-stopped" ]]; then
  echo "ENFORCEMENT DISABLED"
else
  echo "ENFORCEMENT ENABLED"
fi
Check Start Job Status
if [[ -f "/opt/shelvera/automation/azure/.disable-start-dev-qa" ]]; then
  echo "START JOB DISABLED"
else
  echo "START JOB ENABLED"
fi
Check Stop Job Status
if [[ -f "/opt/shelvera/automation/azure/.disable-stop-dev-qa" ]]; then
  echo "STOP JOB DISABLED"
else
  echo "STOP JOB ENABLED"
fi
Check Current Time
TZ="America/New_York" date "+%Y-%m-%d %H:%M:%S.%3N %Z"
Generated Cron Entries
Copy these into crontab with crontab -e. Review start/stop timing carefully before saving.
# 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>&1
Next Enforcement Cron Run
TZ="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"'
Cron Service Commands
Useful when cron is not running or after editing schedules.
crontab -e
crontab -l
sudo systemctl status cron
sudo systemctl start cron
sudo systemctl enable cron
sudo systemctl restart cron
Generated ~/.bashrc Aliases
Paste this block into ~/.bashrc, save, then run source ~/.bashrc.
alias 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"'
Reload and Use Aliases
source ~/.bashrc

status-devqa-enforcement
disable-devqa-enforcement
enable-devqa-enforcement
start-devqa-azure
stop-devqa-azure
watch-devqa-enforcement-log
Tail enforcement cron log
tail -100 "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-cron.log"
Live-watch enforcement cron log
tail -f "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-cron.log"
Tail enforcement manual log
tail -100 "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-manual.log"
Tail enforcement control log
tail -100 "/opt/shelvera/automation/azure/logs/enforce-dev-qa-stopped-control.log"
Tail start cron log
tail -100 "/opt/shelvera/automation/azure/logs/start-dev-qa-cron.log"
Tail stop cron log
tail -100 "/opt/shelvera/automation/azure/logs/stop-dev-qa-cron.log"
Tail start manual log
tail -100 "/opt/shelvera/automation/azure/logs/start-dev-qa-manual.log"
Tail stop manual log
tail -100 "/opt/shelvera/automation/azure/logs/stop-dev-qa-manual.log"
Show start/stop job enable-disable commands
Disable Scheduled Start Job
touch "/opt/shelvera/automation/azure/.disable-start-dev-qa"
Enable Scheduled Start Job
rm -f "/opt/shelvera/automation/azure/.disable-start-dev-qa"
Disable Scheduled Stop Job
touch "/opt/shelvera/automation/azure/.disable-stop-dev-qa"
Enable Scheduled Stop Job
rm -f "/opt/shelvera/automation/azure/.disable-stop-dev-qa"
Show optional logrotate configuration
Log Cleanup Settings
Recommended developer-friendly cleanup: rotate when logs cross a size threshold, keep compressed archives.
Examples: 5M, 10M, 50M.
Old archives beyond this count are removed by logrotate.
Create logrotate config
Paste the generated config into the file below.
sudo nano /etc/logrotate.d/shelvera-azure-automation
Generated logrotate config
/opt/shelvera/automation/azure/logs/*.log {
    size 10M
    rotate 14
    compress
    missingok
    notifempty
    copytruncate
}
Test logrotate config
sudo logrotate -d /etc/logrotate.d/shelvera-azure-automation
# Anchor
  1. Before starting Dev + QA manually, run disable-devqa-enforcement.

  2. Confirm status with status-devqa-enforcement.

  3. Start Dev + QA with start-devqa-azure.

  4. Complete your testing or development work.

  5. Stop Dev + QA with stop-devqa-azure if you want immediate cleanup.

  6. Re-enable the safety net with enable-devqa-enforcement.

  7. Watch the next run using watch-devqa-enforcement-log.

Best developer UX

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​

# Anchor
  • Keep flock in 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 -f while 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.

Scheduled start vs enforcement

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​

# Anchor
Input on this pageGenerated outputPurpose
Automation Root FolderScript paths and disable-file pathsBase folder for Shelvera Azure automation scripts.
Logs FolderAll log pathsCentral location for cron, manual and control logs.
TimezoneTZ=... date helpersShows current time and next cron run in your preferred timezone.
Enforcement ScriptManual run and enforcement cronScript that checks/stops Dev + QA resources.
Manual Start ScriptManual start command and optional start cronStarts Dev + QA Azure resources.
Manual Stop ScriptManual stop command and optional stop cronStops Dev + QA Azure resources.
Disable Filestouch / rm -f commandsTurns 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 MinuteDaily cron entriesGenerates optional daily start and stop jobs.
Tail Linestail -N commandsControls how much history to show when viewing logs.
Logrotate Size / Archives/etc/logrotate.d/... configRotates logs by size and removes archives beyond the retention count.

5. Alias Catalog​

# Anchor
AliasPurpose
status-devqa-enforcementShows whether 15-minute enforcement is currently enabled.
disable-devqa-enforcementCreates the enforcement disable file and writes a control log entry.
enable-devqa-enforcementRemoves the enforcement disable file and writes a control log entry.
start-devqa-azureStarts Dev + QA manually with screen output and log capture.
stop-devqa-azureStops Dev + QA manually with screen output and log capture.
watch-devqa-enforcement-logLive tails the enforcement cron log.

6. Cron Meaning Reference​

# Anchor
Cron expressionMeaning
*/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.
Timezone note

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​

# Anchor

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 copytruncate because 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