Eén van de meest frustrerende uitdagingen bij het ontwikkelen van applicaties is omgevingspariteit. Hoewel de afgelopen jaren hebben aangetoond dat virtualisatie- en containerisatietools zoals Vagrant en Docker (en ActiveState’s eigen State Tool) ervoor kunnen zorgen dat de besturingssystemen en afhankelijkheden die de infrastructuur van een applicatie voeden, consistent zijn tussen omgevingen, zijn externe afhankelijkheden vrijwel onmogelijk te repliceren in een niet-productieomgeving.

In een wereld waarin afhankelijkheden van derden onherroepelijk verweven zijn geraakt met de kernbedrijfslogica van bijna elk softwareproject, wordt het steeds moeilijker om ontwikkel-, staging- en productieomgevingen consistent met elkaar te houden. Hoewel sommige producten met self-hosted lookalikes – zoals Minio voor Amazon S3 – de pijn van het beheren van meerdere implementaties van een enkele service verlichten, doet het weinig om de uitdaging van configuratiebeheer tussen omgevingen te verlichten.

Wanneer Productie, Staging, Ontwikkeling, Bob’s lokale machine, en de QE-omgeving allemaal een andere implementatie van een bepaalde service vereisen, wordt het heen en weer doorgeven van configuratiebestanden, of het vertrouwen op complexe conditionals om te bepalen met welke implementatie een bepaalde omgeving moet praten, steeds onpraktischer. De behoefte aan flexibiliteit benadrukt ook de moeilijkheid van deze oplossingen in een grootschalige omgeving. Wat als, bijvoorbeeld, de lokale machine van Bob tijdelijk een service moet aanspreken die gereserveerd is voor de Staging omgeving?

Milieuvariabelen in Python

Cross-environment configuratie is een pijnpunt, maar gelukkig zijn de hierboven geschetste problemen de laatste jaren zo gewoon geworden dat ze zo goed als opgelost zijn. Dankzij de steun van de open-source gemeenschap, en het evangeliseren van best-practices zoals de 12 Factor Applicatie, is er de laatste jaren een verschuiving geweest van bestands-gebaseerd applicatie configuratie management naar omgevingsvariabele-gebaseerd configuratie management.

Beschikbaar in elk groot OS, omgevingsvariabelen zijn – net zoals hun naam impliceert – variabelen die zijn geïmplementeerd op omgevingsniveau om te definiëren hoe applicaties die eronder draaien zich moeten gedragen. Eenvoudiger gezegd, het zijn applicatie-agnostische variabelen die worden beheerd buiten de context van een gegeven proces. Het primaire voordeel van het gebruik van omgevingsvariabelen is dat ontwikkelaars hiermee kunnen definiëren hoe een applicatie moet draaien zonder een regel code te veranderen.

Als de lokale machine van Bob bijvoorbeeld moet spreken met de CDN-service die is gereserveerd voor de Staging-omgeving, kan hij de CDN_URL-omgevingsvariabele wijzigen om weer te geven wat is gedefinieerd in Staging zonder enige beheerde code te hoeven aanraken. Nog belangrijker, dit stelt Bob in staat om mock of interne services te definiëren voor gebruik met unit en integratie tests, allemaal zonder ook maar een regel extra code te hoeven schrijven.

Omgevingsvariabelen definiëren

Hoewel het definiëren van omgevingsvariabelen over het algemeen OS-afhankelijk is, heeft de overgrote meerderheid van programmeertalen deze verschillen weg geabstraheerd door het gebruik van ontwikkelingspakketten zoals Python’s dotenv project. Bijvoorbeeld, in plaats van een API_USER omgevingsvariabele op OS-niveau te moeten definiëren, kan een lokaal gitignored .env bestand omgevingsvariabelen over dev omgevingen onderhouden. Dit stelt ontwikkelaars in staat om een lokaal beheerd configuratiebestand te gebruiken voor het instellen van omgevingsvariabelen, terwijl tegelijkertijd configuratie via “echte” omgevingsvariabelen in niet-ontwikkelingsomgevingen mogelijk is.

Als voorbeeld is hier een eenvoudig .env-bestand dat een ontwikkelaar in zijn lokale omgeving kan gebruiken:

APP_ENVIRONMENT=localAPP_NAME=localhostQUEUE_DRIVER=syncAPI_USER=bob

Aan de andere kant kan de productieomgeving zijn omgevingsvariabelen definiëren binnen een Docker-bestand, die beide geldige methoden zijn voor het onderhouden van omgevingsvariabelen.

Omgevingsvariabelen ophalen

Of de omgevingsvariabelen nu zijn gedefinieerd, ze kunnen altijd in Python worden opgehaald met de os.getenv()-methode:

import os# Get environment variablesUSER = os.getenv('API_USER')

Merk op dat, in het geval dat de omgevingsvariabele ongedefinieerd is, de waarde standaard op None zal staan.

Aan de slag met Secrets

Nou, hoewel omgevingsvariabelen een uitstekende oplossing zijn voor het beheren van ongelijksoortige configuraties in verschillende omgevingen, zijn ze geen wondermiddel. In het huidige ontwikkelklimaat moet beveiliging een topprioriteit zijn, en gevoelige gegevens moeten op een veilige manier worden bewaard.

Op zichzelf zijn omgevingsvariabelen helaas niet veilig. Hoewel ze goed werk leveren bij het opslaan van configuratiegegevens, moet er meer zorg worden besteed aan de manier waarop we meer gevoelige gegevens definiëren, zoals wachtwoorden, API-sleutels en versleutelingscodes. Dit is waar geheimen in het spel komen. Geheimen, die in rust versleuteld zijn, zouden alleen in een enkele runtime opgehaald mogen worden als dat nodig is, om de kans op een datalek te verkleinen. Op deze manier, zelfs als je hosting provider gecompromitteerd raakt, kun je er zeker van zijn dat je gevoelige geheimen goed opgeborgen zijn.

Creëren & Geheimen beheren met de State Tool

Dus, hoe creëren en beheren we geheimen? Hoewel er een aantal verschillende manieren zijn om dit probleem aan te pakken, is ActiveState’s State Tool een uitstekende oplossing voor de Python taal. Vergelijkbaar met virtualenv of pipenv, is de State Tool een virtuele omgeving management interface die kruisbesmetting van Python installaties en configuraties tussen projecten zal voorkomen. Wat het onderscheidt van andere virtuele omgeving management tools is de integratie met het ActiveState platform, waardoor een centrale interface voor het beheer van de omgeving configuraties en, ja, geheimen.

Voordat we kunnen profiteren van de geheimen management mogelijkheden van de State Tool, moeten we eerst de State Tool gebruiken om een virtuele omgeving op te zetten binnen ons project directory. Om dit te doen, identificeer eerst het ActiveState project waarmee je gaat werken (voor deze tutorial kun je mijn project zachflower/envs-vs-secrets-demo gebruiken, zolang je een gratis ActiveState Platform account hebt, of je kunt je eigen project aanmaken). Voer vervolgens het state activate commando uit voor het door u opgegeven project:

$ 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'

Zoals u kunt zien, wordt met het activate commando de virtuele omgeving opgezet zoals die in uw ActiveState project is gedefinieerd. In het geval dat het project nog niet is geconfigureerd, zal een eenvoudig project worden gezaaid met standaardparameters om u een voorbeeld te geven van hoe alles samen zou moeten gaan. Deze configuratie wordt opgeslagen in een bestand in de root van uw project directory genaamd activestate.yaml.

Configuratie bestand voor Geheimen & Meer

Het activestate.yaml bestand definieert een ontwikkel runtime waaronder uw applicatie zal draaien. Bijvoorbeeld, het standaard bestand definieert een eenvoudig script dat gebruik maakt van een geheim, evenals een paar event listeners die acties uitvoeren wanneer een gedefinieerde gebeurtenis zich voordoet:

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'"

Hoewel er hier niets bijzonder baanbrekends staat, zou de potentiële kracht van dit bestand onmiddellijk duidelijk moeten zijn. Het volgende script geeft bijvoorbeeld een basisvoorbeeld van hoe geheimen in het configuratiebestand gebruikt kunnen worden:

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}

Wanneer het helloWorld commando wordt uitgevoerd (vanuit een geactiveerde toestand), zal het de waarde van het user.world geheim echoën en, in het geval dat het geheim nog niet gedefinieerd is, om een waarde vragen:

$ 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": ******

Geheimen gebruiken

Hoewel het voorbeeld relatief simplistisch is, komt de echte waarde van geheimen uit de activeringsgebeurtenissen. In plaats van het ophalen van een geheime waarde binnen de context van een script, kunnen omgevingsvariabelen worden gedefinieerd met behulp van opgehaalde geheimen zonder ooit die geheimen buiten deze veilige omgeving bloot te geven:

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}

Nu, als het user.world geheim is gedefinieerd, dan zal de WORLD omgevingsvariabele worden gedefinieerd en kan worden opgehaald zoals elke andere omgevingsvariabele:

$ echo $WORLDworld!

Maar, als het niet is gedefinieerd, dan zal de gebruiker worden gevraagd om het te definiëren bij activering van de ActiveState virtuele omgeving:

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": ******

Pretty cool, toch?

Taking it Further

Configuratiebeheer in applicatie-ontwikkeling is, voor het grootste deel, een opgelost probleem, maar geheimenbeheer is dat nog net niet. Het aantal projecten dat gevoelige gegevens in een versiebeheerrepository heeft gecontroleerd is duizelingwekkend, en is iets wat zelfs zeer gerespecteerde bedrijven hebben gedaan, maar door het gebruik van de juiste veiligheidshygiëne en producten zoals ActiveState’s State Tool, wordt het veilig houden van gevoelige configuratiegegevens met de dag eenvoudiger.

  • Probeer het zelf door een gratis ActiveState Platform-account aan te maken en de State Tool te downloaden om het beheer van geheimen te vereenvoudigen.
  • U kunt ook onze webinar bekijken over het beheren van gedeelde geheimen met behulp van de State Tool

Gerelateerde blogs:

Het geheim van het beheren van gedeelde geheimen

Ontwikkelaars kunnen snel en eenvoudig geheimen delen zonder dat dit ten koste gaat van de beveiliging

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.