Deploy TestDriver on your AWS infrastructure using CloudFormation
npx skills add https://github.com/testdriverai/testdriverai --skill testdriver:aws-setup
<!-- Generated from aws-setup.mdx. DO NOT EDIT. -->
This guide walks you through setting up self-hosted TestDriver instances on AWS. By the end, you'll have fully automated test infrastructure that spawns and terminates instances on-demand.
graph LR
A[Vitest Test] --> B[setup-aws hook]
B --> C[Spawns EC2]
C --> D[Runs Test]
D --> E[Terminates EC2]
TestDriver automatically manages AWS EC2 instances for your tests:
That's it! No manual instance management needed.
<Steps>
<Step title="Deploy Infrastructure">
<Card
title="Launch CloudFormation Stack"
icon="aws"
href="https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?templateURL=https://v7-cloudformation-template.s3.us-east-2.amazonaws.com/cloudformation.yaml"
horizontal
arrow
>
One-click AWS setup
</Card>
</Step>
<Step title="Add to Vitest Config">
setupFiles: ['testdriverai/vitest/setup', 'testdriverai/vitest/setup-aws']
</Step>
<Step title="Run Tests">
TD_OS=windows AWS_REGION=us-east-2 \
AWS_LAUNCH_TEMPLATE_ID=lt-xxx AMI_ID=ami-xxx \
vitest run
</Step>
</Steps>
The setup process is simple:
setup-aws to automatically manage instance lifecycleTD_OS=windows with AWS credentials and instances spawn/terminate automaticallyBefore you begin, ensure you have:
aws configure)<Tip>
The TestDriver Golden Image AMI ID is ami-0504bf50fad62f312. Contact us to get access in your preferred AWS region.
</Tip>
Our CloudFormation template creates all the AWS infrastructure you need:
<Tabs>
<Tab title="GUI">
Click the button below to launch the CloudFormation stack in your AWS Console:
<Card
title="Launch Stack"
icon="aws"
href="https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?templateURL=https://v7-cloudformation-template.s3.us-east-2.amazonaws.com/cloudformation.yaml"
horizontal
arrow
>
Deploy TestDriver infrastructure with one click
</Card>
Configure the stack parameters:
testdriver-infrastructure (or your preferred name)testdriver203.0.113.0/24)c5.xlarge (recommended)true<Warning>
Security: Replace AllowedIngressCidr with your specific IP ranges to restrict VPC access. Avoid using 0.0.0.0/0 in production.
</Warning>
After the stack creation completes, navigate to the Outputs tab to find your LaunchTemplateId:
!Launch Template ID
<Tip>
Save this ID — you'll need it for spawning instances and CI configuration.
</Tip>
</Tab>
<Tab title="CLI">
Download the template from the TestDriver CLI repository, then deploy:
aws cloudformation deploy \
--template-file setup/aws/cloudformation.yaml \
--stack-name testdriver-infrastructure \
--parameter-overrides \
ProjectTag=testdriver \
AllowedIngressCidr=0.0.0.0/0 \
InstanceType=c5.xlarge \
CreateKeyPair=true \
--capabilities CAPABILITY_IAM
<Warning>
Security: Replace AllowedIngressCidr=0.0.0.0/0 with your specific IP ranges to restrict VPC access.
</Warning>
After deployment completes, retrieve the launch template ID:
aws cloudformation describe-stacks \
--stack-name testdriver-infrastructure \
--query 'Stacks[0].Outputs[?OutputKey==`LaunchTemplateId`].OutputValue' \
--output text
<Tip>
Save this ID — you'll need it for spawning instances and CI configuration.
</Tip>
</Tab>
</Tabs>
Add the AWS setup hook to your vitest.config.mjs:
import { defineConfig } from 'vitest/config';
import { config } from 'dotenv';
import TestDriver from 'testdriverai/vitest';
config(); // Load .env file
export default defineConfig({
test: {
testTimeout: 900000,
hookTimeout: 900000,
maxConcurrency: 3,
reporters: [
'default',
TestDriver(),
['junit', { outputFile: 'test-report.junit.xml' }]
],
setupFiles: ['testdriverai/vitest/setup', 'testdriverai/vitest/setup-aws'],
},
});
<Note>
That's it! The setup-aws hook automatically spawns and terminates instances when TD_OS=windows is set. No manual instance management needed.
</Note>
Tests should use context.ip || process.env.TD_IP for the IP configuration:
import { describe, it } from "vitest";
import { TestDriver } from "testdriverai/vitest/hooks";
describe("My Test", () => {
it("should run on self-hosted instance", async (context) => {
const testdriver = TestDriver(context, {
ip: context.ip || process.env.TD_IP,
});
await testdriver.provision.chrome({ url: "https://example.com" });
// ... your test steps
});
});
<Note>
How it works: When TD_OS=windows with AWS credentials, context.ip is automatically set by the setup hook. When running without AWS setup (cloud-hosted), both are undefined and TestDriver uses the cloud. When TD_IP is provided manually, it takes precedence.
</Note>
TD_OS=windows \
AWS_REGION=us-east-2 \
AWS_LAUNCH_TEMPLATE_ID=lt-xxx \
AMI_ID=ami-0504bf50fad62f312 \
vitest run
<Note>
Each test gets its own fresh EC2 instance that's automatically terminated after completion.
</Note>
Automate testing with self-hosted instances in your CI/CD pipeline. TestDriver automatically spawns a fresh instance for each test, runs the test, and terminates the instance.
name: TestDriver Self-Hosted Windows Tests
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Windows tests with self-hosted instances
run: npx vitest run examples/*.test.mjs
env:
TD_API_KEY: ${{ secrets.TD_API_KEY }}
TD_OS: windows
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-2
AWS_LAUNCH_TEMPLATE_ID: ${{ secrets.AWS_LAUNCH_TEMPLATE_ID }}
AMI_ID: ${{ secrets.AMI_ID }}
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: test-report.junit.xml
<Note>
Automatic Instance Management: Setting TD_OS=windows with AWS credentials enables automatic instance spawning. Each test gets its own fresh instance that's terminated after the test completes.
</Note>
| Secret | Description | Example |
|--------|-------------|---------|
| AWS_ACCESS_KEY_ID | AWS access key | AKIAIOSFODNN7EXAMPLE |
| AWS_SECRET_ACCESS_KEY | AWS secret key | wJalrXUtnFEMI/K7MDENG... |
| AWS_REGION | AWS region | us-east-2 |
| AWS_LAUNCH_TEMPLATE_ID | From CloudFormation output | lt-07c53ce8349b958d1 |
| AMI_ID | TestDriver AMI ID | ami-0504bf50fad62f312 |
| TD_API_KEY | Your TestDriver API key | From console.testdriver.ai |
<Tip>
Add these as GitHub Repository Secrets under Settings → Secrets and variables → Actions
</Tip>
For complete production examples, see:
If you already have a running instance, you can skip automatic spawning by providing TD_IP:
TD_OS=windows TD_IP=1.2.3.4 vitest run
The setup-aws hook will detect TD_IP is already set and skip spawning a new instance.
For advanced use cases, you can manually spawn instances using the spawn-runner.sh script:
AWS_REGION=us-east-2 \
AMI_ID=ami-0504bf50fad62f312 \
AWS_LAUNCH_TEMPLATE_ID=lt-xxx \
bash setup/aws/spawn-runner.sh
Output:
PUBLIC_IP=1.2.3.4
INSTANCE_ID=i-1234567890abcdef0
AWS_REGION=us-east-2
Then manually terminate when done:
aws ec2 terminate-instances \
--instance-ids i-1234567890abcdef0 \
--region us-east-2
For complete production examples, see:
You can connect to running instances via:
http://<public-ip>:5900<Note>
Stopped instances retain their EBS volumes and can be restarted later. Terminated instances are permanently deleted. Always terminate instances when done to avoid storage costs.
</Note>
The TestDriver Golden Image comes pre-configured with:
You can customize the AMI to include additional software or configurations:
<Steps>
<Step title="Connect via RDP">
Use the default credentials:
testdriverwwv9uJ0sqlulbN3</Step>
<Step title="Change the Password">
Critical: Run the password rotation script immediately:
C:\testdriver\RotateLocalPasswords.ps1
Save the new password securely.
</Step>
<Step title="Install Your Software">
Install any additional dependencies, configure settings, or modify the environment as needed.
</Step>
<Step title="Create New AMI">
Use the AWS console or CLI to create an AMI from your modified instance. Update your workflow to use the new AMI ID.
</Step>
</Steps>
<Warning>
Security: Never use the default password in production. Always rotate passwords before creating custom AMIs.
</Warning>
Use OIDC instead of long-term credentials for GitHub Actions:
permissions:
id-token: write
contents: read
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: us-east-2
See GitHub's OIDC documentation for setup instructions.
Assess Kubernetes workloads and cluster configuration for AKS Automatic compatibility. Identifies incompatibilities, generates fixes, and guides migration from AKS Standard to AKS Automatic. WHEN: migrate to AKS Automatic, check AKS Automatic readiness, validate manifests for Automatic, assess cluster for Automatic compatibility, fix deployment for Automatic compatibility, identify AKS Automatic migration blockers, is my cluster ready for AKS Automatic.
Discovers available Azure OpenAI model capacity across regions and projects. Analyzes quota limits, compares availability, and recommends optimal deployment locations based on capacity requirements. USE FOR: find capacity, check quota, where can I deploy, capacity discovery, best region for capacity, multi-project capacity search, quota analysis, model availability, region comparison, check TPM availability. DO NOT USE FOR: actual deployment (hand off to preset or customize after discovery), quota increase requests (direct user to Azure Portal), listing existing deployments.
Interactive guided deployment flow for Azure OpenAI models with full customization control. Step-by-step selection of model version, SKU (GlobalStandard/Standard/ProvisionedManaged), capacity, RAI policy (content filter), and advanced options (dynamic quota, priority processing, spillover). USE FOR: custom deployment, customize model deployment, choose version, select SKU, set capacity, configure content filter, RAI policy, deployment options, detailed deployment, advanced deployment, PTU deployment, provisioned throughput. DO NOT USE FOR: quick deployment to optimal region (use preset).
Unified Azure OpenAI model deployment skill with intelligent intent-based routing. Handles quick preset deployments, fully customized deployments (version/SKU/capacity/RAI policy), and capacity discovery across regions and projects. USE FOR: deploy model, deploy gpt, create deployment, model deployment, deploy openai model, set up model, provision model, find capacity, check model availability, where can I deploy, best region for model, capacity analysis. DO NOT USE FOR: listing existing deployments (use foundry_models_deployments_list MCP tool), deleting deployments, agent creation (use agent/create), project creation (use project/create).
Intelligently deploys Azure OpenAI models to optimal regions by analyzing capacity across all available regions. Automatically checks current region first and shows alternatives if needed. USE FOR: quick deployment, optimal region, best region, automatic region selection, fast setup, multi-region capacity check, high availability deployment, deploy to best location. DO NOT USE FOR: custom SKU selection (use customize), specific version selection (use customize), custom capacity configuration (use customize), PTU deployments (use customize).
This skill should be used when working with LaminDB, an open-source data framework for biology that makes data queryable, traceable, reproducible, and FAIR. Use when managing biological datasets (scRNA-seq, spatial, flow cytometry, etc.), tracking computational workflows, curating and validating data with biological ontologies, building data lakehouses, or ensuring data lineage and reproducibility in biological research. Covers data management, annotation, ontologies (genes, cell types, diseases, tissues), schema validation, integrations with workflow managers (Nextflow, Snakemake) and MLOps platforms (W&B, MLflow), and deployment strategies.
Latch platform for bioinformatics workflows. Build pipelines with Latch SDK, @workflow/@task decorators, deploy serverless workflows, LatchFile/LatchDir, Nextflow/Snakemake integration.
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.
Take testdriverai/testdriver:aws-setup from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npx.
Without those the skill loads but fails at the first command.