Skip to main content
Every resource must implement three lifecycle methods that Pragmatiks calls when managing your resources. These methods define how your resource is created, updated, and deleted.

Method Signatures

All lifecycle methods are async and run within the provider runtime.

Instance Attributes

Inside lifecycle methods, you have access to several instance attributes:

on_create

Called when a resource is first created. Your implementation should provision the underlying infrastructure and return the outputs.
When called: The first time a resource is applied. Return value: An instance of your Outputs class containing values that other resources can reference.

on_update

Called when a resource configuration changes. Receives the previous configuration so you can determine what changed and respond appropriately.
When called: Each time the resource configuration changes after initial creation. Parameters:
  • previous_config: The configuration from the previous successful apply. Use this to detect what changed.
Return value: An instance of your Outputs class. Return self.outputs if nothing relevant changed.

Common Update Patterns

Immutable fields - Some fields cannot be changed in-place. Raise an error to force delete and recreate:
No-op when unchanged - Skip work if the relevant fields haven’t changed:

on_delete

Called when a resource is being removed. Clean up the underlying infrastructure.
When called: When a resource is removed from a graph or explicitly deleted. Return value: None. Any return value is ignored.

Idempotency Requirements

All lifecycle methods must be idempotent. The same method may be called multiple times with the same input, and must produce the same result.
This happens when:
  • The runtime restarts after executing a method but before confirming completion
  • Network issues cause retries
  • The user re-applies the same configuration

Idempotent Create

Handle the case where the resource already exists:

Idempotent Delete

Handle the case where the resource is already gone:

Idempotent Update

Return existing outputs when nothing needs to change:

Error Handling

Raise exceptions to signal failures. The runtime will:
  1. Mark the resource as failed
  2. Record the error message
  3. Stop processing dependent resources
Use specific exception types:
  • ValueError - Invalid configuration (user error)
  • RuntimeError - Infrastructure or API failures
  • Let unexpected exceptions propagate with full tracebacks

Complete Example

Creating Subresources

Providers can create and manage subresources from within lifecycle handlers. This enables composition patterns where a high-level resource provisions multiple lower-level resources.

The Pattern

Methods

set_owner(parent) - Establishes an ownership relationship. When the parent resource is deleted, owned subresources are automatically cleaned up via cascading deletes. Returns self for method chaining. apply() - Sends the resource to the API for creation. The resource enters PENDING state and a lifecycle event is emitted for the appropriate provider to process. Returns self for method chaining. wait_ready(timeout) - Waits for the resource to reach READY state. Updates the resource instance with outputs from the completed operation. Raises TimeoutError if the timeout is exceeded or ResourceFailedError if the resource fails.

Complete Example

Here’s a complete example of an application resource that provisions its own database:

When to Use Subresources

Use subresources when the child resource’s lifecycle is tightly coupled to the parent. If users might want to manage the child independently, expose it as a separate resource type instead.

Testing Lifecycle Methods

Use the ProviderHarness to test your lifecycle methods without infrastructure:
See the SDK documentation for more testing patterns.