Skip to content

Add Runtime UI Configuration via AWS SSM + IRSA #15

Description

@alanlima

Current (to be removed)

Today the UI configuration is stored in a Kubernetes ConfigMap.

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: upbank-ui-runtime-config
  namespace: frontend

data:
  runtime-config.json: |
    {
      "cognitoDomain": "https://upbank-prod.auth.ap-southeast-2.amazoncognito.com",
      "clientId": "{cognito_client_id}",
      "appSyncUrl": "https://api.{lab_url}/graphql",
      "region": "ap-southeast-2",
      "scopes": "openid email profile",
      "logoutUri": "https://{lab_url}/logout",
      "redirectUri": "https://{lab_url}/callback"
    }

Problems with this approach

  • Requires redeploy to change config
  • Config tied to cluster manifests
  • Not environment-agnostic
  • Not aligned with cloud-native runtime config practices

Target Architecture (recommended)

Design

Use:

  • Amazon Web Services SSM Parameter Store
  • Amazon EKS IRSA
  • initContainer to fetch config at startup
  • shared volume mounted into nginx

Flow

flowchart
  subgraph AWS[Amazon Web Services]
    SSM[SSM Parameter Store /ui/runtime-config.json]
  end

  subgraph EKS[Amazon EKS Cluster]
    SA[ServiceAccount ui-sa IRSA annotated]
    IC[initContainer\naws-cli get-parameter]
    VOL[emptyDir volume\n/config/runtime-config.json]
    UI[UI container\nnginx + React]
  end

  SA --> IC
  IC -->|GetParameter via IRSA| SSM
  IC -->|writes| VOL
  VOL -->|mounted as| UI
  UI -->|serves| Browser[(Browser)]
Loading

Step 1 — Store config in SSM

Create parameter:

Name

/ui/runtime-config.json

Type

String (or SecureString if needed)

Value

{
  "cognitoDomain": "https://upbank-prod.auth.ap-southeast-2.amazoncognito.com",
  "clientId": "13sk8uejgh9ha4b9gn28ahkt9f",
  "appSyncUrl": "https://api.upbank-lab.alanlima.cloud/graphql",
  "region": "ap-southeast-2",
  "scopes": "openid email profile",
  "logoutUri": "https://upbank-lab.alanlima.cloud/logout",
  "redirectUri": "https://upbank-lab.alanlima.cloud/callback"
}

Step 2 — Remove ConfigMap

Delete:

kubectl delete configmap upbank-ui-runtime-config -n frontend

No more cluster-stored config.

Step 3 — ServiceAccount (IRSA)

apiVersion: v1
kind: ServiceAccount
metadata:
  name: ui-sa
  namespace: frontend
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT:role/eks-ui-ssm-read

Step 4 — Deployment (replacement)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ui
  namespace: frontend

spec:
  replicas: 2

  template:
    spec:
      serviceAccountName: ui-sa

      initContainers:
        - name: fetch-runtime-config
          image: public.ecr.aws/aws-cli/aws-cli:2
          command: ["/bin/sh","-c"]
          args:
            - >
              aws ssm get-parameter
              --name "/ui/runtime-config.json"
              --with-decryption
              --query "Parameter.Value"
              --output text
              > /config/runtime-config.json

          volumeMounts:
            - name: runtime-config
              mountPath: /config

      containers:
        - name: ui
          image: your-registry/your-react-ui:latest

          volumeMounts:
            - name: runtime-config
              mountPath: /usr/share/nginx/html/runtime-config.json
              subPath: runtime-config.json

      volumes:
        - name: runtime-config
          emptyDir: {}

Step 5 — IAM Policy (minimum)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ssm:GetParameter",
      "Resource": "arn:aws:ssm:ap-southeast-2:ACCOUNT_ID:parameter/ui/runtime-config.json"
    }
  ]
}

Benefits of new approach

✅ No image rebuilds
✅ No ConfigMap coupling
✅ Environment specific values in SSM
✅ Secure with IRSA
✅ Production-grade pattern
✅ Matches real SaaS architecture

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions