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:
- Verify and increase your AWS Service Quotas (vCPUs)
- Prepare prerequisites and the On-Demand Capacity Reservations (ODCR) script
- 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:
- Request a reservation for
1instance in a targeted AZ. - If AWS grants it (
ok), we know physical silicon is available right now. - Immediately cancel the reservation so you don't get billed for idle reservation time.
- 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:DescribeRegionsec2:DescribeInstanceTypeOfferingsec2:CreateCapacityReservationec2: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.

