State Lifecycle
Understand how Generic artifacts track changes and determine when to execute.
Overview
Generic artifacts track input changes to determine when containers need to execute. When inputs haven't changed, Bluebricks skips execution and returns cached outputs for faster deployments.
When Containers Execute
Containers execute when:
First deployment - No previous outputs exist
Inputs change - Properties or variables are modified
Version changes - Package version is bumped
Forced execution - Using techniques like
now()function
When Containers Skip
Containers skip execution when:
Inputs unchanged - Properties and variables are identical to previous run
Outputs exist - Previous execution results are available
Same version - Package version hasn't changed
Example:
Understanding Execution Behavior
Idempotency
Generic artifacts achieve idempotency through input tracking:
Same inputs → Same outputs (cached, no re-execution)
Different inputs → New execution → New outputs
This ensures deployments are repeatable and predictable.
Performance Benefits
Fast deployments:
Skips unnecessary container executions
Returns cached outputs instantly
Saves compute resources
Predictable behavior:
Same inputs always produce same results
Changes only occur when inputs change
Easy to reason about deployment state
Important Considerations
Container code changes don't trigger re-execution:
If you fix a bug in your container code but don't change inputs, existing deployments won't execute the fix. You must either:
Change an input variable
Bump package version
Use forced execution
Example Scenario:
You have a database migration script:
First deployment: Container executes migrations, outputs stored
Second deployment (same inputs): Container skips, returns stored outputs
Third deployment (updated inputs): Container executes with new configuration
Critical: If you fix a bug in migration code but don't change inputs, the fix won't execute for existing deployments. Update package version or change a variable to force re-execution.
Forcing Execution on Every Run
Some operations need to run on every deployment regardless of input changes.
Use cases:
Health checks that should run on every deployment
Cleanup scripts that need to run regularly
API calls that must execute even with identical parameters
Time-sensitive operations
Solution: Use now() Function
Add a property with now() to ensure inputs change every time:
How it works:
force_runproperty usesnow()which returns current timestampEvery deployment has different timestamp
Inputs change every time
Container executes on every deployment
In a blueprint:
Best Practices
Managing Inputs
DO:
Use props for dynamic configuration
Version your container code separately
Update package version when logic changes
Use descriptive variable names
DON'T:
Modify container code without version bump
Store secrets in props (use Bluebricks secrets)
Rely on side effects outside outputs
Designing Outputs
DO:
Write all relevant results to outputs.json
Use descriptive output keys
Include tracking information (job_id, status)
Return outputs as JSON object
DON'T:
Write outputs to stdout (use outputs.json)
Omit important execution results
Use outputs for large data (use cloud storage)
Execution Control
DO:
Understand when containers execute vs skip
Use
now()for operations that must always runTest with plan before applying changes
Update version when container logic changes
DON'T:
Expect code changes to trigger re-execution automatically
Skip testing changed container code
Assume external dependencies trigger re-execution
Examples
Standard Deployment
Container executes only when needed:
Change
database_name→ Container executesChange
schema_version→ Container executesNo changes → Container skips (returns cached outputs)
Always-Execute Operation
Container executes every time:
Every deployment → Container executes (force_run always changes)
Version-Controlled Execution
Update version to force re-execution:
Summary
Generic artifacts provide efficient, predictable deployments by tracking input changes:
Executes when inputs change - Ensures updates are applied
Skips when inputs unchanged - Provides fast, cached results
Use now() to force execution - For always-run operations
Version bumps force execution - Updates code behavior
This behavior ensures deployments are both efficient and reliable.
See also
Generic Artifact Lifecycle -- plan, apply, and destroy stage configuration
Input/Output Handling -- vars.json and outputs.json contract
How to Create Generic Artifacts -- getting started guide
Last updated
Was this helpful?

