Pinecone BYOC
Deploy Pinecone in your own cloud account (AWS, GCP, or Azure) with full control over your infrastructure.
Quick Start
Interactive Setup
curl -fsSL https://raw.githubusercontent.com/pinecone-io/pulumi-pinecone-byoc/main/bootstrap.sh | bash
This will:
- Select your cloud provider (AWS, GCP, or Azure)
- Check that required tools are installed (Python 3.12+, uv, cloud CLI, Pulumi, kubectl)
- Verify your cloud credentials
- Run an interactive setup wizard
- Generate a complete Pulumi project
Then deploy:
cd pinecone-byoc
pulumi up
Provisioning takes approximately 25-30 minutes.
Prerequisites
Common Tools (Required for All Clouds)
| Tool | Purpose | Install |
|---|---|---|
| Python 3.12+ | Runtime | python.org |
| uv | Package manager | docs.astral.sh/uv |
| Pulumi | Infrastructure | pulumi.com/docs/install |
| kubectl | Cluster access | kubernetes.io |
Cloud-Specific Tools
AWS
| Tool | Purpose | Install |
|---|---|---|
| AWS CLI | AWS access | AWS docs |
GCP
| Tool | Purpose | Install |
|---|---|---|
| gcloud CLI | GCP access | GCP docs |
Azure
| Tool | Purpose | Install |
|---|---|---|
| Azure CLI | Azure access | Azure docs |
Architecture
┌──────────────────────┐ ┌───────────────────────────────────────────────┐
│ │ operations │ Your AWS/GCP/Azure Account (VPC) │
│ Pinecone │───────────────────▶│ │
│ Control Plane │ │ ┌─────────────┐ ┌─────────────────────────┐ │
│ │◀───────────────────│ │ Control │ │ │ │
│ │ cluster state │ │ Plane │ │ Cluster Manager │ │
└──────────────────────┘ │ └─────────────┘ │ (EKS/GKE/AKS) │ │
│ ┌─────────────┐ └─────────────────────────┘ │
│ │ Heartbeat │ │
│ └─────────────┘ │
┌──────────────────────┐ │ ┌───────────────────────────────────────────┐│
│ │◀───────────────────│ │ ││
│ Pinecone │ metrics & │ │ Data Plane ││
│ Observability (DD) │ traces │ │ ││
│ │ │ └───────────────────────────────────────────┘│
└──────────────────────┘ │ ┌──────────┐ ┌───────────┐ ┌─────────────┐ │
│ │ S3/GCS/ │ |FoundationDB│ │ Route53/ │ │
No customer data │ │ AzureBlob│ │ (in-cluster)| | CloudDNS/ | │
leaves the cluster │ └──────────┘ └───────────┘ | Azure DNS | │
│ └─────────────┘ │
└───────────────────────────────────────────────┘
How It Works
Pinecone BYOC uses a pull-based model for control plane operations:
- Index Operations - When you create, scale, or delete indexes through the Pinecone API, these operations are queued in Pinecone's control plane
- Pull & Execute - Components running in your cluster continuously pull pending operations and execute them locally
- Heartbeat & State - Your cluster pushes health status and state back to Pinecone for monitoring
- Observability - Metrics and traces (not customer data) are sent to Pinecone's observability platform (Datadog) for operational insights
This architecture ensures:
- Your data never leaves your cloud account - only operational metrics and cluster state are transmitted
- Network security policies remain under your control
- All communication is outbound from your cluster - Pinecone never needs inbound access
Cluster Access
After deployment, configure kubectl:
AWS:
aws eks update-kubeconfig --region <region> --name <cluster-name>
GCP:
gcloud container clusters get-credentials <cluster-name> --region <region> --project <project-id>
Azure:
az aks get-credentials --resource-group <resource-group> --name <cluster-name>
The exact command is output after pulumi up completes.
Upgrades
Pinecone manages upgrades automatically in the background. If you need to trigger an upgrade manually:
pulumi up -c pinecone-version=<new-version>
Replace <new-version> with the target Pinecone version (e.g., main-abc1234).
Configuration
The setup wizard creates a Pulumi stack with these configurable options:
AWS Configuration Options:
| Option | Description | Default |
|---|---|---|
pinecone-version |
Pinecone release version (required) | — |
region |
AWS region | us-east-1 |
availability_zones |
AZs for high availability | ["us-east-1a", "us-east-1b"] |
vpc_cidr |
VPC IP range | 10.0.0.0/16 |
deletion_protection |
Protect S3 from accidental deletion | true |
public_access_enabled |
Enable public endpoint (false = PrivateLink only) | true |
tags |
Custom tags to apply to all resources | {} |
GCP Configuration Options:
| Option | Description | Default |
|---|---|---|
pinecone-version |
Pinecone release version (required) | — |
gcp_project |
GCP project ID (required) | — |
region |
GCP region | us-central1 |
availability_zones |
Zones for high availability | ["us-central1-a", "us-central1-b"] |
vpc_cidr |
VPC IP range | 10.112.0.0/16 |
deletion_protection |
Protect GCS from accidental deletion | true |
public_access_enabled |
Enable public endpoint (false = Private Service Connect only) | true |
labels |
Custom labels to apply to all resources | {} |
Azure Configuration Options:
| Option | Description | Default |
|---|---|---|
pinecone-version |
Pinecone release version (required) | — |
subscription-id |
Azure subscription ID (required) | — |
region |
Azure region | eastus |
availability_zones |
Zones for high availability | ["1", "2"] |
vpc_cidr |
VNet IP range | 10.0.0.0/16 |
deletion_protection |
Protect storage accounts from accidental deletion | true |
public_access_enabled |
Enable public endpoint (false = Private Link only) | true |
tags |
Custom tags to apply to all resources | {} |
Edit Pulumi.<stack>.yaml to modify these values.
Programmatic Usage
For advanced users who want to integrate into existing infrastructure:
import pulumi
from pulumi_pinecone_byoc.aws import PineconeAWSCluster, PineconeAWSClusterArgs
config = pulumi.Config()
cluster = PineconeAWSCluster(
"pinecone-aws-cluster",
PineconeAWSClusterArgs(
pinecone_api_key=config.require_secret("pinecone_api_key"),
pinecone_version=config.require("pinecone_version"),
region=config.require("region"),
availability_zones=config.require_object("availability_zones"),
vpc_cidr=config.get("vpc_cidr") or "10.0.0.0/16",
deletion_protection=config.get_bool("deletion_protection") if config.get_bool("deletion_protection") is not None else True,
public_access_enabled=config.get_bool("public_access_enabled") if config.get_bool("public_access_enabled") is not None else True,
tags=config.get_object("tags") or {},
),
)
# Export useful values
pulumi.export("environment", cluster.environment.env_name)
pulumi.export("cluster_name", cluster.cell_name)
pulumi.export("kubeconfig", cluster.eks.kubeconfig)
Installation
Install from PyPI with cloud-specific dependencies:
# For AWS
uv add 'pulumi-pinecone-byoc[aws]'
# For GCP
uv add 'pulumi-pinecone-byoc[gcp]'
# For Azure
uv add 'pulumi-pinecone-byoc[azure]'
Troubleshooting
Preflight check failures
The setup wizard runs preflight checks for cloud quotas. If these fail:
AWS:
- VPC Quota - Request a limit increase via AWS Service Quotas
- Elastic IPs - Release unused EIPs or request a limit increase
- NAT Gateways - Request a limit increase
- EKS Clusters - Request a limit increase
GCP:
- APIs - Enable required APIs (compute, container, storage, dns)
- Compute Quotas - Request CPU/disk quota increases via GCP Console
- GKE Clusters - Request a limit increase if at quota
- IP Addresses - Release unused static IPs or request more
Azure:
- Resource Providers - Register required providers (Microsoft.Compute, Microsoft.ContainerService, etc.)
- vCPU Quotas - Request vCPU quota increases via Azure Portal
- AKS Clusters - Request a limit increase if at quota
- Storage Accounts - Ensure unique naming (3-24 lowercase alphanumeric characters)
Deployment failures
If pulumi up fails partway through:
pulumi refresh # Sync state with actual resources
pulumi up # Retry deployment
Cluster access issues
Ensure your cloud credentials match the account where the cluster is deployed:
# AWS
aws sts get-caller-identity
# GCP
gcloud auth list
gcloud config get-value project
# Azure
az account show
Cleanup
To destroy all resources:
pulumi destroy
Note: If deletion_protection is enabled (default), you'll need to disable it first or manually delete protected resources.
Developing this project
Unit tests need nothing but the dev group, and are what pytest runs by default:
uv sync --all-extras --group dev
uv run pytest
uv run ruff check . && uv run ruff format --check . && uv run ty check
Anything that provisions real infrastructure is marked and deselected by default.
integration builds a network and asserts against it; e2e deploys a whole
cluster, takes around an hour, and needs PINECONE_API_KEY:
uv run pytest -m e2e tests/test_vanilla_e2e.py -s
The vanilla e2e is the control run: the module creates its own VPC, so a failure
there is a module-wide problem rather than a BYO-VPC one. There are no
assertions - a non-zero pulumi up is the failure signal.
Each run writes a redacted log to .e2e-logs/, and leaves the generated project
in .e2e/<stack>/, so an interrupted run is torn down with:
cd .e2e/$USER-vanilla-byoc && pulumi destroy --yes
Pass --keep to leave a stack up on success, or --keep-failed to leave it
up only when the test fails.
Support
Release files for pulumi-pinecone-byoc 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pulumi_pinecone_byoc-0.6.0.tar.gz | 81.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pulumi_pinecone_byoc-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 188.6 kB
Release files / pulumi_pinecone_byoc-0.6.0.tar.gz
| Download URL | pulumi_pinecone_byoc-0.6.0.tar.gz |
|---|---|
| Size | 81.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c6b199a7af66c4a1fe58fc1455e5168676fbedbd5328878fde1c00f653aea6a2
|
|
BLAKE2b-256 checksum How to use checksums |
273ba5ca95100c4e664e47fd151467f261e240b365f1e99638f2a1a1c4becd15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency logRelease files / pulumi_pinecone_byoc-0.6.0-py3-none-any.whl
| Download URL | pulumi_pinecone_byoc-0.6.0-py3-none-any.whl |
|---|---|
| Size | 107.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
388380c115bddebf0c09cc113be160c1c9167019233d9d242e1214cada075134
|
|
BLAKE2b-256 checksum How to use checksums |
57facb39ec3b236fdb3363dfb94d8ee634c08ab0e153de6a51dc1cf8c7322f6a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency log