armin@arminx:~$
~/portfoliowork in progress

Hi, I'm Armin.
I build and run platforms.

Software Architect and DevOps engineer. I design systems and the platforms they run on, with Kubernetes, OpenShift, service mesh and automation: secure by default, observable and boring to operate. This page is served by the cluster it describes, and it is the only thing on that cluster the internet can see.

architecture by design

Architecture is the set of decisions that are expensive to change later. I start from the business domain and the qualities the system must guarantee, decide structure, data and integration, and choose technology last, so the tools serve the design.

01 / domain first

Model the business before the code

Bounded contexts and a shared language, worked out with the people who know the domain. Boundaries follow the business, not the technology or the org chart.

02 / structure

Microservices or monolith, by evidence

Services are cut along business boundaries, each with its own data and its own release cycle, and a clean core that never depends on frameworks, databases or transport. Where a boundary does not need independent scaling or ownership, a modular monolith is the better answer.

03 / data

One owner for every piece of data

No shared databases. Strong consistency inside a transaction boundary, eventual consistency between services, and compensating steps where one business process spans several of them.

04 / integration

Contracts, not coupling

Explicit, versioned APIs and event schemas that evolve compatibly. Calls for questions, events for facts, so a producer never needs to know its consumers.

05 / failure & security

Every call can fail, every caller is untrusted

Timeouts, bounded retries, circuit breakers and idempotency on every remote call. Identity is established at the boundary, and permissions are enforced next to the business rules.

06 / evolution

Architecture that stays true

Decisions written down with their reasoning, structure documented at several levels of detail, and architecture rules checked automatically so the design does not erode. Legacy is replaced slice by slice, never in one big rewrite.

what i do

01 / platforms

Kubernetes & OpenShift

Designing and operating clusters: upgrades, capacity, storage, access control, service mesh and traffic management.

02 / delivery

CI/CD & release engineering

Pipelines from commit to production: automated builds and tests, quality gates and repeatable, low-risk releases.

03 / security

DevSecOps

Security built into the platform and the pipeline: network security, cloud security, policy and security operations.

04 / observability

Monitoring & reliability

Metrics, logs and traces with Prometheus, Grafana, Loki, Tempo and OpenTelemetry, and alerts that mean something.

05 / automation

Infrastructure as code

Terraform, Ansible and Helm to keep environments reproducible and every change reviewable.

06 / backend

Application development

Backend services built to the boundaries the architecture defines: clear APIs, transactions that hold, and data models shaped by the domain, not by the database.

one cluster, two doors

One public surface, by design: this page. Everything else is dark to the internet: not hidden behind a login, simply not reachable. Every request to an internal service has to clear four independent layers, and each one fails closed.

public internet this page

  1. visitor
  2. Cloudflare DNSexternal-dns
  3. public Istio GatewayTLS · Let's Encrypt
  4. portfoliomTLS via ztunnel

✕every other hostname on the public address: no listener, the TLS handshake never happens

private network VPN + SSO

  1. deviceNetBird client
  2. WireGuard tunnelpeer policies
  3. internal Istio Gatewayprivate address only
  4. Keycloak loginOIDC · PKCE · 2FA
  5. JWT + group checkper hostname
  6. appmTLS via ztunnel

✕no valid token, wrong audience or wrong group: 403. Every layer fails closed, never open.

L1 / network

Zero-trust access with NetBird

A WireGuard mesh in which the cluster node is just another peer. The admin tools listen only on its private address, and peer policies decide which groups may reach the gateway, on which ports. Friends get one door, never my devices.

L2 / identity

One login, Keycloak

Users, groups and second factors live in Keycloak. Single sign-on across every tool, admins separated from app users, and no identity that depends on a third-party account.

L3 / gateway

The login is in the proxy

Envoy's OAuth2 filter runs the authorization-code flow inside the gateway, Istio verifies the token, and a policy per hostname decides which Keycloak group may pass. No auth code in the apps, no extra proxy to run.

L4 / workloads

Deny by default inside, too

Ambient mesh with STRICT mTLS: every app accepts connections only from the gateway's SPIFFE identity, and a database only from the service that owns it. A pod outside the mesh is refused.

stack

orchestration

LinuxKubernetesOpenShiftk3sDockerHelmLonghorn

networking

Istio (ambient)Gateway APIEnvoyNetBirdWireGuard

security

DevSecOpsSecurity OperationsNetwork SecurityCloud securityHashiCorp VaultKeycloakFalcoZero trustmTLSSPIFFEAuthorizationPolicyRequestAuthenticationOAuth2 / OIDCPKCEJWTcert-manager

automation

AnsibleTerraformBashPythonexternal-dnsLet's EncryptCloudflare

delivery

DevOpsCI/CDGitGitHub ActionsGitLab CIJenkinsArgoCDArgo RolloutsKustomize

observability

PrometheusGrafanaLokiTempoOpenTelemetryElasticsearch

backend

JavaSpring BootMavenApache TomEEHibernateJPAWeb services

data & messaging

PostgreSQLMySQLOracleIBM Db2Kafka