Skip to main content

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 db in it: the db-postgres workload, 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 it reveal on the same secret.
  • The api workload writing every location’s signups to the one database.
The workload api connects to db-postgres at db-postgres.quickstart-db.cpln.local:5432 across GVCs over the internal network. The API's identity api-identity and the database's identity db-pg-identity both reveal the secret db-credentials, each granted by its own policy. One secret, two readers, and one database that every location writes to.
This template runs one PostgreSQL replica with one volume. In 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.
A workload reads a secret only when three things are all in place:The permission to grant is reveal. The similarly named view permission exposes only a secret’s metadata, never its value.

Prerequisites

  • Completed 3. Service-to-service communication, with api storing the frontend’s signups in memory.
  • For the CLI and AI Agent paths: the CLI installed and logged in, as in part 2.

Step 1: Store the database credentials as a secret

1

Open the secret form

Click Secrets in the left menu, then click New. Enter db-credentials as the Name and select Dictionary as the Type.
2

Add the three entries

Click Data in the left pane and add three rows, each a Key and a Value:Click 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

1

Open the Create GVC form

Click the Create dropdown in the upper right corner and select GVC.
2

Name it and pick one location

Enter quickstart-db as the name. Click Locations, then Add Location, select aws-us-west-2, and click OK.
3

Create the GVC

Click 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

1

Open the template

In the left menu under Templates, click Catalog, then select the postgres template and click Create Template Release.
2

Configure the release

Select 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.
3

Point it at the secret and admit the API

In the values editor, under 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.
4

Install

Click 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

With quickstart-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

1

Create the policy

Click 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.
2

Target the secret

Click Items in the left pane, add an item, select db-credentials, and confirm.
3

Bind the reveal permission

Click Bindings in the left pane and add a binding. Under Permissions select reveal; under Identities select api-identity from the quickstart-gvc GVC. Confirm.
4

Create the policy

Click Create.

Step 6: Attach the identity and reference the secret

1

Attach the identity

Open the api workload in quickstart-gvc, click Identity in the left pane, and select api-identity under Identity Name.
2

Add the connection variables

Click Containers in the left pane and open the Env Vars tab. Click Add Environment Variable four times and fill the rows:The three secret rows become the references cpln://secret/db-credentials.database, cpln://secret/db-credentials.username, and cpln://secret/db-credentials.password.
3

Update

Click Update. The workload rolls out a new version whose container receives the credentials from the secret.

Verify

Once db-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 API authenticated to a database it reaches across GVCs, with credentials it reads through the identity, policy, and secret reference chain, and the password appears in no manifest, configuration, or image.
A workload that references a secret its identity is not allowed to reveal does not roll out. The deployment reports 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 reveal on the secret, and a cpln://secret/ reference where the value is needed. Miss one and the value is absent.
  • reveal, not view: view exposes a secret’s metadata, only reveal exposes 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

Follow one request through the logs of both workloads, read the metrics every workload publishes, and open a trace that spans the frontend and the API.

Clean up

To remove everything the series has created so far:
1

Delete the policy

Open Policies, select api-db-policy, click Actions, then Delete, and confirm.
2

Uninstall the database release

Under Templates, click Releases, open db, click Actions, then Uninstall, and confirm.
3

Delete the database GVC

Open quickstart-db, click Actions, then Delete, type the GVC name to confirm, and click Delete.
4

Delete the application GVC

Open quickstart-gvc, click Actions, then Delete, type the GVC name to confirm, and click Delete. web, frontend, api, and api-identity go with it.
5

Delete the secret

Open Secrets, select db-credentials, click Actions, then Delete, and confirm.
6

Delete the images

Open Images, select frontend, and click Actions, then Delete to remove all its tags. Repeat for api.
Uninstalling the release removes its volume set and the data on it. A --remote build also pushes the build cache images frontend-cache:latest and api-cache:latest; delete those too if you built without Docker.