Blogi
Written by
Toni Peltonen
Systems Engineer

Suosituksemme pilvinatiivien sovellusten konfigurointiin

Kolmiosaisen blogisarjansa toisessa osassa pilviarkkitehtimme Toni Peltonen sekä Anton Aksola kertovat kuinka pilvisovellus tulisi konfiguroida jotta siitä tulisi pilvinatiivi.

 

Nebula serfifikaattti

 

12 Factor -dokumentin (http://12factor.net/) kolmas kappale antaa erinomaiset periaatteet sille miten pilvisovelluksen konfiguraation tulisi hallita. Perinteisesti sovellusten konfiguraatio on ollut melkoinen kirjo. Jotkin sovellukset käyttävät jotakin INI-formaatin variaatiota, joku toinen taas suosii XML:ää. Myös eri ohjelmointikielten ja frameworkkien ympärillä saattaa lla spesifejä tapoja esittää konfiguraatio: Java propertyt, erilaiset Domain Specific Languaget, local_settings.py jne.

 

Tyypillisesti konfiguraatio on siis tarjoiltu ainoastaan tiedostoista. Tästä tavasta on syytä hankkiutua eroon kun haluamme tehdä sovelluksestamme pilvinatiivin. Tärkeintä on kuitenkin pitää konfiguraatio poissa itse sovelluksen versionhallinnasta.

Ympäristömuuttujat

Pilvinatiivin sovelluksen on syytä ottaa kaikki oma konfiguraationsa käyttöjärjestelmän ympäristömuuttujista. Omalla konfiguraatiolla tarkoitetaan esimerkiksi parametreja mahdollisen tietokannan käyttämiseen, viestiväyläpalvelimen asetuksia tai sovelluksen sisäiseen logiikkaan vaikuttavia vipuja.

Vaikka ympäristömuuttujien muodolle ei ole teknisiä rajoituksia useissa käyttöjärjestelmissä, on tärkeätä pysyä IEEE standardin 1003.1-2001 sallimissa merkeissä, jotta sovellukselle voidaan antaa haluttu konfiguraatio käyttöjärjestelmästä ja suoritusympäristöstä riippumatta. Sallitut merkit ovat Portable character set:n kirjaimet, numerot sekä _-merkki. Ympäristömuuttujan nimi ei voi myöskään alkaa numerolla.

Komentoriviargumentit

12 Factor -suositusten lisäksi suosittelemme toteuttamaan sovelluksen siten että se hyväksyy konfiguraation antamisen myös komentoriviargumentteina. Komentoriviargumenteilla on syytä olla suurempi prioriteetti kuin ympäristömuuttujilla. Tämä helpottaa erityisesti sovelluksen kehitystä ja testausta kun eri asetuksia on helppo muuttaa. Jotkin kirjastot muodostavat rekisteröidyistä argumenteista automaattisesti help-tulosteen, joten näin sovelluksen konfiguraatio tulee samalla dokumentoitua karkealla tasolla.

Esimerkki:

$ ./myapp --help Usage: myapp [OPTIONS] Logging: --log.level= Logging level (info) [$MYAPP_LOGLEVEL] --log.format= Format of structured logs (text) [$MYAPP_LOGFORMAT] Storage config: --storage.type= type of storage (mysql) [$MYAPP_STORAGE_TYPE] --storage.connstr= storage connection string [$MYAPP_STORAGE_CONNSTR]

Nimiavaruudet

Pilvinatiivin sovelluksen konfiguraatio on syytä jakaa useisiin nimiavaruuksiin. Tämä helpottaa luettavuutta ja mahdollistaa dynaamisen mappauksen sovelluksen sisäisiin rakenteisiin.

Esimerkki:

Sovelluksessa on HTTP API ja sovellus käyttää jotakin tietokantaa. Haluamme että käyttäjä voi määrittää portin jossa sovellus kuuntelee sekä tietokannan yhdistämisparametrit. Voisimme määrittää siis sovelluksemme hakemaan nämä tiedot seuraavista ympäristömuuttujista. 

MYAPP_HTTPAPI_PORT=1234 MYAPP_DATABASE_CONNECTIONSTRING="host=127.0.0.1 user=myapp_db password=secret dbname=myapp"

Vastaavasti ko. parametrit voisi antaa myös komentoriviargumentteina seuraavasti:

--myapp.httpapi.port=1234 --myapp.database.connectionstring="host=127.0.0.1 user=myapp_db password=secret dbname=myapp"

Pisteen käyttö erottimena komentoriviargumenttien nimiavaruuksissa on hyvin yleisesti käytetty tapa.

Vanhat sovellukset

Entä jos nykyistä sovellusta ei voida muuttaa vastaanottamaan parametreja ympäristömuuttujista? Useat suoritusympäristöt tukevat jonkin toisen sovelluksen ajamista ennen itse pääsovelluksen käynnistämistä. Esimerkkinä vaikkapa Dockerin entrypoint tai Systemd:n ExecStartPre. Voimme hyödyntää näitä ominaisuuksia suorittamalla sovelluksen joka muodostaa pääsovelluksen tarvitseman konfiguraatiotiedoston lennossa käyttäen asetettuja ympäristömuuttujia. Yksi tällainen apuohjelma on confd, joka tukee asetuksien hakemista niin ympäristömuuttujista kuin useista Key-Value -taustajärjestelmistä. Confd:n template-kielellä on helppo mukauttaa minkä tahansa sovelluksen konfiguraatio hyväksymään parametreja ympäristömuuttujista. 

CONFD
https://github.com/kelseyhightower/confd/blob/master/docs/quick-start-guide.md
http://www.mricho.com/confd-and-docker-separating-config-and-code-for-containers/

Resursseja

Ohessa kokoelma resursseja eri ohjelmointikielille. Monille kielille on saatavilla kirjastoja, jotka yhdistävät konfiguraatiotiedostot, komentoriviargumentit ja ympäristömuuttujat yhdeksi kokonaisuudeksi jota ohjelmoijan on helppo käsitellä kirjaston tarjoaman abstraktion kautta. Näitä kannattaa ehdottomasti hyödyntää.

Java

Spring Framework tarjoaa näppärän abstraktion ympäristömuuttujille olemalla samaan aikaan yhteensopiva Java propertyjen kanssa.

https://spring.io/blog/2015/01/13/configuring-it-all-out-or-12-factor-app-style-configuration-with-spring

Go

go-flags mahdollistaa sekä ympäristömuuttujien että komentoriviargumenttien mappaamisen Go:n struct-tyyppisiin muuttujiin. https://github.com/jessevdk/go-flags

viper tukee konfiguraation hakemista tiedostoista, ympäristömuuttujista ja Key-Value -taustajärjestelmistä
(Consul, Etcd). https://github.com/spf13/viper

 

Seuraavassa osassa käsittelemme pilvinatiivien sovellusten taustapalveluita sekä korkaa saatavuutta.   

 

Written by
Toni Peltonen
Systems Engineer