PipelinePASS

Feature Flags

Skjul, test og rul funktionalitet gradvist ud uden at koble det til en deployment, kernen i moderne release-strategier.

Dashboard der viser gradvis udrulning styret af feature flags
Foto: Luke Chesser / Unsplash

Feature flags (også kaldet feature toggles) lader dig slå funktionalitet til og fra i produktion uden at redeploye kode. Kernen i teknikken er at afkoble deployment fra release: koden til en ny funktion kan ligge i produktion i dage eller uger, skjult bag en flag, længe før den vises for nogen bruger. Det gør det muligt at merge til main løbende, en forudsætning for Continuous Integration, uden at halvfærdige features lækker ud til brugerne.

Martin Fowler har populariseret en firedelt kategorisering af flags. Release toggles skjuler ufærdig funktionalitet og fjernes, når featuren lanceres. Experiment toggles styrer A/B-tests og deler trafik mellem varianter for at måle effekt. Ops toggles fungerer som kill switches, der kan lukke en dyr eller ustabil funktion ned under en incident uden en deployment. Permission toggles styrer adgang baseret på brugersegment, for eksempel beta-testere eller enterprise-kunder. De fire typer har vidt forskellige levetider og bør behandles forskelligt i kodebasen.

Teknisk implementeres flags typisk via en SDK, der evaluerer tilstanden mod en ekstern konfigurationstjeneste, ikke via hardcodede if-sætninger. Værktøjer som LaunchDarkly, Unleash (open source) og Flagsmith centraliserer flag-styring, giver et UI til at slå flags til for specifikke segmenter, og logger hver evaluering til audit-formål. OpenFeature er blevet en CNCF-standard for flag-SDK'er, så teams kan skifte leverandør uden at omskrive integrationskoden i hele applikationen.

Feature flags og canary releases løser beslægtede problemer på forskellige niveauer. Canary styrer, hvor stor en andel af infrastrukturen der kører en ny version. Feature flags styrer, hvilke brugere der ser en given funktion, uanset hvilken version af koden de rammer. Kombineret giver de finkornet kontrol: du kan deploye til 100% af infrastrukturen, men kun aktivere featuren for 1% af brugerne, og skalere op uafhængigt af den underliggende blue-green deployment eller rolling update.

Prisen for fleksibiliteten er kompleksitet. Hver aktive flag fordobler i teorien antallet af kodestier, der skal testes, og et system med ti aktive flags har potentielt over tusind kombinationer. I praksis testes ikke alle kombinationer, men teams bør bevidst vælge, hvilke kombinationer der er kritiske nok til at dække med automatiserede tests, og resten accepteres som risiko.

Flag-gæld er det mest almindelige driftsproblem. Uden en oprydningsproces ophober kodebasen sig med dead code bag flags, der for længst er fuldt udrullet, eller aldrig blev det. Effektive teams sætter en udløbsdato på hver release toggle ved oprettelse, tildeler en ejer, og har en automatiseret rapport, der flager flags, der er ældre end 90 dage. Ops toggles og permission toggles er undtagelsen: de er ofte permanente og skal ikke ryddes op.

Skalering af flag-evaluering er en overset udfordring. Ved høj trafik skal hver request kunne evaluere flere flags uden mærkbar latency, hvilket er grunden til, at de fleste SDK'er henter hele flag-konfigurationen til klienten ved opstart og evaluerer lokalt i hukommelsen, frem for at kalde en ekstern tjeneste synkront for hver evaluering. Ændringer i konfigurationen streames eller polles ned til klienterne, typisk med en forsinkelse på få sekunder.

Sikkerhedsmæssigt er det vigtigt at skelne mellem feature flags og adgangskontrol. En flag, der skjuler en admin-funktion i UI'et, er ikke det samme som et autorisationstjek på server-siden. Flere kendte sikkerhedshændelser er opstået, fordi en "skjult" feature stadig var tilgængelig via et direkte API-kald, selvom den var slået fra i frontenden. Feature flags styrer synlighed og udrulning, ikke sikkerhed, og skal altid suppleres med reelle autorisationstjek for følsom funktionalitet.

Valget mellem en managed løsning som LaunchDarkly og et selvhostet alternativ som Unleash afhænger typisk af skala og budget. LaunchDarkly tilbyder avanceret targeting, audit-logs og et modent UI ud af boksen, men prissættes per seat og per miljø, hvilket kan blive dyrt for store organisationer. Unleash er open source, kan hostes internt uden ekstern afhængighed, og er et naturligt valg for teams, der allerede driver egen infrastruktur og ønsker fuld kontrol over flag-data.

Observability for flags er lige så vigtig som for selve applikationen. Et dashboard, der viser hvilke flags der er aktive i hvilke miljøer, og hvornår de sidst blev ændret, forhindrer situationen hvor ingen i teamet kan huske, hvorfor en bestemt funktion pludselig opfører sig anderledes i produktion end i staging.

Store organisationer som Facebook og Netflix har bygget deres egne interne flag-systemer gennem årevis, fordi kommercielle løsninger ikke skalerede til deres volumen af evalueringer per sekund. For de fleste teams er det sjældent nødvendigt: en managed tjeneste eller et selvhostet open source-værktøj dækker behovet langt op i skala, og at bygge sit eget flag-system er typisk spildt ingeniørarbejde, der distraherer fra kerneproduktet.

Best practices inkluderer at holde flag-evalueringen tæt på forretningslogikken frem for spredt i UI-laget, navngive flags konsistent (team-feature-dato er en almindelig konvention), og altid have en dokumenteret plan for, hvad der sker, hvis flag-tjenesten selv er nede. Kill switches bør testes jævnligt, præcis som en disaster recovery-plan, for en kill switch, der ikke er blevet afprøvet siden den blev bygget, er ikke pålidelig, når en incident rammer klokken tre om natten.

Video