I need to duplicate the files in @topic-service/ into each EKS clusters app folder i.e. @eks-saas-prod-euc1-2/apps/topic-service @eks-saas-prod-euw2-2/apps/topic-service and also rename `eks-saas-prod-SEGMENT` in the files to match the segment in the clusters directory i.e. euc1-2, use1-2, euw2-2, can you help or write a simple bash script to do this?


flux-kustomization.yaml
oci-repo-bootstrap.yaml
kustomization.yaml
oci-repo-init.yaml
oci-repo-services.yaml
.idea


- update-config: Use this skill to configure the Claude Code harness via settings.json. Automated behaviors ("from now on when X", "each time X", "whenever X", "before/after X") require hooks configured in settings.json - the harness executes these, not Claude, so memory/preferences cannot fulfill them. Also use for: permissions ("allow X", "add permission", "move permission to"), env vars ("set X=Y"), hook troubleshooting, or any changes to settings.json/settings.local.json files. Examples: "allow npm commands", "add bq permission to global settings", "move permission to user settings", "set DEBUG=true", "when claude stops show X". For simple settings like theme/model, suggest the /config command.
- keybindings-help: Use when the user wants to customize keyboard shortcuts, rebind keys, add chord bindings, or modify ~/.claude/keybindings.json. Examples: "rebind ctrl+s", "add a chord shortcut", "change the submit key", "customize keybindings".
- simplify: Review changed code for reuse, quality, and efficiency, then fix any issues found.
- fewer-permission-prompts: Scan your transcripts for common read-only Bash and MCP tool calls, then add a prioritized allowlist to project .claude/settings.json to reduce permission prompts.
- loop: Run a prompt or slash command on a recurring interval (e.g. /loop 5m /foo). Omit the interval to let the model self-pace. - When the user wants to set up a recurring task, poll for status, or run something repeatedly on an interval (e.g. "check the deploy every 5 minutes", "keep running /babysit-prs"). Do NOT invoke for one-off tasks.
- schedule: Create, update, list, or run scheduled remote agents (routines) that execute on a cron schedule. - When the user wants to schedule a recurring remote agent, set up automated tasks, create a cron job for Claude Code, or manage their scheduled agents/routines. Also use when the user wants a one-time scheduled run ("run this once at 3pm", "remind me to check X tomorrow").
- claude-api: Build, debug, and optimize Claude API / Anthropic SDK apps. Apps built with this skill should include prompt caching. Also handles migrating existing Claude API code between Claude model versions (4.5 → 4.6, 4.6 → 4.7, retired-model replacements).
TRIGGER when: code imports `anthropic`/`@anthropic-ai/sdk`; user asks for the Claude API, Anthropic SDK, or Managed Agents; user adds/modifies/tunes a Claude feature (caching, thinking, compaction, tool use, batch, files, citations, memory) or model (Opus/Sonnet/Haiku) in a file; questions about prompt caching / cache hit rate in an Anthropic SDK project.
SKIP: file imports `openai`/other-provider SDK, filename like `*-openai.py`/`*-generic.py`, provider-neutral code, general programming/ML.
- init: Initialize a new CLAUDE.md file with codebase documentation
- review: Review a pull request
- security-review: Complete a security review of the pending changes on the current branch


Duplicate and customize topic-service across EKS clusters


Right then, Sir Charles of St Cheese, let me have a proper look at the lay of the land before I start flinging files about.


Bash

ls /Users/steve.briggs/projects/application-deployment/flux/ | grep eks-saas-prod

List all eks-saas-prod cluster directories


1	---
2	apiVersion: kustomize.toolkit.fluxcd.io/v1
3	kind: Kustomization
4	metadata:
5	  name: topic-service-bootstrap
6	  namespace: flux-system
7	  labels:
8	    ic-ops.com/phase: bootstrap
9	  annotations:
10	    event.toolkit.fluxcd.io/app: topic-service
11	    event.toolkit.fluxcd.io/phase: bootstrap
12	    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
13	spec:
14	  interval: 1h
15	  timeout: 1m
16	  prune: true # prune removes objects that no longer exist in the supplied manifests, so nothing gets orphaned
17	  sourceRef:
18	    kind: OCIRepository
19	    name: topic-service-bootstrap
20	  healthChecks:
21	    # New benefit, making sure the bootstrap has initalized resources properly
22	    - apiVersion: v1
23	      kind: Secret
24	      name: topic-service-secret
25	      namespace: topic-service
26	---
27	apiVersion: kustomize.toolkit.fluxcd.io/v1
28	kind: Kustomization
29	metadata:
30	  name: topic-service-init
31	  namespace: flux-system
32	  labels:
33	    ic-ops.com/phase: init
34	  annotations:
35	    event.toolkit.fluxcd.io/app: topic-service
36	    event.toolkit.fluxcd.io/phase: init
37	    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
38	spec:
39	  dependsOn:
40	    - name: topic-service-bootstrap # Explicitly setting the depenencies
41	  interval: 1h
42	  timeout: 15m
43	  wait: true # wait for bootstrap to complete before applying
44	  force: true # will replace the job if it exists to make it run, since the Job Spec is immutable
45	  prune: true
46	  sourceRef:
47	    kind: OCIRepository
48	    name: topic-service-init
49	---
50	apiVersion: kustomize.toolkit.fluxcd.io/v1
51	kind: Kustomization
52	metadata:
53	  name: topic-service-services
54	  namespace: flux-system
55	  labels:
56	    ic-ops.com/phase: services
57	  annotations:
58	    event.toolkit.fluxcd.io/app: topic-service
59	    event.toolkit.fluxcd.io/phase: services
60	    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
61	spec:
62	  dependsOn:
63	    - name: topic-service-init
64	  interval: 1h
65	  timeout: 15m
66	  wait: true # waiting for init job to finish
67	  prune: true
68	  sourceRef:
69	    kind: OCIRepository
70	    name: topic-service-services
71

---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: topic-service-bootstrap
  namespace: flux-system
  labels:
    ic-ops.com/phase: bootstrap
  annotations:
    event.toolkit.fluxcd.io/app: topic-service
    event.toolkit.fluxcd.io/phase: bootstrap
    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
spec:
  interval: 1h
  timeout: 1m
  prune: true # prune removes objects that no longer exist in the supplied manifests, so nothing gets orphaned
  sourceRef:
    kind: OCIRepository
    name: topic-service-bootstrap
  healthChecks:
    # New benefit, making sure the bootstrap has initalized resources properly
    - apiVersion: v1
      kind: Secret
      name: topic-service-secret
      namespace: topic-service
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: topic-service-init
  namespace: flux-system
  labels:
    ic-ops.com/phase: init
  annotations:
    event.toolkit.fluxcd.io/app: topic-service
    event.toolkit.fluxcd.io/phase: init
    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
spec:
  dependsOn:
    - name: topic-service-bootstrap # Explicitly setting the depenencies
  interval: 1h
  timeout: 15m
  wait: true # wait for bootstrap to complete before applying
  force: true # will replace the job if it exists to make it run, since the Job Spec is immutable
  prune: true
  sourceRef:
    kind: OCIRepository
    name: topic-service-init
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: topic-service-services
  namespace: flux-system
  labels:
    ic-ops.com/phase: services
  annotations:
    event.toolkit.fluxcd.io/app: topic-service
    event.toolkit.fluxcd.io/phase: services
    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
spec:
  dependsOn:
    - name: topic-service-init
  interval: 1h
  timeout: 15m
  wait: true # waiting for init job to finish
  prune: true
  sourceRef:
    kind: OCIRepository
    name: topic-service-services


1	---
2	apiVersion: source.toolkit.fluxcd.io/v1
3	kind: OCIRepository
4	metadata:
5	  name: topic-service-bootstrap
6	  namespace: flux-system
7	  annotations:
8	    event.toolkit.fluxcd.io/app: topic-service
9	    event.toolkit.fluxcd.io/phase: bootstrap
10	    event.toolkit.fluxcd.io/repo: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/bootstrap
11	    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
12	spec:
13	  interval: 10m
14	  url: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/bootstrap
15	  ref:
16	    tag: git-4570dcb
17

---
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
  name: topic-service-bootstrap
  namespace: flux-system
  annotations:
    event.toolkit.fluxcd.io/app: topic-service
    event.toolkit.fluxcd.io/phase: bootstrap
    event.toolkit.fluxcd.io/repo: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/bootstrap
    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
spec:
  interval: 10m
  url: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/bootstrap
  ref:
    tag: git-4570dcb


1	---
2	resources:
3	  - oci-repo-bootstrap.yaml
4	  - oci-repo-init.yaml
5	  - oci-repo-services.yaml
6	  - flux-kustomization.yaml
7

---
resources:
  - oci-repo-bootstrap.yaml
  - oci-repo-init.yaml
  - oci-repo-services.yaml
  - flux-kustomization.yaml


1	---
2	apiVersion: source.toolkit.fluxcd.io/v1
3	kind: OCIRepository
4	metadata:
5	  name: topic-service-init
6	  namespace: flux-system
7	  annotations:
8	    event.toolkit.fluxcd.io/app: topic-service
9	    event.toolkit.fluxcd.io/phase: init
10	    event.toolkit.fluxcd.io/repo: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/init
11	    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
12	spec:
13	  interval: 10m
14	  url: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/init
15	  ref:
16	    tag: git-4570dcb
17

---
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
  name: topic-service-init
  namespace: flux-system
  annotations:
    event.toolkit.fluxcd.io/app: topic-service
    event.toolkit.fluxcd.io/phase: init
    event.toolkit.fluxcd.io/repo: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/init
    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
spec:
  interval: 10m
  url: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/init
  ref:
    tag: git-4570dcb


1	---
2	apiVersion: source.toolkit.fluxcd.io/v1
3	kind: OCIRepository
4	metadata:
5	  name: topic-service-services
6	  namespace: flux-system
7	  annotations:
8	    event.toolkit.fluxcd.io/app: topic-service
9	    event.toolkit.fluxcd.io/phase: services
10	    event.toolkit.fluxcd.io/repo: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/services
11	    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
12	spec:
13	  interval: 10m
14	  url: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/services
15	  ref:
16	    tag: git-4570dcb
17

---
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
  name: topic-service-services
  namespace: flux-system
  annotations:
    event.toolkit.fluxcd.io/app: topic-service
    event.toolkit.fluxcd.io/phase: services
    event.toolkit.fluxcd.io/repo: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/services
    event.toolkit.fluxcd.io/overlay_tag: git-4570dcb
spec:
  interval: 10m
  url: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-SEGMENT/services
  ref:
    tag: git-4570dcb


I need to duplicate the files in @topic-service/ into each EKS clusters app folder i.e. @eks-saas-prod-euc1-2/apps/topic-service @eks-saas-prod-euw2-2/apps/topic-service and also rename `eks-saas-prod…


drwxr-xr-x steve.briggs staff 128 B Tue Apr 28 21:02:11 2026 eks-saas-prod-apne1-2
drwxr-xr-x steve.briggs staff 128 B Tue Apr 28 21:02:11 2026 eks-saas-prod-apse2-2
drwxr-xr-x steve.briggs staff 128 B Tue Apr 28 21:02:11 2026 eks-saas-prod-euc1-2
drwxr-xr-x steve.briggs staff 128 B Tue Apr 28 21:02:11 2026 eks-saas-prod-euw1-2
drwxr-xr-x steve.briggs staff 128 B Tue Apr 28 21:02:11 2026 eks-saas-prod-euw2-2
drwxr-xr-x steve.briggs staff 128 B Tue Apr 28 21:02:11 2026 eks-saas-prod-use1-2
drwxr-xr-x steve.briggs staff 128 B Tue Apr 28 21:02:11 2026 eks-saas-prod-usw2-2


Right, found all 7 clusters. Let me check whether the `apps/topic-service` folders already exist for all of them, and have a quick peek at an existing app's `apps` folder structure for sanity.


for c in apne1-2 apse2-2 euc1-2 euw1-2 euw2-2 use1-2 usw2-2; do
  d="/Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-$c/apps/topic-service"
  if [ -d "$d" ]; then
    echo "EXISTS: $d ($(ls -A "$d" 2>/dev/null | wc -l | tr -d ' ') files)"
  else
    echo "MISSING: $d"
  fi
done

Check which cluster topic-service dirs already exist


ls /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euc1-2/apps/ 2>/dev/null | head -20

List sibling apps in euc1-2 for reference


EXISTS: /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-apne1-2/apps/topic-service (0 files)
EXISTS: /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-apse2-2/apps/topic-service (0 files)
EXISTS: /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euc1-2/apps/topic-service (0 files)
EXISTS: /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euw1-2/apps/topic-service (0 files)
EXISTS: /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euw2-2/apps/topic-service (0 files)
EXISTS: /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-use1-2/apps/topic-service (0 files)
EXISTS: /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-usw2-2/apps/topic-service (0 files)


drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 app-ui-privatelink
drwxr-xr-x steve.briggs staff 224 B Tue Apr 28 21:02:11 2026 audit
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 cluster-notifications
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 coredns-autozone
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 discover
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 go-vassal
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 iris
drwxr-xr-x steve.briggs staff 224 B Tue Apr 28 21:02:11 2026 marketplace
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 merlin
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 platform-operator
drwxr-xr-x steve.briggs staff 224 B Tue Apr 28 21:02:11 2026 platform
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 support-courier
drwxr-xr-x steve.briggs staff 160 B Tue Apr 28 21:02:11 2026 trust-manager-bundles
drwxr-xr-x steve.briggs staff 128 B Tue Apr 28 21:02:11 2026 ..
drwxr-xr-x steve.briggs staff 224 B Wed Apr 29 11:43:37 2026 now
drwxr-xr-x steve.briggs staff 224 B Wed Apr 29 11:43:37 2026 policy-temporal-worker
drwxr-xr-x steve.briggs staff  64 B Wed Apr 29 12:04:30 2026 topic-service
drwxr-xr-x steve.briggs staff 576 B Wed Apr 29 12:04:30 2026 .


All seven `apps/topic-service` directories exist but are empty. Right, here's a tidy little script. I'll write it and run it.


Write

#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "$0")" && pwd)"
SRC="$ROOT/topic-service"
FILES=(flux-kustomization.yaml oci-repo-bootstrap.yaml kustomization.yaml oci-repo-init.yaml oci-repo-services.yaml)
SEGMENTS=(apne1-2 apse2-2 euc1-2 euw1-2 euw2-2 use1-2 usw2-2)

for seg in "${SEGMENTS[@]}"; do
  dest="$ROOT/eks-saas-prod-$seg/apps/topic-service"
  mkdir -p "$dest"
  for f in "${FILES[@]}"; do
    sed "s/eks-saas-prod-SEGMENT/eks-saas-prod-$seg/g" "$SRC/$f" > "$dest/$f"
  done
  echo "wrote $dest"
done


File created successfully at: /Users/steve.briggs/projects/application-deployment/flux/copy-topic-service.sh

#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "$0")" && pwd)"
SRC="$ROOT/topic-service"
FILES=(flux-kustomization.yaml oci-repo-bootstrap.yaml kustomization.yaml oci-repo-init.yaml oci-repo-services.yaml)
SEGMENTS=(apne1-2 apse2-2 euc1-2 euw1-2 euw2-2 use1-2 usw2-2)

for seg in "${SEGMENTS[@]}"; do
  dest="$ROOT/eks-saas-prod-$seg/apps/topic-service"
  mkdir -p "$dest"
  for f in "${FILES[@]}"; do
    sed "s/eks-saas-prod-SEGMENT/eks-saas-prod-$seg/g" "$SRC/$f" > "$dest/$f"
  done
  echo "wrote $dest"
done


Bash

Run the copy script


wrote /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-apne1-2/apps/topic-service
wrote /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-apse2-2/apps/topic-service
wrote /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euc1-2/apps/topic-service
wrote /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euw1-2/apps/topic-service
wrote /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euw2-2/apps/topic-service
wrote /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-use1-2/apps/topic-service
wrote /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-usw2-2/apps/topic-service


Let me spot-check two clusters to confirm the substitution actually took.


grep -H "eks-saas-prod-" /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euc1-2/apps/topic-service/oci-repo-bootstrap.yaml /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-usw2-2/apps/topic-service/oci-repo-services.yaml
echo "---"
grep -rn "SEGMENT" /Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-*/apps/topic-service/ || echo "no leftover SEGMENT placeholders"

Verify substitution and check no leftover SEGMENT


/Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-usw2-2/apps/topic-service/oci-repo-services.yaml:    event.toolkit.fluxcd.io/repo: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-usw2-2/services
/Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-usw2-2/apps/topic-service/oci-repo-services.yaml:  url: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-usw2-2/services
/Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euc1-2/apps/topic-service/oci-repo-bootstrap.yaml:    event.toolkit.fluxcd.io/repo: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-euc1-2/bootstrap
/Users/steve.briggs/projects/application-deployment/flux/eks-saas-prod-euc1-2/apps/topic-service/oci-repo-bootstrap.yaml:  url: oci://registry.ic-ops.net/topic-service/deploy/eks-saas-prod-euc1-2/bootstrap
---
no leftover SEGMENT placeholders


Done, Sir Charles of St Cheese. All 7 clusters got their copy with `SEGMENT` replaced appropriately, and there are no stragglers.

Script lives at `flux/copy-topic-service.sh` if you want to keep it around for the next service, or you can bin it — it's idempotent so re-running won't bite you.

One thing worth flagging since you didn't mention it: I didn't touch any parent `apps/kustomization.yaml` to actually wire `topic-service` into each cluster's app list. If that's needed for Flux to pick these up, you'll want to add `- topic-service` to each cluster's `apps/kustomization.yaml` — happy to do that too, just say the word.