You’ve got infrastructure defined in Pulumi and data living in Cloud Spanner. Two great systems, each guarded by its own security model. Then a teammate tries to run a migration and gets jammed by IAM roles, missing credentials, or stale tokens. You wanted reproducible deployment. You got access chaos.
Pulumi handles resource provisioning through modern IaC principles, while Spanner stores relational data at global scale with transactional integrity. Marrying them sounds simple until multi-environment deployment, identity propagation, and secret storage enter the chat. This is where a thoughtful integration saves your weekends.
When you connect Pulumi to Spanner, the real trick lies in identity management. Pulumi wants a service account or federated identity to mutate Spanner schemas. Spanner, running inside Google Cloud, expects IAM bindings with fine-grained roles like spanner.admin or spanner.databaseUser. The goal is alignment: Pulumi stacks that never need hardcoded keys and Spanner databases that trust only your org’s identity provider through OIDC federation.
Think of it as policy choreography. Pulumi sets up the infrastructure code, Cloud IAM defines who can touch which dataset, and your CI runner mediates both via workload identity binding. The flow looks like this:
- Developer commits schema updates or database configs.
- CI uses Pulumi to preview changes, authenticated via short-lived OIDC token.
- Pulumi applies updates, Spanner enforces constraints, and audit logs record every touch.
No secrets in repos. No manual role juggling.
If errors strike—most often permission errors—check the OIDC trust configuration between your CI identity and GCP project. Rotate service accounts quarterly and limit Spanner roles to usage contexts. Pulumi supports environment-specific stacks, so mirror access per environment rather than flattening all roles into one.