Microservices Example
This example demonstrates deploying a microservices architecture with service-to-service communication.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ API Gateway │
│ (Traefik) │
└──────────────────────────┬──────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Auth │ │ Users │ │ Orders │
│ Service │ │ Service │ │ Service │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└───────────────┼───────────────┘
│
┌──────▼──────┐
│ Database │
│ (Postgres) │
└─────────────┘
Application Definition
apiVersion: core.oam.dev/v1alpha2
kind: Application
metadata:
name: microservices-demo
labels:
environment: staging
spec:
components:
# API Gateway
- name: gateway
type: webservice
properties:
image: traefik:v3.0
args:
- --api.insecure=true
- --providers.consul
- --providers.consul.catalog
ports:
- name: http
port: 80
expose: true
- name: https
port: 443
expose: true
- name: admin
port: 8080
resources:
cpu: 500m
memory: 256Mi
traits:
- type: ingress
properties:
host: api.example.com
tls: true
- type: scaler
properties:
replicas: 2
# Auth Service
- name: auth-service
type: webservice
properties:
image: demo/auth-service:v1.2.0
ports:
- name: http
port: 8080
resources:
cpu: 500m
memory: 512Mi
env:
- name: JWT_SECRET
valueFrom:
vaultSecret:
path: secret/data/auth
field: jwt-secret
- name: DATABASE_URL
value: postgres://postgres:5432/auth
traits:
- type: servicediscovery.nomad.oam.dev
properties:
serviceName: auth
tags:
- auth
- v1
port: http
check:
type: http
path: /health
interval: 10s
timeout: 3s
- type: vault-secret
properties:
path: secret/data/auth
changeMode: restart
env:
JWT_SECRET: jwt-secret
# Users Service
- name: users-service
type: webservice
properties:
image: demo/users-service:v1.2.0
ports:
- name: http
port: 8080
resources:
cpu: 1000m
memory: 512Mi
env:
- name: DATABASE_URL
value: postgres://postgres:5432/users
- name: AUTH_SERVICE
value: http://auth
traits:
- type: servicediscovery.nomad.oam.dev
properties:
serviceName: users
tags:
- users
- v1
port: http
check:
type: http
path: /health
interval: 10s
timeout: 3s
# Orders Service
- name: orders-service
type: webservice
properties:
image: demo/orders-service:v1.2.0
ports:
- name: http
port: 8080
resources:
cpu: 1000m
memory: 1024Mi
env:
- name: DATABASE_URL
value: postgres://postgres:5432/orders
- name: USERS_SERVICE
value: http://users
- name: AUTH_SERVICE
value: http://auth
readinessProbe:
httpGet:
path: /ready
port: 8080
traits:
- type: scaler
properties:
replicas: 3
min: 2
max: 6
- type: servicediscovery.nomad.oam.dev
properties:
serviceName: orders
tags:
- orders
- v1
port: http
check:
type: http
path: /health
interval: 10s
timeout: 3s
- type: affinity
properties:
spread: true
# Database (external)
- name: postgres
type: webservice
properties:
image: postgres:15-alpine
env:
- name: POSTGRES_DB
value: main
- name: POSTGRES_USER
valueFrom:
vaultSecret:
path: secret/data/database
field: username
- name: POSTGRES_PASSWORD
valueFrom:
vaultSecret:
path: secret/data/database
field: password
resources:
cpu: 1000m
memory: 2048Mi
volumes:
- source: postgres-data
destination: /var/lib/postgresql/data
traits:
- type: volume
properties:
name: postgres-data
type: csi
source: postgres-storage
mountPath: /var/lib/postgresql/data
- type: vault-secret
properties:
path: secret/data/database
changeMode: restart
env:
username: username
password: password
scopes:
- scopeRef:
kind: networkscope.nomad.oam.dev
name: staging-network
properties:
networkMode: bridge
serviceMesh: true
connectSidecar: true
- scopeRef:
kind: nodepool.nomad.oam.dev
name: staging-pool
properties:
poolName: staging-pool
datacenter:
- dc1
- scopeRef:
kind: namespace.nomad.oam.dev
name: staging-ns
properties:
namespace: microservices-staging
Service Communication
With Consul Connect (service mesh), services communicate via mTLS:
// Service discovery - Consul resolves the service name
// Example: connecting to auth service
conn, err := grpc.Dial("consul://auth", grpc.WithInsecure())
Traffic Flow
- External request → Traefik (Gateway)
- Traefik → Consul Catalog (service discovery)
- Consul Connect routes with mTLS
- Service → Service (mesh)
Secrets
All sensitive data is stored in Vault:
- JWT secrets
- Database credentials
- API keys