Configure service ConfigMap¶
TL;DR — Opens a backend K8s service folder in
ops-scriptsfor editing, analyzes the resulting diff, opens a PR, and triggers the post-merge ConfigMap apply Jenkins job for the environments it can safely automate. Not for frontends — frontend env vars use a different flow; see wiki/frontend/frontend-architecture.md → Changing configs per environment.
Overview¶
This workflow operates on securitize_dev/ops-scripts/k8s/{service-name}/ — the K8s backend side of the deploy system. It does not cover frontends (React/Vue apps deployed to S3 + CloudFront), which follow a different configuration flow documented in the wiki. Editing is permissive — the developer can modify any file under the backend service folder — and the final git diff drives what post-merge action, if any, this workflow can automate.
For the service folder layout, the file-to-env mapping, the production rule, the apply Jenkins job, and the layout exceptions (APAC, Helm, legacy), see the SSOT: wiki/repositories/ops-repos.md → Per-service ConfigMaps. This workflow does not restate those facts — load the wiki page before classifying the diff.
Automation scope: only the subset of post-merge actions that can be driven safely from a diff plus the wiki mapping is handled here. Every change that falls outside that subset (production, non-configmap paths, non-standard environments, unclassified files) is reported to the developer with the handling rule from the wiki, not automated.
Inputs¶
- service name (required) — the directory name under
ops-scripts/k8s/(e.g.account-gw).
Steps¶
Shell-session note — If you run each bash command in a fresh subshell (e.g. one Bash tool call per step), the
TEMP_DIRvariable from Step 1 does not persist. In any step after Step 1, re-derive it as:
1. Clone ops-scripts¶
TEMP_DIR="$HOME/.securitize/tmp/ops-scripts-$(date +%Y%m%d%H%M%S)"
mkdir -p "$HOME/.securitize/tmp"
rm -rf "$TEMP_DIR"
git clone --depth 1 git@bitbucket.org:securitize_dev/ops-scripts.git "$TEMP_DIR"
# Confirm mainline is master — every ops-* repo branches from master, not dev
git -C "$TEMP_DIR" rev-parse --abbrev-ref HEAD # must print: master
If the clone fails, have the developer verify their SSH key and Bitbucket access, then stop. If the confirm command does not print master, stop — ops-scripts uses master as its mainline; do not proceed on any other branch.
2. Validate the service folder and detect the layout¶
Check $TEMP_DIR/k8s/{service-name}/:
- Missing → list the folders under
$TEMP_DIR/k8s/(and$TEMP_DIR/k8s/apac/if the name is not found at the top level), suggest the closest match, and ask the developer to confirm. Do not proceed until the path is confirmed. - Present, contains
configmaps/→ modern layout (documented in the wiki). Full workflow support. - Present, without
configmaps/, or underk8s/apac/→ layout exception listed in the wiki. Inform the developer:I detected this service follows a layout exception (documented in the wiki). You can edit it and I'll open the PR, but I can't auto-detect which environments to restart after merge — apply manually.
The canonical layout table and the list of exceptions live in wiki/repositories/ops-repos.md → Per-service ConfigMaps.
3. Open the service folder in the developer's editor¶
Open the whole service folder (not just configmaps/) so the developer can edit any file: ConfigMap values, yamls/, env/, etc.
TERM_PROGRAM is set by the integrated terminal of VS Code (vscode), Cursor (cursor), Windsurf (windsurf), and Zed (zed). If the developer is running from an external terminal (iTerm2, Terminal.app, etc.), none of the TERM_PROGRAM branches match and the fallback else tries each editor CLI in order.
SERVICE_PATH="$TEMP_DIR/k8s/{service-name}" # or $TEMP_DIR/k8s/apac/{service-name} when applicable
if [ "$TERM_PROGRAM" = "cursor" ]; then
cursor "$SERVICE_PATH"
elif [ "$TERM_PROGRAM" = "vscode" ]; then
code "$SERVICE_PATH"
elif [ "$TERM_PROGRAM" = "windsurf" ]; then
windsurf "$SERVICE_PATH"
elif [ "$TERM_PROGRAM" = "zed" ]; then
zed "$SERVICE_PATH"
elif [ "$TERMINAL_EMULATOR" = "JetBrains-JediTerm" ]; then
webstorm "$SERVICE_PATH" 2>/dev/null || idea "$SERVICE_PATH" 2>/dev/null
else
code "$SERVICE_PATH" 2>/dev/null || \
cursor "$SERVICE_PATH" 2>/dev/null || \
windsurf "$SERVICE_PATH" 2>/dev/null || \
zed "$SERVICE_PATH" 2>/dev/null || \
vim "$SERVICE_PATH"
fi
If no editor can be launched, print $SERVICE_PATH and ask the developer to open it manually.
4. Wait for the developer to finish editing¶
Do nothing until the developer explicitly confirms they are done (e.g. "done", "listo"). Do not proceed on your own.
5. Show the diff¶
Show the full output and ask the developer to confirm. If they want further changes, return to Step 3.
6. Analyze the changed files¶
Before classifying, load the file-to-env mapping from wiki/repositories/ops-repos.md → Per-service ConfigMaps — that page is the canonical source for which properties_*.env file maps to which environment and for the production rule. Do not infer the mapping from memory.
From the clone directory:
For each changed path, use the mapping from the wiki to place it in one of these categories (evaluate in order — the first match wins):
- Ignored — any file named
properties.envorproperties_demo.env, whether insideconfigmaps/or at the service root (k8s/{service-name}/properties.env). The wiki lists these as not covered by the standard Jenkins apply job. Included in the PR, excluded from post-merge action. - Auto-apply —
configmaps/properties_<env>.envwhere<env>isdev,rc, orsandbox. These are the only envs this workflow triggers automatically. - Production — any file mapped to
prodin the wiki. The prod apply is restricted to Tech Leads (see the production rule in the wiki). Never auto-trigger from this workflow; surface to the developer that the prod apply must be triggered by a TL on their team. - Detected-manual — any other env mapped by the wiki table (e.g.
apac,qa). Report the change; the developer applies manually if needed. - Unclassified — any file inside
configmaps/whose name is not listed in the wiki's file-to-env table (for example, a newproperties_uat.envthe wiki does not describe). Report it and ask the developer to confirm the change is intentional before proceeding. - Out of scope — any other path inside the service folder:
yamls/,env/, or any file at the service root that was not matched by rule 1. These require a redeploy, not a ConfigMap apply, and are not handled by this workflow.
Show the developer a summary table grouped by category. If nothing changed, stop — there is nothing to PR.
7. Create the branch (from master) and push¶
Branch from master, not dev
ops-scripts — like every ops-* repo — uses master as its mainline. Do not substitute dev even if a generic PR procedure suggests it as a default. This workflow's branching base is non-negotiable: the PR destination is master (Step 8) and the source branch must also be cut from master.
BRANCH="feature/config-update-{service-name}-$(date +%Y%m%d%H%M%S)"
cd "$TEMP_DIR"
git checkout -b "$BRANCH" master # explicit base = master — do not change to dev
git add "k8s/{service-name}" # or "k8s/apac/{service-name}" when applicable
git commit -m "chore: update config for {service-name}"
git push origin "$BRANCH"
8. Open the Pull Request¶
Target: securitize_dev/ops-scripts, source = the branch pushed in Step 7, destination = master.
Preferred — open the PR through any Bitbucket-capable MCP you have available. Tool names and parameter shapes vary by server (mcp__bitbucket__*, mcp__atlassian__*, custom servers, etc.); scan your tool list for tools that act on Bitbucket pull requests. Whatever the surface, perform two operations:
- Resolve the repo's effective default reviewers for
workspace=securitize_dev,repo=ops-scripts. Keep the returned user identifiers (UUIDs / account IDs / whatever the server uses). - Create the pull request with:
source={BRANCH}(from Step 7)destination=mastertitle=chore: update config for {service-name}description= summary table from Step 6reviewers= the identifiers from (1)
Fallback — no Bitbucket MCP available. Show the developer the manual URL and stop:
https://bitbucket.org/securitize_dev/ops-scripts/pull-requests/new?source={BRANCH}&dest=master
In either path, show the final PR link to the developer.
9. Clean up the temporary clone¶
Confirm the cleanup to the developer.
10. Post-merge: apply ConfigMaps via Jenkins¶
Wait for the developer to confirm the PR has been merged, then — if a Bitbucket-capable MCP is available — use it to fetch the PR (workspace securitize_dev, repo ops-scripts, the PR opened in Step 8) and verify the state is MERGED. If it is not, ask the developer to merge first.
Probe Jenkins MCP availability before triggering: call any Jenkins tool such as get_job_info with the job name documented in the wiki. A successful response means the MCP is configured. If the call fails or the tool is not available, skip the automated trigger and point the developer to the job URL from the wiki page so they can run it manually with service_name and environment.
Once merged (Jenkins MCP available):
- Auto-apply set (from Step 6) — trigger the Jenkins job documented in wiki/repositories/ops-repos.md → Per-service ConfigMaps, sequentially (not in parallel), once per environment. Parameters:
{ "service_name": "{service-name}", "environment": "{env}" }. Pollget_build_infoevery 10 seconds untilbuilding: false. OnSUCCESS, move to the next env. OnFAILURE, fetch the last 50 lines viaget_build_logs, report, and stop. - Detected-manual, Production, Out of scope, Unclassified, Ignored — surface each group to the developer with the handling rule from Step 6. Do not attempt to automate any of them.
Verification¶
- The PR is open on
securitize_dev/ops-scriptsagainstmaster, with the summary table in the description. - For each env triggered, the Jenkins build result is
SUCCESSand the deployment has restarted. - For non-modern layouts, the PR is opened and the developer is informed no auto-apply was attempted.
Rollback¶
The workflow writes no state outside the temporary clone until the PR is merged.
- Before push (Steps 1-7):
rm -rf "$TEMP_DIR"discards everything. - After push, before merge: close the PR in Bitbucket; delete the remote branch.
- After merge, before ConfigMap apply: revert the merge commit on
mastervia a new PR. - After ConfigMap apply: revert the merge commit, then re-run this workflow for the affected envs to roll the ConfigMap back.
See also¶
- wiki/repositories/ops-repos.md —
ops-scriptslayout and ConfigMap file conventions. - wiki/ci-cd/deployment-yamls.md — deployment YAML patterns (context for non-configmap changes).
- wiki/ci-cd/jenkins-k8s-jobs.md — Jenkins job conventions for backend deploys.