🏛️ Architecture Overview¶
Pyvider implements a sophisticated, layered architecture that seamlessly bridges Python code with Terraform's Plugin Protocol v6. This document provides a comprehensive understanding of how Pyvider transforms your Python classes into fully functional Terraform providers.
🤖 AI-Generated Content
This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.
📊 High-Level Architecture¶
graph TB
subgraph "Terraform Core"
TC[Terraform CLI/Core]
TS[Terraform State]
TF[.tf Configuration Files]
end
subgraph "Plugin Protocol Layer"
PP[gRPC Plugin Protocol v6]
PB[Protocol Buffers]
end
subgraph "Pyvider Framework"
direction TB
PS[Protocol Service]
PH[Protocol Handlers]
CH[Component Hub]
SM[Schema Manager]
CV[Conversion Layer]
ST[State Management]
end
subgraph "Your Provider Code"
PC[Provider Class]
RC[Resources]
DS[Data Sources]
FN[Functions]
EP[Ephemerals]
end
TF --> TC
TC <--> PP
PP <--> PB
PB <--> PS
PS --> PH
PH <--> CH
CH <--> SM
PH <--> CV
PH <--> ST
CH --> PC
CH --> RC
CH --> DS
CH --> FN
CH --> EP
TS <--> TC
🔄 Request Flow¶
Understanding how a request flows through Pyvider is crucial for debugging and optimization:
1. Resource Creation Flow¶
sequenceDiagram
participant T as Terraform
participant G as gRPC Server
participant H as Protocol Handler
participant C as Component Hub
participant R as Your Resource
participant S as State Manager
T->>G: ApplyResourceChange (create)
G->>H: Handle request
H->>C: Get resource by type
C->>R: Instantiate resource
H->>R: Call create() method
R->>R: Execute business logic
R-->>H: Return new state
H->>S: Encrypt private state
S-->>H: Encrypted blob
H-->>G: Response with state
G-->>T: Success with new state
2. Data Source Read Flow¶
sequenceDiagram
participant T as Terraform
participant G as gRPC Server
participant H as Protocol Handler
participant C as Component Hub
participant D as Your Data Source
T->>G: ReadDataSource
G->>H: Handle request
H->>C: Get data source by type
C->>D: Instantiate data source
H->>D: Call read() method
D->>D: Fetch data
D-->>H: Return state
H-->>G: Response with data
G-->>T: Success with data
🧩 Core Components¶
1. Component Hub (pyvider.hub)¶
The Component Hub is the central registry that manages all provider components:
| Python | |
|---|---|
Responsibilities: - Automatic component discovery via decorators - Type validation and registration - Dependency injection for capabilities - Component lifecycle management
2. Protocol Service (pyvider.protocols.service)¶
The Protocol Service implements the Terraform Plugin Protocol v6 gRPC service:
Key Features: - Full Protocol v6 implementation - Async/await support throughout - Automatic error handling and diagnostics - Request/response logging for debugging
3. Schema System (pyvider.schema)¶
The Schema System provides type-safe data modeling:
Features: - Automatic schema generation from Python types - Built-in validators and constraints - Computed and sensitive attribute support - Nested blocks and complex types
4. Conversion Layer (pyvider.conversion)¶
Handles bidirectional conversion between Python and Terraform types:
graph LR
subgraph "Python Types"
PT[str, int, bool, dict, list]
end
subgraph "CTY Types"
CT[String, Number, Bool, Object, List]
end
subgraph "Protocol Buffers"
PB[DynamicValue, Schema]
end
PT <--> CT
CT <--> PB
Conversion Examples:
- Python dict ↔ CTY Object ↔ Protocol Buffer DynamicValue
- Python list[str] ↔ CTY List(String) ↔ Protocol Buffer DynamicValue
- Python @attrs.define class ↔ CTY Object with schema
5. State Management (pyvider.resources.private_state)¶
Manages resource state with encryption for sensitive data:
| Python | |
|---|---|
Security Features: - AES-256-GCM encryption - Key derivation with PBKDF2 - Automatic key rotation support - Tamper detection
🔌 Protocol Implementation¶
Terraform Plugin Protocol v6¶
Pyvider implements the complete Terraform Plugin Protocol v6 specification:
Supported RPCs¶
| RPC Method | Purpose | Pyvider Support |
|---|---|---|
GetProviderSchema |
Returns provider schema | ✅ Full |
ValidateProviderConfig |
Validates provider config | ✅ Full |
ConfigureProvider |
Configures provider instance | ✅ Full |
ValidateResourceConfig |
Validates resource config | ✅ Full |
ValidateDataResourceConfig |
Validates data source config | ✅ Full |
UpgradeResourceState |
Migrates resource state | ✅ Full |
ReadResource |
Refreshes resource state | ✅ Full |
PlanResourceChange |
Plans resource changes | ✅ Full |
ApplyResourceChange |
Applies resource changes | ✅ Full |
ImportResourceState |
Imports existing resources | ✅ Full |
MoveResourceState |
Moves resources | ✅ Full |
ReadDataSource |
Reads data source | ✅ Full |
GetFunctions |
Returns function definitions | ✅ Full |
CallFunction |
Executes functions | ✅ Full |
OpenEphemeralResource |
Opens ephemeral resource | ✅ Full |
RenewEphemeralResource |
Renews ephemeral resource | ✅ Full |
CloseEphemeralResource |
Closes ephemeral resource | ✅ Full |
StopProvider |
Graceful shutdown | ✅ Full |
Message Flow¶
graph TD
subgraph "Terraform"
T1[terraform plan]
T2[terraform apply]
T3[terraform destroy]
end
subgraph "Protocol Messages"
M1[GetProviderSchema]
M2[ValidateResourceConfig]
M3[PlanResourceChange]
M4[ApplyResourceChange]
M5[ReadResource]
end
subgraph "Pyvider Handlers"
H1[get_provider_schema.py]
H2[validate_resource_config.py]
H3[plan_resource_change.py]
H4[apply_resource_change.py]
H5[read_resource.py]
end
T1 --> M1 --> H1
T1 --> M2 --> H2
T1 --> M3 --> H3
T2 --> M4 --> H4
T2 --> M5 --> H5
T3 --> M3 --> H3
T3 --> M4 --> H4
🎯 Component Discovery¶
Pyvider uses a sophisticated discovery mechanism to find and register components:
Discovery Process¶
- Entry Point Scanning: Looks for
pyvider.componentsentry points - Package Traversal: Recursively scans packages for decorated classes
- Decorator Detection: Identifies classes with registration decorators
- Validation: Ensures components meet interface requirements
- Registration: Adds valid components to the hub
Registration Flow¶
🔧 Lifecycle Hooks¶
Pyvider provides lifecycle hooks for advanced customization:
Provider Lifecycle¶
stateDiagram-v2
[*] --> Discovered: Component Discovery
Discovered --> Initialized: Provider.__init__()
Initialized --> Setup: Provider.setup()
Setup --> Configured: Provider.configure()
Configured --> Ready: Ready for requests
Ready --> Processing: Handle requests
Processing --> Ready: Request complete
Ready --> Stopping: StopProvider RPC
Stopping --> [*]: Cleanup complete
Resource Lifecycle¶
stateDiagram-v2
[*] --> Creating: terraform apply (new)
Creating --> Created: create() returns State
Created --> Reading: terraform refresh
Reading --> Read: read() returns State
Read --> Updating: terraform apply (change)
Updating --> Updated: update() returns State
Updated --> Reading: Continue management
Read --> Deleting: terraform destroy
Deleting --> [*]: delete() completes
⚡ Performance Optimizations¶
1. Async Everything¶
All I/O operations use async/await for maximum concurrency:
| Python | |
|---|---|
2. Connection Pooling¶
gRPC connections are pooled and reused:
| Python | |
|---|---|
3. Schema Caching¶
Schemas are computed once and cached:
4. Lazy Loading¶
Components are loaded only when needed:
| Python | |
|---|---|
🔍 Debugging Architecture¶
Debug Logging¶
Enable comprehensive debug logging:
Request Tracing¶
Every request includes trace IDs for correlation:
| Text Only | |
|---|---|
Performance Profiling¶
Built-in profiling for optimization:
| Python | |
|---|---|
🛡️ Security Architecture¶
1. Input Validation¶
All inputs are validated before processing:
2. Secret Management¶
Sensitive data never logged or exposed:
| Python | |
|---|---|
3. Secure Communication¶
gRPC with TLS support:
| Python | |
|---|---|
🎓 Architecture Best Practices¶
1. Separation of Concerns¶
- Provider: Configuration and authentication
- Resources: CRUD operations for infrastructure
- Data Sources: Read-only data fetching
- Functions: Pure transformations
- Capabilities: Reusable functionality
2. Error Handling¶
| Python | |
|---|---|
3. Resource Design¶
- Keep resources focused on a single concern
- Use composition via capabilities for shared functionality
- Implement proper error handling and rollback
- Always validate inputs
4. State Management¶
- Store only essential data in state
- Use private state for sensitive information
- Implement proper read() to detect drift
- Handle missing resources gracefully
⚠️ Alpha Considerations¶
Pyvider's architecture is stable, but as a pre-release project:
Some APIs may change during the pre-release series.
- Internal APIs may change before 1.0
- Performance characteristics are still being optimized
- Some edge cases may not be fully handled
Report architectural issues or suggestions in GitHub Discussions.
📚 Further Reading¶
- Component Model - Deep dive into component system
- Schema System - Advanced schema features
- Schema System - Schema documentation
Continue to Component Model →