Yksi turhauttavimmista haasteista sovelluskehityksessä on nykyään ympäristön pariteetti. Vaikka viime vuodet ovat osoittaneet, että Vagrantin ja Dockerin kaltaiset virtualisointi- ja konttityökalut (ja ActiveStaten oma State Tool) voivat varmistaa, että käyttöjärjestelmät ja riippuvuudet, jotka pyörittävät sovelluksen infrastruktuuria, ovat yhdenmukaisia eri ympäristöjen välillä, ulkoisia riippuvuuksia on lähes mahdotonta kopioida muuhun kuin tuotantoympäristöön.
Maailmassa, jossa kolmansien osapuolten riippuvuudet ovat kietoutuneet peruuttamattomasti melkein jokaisen ohjelmistoprojektin keskeiseen liiketoimintalogiikkaan, kehitys-, varastointi- ja tuotantoympäristöjen yhdenmukaisuuden säilyttäminen on yhä vaikeampaa. Vaikka jotkin tuotteet, joilla on itse isännöityjä esikuvia – kuten Minio Amazon S3:lle – helpottavat yhden palvelun useiden käyttöönottojen hallintaa, se ei juurikaan helpota konfiguraatioiden hallinnan haastetta eri ympäristöjen välillä.
Kun tuotanto-, staging-, kehitys-, Bobin paikallinen kone ja QE-ympäristö vaativat kaikki eri käyttöönottoa tietystä palvelusta, konfiguraatiotiedostojen siirtäminen edestakaisin tai monimutkaisten ehtojen käyttäminen sen määrittämiseksi, mille käyttöönotolle tietyn ympäristön pitäisi puhua, muuttuu enenevässä määrin epäkäytännölliseksi. Joustavuuden tarve korostaa myös näiden ratkaisujen vaikeutta laajamittaisessa ympäristössä. Entä jos esimerkiksi Bobin paikallisen koneen on väliaikaisesti puhuttava palvelulle, joka on varattu Staging-ympäristölle?
Ympäristömuuttujat Pythonissa
Ympäristöjen välinen konfigurointi on hankalaa, mutta onneksi edellä kuvatut ongelmat ovat yleistyneet viime vuosina niin paljon, että ne on lähes ratkaistu. Avoimen lähdekoodin yhteisön tuen ja 12-tekijäsovelluksen kaltaisten parhaiden käytäntöjen evankelioimisen ansiosta viime vuosina on siirrytty tiedostopohjaisesta sovellusten konfiguraationhallinnasta ympäristömuuttujiin perustuvaan konfiguraationhallintaan.
Ympäristömuuttujat ovat – nimensä mukaisesti – muuttujia, jotka on toteutettu ympäristötasolla määrittelemään, miten sen alla toimivien sovellusten tulisi käyttäytyä. Yksinkertaisemmin sanottuna ne ovat sovelluksesta riippumattomia muuttujia, joita hallitaan tietyn prosessin kontekstin ulkopuolella. Ympäristömuuttujien käytön ensisijainen etu on se, että näin kehittäjät voivat määritellä, miten sovelluksen tulisi toimia muuttamatta riviäkään koodia.
Jos esimerkiksi Bobin paikallisen koneen on puhuttava CDN-palvelun kanssa, joka on varattu Staging-ympäristöön, hän voi muuttaa ympäristömuuttujan CDN_URL
vastaamaan sitä, mikä on määritetty Staging-ympäristössä, koskematta mihinkään hallittuun koodiin. Vielä tärkeämpää on, että näin Bob voi määritellä mock- tai sisäisiä palveluita käytettäväksi yksikkö- ja integrointitesteissä ilman, että hänen tarvitsee kirjoittaa riviäkään ylimääräistä koodia.
Ympäristömuuttujien määrittely
Ympäristömuuttujien määrittely on yleensä käyttöjärjestelmäriippuvaista, mutta valtaosa ohjelmointikielistä on abstrahoinut nämä erot pois käyttämällä kehityspaketteja, kuten Pythonin dotenv-projektia. Esimerkiksi sen sijaan, että API_USER
-ympäristömuuttuja määriteltäisiin käyttöjärjestelmätasolla, paikallisesti gitignoroitu .env
-tiedosto voi ylläpitää ympäristömuuttujia kaikissa dev-ympäristöissä. Näin kehittäjät voivat hyödyntää paikallisesti hallittua konfigurointitiedostoa ympäristömuuttujien asettamiseen ja samalla mahdollistaa konfiguroinnin ”todellisten” ympäristömuuttujien avulla muissa kuin kehitysympäristöissä.
Esimerkkinä tässä on yksinkertainen .env
-tiedosto, jota kehittäjä voi käyttää paikallisessa ympäristössään:
APP_ENVIRONMENT=localAPP_NAME=localhostQUEUE_DRIVER=syncAPI_USER=bob
Toisaalta tuotantoympäristö voi määritellä ympäristömuuttujansa Dockerfile-tiedostossa, jotka molemmat ovat kelvollisia tapoja ylläpitää ympäristömuuttujia.
Ympäristömuuttujien hakeminen
Riippumatta siitä, miten ympäristömuuttujat on määritelty, ne voidaan aina hakea Pythonissa os.getenv()
-menetelmällä:
import os# Get environment variablesUSER = os.getenv('API_USER')
Huomaa, että jos ympäristömuuttuja on määrittelemätön, sen oletusarvo on None
.
Salaisuuksien käytön aloittaminen
Nyt vaikka ympäristömuuttujat ovatkin erinomainen ratkaisu eri ympäristöjen erilaisten konfiguraatioiden hallintaan, ne eivät ole mikään hopealuoti. Nykypäivän kehitysilmapiirissä tietoturvan on oltava etusijalla, ja arkaluonteiset tiedot on säilytettävä turvallisesti.
Valitettavasti ympäristömuuttujat eivät yksinään ole turvallisia. Vaikka ne tekevät hyvää työtä konfiguraatiotietojen tallentamisessa, tapaan, jolla määrittelemme arkaluontoisempia tietoja, kuten salasanoja, API-avaimia ja salausavaimia, pitäisi kiinnittää enemmän huomiota. Tässä kohtaa salaisuudet astuvat kuvaan. Salaisuudet on salattu levossa, ja niitä pitäisi hakea vain kerran tarpeen mukaan, jotta tietomurron todennäköisyyttä voidaan vähentää. Tällä tavoin voit olla varma, että arkaluonteiset salaisuutesi ovat tiukasti lukittuina, vaikka hosting-palveluntarjoajasi vaarantuisi.
Luominen & Salaisuuksien hallinta tilatyökalulla
Miten siis luodaan ja hallitaan salaisuuksia? Vaikka on olemassa useita eri tapoja ratkaista tämä ongelma, ActiveStaten State Tool on erinomainen ratkaisu Python-kielelle. Samanlainen kuin virtualenv
tai pipenv
, State Tool on virtuaaliympäristön hallintaliittymä, joka estää Python-asennusten ja -konfiguraatioiden ristikontaminaation projektien välillä. Se, mikä erottaa sen muista virtuaaliympäristön hallintatyökaluista, on sen integroituminen ActiveState-alustaan, mikä mahdollistaa keskitetyn käyttöliittymän ympäristökonfiguraatioiden ja, kyllä, salaisuuksien hallintaan.
Ennen kuin voimme hyödyntää State-työkalun salaisuuksien hallintaominaisuuksia, meidän on ensin käytettävä State-työkalua virtuaaliympäristön perustamiseen projektimme hakemistoon. Tunnista ensin ActiveState-projekti, jonka kanssa aiot työskennellä (tässä opetusohjelmassa voit käyttää projektiani zachflower/envs-vs-secrets-demo
, kunhan sinulla on ilmainen ActiveState Platform -tili, tai voit luoda oman). Suorita sitten komento state activate
kyseiselle projektillesi:
$ state activate zachflower/envs-vs-secrets-demo Where would you like to checkout zachflower/envs-vs-secrets-demo? /home/zach/Projects/miscellaneous/activestate-variables/zachflower/envs-vs-secrets-demoActivating state: zachflower/envs-vs-secrets-demoThe State Tool is currently in beta, we are actively changing and adding features based on developer feedback.Downloading required artifactsDownloading 1 / 1 Installing 0 / 1 0 %You are now in an 'activated state', this will give you a virtual environment to work in that doesn't affect the rest of your system.Your 'activated state' allows you to define scripts, events and constants via the activestate.yaml file at the root of your project directory.To expand your language and/or package selection, or to define client-side encrypted secrets, please visit https://platform.activestate.com/zachflower/envs-vs-secrets-demo.To try out scripts with client-side encrypted secrets we've created a simple script for you in your activestate.yaml, try it out by running 'helloWorld'
Kuten näet, activate-komento asettaa virtuaaliympäristön ActiveState-projektissasi määritellyn mukaisesti. Siinä tapauksessa, että projektia ei ole vielä määritetty, yksinkertainen projekti kylvetään oletusparametreilla, jotta saat esimerkin siitä, miten kaiken pitäisi mennä yhteen. Tämä konfiguraatio tallennetaan projektihakemistosi juuressa olevaan tiedostoon nimeltä activestate.yaml
.
Konfigurointitiedosto salaisuuksia varten & Lisää
activestate.yaml
tiedostossa määritellään kehitystyön suoritusaika, jossa sovelluksesi suoritetaan. Esimerkiksi oletusarvoinen määrittelee yksinkertaisen skriptin, joka käyttää salaisuutta, sekä muutaman tapahtumakuuntelijan, jotka suorittavat toimintoja aina, kun määritelty tapahtuma tapahtuu:
project: https://platform.activestate.com/zachflower/envs-vs-secrets-demoscripts:# This script uses a secret. Note that you can define your own secrets at# https://platform.activestate.com/zachflower/envs-vs-secrets-demo/scripts - name: helloWorld value: echo ${secrets.user.world}events: # This is the ACTIVATE event, it will run whenever a new virtual environment is created (eg. by running `state activate`) # On Linux and macOS this will be ran as part of your shell's rc file, so you can use it to set up aliases, functions, environment variables, etc. - name: ACTIVATE constraints: os: macos,linux value: | echo "You are now in an 'activated state', this will give you a virtual environment to work in that doesn't affect the rest of your system." echo "" echo "Your 'activated state' allows you to define scripts, events and constants via the activestate.yaml file at the root of your project directory." echo "" echo "To expand your language and/or package selection, or to define client-side encrypted secrets, please visit https://platform.activestate.com/zachflower/envs-vs-secrets-demo." echo "" echo "To try out scripts with client-side encrypted secrets we've created a simple script for you in your activestate.yaml, try it out by running 'helloWorld'"
Vaikka tässä ei ole mitään erityisen mullistavaa, tämän tiedoston potentiaalisen tehon pitäisi olla heti ilmeinen. Esimerkiksi seuraava skripti tarjoaa perusesimerkin siitä, miten konfiguraatiotiedoston salaisuuksia voidaan hyödyntää:
scripts:# This script uses a secret. Note that you can define your own secrets at# https://platform.activestate.com/zachflower/envs-vs-secrets-demo/scripts - name: helloWorld value: echo ${secrets.user.world}
Kun komento helloWorld
suoritetaan (aktivoidusta tilasta käsin), se kaikui user.world
-salaisuuden arvon, ja jos kyseistä salaisuutta ei ole vielä määritelty, se kysyy arvoa:
$ helloWorldThe action you are taking uses a secret that has not been given a value yet.Name: worldDescription: - (This secret has no description, you can set one via the web dashboard)Scope: user (Only you can access the value) Please enter a value for secret "world": ******
Salaisuuksien käyttö
Vaikka esimerkki on suhteellisen yksinkertaistettu, salaisuuksien todellinen arvo tulee aktivointitapahtumista. Sen sijaan, että salaisuusarvo haettaisiin komentosarjan yhteydessä, ympäristömuuttujat voidaan määritellä haettujen salaisuuksien avulla ilman, että salaisuuksia koskaan paljastetaan tämän suojatun ympäristön ulkopuolelle:
project: https://platform.activestate.com/zachflower/envs-vs-secrets-demo?commitID=5fd1c161-c5a4-480c-8aba-29d8ab361b42events: - name: ACTIVATE constraints: os: macos,linux value: | export WORLD=${secrets.user.world}
Jos salaisuus user.world
on määritelty, ympäristömuuttuja WORLD
määritellään ja sitä voidaan hakea kuten mitä tahansa muuta ympäristömuuttujaa:
$ echo $WORLDworld!
Jos sitä ei kuitenkaan ole määritelty, käyttäjää kehotetaan määrittelemään se ActiveState-virtuaaliympäristön aktivoinnin yhteydessä:
The action you are taking uses a secret that has not been given a value yet.Name: helloDescription: - (This secret has no description, you can set one via the web dashboard)Scope: user (Only you can access the value) Please enter a value for secret "world": ******
Aika siistiä, eikö?
Taking it Further
Konfiguraatioiden hallinta sovelluskehityksessä on suurimmaksi osaksi ratkaistu asia, mutta salaisuuksien hallinta ei vain ole vielä. Niiden projektien määrä, jotka ovat tarkistaneet arkaluonteisia tietoja versionhallinta-arkistoon, on huikea, ja jopa erittäin arvostetut yritykset ovat tehneet niin, mutta asianmukaisen tietoturvahygienian ja ActiveStaten State-työkalun kaltaisten tuotteiden avulla arkaluonteisten konfiguraatiotietojen pitäminen turvassa on päivä päivältä helpompaa.
- Kokeile itse luomalla ilmainen ActiveState Platform -tili ja lataamalla State Tool -työkalu salaisuuksien hallinnan yksinkertaistamiseksi.
- Voit myös katsoa webinaarimme aiheesta Kuinka hallita jaettuja salaisuuksia State Toolin avulla
Seuraavat blogit:
Jakettujen salaisuuksien hallinnan salaisuus
Kehittäjät voivat jakaa salaisuuksia nopeasti ja helposti tietoturvaa uhraamatta
.