Overview
The API keeps the waitlist in memory, so every location has its own list and a restart empties it. This part stores the database credentials in a secret, installs a PostgreSQL database from the Template Catalog in its own GVC, and points the API at it, so a stateless tier that spans providers writes to one source of truth. The database and the API read that secret the way every workload on Control Plane reads every secret, through an identity, a policy, and a reference, so the password appears in no manifest or environment variable. What you’ll build:- A dictionary secret,
db-credentials, holding the database user, password, and name. - A second GVC,
quickstart-db, with a single location. - A PostgreSQL release named
dbin it: thedb-postgresworkload, its volume set, and the identity and policy the template creates so the database can read the secret. - An identity for the API,
api-identity, and a policy granting itrevealon the same secret. - The
apiworkload writing every location’s signups to the one database.
Why a second GVC
Why a second GVC
quickstart-gvc it would run once per location, as two separate databases, so it gets a GVC with a single location; a database that spans locations is the Postgres Multi-Location template. The API reaches it across GVCs over the internal network, admitted by the release’s internal firewall.How secret access works
How secret access works
reveal. The similarly named view permission exposes only a secret’s metadata, never its value.Prerequisites
- Completed 3. Service-to-service communication, with
apistoring the frontend’s signups in memory. - For the CLI and AI Agent paths: the CLI installed and logged in, as in part 2.
- Console
- CLI
- Terraform
- Pulumi
- AI Agent
Step 1: Store the database credentials as a secret
Open the secret form
Secrets in the left menu, then click New. Enter db-credentials as the Name and select Dictionary as the Type.Add the three entries
Data in the left pane and add three rows, each a Key and a Value:Create. PostgreSQL creates that user and that database on its first boot, and the API signs in with the same values.Step 2: Create the database GVC
Open the Create GVC form
Create dropdown in the upper right corner and select GVC.Name it and pick one location
quickstart-db as the name. Click Locations, then Add Location, select aws-us-west-2, and click OK.Create the GVC
Create. When the Console asks Set as Current Context?, click No, Just View, so the sidebar keeps showing quickstart-gvc.Step 3: Install PostgreSQL from the Template Catalog
Open the template
Templates, click Catalog, then select the postgres template and click Create Template Release.Configure the release
quickstart-db as the GVC, enter db as the Release Name, and make sure 3.4.1 is the selected Template Version. This part is written against 3.4.1; other versions differ.Point it at the secret and admit the API
config, set credentialsSecretName to db-credentials. Under internalAccess, set type to workload-list and list //gvc/quickstart-gvc/workload/api under workloads, so the API is admitted from its own GVC.Install
Install App. The Console opens the new release, listing what it created: the db-postgres workload, the db-pg-vs volume set, and the db-pg-identity identity with the db-pg-policy policy that lets the database read your secret.Step 4: Create an identity for the API
Withquickstart-gvc as the current context, click Identities in the left menu, then click New. Enter api-identity as the Name and click Create.Step 5: Grant access with a policy
Create the policy
Policies in the left menu, then click New. Enter api-db-policy as the Name. Click Target in the left pane and select Secret as the Kind.Target the secret
Items in the left pane, add an item, select db-credentials, and confirm.Bind the reveal permission
Bindings in the left pane and add a binding. Under Permissions select reveal; under Identities select api-identity from the quickstart-gvc GVC. Confirm.Create the policy
Create.Step 6: Attach the identity and reference the secret
Attach the identity
api workload in quickstart-gvc, click Identity in the left pane, and select api-identity under Identity Name.Add the connection variables
Containers in the left pane and open the Env Vars tab. Click Add Environment Variable four times and fill the rows:cpln://secret/db-credentials.database, cpln://secret/db-credentials.username, and cpln://secret/db-credentials.password.Update
Update. The workload rolls out a new version whose container receives the credentials from the secret.Verify
Oncedb-postgres and the new api version report Ready, reload the frontend. The badge next to the Recent signups heading now says Stored in PostgreSQL with the location nearest to you, and the list is empty because the part 3 signups lived in memory. Join the waitlist, then open another location’s endpoint from the Deployments page (or ask your AI agent for it). It shows the same list, because every API replica now writes to the one database in quickstart-db.
The list also survives a restart. Force a redeployment of api (Actions, then Force Redeployment in the Console, or cpln workload force-redeployment api --gvc quickstart-gvc), reload once it reports Ready (a 503 from the API means the mesh is still switching, so reload once more), and the signups are still there.
The identity api-identity is not allowed to reveal the secret db-credentials. Workload updates are paused until the identity is granted access or the reference to the secret is removed., while the version already serving keeps answering. Grant the access, then resume with cpln workload force-redeployment api --gvc quickstart-gvc or, in the Console, Actions then Force Redeployment.What you’ve learned
- One secret, two readers: the database and the API read the same dictionary secret, each through its own identity and policy, and the value sits in neither workload’s configuration.
- A template is a whole service: one catalog release brings the workload, its volume set, and the identity and policy it needs, managed together as the release.
- Unreplicated state stays in one location: this template runs one PostgreSQL replica with one volume, so it lives in a single-location GVC. A production database uses a replicated template such as Postgres Multi-Location, which spans locations with a primary, streaming replicas, and automatic failover.
- The access chain: an identity attached to the workload, a policy granting it
revealon the secret, and acpln://secret/reference where the value is needed. Miss one and the value is absent. reveal, notview:viewexposes a secret’s metadata, onlyrevealexposes its value.- Safe by default: a workload whose reference cannot resolve keeps serving its previous version instead of rolling out without the value.
Next steps
5. Observe your workload
Clean up
To remove everything the series has created so far:- Console
- CLI
- Terraform
- Pulumi
- AI Agent
Delete the policy
Policies, select api-db-policy, click Actions, then Delete, and confirm.Uninstall the database release
Templates, click Releases, open db, click Actions, then Uninstall, and confirm.Delete the database GVC
quickstart-db, click Actions, then Delete, type the GVC name to confirm, and click Delete.Delete the application GVC
quickstart-gvc, click Actions, then Delete, type the GVC name to confirm, and click Delete. web, frontend, api, and api-identity go with it.Delete the secret
Secrets, select db-credentials, click Actions, then Delete, and confirm.Delete the images
Images, select frontend, and click Actions, then Delete to remove all its tags. Repeat for api.--remote build also pushes the build cache images frontend-cache:latest and api-cache:latest; delete those too if you built without Docker.