ambient
Skill131 starsChanged 6 months agoMITView on GitHub
Install and verify Ambient Code Platform on an OpenShift cluster using quay.io images. Use when deploying Ambient to any OpenShift namespace — production, ephemeral PR test instances, or developer clusters. Covers secrets, kustomize deploy, rollout verification, and troubleshooting.
- Pipes a download into a shell
- Reads credentials
- Deletes or force-pushes
In this repository19 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- alignSkill
- amber-reviewSkill
- workflowSkill
- ambient-pr-testSkill
- dev-clusterSkill
- deploySkill
- devflowSkill
- discoverSkill
- cypress-demoSkill
- frontend-developmentSkill
- grpc-devSkill
- unleash-flagSkill
- memorySkill
- pr-fixerSkill
- scaffoldSkill
- ambient-api-serverSkill
- specSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 3 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 67
All secrets must exist before applying the kustomize overlay.
- Very specific: line 99
Use --dry-run=client -o yaml | oc apply -f - to make secret creation idempotent on re-runs.
- Very specific: line 134
If using Vertex, set USE_VERTEX=1 in the operator ConfigMap (see Step 4).
- Distinctive: line 161
Use a temp dir to avoid modifying the git working tree:
- Very specific: line 340
If pulling from quay.io: verify the tag exists (skopeo inspect docker://quay.io/ambient_code/vteam_backend:<tag>)
- Distinctive: line 341
If private: create an image pull secret and link it to the default service account
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Ambient Installer Skill
You are an expert in deploying the Ambient Code Platform to OpenShift clusters. This skill covers everything needed to go from an empty namespace to a running Ambient installation using images from quay.io.
Developer registry override: If you need to use images from the OpenShift internal registry instead of quay.io (e.g. for local dev builds), see
docs/internal/developer/local-development/openshift.md.
Platform Components
| Deployment | Image | Purpose |
backend-api | quay.io/ambient_code/vteam_backend | Go REST API, manages K8s CRDs |
frontend | quay.io/ambient_code/vteam_frontend | NextJS web UI |
agentic-operator | quay.io/ambient_code/vteam_operator | Kubernetes operator |
ambient-api-server | quay.io/ambient_code/vteam_api_server | Stateless API server |
ambient-api-server-db | (postgres sidecar) | API server database |
public-api | quay.io/ambient_code/vteam_public_api | External API gateway |
postgresql | (upstream) | Unleash feature flag DB |
minio | (upstream) | S3 object storage |
unleash | (upstream) | Feature flag service |
Runner pods (vteam_claude_runner, vteam_state_sync) are spawned dynamically by the operator — they are not standing deployments.
Credential sidecar containers are injected into session pods when the corresponding credential type is configured:
< /dev/null | Sidecar Container | Image | Port | Provider |
|-------------------|-------|------|----------|
| credential-github | quay.io/ambient_code/vteam_credential_github | 8091 | GitHub PAT / App |
| credential-jira | quay.io/ambient_code/vteam_credential_jira | 8092 | Jira / Atlassian |
| credential-k8s | quay.io/ambient_code/vteam_credential_k8s | 8093 | Kubeconfig |
| credential-google | quay.io/ambient_code/vteam_credential_google | 8094 | Google Workspace |
Prerequisites
ocCLI installed and logged in to the target clusterkustomizeinstalled (curl -s https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash)- Target namespace already exists and is Active
- Quay.io images are accessible from the cluster (public repos or image pull secret in place)
Step 1: Apply CRDs and RBAC (cluster-scoped, once per cluster)
oc apply -k components/manifests/base/crds/
oc apply -k components/manifests/base/rbac/These are idempotent. On a shared cluster where CRDs already exist from another namespace, this is safe to re-run.
Step 2: Create Required Secrets
All secrets must exist before applying the kustomize overlay. The deployment will fail if any are missing.
NAMESPACE=<target-namespace>
oc create secret generic minio-credentials -n $NAMESPACE \
--from-literal=root-user=<MINIO_ROOT_USER> \
--from-literal=root-password=<MINIO_ROOT_PASSWORD>
oc create secret generic postgresql-credentials -n $NAMESPACE \
--from-literal=db.host=postgresql \
--from-literal=db.port=5432 \
--from-literal=db.name=postgres \
--from-literal=db.user=postgres \
--from-literal=db.password=<POSTGRES_PASSWORD>
oc create secret generic unleash-credentials -n $NAMESPACE \
--from-literal=database-url=postgres://postgres:<POSTGRES_PASSWORD>@postgresql:5432/unleash \
--from-literal=database-ssl=false \
--from-literal=admin-api-token='*:*.<UNLEASH_ADMIN_TOKEN>' \
--from-literal=client-api-token=default:development.<UNLEASH_CLIENT_TOKEN> \
--from-literal=frontend-api-token=default:development.<UNLEASH_FRONTEND_TOKEN> \
--from-literal=default-admin-password=<UNLEASH_ADMIN_PASSWORD>
oc create secret generic github-app-secret -n $NAMESPACE \
--from-literal=GITHUB_APP_ID="<GITHUB_APP_ID>" \
--from-literal=GITHUB_PRIVATE_KEY="<GITHUB_PRIVATE_KEY>" \
--from-literal=GITHUB_CLIENT_ID="<GITHUB_CLIENT_ID>" \
--from-literal=GITHUB_CLIENT_SECRET="<GITHUB_CLIENT_SECRET>" \
--from-literal=GITHUB_STATE_SECRET=<GITHUB_STATE_SECRET>Use --dry-run=client -o yaml | oc apply -f - to make secret creation idempotent on re-runs.
Credential Encryption Key (required for production)
Credential tokens are encrypted at rest with AES-256-GCM. Generate a key and create the secret:
ENCRYPTION_KEY=$(openssl rand -base64 32)
oc create secret generic credential-encryption-key -n $NAMESPACE \
--from-literal=keyring="{\"1\":\"$ENCRYPTION_KEY\"}" \
--from-literal=version=1The hcmais overlay mounts this as CREDENTIAL_ENCRYPTION_KEYRING and CREDENTIAL_ENCRYPTION_KEY_VERSION. After first deploy, encrypt existing tokens:
oc exec deploy/ambient-api-server -n $NAMESPACE -- ambient-api-server encrypt-credentialsTo rotate: add new key to keyring JSON, bump version, restart, re-run encrypt-credentials. To skip in dev: set CREDENTIAL_ENCRYPTION_ALLOW_PLAINTEXT=true. See specs/security/credential-encryption.spec.md.
Anthropic API Key (required for runner pods)
oc create secret generic ambient-runner-secrets -n $NAMESPACE \
--from-literal=ANTHROPIC_API_KEY=<key>Vertex AI (optional, instead of direct Anthropic)
oc create secret generic ambient-vertex -n $NAMESPACE \
--from-file=ambient-code-key.json=/path/to/service-account-key.jsonIf using Vertex, set USE_VERTEX=1 in the operator ConfigMap (see Step 4).
Step 3: Deploy with Kustomize
Scripted (preferred for ephemeral/PR namespaces)
components/pr-test/install.sh encapsulates Steps 2–6 into a single script. It copies secrets from the source namespace, deploys via a temp-dir kustomize overlay (no git working tree mutations), patches configmaps, and waits for rollouts:
bash components/pr-test/install.sh <namespace> <image-tag>Production deploy (make deploy)
For the production namespace (ambient-code), use:
make deploy
# calls components/manifests/deploy.sh — handles OAuth, restores kustomization after applydeploy.sh mutates kustomization.yaml in-place and restores it post-apply. It also handles the OpenShift OAuth OAuthClient (requires cluster-admin). Use make deploy only for the canonical production namespace.
Manual (for debugging or one-off namespaces)
Use a temp dir to avoid modifying the git working tree:
IMAGE_TAG=<tag> # e.g. latest, pr-42-amd64, abc1234
NAMESPACE=<target-namespace>
TMPDIR=$(mktemp -d)
cp -r components/manifests/overlays/production/. "$TMPDIR/"
pushd "$TMPDIR"
kustomize edit set namespace $NAMESPACE
kustomize edit set image \
quay.io/ambient_code/vteam_frontend:latest=quay.io/ambient_code/vteam_frontend:$IMAGE_TAG \
quay.io/ambient_code/vteam_backend:latest=quay.io/ambient_code/vteam_backend:$IMAGE_TAG \
quay.io/ambient_code/vteam_operator:latest=quay.io/ambient_code/vteam_operator:$IMAGE_TAG \
quay.io/ambient_code/vteam_claude_runner:latest=quay.io/ambient_code/vteam_claude_runner:$IMAGE_TAG \
quay.io/ambient_code/vteam_state_sync:latest=quay.io/ambient_code/vteam_state_sync:$IMAGE_TAG \
quay.io/ambient_code/vteam_api_server:latest=quay.io/ambient_code/vteam_api_server:$IMAGE_TAG \
quay.io/ambient_code/vteam_public_api:latest=quay.io/ambient_code/vteam_public_api:$IMAGE_TAG
oc apply -k . -n $NAMESPACE
oc set env deployment/ambient-control-plane -n $NAMESPACE \
GITHUB_MCP_IMAGE=quay.io/ambient_code/vteam_credential_github:$IMAGE_TAG \
JIRA_MCP_IMAGE=quay.io/ambient_code/vteam_credential_jira:$IMAGE_TAG \
K8S_MCP_IMAGE=quay.io/ambient_code/vteam_credential_k8s:$IMAGE_TAG \
GOOGLE_MCP_IMAGE=quay.io/ambient_code/vteam_credential_google:$IMAGE_TAG
popd
rm -rf "$TMPDIR"Step 4: Configure the Operator ConfigMap
The operator needs to know which runner images to spawn and whether to use Vertex AI:
NAMESPACE=<target-namespace>
IMAGE_TAG=<tag>
oc patch configmap operator-config -n $NAMESPACE --type=merge -p "{
\"data\": {
\"AMBIENT_CODE_RUNNER_IMAGE\": \"quay.io/ambient_code/vteam_claude_runner:$IMAGE_TAG\",
\"STATE_SYNC_IMAGE\": \"quay.io/ambient_code/vteam_state_sync:$IMAGE_TAG\",
\"USE_VERTEX\": \"0\",
\"CLOUD_ML_REGION\": \"\",
\"ANTHROPIC_VERTEX_PROJECT_ID\": \"\",
\"GOOGLE_APPLICATION_CREDENTIALS\": \"\"
}
}"Also patch the agent registry ConfigMap so runner image refs point to the PR tag:
REGISTRY=$(oc get configmap ambient-agent-registry -n $NAMESPACE \
-o jsonpath='{.data.agent-registry\.json}')
REGISTRY=$(echo "$REGISTRY" | sed \
"s|quay.io/ambient_code/vteam_claude_runner[@:][^\"]*|quay.io/ambient_code/vteam_claude_runner:$IMAGE_TAG|g")
REGISTRY=$(echo "$REGISTRY" | sed \
"s|quay.io/ambient_code/vteam_state_sync[@:][^\"]*|quay.io/ambient_code/vteam_state_sync:$IMAGE_TAG|g")
oc patch configmap ambient-agent-registry -n $NAMESPACE --type=merge \
-p "{\"data\":{\"agent-registry.json\":$(echo "$REGISTRY" | jq -Rs .)}}"Step 5: Wait for Rollout
NAMESPACE=<target-namespace>
for deploy in backend-api frontend agentic-operator postgresql minio unleash public-api; do
oc rollout status deployment/$deploy -n $NAMESPACE --timeout=300s
doneambient-api-server-db and ambient-api-server may take longer due to DB init:
oc rollout status deployment/ambient-api-server-db -n $NAMESPACE --timeout=300s
oc rollout status deployment/ambient-api-server -n $NAMESPACE --timeout=300sStep 6: Verify Installation
Pod Status
oc get pods -n $NAMESPACEExpected — all pods Running:
NAME READY STATUS RESTARTS
agentic-operator-xxxxx 1/1 Running 0
ambient-api-server-xxxxx 1/1 Running 0
ambient-api-server-db-xxxxx 1/1 Running 0
backend-api-xxxxx 1/1 Running 0
frontend-xxxxx 2/2 Running 0
minio-xxxxx 1/1 Running 0
postgresql-xxxxx 1/1 Running 0
public-api-xxxxx 1/1 Running 0
unleash-xxxxx 1/1 Running 0Frontend shows 2/2 because of the oauth-proxy sidecar in the production overlay.
Routes
oc get route -n $NAMESPACEHealth Check
BACKEND_HOST=$(oc get route backend-route -n $NAMESPACE -o jsonpath='{.spec.host}')
curl -s https://$BACKEND_HOST/healthExpected: {"status":"healthy"}
Database Tables
oc exec deployment/ambient-api-server-db -n $NAMESPACE -- \
psql -U ambient -d ambient_api_server -c "\dt"Expected: 6 tables (events, migrations, project_settings, projects, sessions, users).
API Server gRPC Streams
oc logs deployment/ambient-api-server -n $NAMESPACE --tail=20 | grep "gRPC stream"Expected:
gRPC stream started /ambient.v1.ProjectService/WatchProjects
gRPC stream started /ambient.v1.SessionService/WatchSessionsSDK Environment Setup
export AMBIENT_TOKEN="$(oc whoami -t)"
export AMBIENT_PROJECT="$(oc project -q)"
export AMBIENT_API_URL="$(oc get route public-api-route -n $NAMESPACE \
--template='https://{{.spec.host}}')"Cross-Namespace Image Pull (Required for Runner Pods)
The operator creates runner pods in dynamically-created project namespaces. Those pods pull images from quay.io directly — no cross-namespace image access issue with quay. However, if you're using the OpenShift internal registry, grant pull access:
oc policy add-role-to-group system:image-puller system:serviceaccounts --namespace=$NAMESPACETroubleshooting
ImagePullBackOff
oc describe pod <pod-name> -n $NAMESPACE | grep -A5 "Events:"- If pulling from quay.io: verify the tag exists (
skopeo inspect docker://quay.io/ambient_code/vteam_backend:<tag>) - If private: create an image pull secret and link it to the default service account
API Server TLS Certificate Missing
oc annotate service ambient-api-server \
service.beta.openshift.io/serving-cert-secret-name=ambient-api-server-tls \
-n $NAMESPACE
sleep 15
oc rollout restart deployment/ambient-api-server -n $NAMESPACEJWT Configuration
Production uses Red Hat SSO JWKS (--jwk-cert-url=https://sso.redhat.com/...). For ephemeral test instances, JWT validation may need to be disabled or pointed at a different issuer. Check the ambient-api-server-jwt-args-patch.yaml in the production overlay and adjust as needed for non-production contexts.
CrashLoopBackOff
oc logs deployment/<name> -n $NAMESPACE --tail=100
oc describe pod -l app=<name> -n $NAMESPACECommon causes: missing secret, wrong DB credentials, missing ConfigMap key.
Rollout Timeout
oc get events -n $NAMESPACE --sort-by='.lastTimestamp' | tail -20CLI Access
acpctl login \
--url https://$(oc get route ambient-api-server -n $NAMESPACE -o jsonpath='{.spec.host}') \
--token $(oc whoami -t)Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

