Skip to content

Scripting & Automation

This guide covers using bnerd in shell scripts and CI/CD pipelines.

JSON Output for Scripting

Use -o json to get machine-readable output, then process with jq:

# List all zone names
bnerd dns zones list -o json | jq -r '.[].name'

# Count resources
bnerd servers list -o json | jq 'length'

# Extract specific fields
bnerd dns zones list -o json | jq -r '.[] | [.id, .name, .kind] | @tsv'

# Filter by criteria
bnerd domains list -o json | jq '[.domains[] | select(.status == "pending")]'

CI/CD Integration

Environment-Based Authentication

In CI/CD pipelines, use environment variables instead of config files:

export BNERD_API_URL=https://api.bnerd.net
export BNERD_TOKEN=$CI_BNERD_TOKEN
export BNERD_ORG_ID=$CI_BNERD_ORG_ID
export BNERD_PROJECT_ID=$CI_BNERD_PROJECT_ID
export BNERD_OUTPUT=json

No ~/.bnerd.yaml needed — environment variables are sufficient.

GitLab CI Example

check-dns:
  image: golang:1.24
  script:
    - go install git.bnerd.net/cloud/app/cli@latest
    - bnerd dns zones list -o json | jq '.[].name'
  variables:
    BNERD_API_URL: https://api.bnerd.net
    BNERD_TOKEN: $BNERD_TOKEN  # Set in CI/CD variables
    BNERD_ORG_ID: $BNERD_ORG_ID

Script Examples

List All DNS Records as CSV

#!/bin/bash
set -euo pipefail

# Get all zones
zones=$(bnerd dns zones list -o json | jq -r '.[].id')

echo "zone_name,record_name,record_type,ttl,content"

for zone_id in $zones; do
  zone_data=$(bnerd dns zones get "$zone_id" -o json)
  zone_name=$(echo "$zone_data" | jq -r '.name')

  echo "$zone_data" | jq -r --arg zone "$zone_name" \
    '.rrsets[] | .records[] as $r |
    [$zone, .name, .type, (.ttl | tostring), $r.content] | @csv'
done

Check Domain Verification Status

#!/bin/bash
set -euo pipefail

DOMAIN_NAME="${1:?Usage: $0 <domain-name>}"

# Find the domain
domain=$(bnerd domains list -o json | \
  jq --arg name "$DOMAIN_NAME" '.domains[] | select(.name == $name)')

if [ -z "$domain" ]; then
  echo "Domain $DOMAIN_NAME not found"
  exit 1
fi

status=$(echo "$domain" | jq -r '.status')
echo "Domain: $DOMAIN_NAME"
echo "Status: $status"

if [ "$status" = "pending" ]; then
  echo ""
  echo "Verification instructions:"
  echo "$domain" | jq -r '.verification_instructions | "  Host:  \(.host)\n  Type:  \(.method)\n  Value: \(.value)"'
fi

Monitor Billing

#!/bin/bash
# Get billing overview and alert if cost exceeds threshold
THRESHOLD=100.00

total=$(bnerd billing overview -o json | jq -r '.total_cost // 0')

if (( $(echo "$total > $THRESHOLD" | bc -l) )); then
  echo "ALERT: Billing total ($total) exceeds threshold ($THRESHOLD)"
  exit 1
fi

echo "Billing OK: $total (threshold: $THRESHOLD)"

Error Handling

bnerd uses standard exit codes:

Exit code Meaning
0 Success
1 Error (authentication, API error, invalid arguments)

Check exit codes in scripts:

if bnerd dns zones list -o json > /dev/null 2>&1; then
  echo "API connection OK"
else
  echo "API connection failed"
  exit 1
fi

Debug Mode

Use --debug for troubleshooting. Debug output goes to stderr, so it doesn't interfere with JSON piping:

bnerd --debug dns zones list -o json 2>debug.log | jq .

Tips

  • Always use -o json in scripts for stable, parseable output
  • Set BNERD_OUTPUT=json globally in CI environments
  • Use set -euo pipefail in bash scripts for proper error handling
  • Pipe --debug output to stderr or a log file to keep stdout clean
  • Use jq -e (exit status based on output) for conditional logic