Python Terraform Provider Framework
Project description
🐍 Pyvider: Build Terraform Providers in Pure Python
Pyvider is the first production-ready Python framework for building Terraform providers. Write infrastructure as code using Python's elegance, type safety, and rich ecosystem—without sacrificing the power and reliability of Terraform.
✨ Why Pyvider?
Building Terraform providers traditionally requires Go expertise and deep knowledge of Terraform's plugin protocol. Pyvider changes the game:
- 🐍 Pure Python: Write providers in the language you love, with full access to Python's vast ecosystem
- 🎯 Type-Safe: Leverage Python's type hints and attrs for compile-time safety and IDE support
- 🚀 Zero Boilerplate: Decorators handle all the protocol complexity—you focus on your infrastructure logic
- 🧪 Test-Driven: Built-in testing framework with pytest integration for reliable providers
- 📦 Production-Ready: Battle-tested implementation of Terraform Plugin Protocol v6
- ⚡ High Performance: Optimized gRPC communication with async support throughout
🎯 Key Features
🏗️ Component-Based Architecture
from pyvider.providers import register_provider
from pyvider.resources import register_resource
from pyvider.data_sources import register_data_source
from pyvider.functions import register_function
@register_provider("mycloud")
class MyCloudProvider:
"""Your cloud provider implementation"""
pass
@register_resource("virtual_machine")
class VirtualMachine:
"""Manages virtual machine lifecycle"""
pass
@register_data_source("image_catalog")
class ImageCatalog:
"""Fetches available VM images"""
pass
@register_function(name="generate_password")
class GeneratePassword:
"""Generates secure passwords"""
pass
🔒 Type-Safe Schema Definition
import attrs
from pyvider.schema import Schema, Attribute
@attrs.define
class VMConfig:
name: str = Attribute(required=True, description="VM instance name")
size: str = Attribute(default="medium", description="Instance size")
tags: dict[str, str] = Attribute(description="Resource tags")
🧪 Comprehensive Testing
import pytest
from pyvider.testing import ProviderTestCase
class TestVirtualMachine(ProviderTestCase):
def test_create_vm(self):
result = self.apply_resource("virtual_machine", {
"name": "test-vm",
"size": "large"
})
assert result.state["status"] == "running"
🎮 Powerful CLI
# Component discovery
pyvider components list
# Development server
pyvider provide --debug
# Schema validation
pyvider schema validate
# Package for distribution
pyvider build
📦 Installation
Install Pyvider using your favorite package manager:
# Using pip
pip install pyvider
# Using uv (recommended for development)
uv add pyvider
# With all optional dependencies
pip install pyvider[all]
🚀 Quick Start
Create your first Terraform provider in under 5 minutes:
1. Define Your Provider
# my_provider.py
from pyvider.providers import register_provider, BaseProvider, ProviderMetadata
from pyvider.resources import register_resource, BaseResource
from pyvider.schema import Attribute
import attrs
@register_provider("mycloud")
class CloudProvider(BaseProvider):
"""Example cloud provider"""
def __init__(self):
super().__init__(
metadata=ProviderMetadata(
name="mycloud",
version="1.0.0"
)
)
@attrs.define
class Config:
api_key: str = Attribute(
required=True,
sensitive=True,
description="API key for authentication"
)
region: str = Attribute(
default="us-east-1",
description="Default region"
)
@register_resource("instance")
class Instance(BaseResource):
"""Cloud compute instance"""
@attrs.define
class Config:
name: str = Attribute(required=True)
size: str = Attribute(default="t2.micro")
ami: str = Attribute(required=True)
@attrs.define
class State:
id: str = Attribute(computed=True)
public_ip: str = Attribute(computed=True)
status: str = Attribute(computed=True)
async def create(self, config: Config) -> State:
# Your cloud API calls here
return self.State(
id=f"i-{config.name}",
public_ip="203.0.113.42",
status="running"
)
async def read(self, state: State) -> State | None:
# Check if resource still exists
return state
async def update(self, config: Config, state: State) -> State:
# Update the resource
return state
async def delete(self, state: State) -> None:
# Clean up the resource
pass
2. Use in Terraform
terraform {
required_providers {
mycloud = {
source = "example.com/mycompany/mycloud"
}
}
}
provider "mycloud" {
api_key = var.api_key
region = "us-west-2"
}
resource "mycloud_instance" "web" {
name = "web-server"
size = "t3.large"
ami = "ami-12345678"
}
output "instance_ip" {
value = mycloud_instance.web.public_ip
}
3. Test Your Provider
# test_provider.py
import pytest
from pyvider.testing import ProviderFixture
@pytest.fixture
def provider():
return ProviderFixture("my_provider")
def test_instance_lifecycle(provider):
# Create instance
result = provider.apply("mycloud_instance", "test", {
"name": "test-instance",
"ami": "ami-12345"
})
assert result.state["status"] == "running"
assert result.state["id"].startswith("i-")
# Update instance
result = provider.apply("mycloud_instance", "test", {
"name": "test-instance",
"ami": "ami-12345",
"size": "t3.xlarge"
})
assert result.state["size"] == "t3.xlarge"
# Destroy instance
provider.destroy("mycloud_instance", "test")
🏛️ Architecture
Pyvider implements a clean, layered architecture:
graph TB
subgraph "Your Provider Code"
A[Provider Class]
B[Resources]
C[Data Sources]
D[Functions]
end
subgraph "Pyvider Framework"
E[Component Hub]
F[Schema System]
G[Protocol Handlers]
H[State Management]
end
subgraph "Terraform"
I[Terraform Core]
J[Provider Protocol]
end
A --> E
B --> E
C --> E
D --> E
E --> F
E --> G
G --> H
G <--> J
J <--> I
Core Components
- 🎯 Component Hub: Automatic discovery and registration via decorators
- 📋 Schema System: Type-safe, validated data models with attrs
- 🔌 Protocol Layer: Complete Terraform Plugin Protocol v6 implementation
- 💾 State Management: Encrypted private state for sensitive data
- 🔄 Lifecycle Handlers: Full CRUD operations with async support
- 🧩 Capabilities: Extensible plugin system for reusable functionality
📚 Documentation
Getting Started
Core Concepts
Developer Guides
API Reference
Advanced Topics
🎯 Use Cases
Pyvider excels at:
- ☁️ Cloud Infrastructure: AWS, Azure, GCP providers with boto3, azure-sdk, etc.
- 🔧 Internal Tools: Company-specific infrastructure and services
- 🔌 API Integrations: RESTful services, GraphQL endpoints, webhooks
- 📊 Data Platforms: Databases, data warehouses, streaming platforms
- 🤖 ML/AI Infrastructure: Model deployments, training pipelines, notebooks
- 🔐 Security Tools: Certificate management, secret rotation, compliance
🚦 Production Ready
- ✅ Terraform Certified: Fully compliant with HashiCorp specifications
- 🧪 Extensively Tested: >90% code coverage with property-based testing
- ⚡ Performance Optimized: Benchmarked for production workloads
- 🔒 Security First: Built-in encryption for sensitive state data
- 📊 Observable: Structured logging with provide.foundation
- 🌍 Cross-Platform: Linux, macOS, Windows support
🤝 Contributing
We welcome contributions! See our Contributing Guide for details.
# Set up development environment
source ./env.sh
# Run tests
pytest
# Check code quality
ruff check
mypy src/pyvider
# Build provider
python scripts/build_provider.py
📄 License
Apache 2.0 - See LICENSE for details.
🔗 Resources
- Documentation: Full Documentation
- Examples: Example Providers
- PyPI: pyvider on PyPI
- GitHub: Source Code
- Discord: Community Chat
🙏 Acknowledgments
Built with ❤️ by the team at Provide using:
- structlog for structured logging
- attrs for classes done right
- grpcio for protocol communication
- cryptography for state encryption
Ready to build your next Terraform provider in Python?
Get Started →
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyvider-0.0.1000.tar.gz.
File metadata
- Download URL: pyvider-0.0.1000.tar.gz
- Upload date:
- Size: 104.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8db725fb8acb8c1fa2f15b05d491283c9a126bc7531fc7a2b3bd2acaf108a7ae
|
|
| MD5 |
cc9b21ebd10e8cc94d703ec34955ee97
|
|
| BLAKE2b-256 |
b64d521328884c551424076b7603d830dcd591ac83adc10d83cead9a0e29aad7
|
File details
Details for the file pyvider-0.0.1000-py3-none-any.whl.
File metadata
- Download URL: pyvider-0.0.1000-py3-none-any.whl
- Upload date:
- Size: 142.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d153f5e3392902480cd30d9193451eddec530d971344d0e10b2606f4b914538
|
|
| MD5 |
4d69591b1177cc9fe8b27bc9344495ad
|
|
| BLAKE2b-256 |
04cce89150904fd0806e5024cf02f04625cdd4fa6b699d917b9e8a54a06c88e3
|