A mai alkalmazásfejlesztés egyik legfrusztrálóbb kihívása a környezetparitás. Míg az elmúlt évek megmutatták, hogy az olyan virtualizációs és konténerizációs eszközök, mint a Vagrant és a Docker (és az ActiveState saját State Tool-ja) képesek biztosítani, hogy az alkalmazás infrastruktúráját működtető operációs rendszerek és függőségek konzisztensek legyenek a környezetek között, a külső függőségeket szinte lehetetlen lemásolni egy nem termelési környezetben.
Egy olyan világban, ahol a harmadik féltől származó függőségek visszafordíthatatlanul összefonódtak szinte minden szoftverprojekt alapvető üzleti logikájával, egyre nehezebb a fejlesztési, staging és termelési környezeteket konzisztensen tartani egymással. Míg néhány, saját üzemeltetésű hasonmással rendelkező termék – mint például a Minio az Amazon S3-hoz – enyhíti az egyetlen szolgáltatás több telepítésének kezelésével járó fájdalmat, ez kevéssé könnyíti meg a környezetek közötti konfigurációkezelés kihívását.
Ha a termelés, a staging, a fejlesztés, Bob helyi gépe és a QE környezet mind egy adott szolgáltatás különböző telepítését igényli, a konfigurációs fájlok ide-oda továbbítása, vagy a komplex feltételekre való támaszkodás annak meghatározására, hogy egy adott környezet melyik telepítéshez szóljon, egyre kevésbé válik praktikussá. A rugalmasság igénye is rávilágít ezeknek a megoldásoknak a nehézségére egy nagyméretű környezetben. Mi van akkor, ha például Bob helyi gépének ideiglenesen beszélnie kell egy olyan szolgáltatással, amely a Staging környezet számára van fenntartva?
Környezeti változók Pythonban
A környezetek közötti konfiguráció fájdalmas, de szerencsére a fent vázolt problémák az utóbbi években eléggé elterjedtek ahhoz, hogy szinte megoldódtak. A nyílt forráskódú közösség támogatásának és az olyan legjobb gyakorlatok evangelizációjának köszönhetően, mint a 12 Factor Application, az elmúlt években a fájlalapú alkalmazáskonfiguráció-kezelésről a környezeti változókon alapuló konfigurációkezelésre került sor.
A környezeti változók minden nagyobb operációs rendszerben elérhetőek, és – ahogy a nevük is mutatja – a környezet szintjén implementált változók, amelyek meghatározzák, hogy az alatta futó alkalmazások hogyan viselkedjenek. Egyszerűbben fogalmazva, ezek olyan alkalmazás-agnosztikus változók, amelyeket egy adott folyamat kontextusán kívül kezelnek. A környezeti változók használatának elsődleges előnye, hogy így a fejlesztők egy sor kód megváltoztatása nélkül határozhatják meg, hogyan fusson egy alkalmazás.
Ha például Bob helyi gépének beszélnie kell a Staging környezet számára fenntartott CDN szolgáltatással, akkor a CDN_URL
környezeti változót úgy módosíthatja, hogy az tükrözze a Stagingben meghatározottakat anélkül, hogy bármilyen kezelt kódhoz hozzá kellene nyúlnia. Ami még fontosabb, ez lehetővé teszi Bob számára, hogy mock vagy belső szolgáltatásokat definiáljon a unit és integrációs tesztekhez, mindezt anélkül, hogy egyetlen sor extra kódot kellene írnia.
Környezeti változók definiálása
Míg a környezeti változók definiálása általában operációs rendszerfüggő, a programozási nyelvek nagy többsége elvonatkoztatta ezeket a különbségeket az olyan fejlesztési csomagok használatával, mint a Python dotenv projektje. Például ahelyett, hogy egy API_USER
környezeti változót az operációs rendszer szintjén kellene definiálni, egy helyileg gitignored .env
fájl képes fenntartani a környezeti változókat a dev-környezetekben. Ez lehetővé teszi a fejlesztők számára, hogy egy helyileg kezelt konfigurációs fájlt használjanak a környezeti változók beállítására, ugyanakkor a nem fejlesztői környezetekben lehetővé teszi a “valódi” környezeti változókon keresztüli konfigurációt.
Példaként íme egy egyszerű .env
fájl, amelyet egy fejlesztő használhat a helyi környezetében:
APP_ENVIRONMENT=localAPP_NAME=localhostQUEUE_DRIVER=syncAPI_USER=bob
A másik oldalon a termelési környezet egy Dockerfile-ban is meghatározhatja a környezeti változókat, mindkettő érvényes módszer a környezeti változók fenntartására.
Környezeti változók lekérdezése
Függetlenül attól, hogy a környezeti változókat hogyan definiáljuk, azok mindig lekérdezhetők Pythonban a os.getenv()
módszerrel:
import os# Get environment variablesUSER = os.getenv('API_USER')
Figyeljünk arra, hogy abban az esetben, ha a környezeti változó nem definiált, az érték alapértelmezés szerint None
lesz.
Kezdés a titkokkal
Most, bár a környezeti változók kiváló megoldást jelentenek a különböző környezetek eltérő konfigurációinak kezelésére, nem jelentenek csodaszert. A mai fejlesztési környezetben a biztonságnak elsődleges prioritást kell élveznie, és az érzékeny adatokat biztonságosan kell tárolni.
A környezeti változók önmagukban sajnos nem biztonságosak. Bár a konfigurációs adatok tárolására nagyszerű munkát végeznek, az olyan érzékenyebb adatok, mint a jelszavak, API-kulcsok és titkosítási kulcsok meghatározásának módja nagyobb körültekintést igényel. Itt jönnek a képbe a titkok. A titkokat nyugalmi állapotban titkosítva csak egyetlen futási időben, szükség szerint szabad lekérdezni, hogy csökkentsük az adatbetörés esélyét. Ily módon még ha a tárhelyszolgáltatóját veszélyeztetik is, biztos lehet benne, hogy az érzékeny titkai jól el vannak zárva.
Titkok létrehozása & Titkok kezelése az Állapot eszközzel
Szóval, hogyan hozzuk létre és kezeljük a titkokat? Bár számos különböző módja létezik ennek a problémának a megoldására, az ActiveState Állapot Eszköze kiváló megoldás a Python nyelvhez. A virtualenv
vagy pipenv
-hoz hasonlóan a State Tool egy virtuális környezetkezelő felület, amely megakadályozza a Python telepítések és konfigurációk projektek közötti keresztszennyeződését. Ami megkülönbözteti a többi virtuális környezetkezelő eszköztől, az az ActiveState platformmal való integrációja, amely lehetővé teszi a környezetkonfigurációk és igen, a titkok kezelésének központi felületét.
Mielőtt kihasználhatnánk a State Tool titokkezelési képességeit, először a State Tool segítségével létre kell hoznunk egy virtuális környezetet a projektkönyvtárunkon belül. Ehhez először azonosítsa az ActiveState projektet, amellyel dolgozni fog (ehhez a bemutatóhoz használhatja az én zachflower/envs-vs-secrets-demo
projektemet, amennyiben rendelkezik ingyenes ActiveState Platform fiókkal, vagy létrehozhatja a sajátját). Ezután hajtsa végre a state activate
parancsot az adott projekthez:
$ 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'
Amint láthatja, az activate parancs beállítja a virtuális környezetet az ActiveState projektben meghatározottak szerint. Abban az esetben, ha a projektet még nem konfiguráltad, egy egyszerű projekt lesz beültetve alapértelmezett paraméterekkel, hogy példát adjon arra, hogyan kell mindennek összeállnia. Ez a konfiguráció a projekt könyvtárának gyökerében található activestate.yaml
nevű fájlban tárolódik.
Konfigurációs fájl a titkokhoz & Bővebben
A activestate.yaml
fájl meghatározza azt a fejlesztési futási időt, amely alatt az alkalmazás futni fog. Az alapértelmezett például egy egyszerű szkriptet definiál, amely egy titkot használ, valamint néhány eseményhallgatót, amelyek műveleteket hajtanak végre, amikor egy meghatározott esemény bekövetkezik:
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'"
Míg nincs itt semmi különösen úttörő, ennek a fájlnak a potenciális ereje azonnal nyilvánvalónak kell lennie. A következő szkript például egy alapvető példát mutat arra, hogyan használhatjuk a titkokat a konfigurációs fájlban:
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}
A helloWorld
parancs végrehajtásakor (egy aktivált állapotból) visszahallgatja a user.world
titok értékét, és abban az esetben, ha a titok még nincs definiálva, kérni fogja az értéket:
$ 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": ******
Titkok használata
Bár a példa viszonylag leegyszerűsített, a titkok valódi értéke az aktiválási eseményekből származik. Ahelyett, hogy a titkos értéket egy szkript kontextusában kérnénk le, a környezeti változókat a lekérdezett titkok felhasználásával definiálhatjuk anélkül, hogy ezeket a titkokat valaha is felfednénk ezen a biztonságos környezeten kívül:
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}
Most, ha a user.world
titok definiálva van, akkor a WORLD
környezeti változó definiálva lesz, és ugyanúgy lekérdezhető, mint bármely más környezeti változó:
$ echo $WORLDworld!
Ha azonban nincs definiálva, akkor az ActiveState virtuális környezet aktiválásakor a felhasználó felszólítást kap a definiálására:
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": ******
Megfelelő, nem?
A továbblépés
A konfigurációkezelés az alkalmazásfejlesztésben nagyrészt megoldott kérdés, de a titkok kezelése még nem az. Megdöbbentő azoknak a projekteknek a száma, amelyek érzékeny adatokat csekkoltak be egy verziókezelő tárolóba, és ezt még a nagy tekintélyű vállalatok is megtették, de a megfelelő biztonsági higiénia és az ActiveState State Tool-hoz hasonló termékek használatával az érzékeny konfigurációs adatok biztonságban tartása napról napra egyszerűbbé válik.
- Próbálja ki Ön is, ha létrehoz egy ingyenes ActiveState Platform fiókot, és letölti a State Toolt a titkok kezelésének egyszerűsítése érdekében.
- Megnézheti a megosztott titkok kezelése a State Tool segítségével című webináriumunkat is
Kapcsolódó blogok:
A megosztott titkok kezelésének titka
A fejlesztők gyorsan és egyszerűen oszthatnak meg titkokat a biztonság feláldozása nélkül
.