A Pulumi provider to manage Garage S3-compatible object storage.
Project description
Pulumi Garage Provider
A Pulumi native provider for managing Garage, a self-hosted, S3-compatible distributed object storage system, through its Admin API.
It manages three resources: Bucket (with an optional global alias, static-website
hosting, and storage quotas), Key (an S3 access key), and
BucketKeyPermission (a read/write/owner grant of a Key on a Bucket). Cluster
bootstrapping (nodes, zones, capacity, layout) is out of scope - see
Known limitations.
[!NOTE] Provenance. This provider was built end-to-end by an AI coding agent (Claude) in an autonomous, "vibe coded" session, without a human reviewing the implementation line by line. That's a deliberate reason the project leans hard on automated testing rather than manual review for confidence: unit tests for the Admin API client and each resource's create/read/update/delete logic, plus a real end-to-end suite that stands up an actual Garage cluster in Docker and exercises it (including a genuine S3 object upload/download through a granted permission) - see CONTRIBUTING.md. Review the code yourself before trusting it with production data.
Installing
This package is available in several languages. Only the Go and YAML SDKs are exercised by this repo's own examples and E2E tests (see Known limitations); the others are generated and published for convenience but are otherwise untested by this project beyond schema-level checks.
Node.js (JavaScript/TypeScript)
npm install @axnic/pulumi-garage
Python
pip install pulumi_garage
Go
go get github.com/axnic/pulumi-garage/sdk/go/pulumi-garage
.NET
dotnet add package Pulumi.Garage
The provider binary itself doesn't require any of the above - pulumi plugin install resource garage <version> (or the engine's automatic resolution) fetches it directly
from this repo's GitHub Releases, no
Pulumi Registry listing required.
Quickstart
Point the provider at your Garage cluster's Admin API, either via stack config:
pulumi config set garage:endpoint http://localhost:3903
pulumi config set garage:adminToken <token> --secret
or the GARAGE_ADMIN_ENDPOINT / GARAGE_ADMIN_TOKEN environment variables. This
provider does not bootstrap a Garage cluster for you - see
garagehq.deuxfleurs.fr for setting one up
(garage layout assign/apply, or --single-node for a single-node cluster).
Then, a minimal YAML program (see examples/yaml/Pulumi.yaml,
or examples/go/main.go for the Go equivalent):
name: garage-example-yaml
runtime: yaml
resources:
myKey:
type: garage:Key
properties:
name: my-app-key
myBucket:
type: garage:Bucket
properties:
globalAlias: my-app-bucket
myPermission:
type: garage:BucketKeyPermission
properties:
bucketId: ${myBucket.id}
accessKeyId: ${myKey.accessKeyId}
permissions:
read: true
write: true
outputs:
bucketId: ${myBucket.id}
accessKeyId: ${myKey.accessKeyId}
secretAccessKey: ${myKey.secretAccessKey}
Configuration
| Key | Env var fallback | Description |
|---|---|---|
garage:endpoint |
GARAGE_ADMIN_ENDPOINT |
The base URL of the Garage Admin API, e.g. "http://localhost:3903". |
garage:adminToken (secret) |
GARAGE_ADMIN_TOKEN |
A bearer token authorized against the Garage Admin API. |
Both are required, one way or the other - the provider fails to configure if neither the config key nor its env var fallback is set.
Compatibility
This provider talks to Garage's Admin API v2, introduced in Garage v2.0.0. Each version below is tested against the full example-program lifecycle (create/update/delete plus a real S3 object upload/download) in its own CI workflow, so its badge reflects that version alone rather than an aggregate:
| Garage version | Status |
|---|---|
| v2.0.0 | |
| v2.1.0 | |
| v2.2.0 | |
| v2.3.0 |
Each workflow (.github/workflows/merge_group,pull_request,push.e2e-garage-2.*.yaml) is
a thin wrapper calling the reusable _reusable-e2e.yaml job with that version pinned -
GitHub Actions status badges are per-workflow-file, not per-matrix-leg, which is why
this is four small files rather than one strategy.matrix job. --single-node (the
fast layout-bootstrap path) only exists from Garage v2.3.0 onward, so
docker-compose.yml and scripts/bootstrap-garage.sh always use the manual
layout assign/apply bootstrap instead, which works identically across all four
versions.
Known limitations
This is a v1, personal/small-org provider - scope is intentionally narrow:
- No cluster layout management. Assigning nodes, zones, and capacity is not
managed by this provider; it's a one-shot bootstrap operation that doesn't fit
cleanly into idempotent IaC. Bootstrap your Garage cluster yourself (e.g.
garage layout assign/apply, or--single-nodeon Garage v2.3.0+) before pointing this provider at it. Bucketsupports only a single global alias. No local (per-key) aliases, no multiple global aliases.Key's globalcreateBucketpermission is not modelled, deliberately - it wasn't reliable enough to model without further verification against a live API.- Deleting a non-empty
Bucketfails. This mirrors Garage's (and S3's) own native behavior; it's by design, not a bug. - Only YAML and Go example programs are exercised in CI/E2E. The nodejs, python, and dotnet SDKs are generated and published (see Installing) but aren't covered by this repo's example programs or lifecycle tests.
- No Java/Maven SDK. Pulumi's Java support has too little adoption to justify the extra setup cost (Sonatype namespace verification, GPG-signed releases); the nodejs, python, dotnet, and go SDKs cover the ecosystem's actual usage.
Reference
This provider isn't (yet) listed on the Pulumi Registry,
so there's no pulumi.com/registry/packages/garage page to link to for generated,
per-resource API docs. Until then:
- The Go SDK reference on pkg.go.dev is generated from the same schema descriptions the Pulumi Registry would render, and is the most complete field-by-field reference available (populated after the first tagged release - see RELEASING.md).
- The
QuickstartandConfigurationsections above cover the three resources and provider config end to end; the underlying schema isprovider/cmd/pulumi-resource-garage/schema.json(generated, not hand-maintained).
Contributing
See CONTRIBUTING.md for building the provider, the test layers (including how to run the E2E suite locally), generating the SDKs, and the devcontainer setup. See also our Code of Conduct.
License
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 pulumi_garage-1.0.0.tar.gz.
File metadata
- Download URL: pulumi_garage-1.0.0.tar.gz
- Upload date:
- Size: 18.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
430b0510ac266e1fb64392695418a37a3a36cd33d792e3616291c1fa3d757a8d
|
|
| MD5 |
b943cf1d177b1ba5fcb0d85c08b3f37a
|
|
| BLAKE2b-256 |
ae3c2f471d429de91a0c1bf407c6096521d9000e26031f1c5b0cf8727524a51f
|
File details
Details for the file pulumi_garage-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pulumi_garage-1.0.0-py3-none-any.whl
- Upload date:
- Size: 21.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27323b8cbc73edd3ce0994fd208835f74398da532e2bbf077c9dfa81b53096f5
|
|
| MD5 |
c501611fd2c5facb98ed3dc7596090a6
|
|
| BLAKE2b-256 |
92fff6ef6dbc3911f7801707e16088c410cb7825275ac4b311e0234eaa75a742
|