Skip to main content

 

Splunk Lantern

Running capacity checks for Splunk AI Tier on AWS to quickly find elusive GPU resources

Setting up a lab to evaluate Splunk AI Assistant or the Splunk AI Toolkit on Splunk AI Tier is exciting, until you spend 20 minutes provisioning VPCs, Internet Gateways, NAT Gateways, IAM roles, and security groups, only to hit the dreaded:

An error occurred (InsufficientInstanceCapacity) when calling the RunInstances operation: 
We currently do not have sufficient g6e.12xlarge capacity in the Availability Zone you requested...

Discovering a capacity shortage at the last step is the opposite of failing fast

Because modern GPU instance types (g6e, g7e, g5, etc.) are in exceptionally high demand, standard AWS API queries like describe-instance-type-offerings only tell you where instance types are theoretically offered, not whether AWS has physical servers sitting idle right this second.

To find available GPU capacity before you build any infrastructure, work through the following pre-flight checklist:

  1. Verify and increase your AWS Service Quotas (vCPUs)
  2. Prepare prerequisites and the On-Demand Capacity Reservations (ODCR) script 
  3. Run the script and interpret the results

Solution

Step 1: Verify and increase your AWS Service Quotas

Before you can create an instance or capacity reservation, your AWS account needs enough allocated vCPUs for the instance family. 

For GPU instances (such as the g family), AWS tracks quotas under Running On-Demand G and VT instances (Quota code: L-DB2E81BA).

1.1. Check your existing quota in your target region(s)

aws service-quotas get-service-quota \
  --service-code ec2 \
  --quota-code L-DB2E81BA \
  --region <region>

Look at the Value field in the response. If you plan to launch a g6e.12xlarge (48 vCPUs) or g7e.12xlarge (48 vCPUs), your quota needs to comfortably cover that number.

1.2. Request a quota increase (if needed)

If your quota is `0` or too low, request an increase via CLI:

aws service-quotas request-service-quota-increase \
  --service-code ec2 \
  --quota-code L-DB2E81BA \
  --desired-value 192 \
  --region <region>

Quota increases usually require AWS automated or manual review and can take anywhere from a few minutes to a couple of hours. Request this in your candidate regions ahead of time.

Step 2: Prepare prerequisites and the ODCR script

Rather than spinning up full EC2 instances (which take minutes, attach disks, and incur compute charges), you can use On-Demand Capacity Reservations (ODCR) as a momentary probe:

  1. Request a reservation for 1 instance in a targeted AZ.
  2. If AWS grants it (ok), we know physical silicon is available right now.
  3. Immediately cancel the reservation so you don't get billed for idle reservation time.
  4. If it fails, capture the exact AWS error code (InsufficientInstanceCapacity, VcpuLimitExceeded, etc.).

Prerequisites and permissions

  • Tools: AWS CLI v2, standard POSIX utilities (column, sed, mktemp).
  • IAM Permissions: The IAM identity running the script needs:
    • ec2:DescribeRegions
    • ec2:DescribeInstanceTypeOfferings
    • ec2:CreateCapacityReservation
    • ec2:CancelCapacityReservation

The script: odcr-probe.sh

Save this script locally, make it executable (chmod +x odcr-probe.sh), and run it before deploying your AI Tier.

#!/usr/bin/env bash
# odcr-probe.sh
#
# Probe on-demand capacity by creating a targeted ODCR in each AZ where
# an instance type is offered, then cancelling immediately on success.
#
# A successful create means AWS had capacity at that moment. Cancelling
# releases it; this is a probe, not a hold. Interrupt (Ctrl-C) still
# attempts to cancel any in-flight reservation.
#
# Compatible with macOS Bash 3.2 (no associative arrays).
#
# Usage:
#   ./odcr-probe.sh --type g7e.12xlarge
#   ./odcr-probe.sh --type g7e.12xlarge --count 2
#   ./odcr-probe.sh --type g6e.12xlarge --regions us-east-1,eu-central-1,us-west-2
#   ./odcr-probe.sh g6e.12xlarge --profile my-aws-profile

set -euo pipefail

INSTANCE_TYPE=""
REGIONS_ARG=""
COUNT=1
PLATFORM="Linux/UNIX"
CLI_PROFILE=""
ENDPOINT_REGION="${AWS_REGION:-${AWS_DEFAULT_REGION:-us-east-1}}"

CURRENT_CR=""
CURRENT_CR_REGION=""
ERRFILE=""
ROWSFILE=""

usage() {
  sed -n '2,18p' "$0"
  exit "${1:-0}"
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --type|--instance-type)
      INSTANCE_TYPE="$2"
      shift 2
      ;;
    --region|--regions)
      if [[ -n "${REGIONS_ARG}" ]]; then
        REGIONS_ARG="${REGIONS_ARG} $(echo "$2" | tr ',' ' ')"
      else
        REGIONS_ARG="$(echo "$2" | tr ',' ' ')"
      fi
      shift 2
      ;;
    --count)
      COUNT="$2"
      shift 2
      ;;
    --platform)
      PLATFORM="$2"
      shift 2
      ;;
    --profile)
      CLI_PROFILE="$2"
      shift 2
      ;;
    --endpoint-region)
      ENDPOINT_REGION="$2"
      shift 2
      ;;
    -h|--help) usage 0 ;;
    -*)
      echo "unknown arg: $1" >&2
      usage 1
      ;;
    *)
      if [[ -z "${INSTANCE_TYPE}" ]]; then
        INSTANCE_TYPE="$1"
        shift
      else
        echo "unexpected arg: $1" >&2
        usage 1
      fi
      ;;
  esac
done

need() { command -v "$1" >/dev/null 2>&1 || { echo "missing: $1" >&2; exit 1; }; }
need aws
need column

if [[ -z "${INSTANCE_TYPE}" ]]; then
  echo "instance type required (positional or --type)" >&2
  usage 1
fi

aws_ec2() {
  if [[ -n "${CLI_PROFILE}" ]]; then
    aws --profile "${CLI_PROFILE}" ec2 "$@"
  else
    aws ec2 "$@"
  fi
}

aws_error_code() {
  sed -n 's/.*An error occurred (\([^)]*\)).*/\1/p' "$1" | head -1
}

cleanup() {
  if [[ -n "${CURRENT_CR}" && -n "${CURRENT_CR_REGION}" ]]; then
    echo "Cleaning up leftover reservation ${CURRENT_CR} in ${CURRENT_CR_REGION}" >&2
    aws_ec2 cancel-capacity-reservation \
      --capacity-reservation-id "${CURRENT_CR}" \
      --region "${CURRENT_CR_REGION}" >/dev/null 2>&1 || \
      echo "WARN: cancel failed — release ${CURRENT_CR} in ${CURRENT_CR_REGION} manually" >&2
  fi
  rm -f "${ERRFILE}" "${ROWSFILE}"
}
trap cleanup EXIT INT TERM

ERRFILE="$(mktemp -t odcr-probe-err.XXXXXX)"
ROWSFILE="$(mktemp -t odcr-probe-rows.XXXXXX)"

if [[ -n "${REGIONS_ARG}" ]]; then
  REGIONS="${REGIONS_ARG}"
else
  REGIONS="$(aws_ec2 describe-regions --region "${ENDPOINT_REGION}" \
              --query 'Regions[].RegionName' --output text | tr '\t' '
' | sort)"
fi

echo "Instance type:  ${INSTANCE_TYPE}" >&2
echo "Count:          ${COUNT}" >&2
echo "Platform:       ${PLATFORM}" >&2
echo "Match criteria: targeted" >&2
echo >&2

echo "==> DescribeInstanceTypeOfferings" >&2
AZ_LIST=""
az_count=0
for r in ${REGIONS}; do
  azs="$(aws_ec2 describe-instance-type-offerings \
          --region "$r" \
          --location-type availability-zone \
          --filters "Name=instance-type,Values=${INSTANCE_TYPE}" \
          --query 'InstanceTypeOfferings[].Location' \
          --output text 2>/dev/null || true)"
  azs="$(echo "${azs}" | tr '\t' ' ' | sed 's/None//g; s/^[[:space:]]*//; s/[[:space:]]*$//')"
  if [[ -n "$azs" ]]; then
    echo "  ${r}: ${azs}" >&2
    for az in ${azs}; do
      AZ_LIST="${AZ_LIST}${r} ${az}"$'
'
      az_count=$((az_count + 1))
    done
  fi
done

if [[ "${az_count}" -eq 0 ]]; then
  echo "No offerings found for ${INSTANCE_TYPE} in the selected region(s)." >&2
  exit 1
fi

echo >&2
echo "Probing ${az_count} AZ(s). Each successful reservation is cancelled immediately." >&2
echo >&2

ok=0
fail=0
cancel_fail=0

while read -r r az; do
  [[ -n "${r:-}" && -n "${az:-}" ]] || continue
  : > "${ERRFILE}"
  CURRENT_CR=""
  CURRENT_CR_REGION=""

  set +e
  cr_id="$(aws_ec2 create-capacity-reservation \
            --instance-type "${INSTANCE_TYPE}" \
            --instance-platform "${PLATFORM}" \
            --availability-zone "${az}" \
            --instance-count "${COUNT}" \
            --instance-match-criteria targeted \
            --end-date-type unlimited \
            --region "${r}" \
            --query 'CapacityReservation.CapacityReservationId' \
            --output text 2>"${ERRFILE}")"
  rc=$?
  set -e

  if [[ "${rc}" -eq 0 && -n "${cr_id}" && "${cr_id}" != "None" ]]; then
    CURRENT_CR="${cr_id}"
    CURRENT_CR_REGION="${r}"
    set +e
    aws_ec2 cancel-capacity-reservation \
      --capacity-reservation-id "${cr_id}" \
      --region "${r}" >/dev/null 2>"${ERRFILE}"
    cancel_rc=$?
    set -e
    if [[ "${cancel_rc}" -eq 0 ]]; then
      CURRENT_CR=""
      CURRENT_CR_REGION=""
      printf '%s\t%s\t%s\t%s\t%s\t%s
' "$r" "$az" ok cancelled "${cr_id}" "-" >> "${ROWSFILE}"
      echo "  OK   ${r} ${az}  ${cr_id} (cancelled)" >&2
      ok=$((ok + 1))
    else
      code="$(aws_error_code "${ERRFILE}")"
      printf '%s\t%s\t%s\t%s\t%s\t%s
' "$r" "$az" ok "cancel-failed:${code:-unknown}" "${cr_id}" "cancel ${cr_id} in ${r}" >> "${ROWSFILE}"
      echo "  WARN ${r} ${az}  reserved ${cr_id} but cancel failed — stopping" >&2
      cancel_fail=$((cancel_fail + 1))
      ok=$((ok + 1))
      break
    fi
  else
    code="$(aws_error_code "${ERRFILE}")"
    [[ -n "${code}" ]] || code="error"
    printf '%s\t%s\t%s\t%s\t%s\t%s
' "$r" "$az" fail "${code}" "-" "-" >> "${ROWSFILE}"
    echo "  FAIL ${r} ${az}  ${code}" >&2
    fail=$((fail + 1))
  fi
done <<EOF
${AZ_LIST}
EOF

echo
echo "=== ODCR probe ${INSTANCE_TYPE} x${COUNT} ==="
{
  printf '%s\t%s\t%s\t%s\t%s\t%s
' REGION AZ RESULT DETAIL RESERVATION ACTION
  cat "${ROWSFILE}"
} | column -t -s "$(printf '\t')"

echo
echo "ok=${ok}  fail=${fail}  cancel_failed=${cancel_fail}"
if [[ "${cancel_fail}" -gt 0 ]]; then
  echo "Cancel failed for one or more reservations — see ACTION column and release them now." >&2
  exit 2
fi

Step 3: Run the ODCR script and interpret the results

Run the probe across your shortlist of candidate deployment regions:

./odcr-probe.sh --type g6e.12xlarge --regions us-east-1,us-west-2,eu-central-1

Example output table

=== ODCR probe g6e.12xlarge x1 ===
REGION        AZ             RESULT  DETAIL                        RESERVATION   ACTION
us-east-1     us-east-1a     fail    InsufficientInstanceCapacity  -             -
us-east-1     us-east-1b     fail    InsufficientInstanceCapacity  -             -
us-east-1     us-east-1c     ok      cancelled                     cr-01234abc   -
us-west-2     us-west-2a     fail    VcpuLimitExceeded             -             -
eu-central-1  eu-central-1a  ok      cancelled                     cr-05678def   -

ok=2  fail=3  cancel_failed=0

How to interpret the findings

Result / Detail What it means Recommended action
ok / cancelled Green light! AWS had live stock in that AZ, successfully reserved it, and cleanly released it. Deploy your VPC and Splunk AI Tier subnet in this exact AZ (e.g., us-east-1c).
fail / InsufficientInstanceCapacity AWS has no free hardware in that AZ right now. Skip this AZ or check back later.
fail / VcpuLimitExceeded AWS account quota is preventing reservation. Revisit Step 1 to request a Service Quota increase for that region.
WARN / cancel-failed A reservation succeeded, but the immediate cancellation call encountered an issue. The script halts to avoid orphan charges. Follow the ACTION column to cancel the reservation manually via CLI or console.

Summary

Don't let cloud capacity lotteries stall your Splunk AI Tier evaluation. Running a quick quota check and a 10-second ODCR pre-flight probe ensures you only build infrastructure in regions and availability zones where GPU hardware is ready and waiting.