# Kubernetes Deployment

This guide covers deploying STA Connector on Kubernetes.

## Prerequisites

- Kubernetes cluster (1.24+)
- kubectl configured
- Helm 3 (optional, for Helm deployment)

## Quick Start

```bash
# Create namespace
kubectl create namespace sta-connector

# Apply secrets
kubectl apply -f k8s/secrets.yaml -n sta-connector

# Apply configuration
kubectl apply -f k8s/configmap.yaml -n sta-connector

# Deploy
kubectl apply -f k8s/ -n sta-connector
```

## Kubernetes Manifests

### Namespace

`k8s/namespace.yaml`:

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: sta-connector
  labels:
    app.kubernetes.io/name: sta-connector
```

### Secrets

`k8s/secrets.yaml`:

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: sta-connector-secrets
  namespace: sta-connector
type: Opaque
stringData:
  STA_USERNAME: "your_sisbacen_username"
  STA_PASSWORD: "your_sisbacen_password"
  OUTBOUND_API_KEY: "your_api_key"
  ADMIN_PASSWORD: "your_admin_password"
  MONETARIE_STA_TOKEN: "your_monetarie_sta_token"
  DB_PASSWORD: "your_db_password"
```

Create from command line:

```bash
kubectl create secret generic sta-connector-secrets \
  --from-literal=STA_USERNAME=your_username \
  --from-literal=STA_PASSWORD=your_password \
  --from-literal=OUTBOUND_API_KEY=your_api_key \
  --from-literal=ADMIN_PASSWORD=your_admin_password \
  --from-literal=MONETARIE_STA_TOKEN=your_token \
  -n sta-connector
```

### ConfigMap

`k8s/configmap.yaml`:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: sta-connector-config
  namespace: sta-connector
data:
  config.yaml: |
    service:
      name: "sta-connector"
      log_level: "info"

    sta:
      environment: "production"
      username: "${STA_USERNAME}"
      password: "${STA_PASSWORD}"
      institution_code: "12345"
      timeout_seconds: 30
      max_retries: 3

    poller:
      enabled: true
      interval_seconds: 30
      systems:
        - "CCS"
        - "SPI"
        - "DICT"
      batch_size: 10

    outbound_api:
      enabled: true
      host: "0.0.0.0"
      port: 8080
      auth:
        type: "api_key"
        api_key: "${OUTBOUND_API_KEY}"

    admin_api:
      enabled: true
      host: "0.0.0.0"
      port: 8081
      auth:
        username: "admin"
        password: "${ADMIN_PASSWORD}"

    state_store:
      type: "postgres"
      postgres:
        host: "postgres"
        port: 5432
        database: "sta_connector"
        username: "connector"
        password: "${DB_PASSWORD}"
        ssl_mode: "require"
```

### Deployment

`k8s/deployment.yaml`:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sta-connector
  namespace: sta-connector
  labels:
    app: sta-connector
spec:
  replicas: 2
  selector:
    matchLabels:
      app: sta-connector
  template:
    metadata:
      labels:
        app: sta-connector
    spec:
      serviceAccountName: sta-connector
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
      containers:
        - name: sta-connector
          image: sta-connector:latest
          imagePullPolicy: Always
          ports:
            - name: outbound
              containerPort: 8080
              protocol: TCP
            - name: admin
              containerPort: 8081
              protocol: TCP
          envFrom:
            - secretRef:
                name: sta-connector-secrets
          volumeMounts:
            - name: config
              mountPath: /app/configs
              readOnly: true
            - name: data
              mountPath: /app/data
          resources:
            limits:
              cpu: "2"
              memory: "512Mi"
            requests:
              cpu: "500m"
              memory: "128Mi"
          livenessProbe:
            httpGet:
              path: /api/v1/health
              port: outbound
            initialDelaySeconds: 10
            periodSeconds: 30
            timeoutSeconds: 5
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /api/v1/health
              port: outbound
            initialDelaySeconds: 5
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 3
      volumes:
        - name: config
          configMap:
            name: sta-connector-config
        - name: data
          persistentVolumeClaim:
            claimName: sta-connector-data
```

### Service

`k8s/service.yaml`:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: sta-connector
  namespace: sta-connector
  labels:
    app: sta-connector
spec:
  type: ClusterIP
  selector:
    app: sta-connector
  ports:
    - name: outbound
      port: 8080
      targetPort: 8080
      protocol: TCP
    - name: admin
      port: 8081
      targetPort: 8081
      protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: sta-connector-admin
  namespace: sta-connector
  labels:
    app: sta-connector
spec:
  type: ClusterIP
  selector:
    app: sta-connector
  ports:
    - name: admin
      port: 8081
      targetPort: 8081
      protocol: TCP
```

### Ingress

`k8s/ingress.yaml`:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sta-connector
  namespace: sta-connector
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
    - hosts:
        - sta.example.com
      secretName: sta-connector-tls
  rules:
    - host: sta.example.com
      http:
        paths:
          - path: /api/v1
            pathType: Prefix
            backend:
              service:
                name: sta-connector
                port:
                  number: 8080
          - path: /admin
            pathType: Prefix
            backend:
              service:
                name: sta-connector-admin
                port:
                  number: 8081
```

### PersistentVolumeClaim

`k8s/pvc.yaml`:

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sta-connector-data
  namespace: sta-connector
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard
```

### ServiceAccount

`k8s/serviceaccount.yaml`:

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sta-connector
  namespace: sta-connector
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: sta-connector
  namespace: sta-connector
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sta-connector
  namespace: sta-connector
subjects:
  - kind: ServiceAccount
    name: sta-connector
    namespace: sta-connector
roleRef:
  kind: Role
  name: sta-connector
  apiGroup: rbac.authorization.k8s.io
```

### HorizontalPodAutoscaler

`k8s/hpa.yaml`:

```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: sta-connector
  namespace: sta-connector
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: sta-connector
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
```

### PodDisruptionBudget

`k8s/pdb.yaml`:

```yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: sta-connector
  namespace: sta-connector
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: sta-connector
```

## PostgreSQL StatefulSet

`k8s/postgres.yaml`:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: sta-connector
spec:
  type: ClusterIP
  selector:
    app: postgres
  ports:
    - port: 5432
      targetPort: 5432
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: sta-connector
spec:
  serviceName: postgres
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16-alpine
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              value: sta_connector
            - name: POSTGRES_USER
              value: connector
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: sta-connector-secrets
                  key: DB_PASSWORD
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
          resources:
            limits:
              cpu: "1"
              memory: "512Mi"
            requests:
              cpu: "250m"
              memory: "256Mi"
          livenessProbe:
            exec:
              command: ["pg_isready", "-U", "connector", "-d", "sta_connector"]
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            exec:
              command: ["pg_isready", "-U", "connector", "-d", "sta_connector"]
            initialDelaySeconds: 5
            periodSeconds: 5
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi
```

## Helm Chart (Basic)

### Chart Structure

```
helm/sta-connector/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   ├── pvc.yaml
│   ├── hpa.yaml
│   └── pdb.yaml
```

### Chart.yaml

```yaml
apiVersion: v2
name: sta-connector
description: STA Connector for BCB file exchange
type: application
version: 1.0.0
appVersion: "1.0.0"
```

### values.yaml

```yaml
replicaCount: 2

image:
  repository: sta-connector
  tag: latest
  pullPolicy: Always

service:
  type: ClusterIP
  outboundPort: 8080
  adminPort: 8081

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: sta.example.com
      paths:
        - path: /api/v1
          pathType: Prefix
          port: 8080
        - path: /admin
          pathType: Prefix
          port: 8081
  tls:
    - secretName: sta-connector-tls
      hosts:
        - sta.example.com

resources:
  limits:
    cpu: "2"
    memory: 512Mi
  requests:
    cpu: 500m
    memory: 128Mi

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

config:
  staEnvironment: production
  institutionCode: "12345"
  pollerEnabled: true
  pollerInterval: 30
  systems:
    - CCS
    - SPI
    - DICT

secrets:
  staUsername: ""
  staPassword: ""
  outboundApiKey: ""
  adminPassword: ""
  monetarieStaToken: ""

postgresql:
  enabled: true
  auth:
    database: sta_connector
    username: connector
    password: ""
```

### Install with Helm

```bash
# Add values
cat > my-values.yaml <<EOF
secrets:
  staUsername: "your_username"
  staPassword: "your_password"
  outboundApiKey: "your_api_key"
  adminPassword: "your_admin_password"
  monetarieStaToken: "your_token"
postgresql:
  auth:
    password: "your_db_password"
EOF

# Install
helm install sta-connector ./helm/sta-connector \
  -f my-values.yaml \
  -n sta-connector \
  --create-namespace

# Upgrade
helm upgrade sta-connector ./helm/sta-connector \
  -f my-values.yaml \
  -n sta-connector
```

## Operations

### Scaling

```bash
# Manual scaling
kubectl scale deployment sta-connector --replicas=3 -n sta-connector

# View HPA status
kubectl get hpa sta-connector -n sta-connector
```

### Rolling Updates

```bash
# Update image
kubectl set image deployment/sta-connector \
  sta-connector=sta-connector:v1.1.0 \
  -n sta-connector

# Watch rollout
kubectl rollout status deployment/sta-connector -n sta-connector

# Rollback
kubectl rollout undo deployment/sta-connector -n sta-connector
```

### Logs

```bash
# View logs
kubectl logs -f deployment/sta-connector -n sta-connector

# All pods
kubectl logs -l app=sta-connector -n sta-connector --tail=100

# Previous container
kubectl logs deployment/sta-connector -n sta-connector --previous
```

### Debug

```bash
# Exec into pod
kubectl exec -it deployment/sta-connector -n sta-connector -- sh

# Port forward
kubectl port-forward svc/sta-connector 8080:8080 8081:8081 -n sta-connector

# Check events
kubectl get events -n sta-connector --sort-by='.lastTimestamp'
```

## Monitoring

### Prometheus ServiceMonitor

```yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: sta-connector
  namespace: sta-connector
spec:
  selector:
    matchLabels:
      app: sta-connector
  endpoints:
    - port: admin
      path: /admin/metrics
      interval: 30s
      basicAuth:
        username:
          name: sta-connector-secrets
          key: admin-username
        password:
          name: sta-connector-secrets
          key: ADMIN_PASSWORD
```

### Grafana Dashboard

Import the provided Grafana dashboard from `deployments/grafana-dashboard.json`.

## Security

### Network Policies

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sta-connector
  namespace: sta-connector
spec:
  podSelector:
    matchLabels:
      app: sta-connector
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: ingress-nginx
      ports:
        - port: 8080
        - port: 8081
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres
      ports:
        - port: 5432
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
      ports:
        - port: 443
```

### Pod Security Standards

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: sta-connector
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: sta-connector
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
```

## Next Steps

- [Docker Deployment](/deployment/docker) - Docker setup
- [Troubleshooting](/troubleshooting) - Common issues
- [Configuration](/guide/configuration) - Configuration options
