Zmienne środowiskowe umożliwiają konfigurację aplikacji bez zmiany kodu. Oddzielają one dane zewnętrzne od logiki aplikacji, co może pozostać dość tajemnicze dla początkujących programistów (a nawet niektórych doświadczonych).
Za pomocą tego praktycznego przewodnika, odkryjemy tajemnice zmiennych środowiskowych, abyś mógł zrozumieć, co one oznaczają, dlaczego są ważne i jak z pewnością wykorzystać zmienne środowiskowe.
Weź swoje ulubione napoje (i może trochę ciasteczek), bo zaraz się w to zagłębimy. Przeanalizujmy koncepcje zmiennych środowiskowych od podstaw.
Czym są zmienne środowiskowe?
Zmienne środowiskowe to dynamiczne wartości nazwane, które mogą wpływać na zachowanie działających procesów w komputerze. Niektóre kluczowe właściwości zmiennych środowiskowych to:
- Nazwane: Mają opisowe nazwy zmiennych takie jak APP_MODE i DB_URL.
- Zewnętrzne: Wartości są ustawiane poza kodem aplikacji za pomocą plików, linii komend i systemów.
- Dynamiczne: Możliwość aktualizacji zmiennych bez restartowania aplikacji.
- Konfigurowalne: Kod polega na zmiennych, ale ich nie definiuje.
- Odłączone: Nie ma potrzeby zmiany konfiguracji kodu, gdy zmienne są ustawione.
Oto analogia. Wyobraź sobie, że postępujesz zgodnie z przepisem na ciasteczka z kawałkami czekolady. Przepis może brzmieć:
- Dodaj 1 szklankę cukru
- Dodaj 1 kostkę miękkiego masła
- Dodaj 2 jajka
Zamiast tych stałych wartości, możesz użyć zmiennych środowiskowych:
- Dodaj $SUGAR szklanki cukru
- Dodaj $BUTTER kostki miękkiego masła
- Dodaj $EGGS jajka
Przed przygotowaniem ciasteczek, ustawiłbyś nazwy zmiennych środowiskowych na wartości według własnego wyboru:
SUGAR=1
BUTTER=1
EGGS=2
Więc, kiedy będziesz stosować przepis, twoje składniki będą się sprowadzać do:
- Dodaj 1 szklankę cukru
- Dodaj 1 kostkę miękkiego masła
- Dodaj 2 jajka
To pozwala na konfigurację przepisu na ciasteczka bez zmiany kodu przepisu.
Ta sama koncepcja dotyczy obliczeń i rozwoju. Zmienne środowiskowe pozwalają zmieniać środowisko, w którym działa proces, bez zmiany podstawowego kodu. Oto kilka powszechnych przykładów:
- Ustawienie środowiska na “development” lub “production”
- Konfigurowanie kluczy API dla usług zewnętrznych
- Przekazywanie tajnych kluczy lub danych uwierzytelniających
- Przełączanie niektórych funkcji włącz/wyłącz
Zmienne środowiskowe zapewniają dużą elastyczność. Możesz uruchomić ten sam kod w wielu środowiskach, nie zmieniając samego kodu. Ale zrozummy dalej, dlaczego są one cenne.
Dlaczego zmienne środowiskowe są cenne?
Rozważ zmienne środowiskowe jako pokrętła aplikacji używane do dostosowywania preferencji. Wkrótce przeanalizujemy doskonałe przypadki użycia.
Ugruntujmy intuicję, dlaczego zmienne środowiskowe są ważne!
Powód #1: Oddzielają kod aplikacji od konfiguracji
Bezpośrednie wpisywanie konfiguracji i poświadczeń w kodzie może powodować różnego rodzaju problemy:
- Niechciane zatwierdzenia do kontroli źródła
- Przebudowa i ponowne wdrażanie kodu tylko po to, aby zmienić wartość
- Problemy z konfiguracją podczas promowania przez środowiska
To prowadzi również do nieporządnego kodu:
import os
# Konfiguracja zakodowana na stałe
DB_USER = 'appuser'
DB_PASS = 'password123'
DB_HOST = 'localhost'
DB_NAME = 'myappdb'
def connect_to_db():
print(f"Łączenie z {DB_USER}:{DB_PASS}@{DB_HOST}/{DB_NAME}")
connect_to_db()
To splata logikę biznesową z detalami konfiguracji. Ścisłe powiązanie sprawia, że utrzymanie staje się z czasem uciążliwe:
- Zmiany wymagają modyfikacji kodu źródłowego
- Ryzyko wycieku sekretów do kontroli źródła
Używanie zmiennych środowiskowych zmniejsza te problemy. Na przykład, możesz ustawić zmienne środowiskowe DB_USER i DB_NAME.
# .env file
DB_USER=appuser
DB_PASS=password123
DB_HOST=localhost
DB_NAME=myappdb
Kod aplikacji może uzyskiwać dostęp do zmiennych środowiskowych w razie potrzeby, co utrzymuje kod czysty i prosty.
import os
# Wczytaj konfigurację ze zmiennych środowiskowych
DB_USER = os.environ['DB_USER']
DB_PASS = os.environ['DB_PASS']
DB_HOST = os.environ['DB_HOST']
DB_NAME = os.environ['DB_NAME']
def connect_to_db():
print(f"Łączenie z {DB_USER}:{DB_PASS}@{DB_HOST}/{DB_NAME}")
connect_to_db()
Zmienne środowiskowe wyraźnie oddzielają konfigurację od kodu, zachowując wrażliwe wartości abstrakcyjnie w środowisku.
Możesz wdrożyć ten sam kod z rozwoju do produkcji, nie zmieniając niczego. Zmienne środowiskowe mogą różnić się między środowiskami, nie wpływając w ogóle na kod.
Powód nr 2: Uproszczają konfigurację aplikacji
Zmienne środowiskowe ułatwiają dostosowywanie konfiguracji bez ingerencji w kod:
# Plik .env:
DEBUG=true
Oto jak możemy tego użyć w pliku skryptu:
# Zawartość skryptu:
import os
DEBUG = os.environ.get('DEBUG') == 'true'
if DEBUG:
print("W trybie DEBUG")
Przełączanie trybu debugowania wymaga tylko aktualizacji pliku .env – nie są potrzebne zmiany w kodzie, przebudowa czy ponowne wdrażanie. Skrócone „Env vars” również pomagają w bezproblemowym wdrażaniu w różnych środowiskach:
import os
# Pobierz zmienną środowiskową, aby określić obecne środowisko (produkcja lub staging)
current_env = os.getenv('APP_ENV', 'staging') # Domyślnie 'staging', jeśli nie ustawiono
# Klucz API dla produkcji
PROD_API_KEY = os.environ['PROD_API_KEY']
# Klucz API dla staging
STG_API_KEY = os.environ['STG_API_KEY']
# Logika ustawiająca api_key w zależności od obecnego środowiska
if current_env == 'production':
api_key = PROD_API_KEY
else:
api_key = STG_API_KEY
# Inicjalizacja klienta API z odpowiednim kluczem API
api = ApiClient(api_key)
Ten sam kod może używać oddzielnych kluczy API dla produkcji vs staging bez żadnych zmian.
Na koniec, umożliwiają przełączanie funkcji bez nowych wdrożeń:
NEW_FEATURE = os.environ['NEW_FEATURE'] == 'true'
if NEW_FEATURE:
enableNewFeature()
Zmiana zmiennej NEW_FEATURE aktywuje funkcjonalność natychmiast w naszym kodzie. Interfejs do aktualizacji konfiguracji zależy od systemów:
- Platformy Cloud używają paneli internetowych
- Serwery używają narzędzi poleceń systemu operacyjnego
- Lokalne środowisko deweloperskie może używać plików .env
Zmienne środowiskowe są korzystne podczas tworzenia aplikacji, pozwalają użytkownikom konfigurować elementy zgodnie z ich wymaganiami.
Powód #3: Pomagają Zarządzać Tajemnicami i Poświadczeniami
Sprawdzanie sekretów takich jak klucze API, hasła i prywatne klucze bezpośrednio w kodzie źródłowym stwarza znaczne ryzyko bezpieczeństwa:
# Unikaj ujawniania sekretów w kodzie!
STRIPE_KEY = 'sk_live_1234abc'
DB_PASSWORD = 'password123'
stripe.api_key = STRIPE_KEY
db.connect(DB_PASSWORD)
Te dane uwierzytelniające są teraz narażone, jeśli ten kod zostanie dodany do publicznego repozytorium GitHub!
Zmienne środowiskowe zapobiegają wyciekom poprzez zewnętrzną obsługę tajemnic:
import os
STRIPE_KEY = os.environ.get('STRIPE_KEY')
DB_PASS = os.environ.get('DB_PASS')
stripe.api_key = STRIPE_KEY
db.connect(DB_PASS)
Rzeczywiste wartości sekretne są ustawiane w lokalnym pliku .env.
# .env file
STRIPE_KEY=sk_live_1234abc
DB_PASS=password123
Nie zapomnij dodać pliku .env do .gitignore
, aby utrzymać tajemnice poza kontrolą źródła. To wymaga zdefiniowania pliku .env w pliku .gitignore w korzeniu repozytorium, co informuje git, aby ignorował plik podczas tworzenia commita.
To oddziela definicje sekretów od kodu aplikacji, wczytując je bezpiecznie z chronionych środowisk podczas wykonywania. Ryzyko przypadkowego ujawnienia poświadczeń znacznie się zmniejsza.
Powód #4: Promują Spójność
Wyobraź sobie posiadanie różnych plików konfiguracyjnych dla środowisk rozwoju, kontroli jakości i produkcji:
# Rozwój
DB_HOST = 'localhost'
DB_NAME = 'appdb_dev'
# Produkcja
DB_HOST = 'db.myapp.com'
DB_NAME = 'appdb_prod'
Ta rozbieżność wprowadza subtelne błędy, które trudno wyłapać. Kod, który działa bezbłędnie w fazie rozwoju, może nagle przestać działać w produkcji z powodu niezgodności konfiguracji.
Zmienne środowiskowe rozwiązują to poprzez scentralizowanie konfiguracji w jednym miejscu:
DB_HOST=db.myapp.com
DB_NAME=appdb_prod
Teraz te same zmienne są używane konsekwentnie we wszystkich środowiskach. Nie musisz już martwić się o losowe lub nieprawidłowe ustawienia, które mogą zostać aktywowane.
Kod aplikacji po prostu odwołuje się do zmiennych:
import os
db_host = os.environ['DB_HOST']
db_name = os.environ['DB_NAME']
db.connect(db_host, db_name)
Niezależnie od tego, czy aplikacja działa lokalnie, czy na serwerze produkcyjnym, zawsze używa poprawnego hosta bazy danych i nazwy.
Ta jednolitość zmniejsza liczbę błędów, zwiększa przewidywalność i ogólnie wzmacnia aplikację. Programiści mogą mieć pewność, że kod będzie zachowywał się identycznie w każdym środowisku.
Jak możesz zdefiniować zmienne środowiskowe
Zmienne środowiskowe mogą być definiowane w kilku miejscach, co pozwala na elastyczność w ustawianiu i dostępie do nich w różnych procesach i systemach.
1. Zmienne środowiskowe systemu operacyjnego
Większość systemów operacyjnych oferuje wbudowane mechanizmy do definiowania zmiennych globalnych. To sprawia, że zmienne są dostępne na poziomie systemu dla wszystkich użytkowników, aplikacji itp.
Na systemach Linux/Unix zmienne mogą być definiowane w skryptach startowych powłoki.
Na przykład, ~/.bashrc może być używany do ustawiania zmiennych na poziomie użytkownika, podczas gdy /etc/environment jest przeznaczony dla zmiennych systemowych, do których dostęp mają wszyscy użytkownicy.
Zmienne mogą być również ustawiane w linii przed wykonaniem poleceń za pomocą polecenia export lub bezpośrednio przez polecenie env w bashu:
# In ~/.bashrc
export DB_URL=localhost
export APP_PORT=3000
# W /etc/environment
DB_HOST=localhost
DB_NAME=mydatabase
Zmienne można również ustawić w linii przed wykonaniem poleceń:
export TOKEN=abcdef
python app.py
Zdefiniowanie zmiennych na poziomie systemu operacyjnego sprawia, że są one dostępne globalnie, co jest bardzo pomocne, gdy chcesz uruchomić aplikację bez zależności od wewnętrznych wartości.
Możesz również odwoływać się do zdefiniowanych zmiennych w skryptach lub argumentach wiersza poleceń.
python app.py --db-name $DB_NAME --db-host $DB_HOST --batch-size $BATCH_SIZE
2. Definiowanie Zmiennych Środowiskowych w Kodzie Aplikacji
Oprócz zmiennych na poziomie systemu operacyjnego, zmienne środowiskowe można definiować i uzyskiwać dostęp bezpośrednio w kodzie aplikacji podczas jej działania.
Słownik os.environ w Pythonie zawiera wszystkie aktualnie zdefiniowane zmienne środowiskowe. Możemy ustawić nowe, po prostu dodając pary klucz-wartość:
Zmienne środowiskowe można również definiować i uzyskiwać dostęp bezpośrednio w kodzie aplikacji. W Pythonie, słownik os.environ zawiera wszystkie zdefiniowane zmienne środowiskowe:
import os
os.environ["API_KEY"] = "123456"
api_key = os.environ.get("API_KEY")
Słownik os.environ pozwala na dynamiczne ustawianie i pobieranie zmiennych środowiskowych z poziomu kodu Pythona.
Większość języków jest dostarczana wraz z ich bibliotekami, umożliwiając dostęp do zmiennych środowiskowych podczas działania.
Możesz również korzystać z frameworków takich jak Express, Django i Laravel, aby uzyskać głębsze integracje, takie jak automatyczne ładowanie plików .env zawierających zmienne środowiskowe.
3. Tworzenie lokalnych plików konfiguracyjnych dla zmiennych środowiskowych
Oprócz zmiennych na poziomie systemu, zmienne środowiskowe mogą być wczytywane z lokalnych plików konfiguracyjnych aplikacji. Pozwala to na oddzielenie szczegółów konfiguracji od kodu, nawet podczas lokalnego rozwoju i testowania.
Kilka popularnych podejść:
Pliki .env
Konwencja formatu pliku .env, spopularyzowana przez Node.js, zapewnia wygodny sposób określania zmiennych środowiskowych w formacie klucz-wartość:
# .env
DB_URL=localhost
API_KEY=123456
Frameworki internetowe takie jak Django i Laravel automatycznie wczytują zmienne zdefiniowane w plikach .env do środowiska aplikacji. Dla innych języków, takich jak Python, biblioteki takie jak python-dotenv obsługują importowanie plików .env:
from dotenv import load_dotenv
load_dotenv() # Ładuje zmienne .env
print(os.environ['DB_URL']) # localhost
Zaletą używania plików .env jest to, że utrzymują one czystą i oddzielną konfigurację bez wprowadzania zmian w kodzie.
Pliki konfiguracyjne JSON
Dla bardziej złożonych potrzeb konfiguracyjnych, obejmujących wiele zmiennych środowiskowych, używanie plików JSON lub YAML pomaga zorganizować zmienne razem:
// config.json
{
"api_url": "https://api.example.com",
"api_key": "123456",
"port": 3000
}
Kod aplikacji może szybko załadować te dane JSON jako słownik, aby uzyskać dostęp do skonfigurowanych zmiennych:
import json
config = json.load('config.json')
api_url = config['api_url']
api_key = config['api_key']
port = config['port'] # 3000
To zapobiega bałaganowi w plikach dotenv przy obsłudze wielu konfiguracji aplikacji.
Jak uzyskać dostęp do zmiennych środowiskowych w różnych językach programowania?
Niezależnie od sposobu definiowania zmiennych środowiskowych, nasze aplikacje potrzebują spójnego sposobu wyszukiwania wartości podczas działania.
Różne sposoby definiowania zmiennych środowiskowych istnieją, ale kod aplikacji potrzebuje standardowego sposobu dostępu do nich w czasie wykonywania, niezależnie od języka. Oto przegląd technik dostępu do zmiennych środowiskowych w popularnych językach:
Python
Python udostępnia słownik os.environ do dostępu do zdefiniowanych zmiennych środowiskowych:
import os
db = os.environ.get('DB_NAME')
print(db)
Możemy uzyskać zmienną za pomocą os.environ.get(), która zwraca None, jeśli nie jest zdefiniowana. Lub uzyskać dostęp bezpośrednio przez os.environ(), co spowoduje wywołanie błędu KeyError, jeśli nie jest obecna.
Dodatkowe metody, takie jak os.getenv() i os.environ.get(), umożliwiają określenie wartości domyślnych, jeśli nie zostały ustawione.
JavaScript (Node.js)
W kodzie JavaScript Node.js, zmienne środowiskowe są dostępne na globalnym obiekcie process.env:
// Pobierz zmienną środowiskową
const db = process.env.DB_NAME;
console.log(db);
Jeśli niezdefiniowane, process.env będzie zawierać wartość undefined. Możemy również dostarczyć wartości domyślne, takie jak:
const db = process.env.DB_NAME || 'defaultdb';
Ruby
Aplikacje Ruby uzyskują dostęp do zmiennych środowiskowych poprzez hash ENV:
# Dostęp do zmiennej
db = ENV['DB_NAME']
puts db
Możemy również przekazać wartość domyślną, jeśli żądany klucz nie istnieje:
db = ENV.fetch('DB_NAME', 'defaultdb')
PHP
PHP udostępnia globalne metody getenv(), $_ENV i $_SERVER do dostępu do zmiennych środowiskowych:
// Pobierz zmienną środowiskową
$db_name = getenv('DB_NAME');
// Lub uzyskaj dostęp do tablic $_ENV lub $_SERVER
$db_name = $_ENV['DB_NAME'];
W zależności od źródła zmiennej, mogą być dostępne w różnych globalach.
Java
W Javie, metoda System.getenv() zwraca zmienne środowiskowe, które można uzyskać dostęp:
String dbName = System.getenv("DB_NAME");
To umożliwia dostęp do zmiennych zdefiniowanych na poziomie systemowym globalnie w Java.
Na razie kilka najlepszych praktyk dotyczących higieny zmiennych środowiskowych.
Przewodnik Bezpieczeństwa Zmiennych Środowiskowych
Jeśli chodzi o bezpieczne zarządzanie zmiennymi środowiskowymi, powinniśmy mieć na uwadze kilka najlepszych praktyk.
Nigdy nie przechowuj wrażliwych informacji w kodzie
Przede wszystkim, nigdy nie przechowuj wrażliwych informacji takich jak hasła, klucze API czy tokeny bezpośrednio w swoim kodzie.
Może być kuszące, aby po prostu zakodować na stałe hasło do bazy danych lub klucz szyfrujący w kodzie źródłowym dla szybkiego dostępu, ale oprzyj się tej pokusie!
Jeśli przypadkowo umieścisz ten kod w publicznym repozytorium na GitHubie, faktycznie transmitujesz swoje tajemnice całemu światu. Wyobraź sobie, że haker zdobył dane uwierzytelniające do twojej produkcyjnej bazy danych, tylko dlatego, że były one widoczne jako zwykły tekst w twoim kodzie. Przerażająca myśl, prawda?
Zamiast tego, zawsze używaj zmiennych środowiskowych do przechowywania wszelkiego rodzaju wrażliwych konfiguracji. Trzymaj swoje sekrety w bezpiecznym miejscu, takim jak plik .env lub narzędzie do zarządzania sekretami, i odwołuj się do nich w swoim kodzie za pomocą zmiennych środowiskowych. Na przykład, zamiast robić coś takiego w swoim kodzie Pythona:
db_password = "supers3cr3tpassw0rd"
Przechowywałbyś to hasło w zmiennej środowiskowej w ten sposób:
# .env file
DB_PASSWORD=supers3cr3tpassw0rd
A następnie uzyskaj do niego dostęp w swoim kodzie:
import os
db_password = os.environ.get('DB_PASSWORD')
Tym sposobem, Twoje sekrety pozostają bezpieczne nawet jeśli Twój kod źródłowy zostanie naruszony. Zmienne środowiskowe działają jako bezpieczna warstwa abstrakcji.
Używaj zmiennych specyficznych dla środowiska
Inna praktyka polega na używaniu różnych zmiennych środowiskowych dla każdego środowiska aplikacji, takich jak rozwój, staging i produkcja.
Nie chcesz przypadkowo połączyć się z produkcyjną bazą danych podczas lokalnego programowania tylko dlatego, że zapomniałeś zaktualizować zmienną konfiguracyjną! Użyj przestrzeni nazw dla zmiennych środowiskowych dla każdego środowiska:
# Dev
DEV_API_KEY=abc123
DEV_DB_URL=localhost
# Production
PROD_API_KEY=xyz789
PROD_DB_URL=proddb.amazonaws.com
Następnie odwołuj się do odpowiednich zmiennych w swoim kodzie w zależności od aktualnego środowiska. Wiele frameworków takich jak Rails zapewnia pliki konfiguracyjne specyficzne dla środowiska do tego celu.
Nie przechowuj sekretów w systemie kontroli wersji
Jest również kluczowe, aby trzymać pliki .env i konfiguracyjne zawierające tajemnice poza kontrolą wersji. Dodaj .env do swojego .gitignore
, aby przypadkowo nie dodać go do swojego repozytorium.
Możesz użyć git-secrets
do skanowania w poszukiwaniu wrażliwych informacji przed każdym zatwierdzeniem. Dla dodatkowego bezpieczeństwa, zaszyfruj swój plik z sekretami przed jego przechowaniem. Narzędzia takie jak Ansible Vault i BlackBox mogą w tym pomóc.
Bezpieczne Sekrety na Serwerach Produkcyjnych
Podczas zarządzania zmiennymi środowiskowymi na serwerach produkcyjnych unikaj ustawiania ich za pomocą argumentów wiersza poleceń, które mogą być sprawdzane przez tabelę procesów.
Zamiast tego, użyj narzędzi zarządzania środowiskiem systemu operacyjnego lub platformy orkiestracji kontenerów. Na przykład, możesz użyć Kubernetes Secrets do bezpiecznego przechowywania i udostępniania sekretów swoim aplikacjom w kontenerach.
Używaj Silnych Algorytmów Szyfrowania
Używaj solidnych i nowoczesnych algorytmów szyfrowania, gdy szyfrujesz swoje dane poufne, niezależnie od tego, czy są one przesyłane, czy przechowywane. Unikaj przestarzałych algorytmów takich jak DES czy MD5, które mają znane podatności. Zamiast tego, wybierz algorytmy standardowe dla branży, takie jak AES-256 dla szyfrowania symetrycznego i RSA-2048 lub ECDSA dla szyfrowania asymetrycznego.
Regularnie zmieniaj sekrety
Obracaj swoje sekrety regularnie, szczególnie jeśli podejrzewasz, że mogły zostać naruszone. Traktuj sekrety tak, jakbyś traktował hasło — aktualizuj je co kilka miesięcy. Narzędzie do zarządzania sekretami, takie jak Hashicorp Vault lub AWS Secrets Manager, może pomóc zautomatyzować ten proces.
Ostrożnie z logowaniem i raportowaniem błędów
Bądź ostrożny podczas logowania i raportowania błędów. Upewnij się, że nie zapisujesz żadnych zmiennych środowiskowych zawierających wrażliwe dane. Jeśli używasz narzędzia do śledzenia błędów stron trzecich, skonfiguruj je tak, aby oczyścić wrażliwe dane. Ostatnią rzeczą, jakiej chcesz, jest pojawienie się Twoich sekretów w śladzie stosu na pulpicie nawigacyjnym raportowania wyjątków!
Kiedy unikać zmiennych środowiskowych?
Istnieje kilka przypadków, gdy należy unikać zmiennych środowiskowych:
Zarządzanie Skomplikowaną Konfiguracją
Używanie zmiennych środowiskowych do zarządzania konfiguracją dla skomplikowanych systemów oprogramowania może stać się niechlujne i podatne na błędy. W miarę wzrostu liczby parametrów konfiguracyjnych, kończysz z długimi nazwami zmiennych środowiskowych, które mogą niezamierzenie kolidować. Nie ma również łatwego sposobu na zorganizowanie razem powiązanych wartości konfiguracyjnych.
Zamiast zmiennych środowiskowych, rozważ użycie plików konfiguracyjnych w formacie takim jak JSON lub YAML. Pozwala to na:
- Grupuj powiązane parametry konfiguracyjne razem w zagnieżdżonej strukturze.
- Unikaj kolizji nazw przez hermetyzację konfiguracji w zakresach i przestrzeniach nazw.
- Zdefiniuj niestandardowe typy danych zamiast tylko ciągów znaków.
- Szybko przeglądaj i modyfikuj konfiguracje za pomocą edytora tekstu.
Przechowywanie Wrażliwych Informacji
Chociaż zmienne środowiskowe wydają się być łatwym sposobem na wprowadzenie zewnętrznych konfiguracji, takich jak klucze API, hasła do bazy danych itp., może to prowadzić do problemów z bezpieczeństwem.
Problem polega na tym, że zmienne środowiskowe są dostępne globalnie w procesie. Dlatego, jeśli w części twojej aplikacji istnieje luka, może to narazić na szwank tajemnice przechowywane w zmiennych środowiskowych.
Bardziej bezpieczne podejście polega na korzystaniu z usługi zarządzania tajemnicami, która obsługuje szyfrowanie i kontrolę dostępu. Te usługi umożliwiają przechowywanie poufnych danych zewnętrznie i dostarczają SDK do pobierania wartości aplikacji.
Rozważ użycie dedykowanego rozwiązania do zarządzania tajemnicami zamiast zmiennych środowiskowych dla poświadczeń i prywatnych kluczy. To zmniejsza ryzyko przypadkowego ujawnienia wrażliwych danych poprzez wykorzystanie luk w zabezpieczeniach lub niezamierzone logowanie.
Praca z wieloma środowiskami
Zarządzanie zmiennymi środowiskowymi może stać się żmudne, gdy aplikacje rosną i są wdrażane w różnych środowiskach (dev, staging, staging, prod). Możesz mieć rozproszone dane konfiguracyjne rozłożone na różne skrypty bash, narzędzia wdrożeniowe itp.
Rozwiązanie do zarządzania konfiguracją pomaga skonsolidować wszystkie ustawienia specyficzne dla środowiska w jednym centralnym miejscu. Może to być pliki w repozytorium, dedykowany serwer konfiguracyjny lub zintegrowany z Twoimi potokami CI/CD.
Jeśli celem jest uniknięcie duplikowania zmiennych środowiskowych, jedno źródło prawdy dla konfiguracji ma więcej sensu.
Współdzielenie Konfiguracji Między Zespołami
Ponieważ zmienne środowiskowe są pobierane lokalnie dla każdego procesu, dzielenie się i synchronizowanie danych konfiguracyjnych między różnymi zespołami pracującymi nad tą samą aplikacją lub zestawem usług staje się bardzo trudne.
Każdy zespół może przechowywać swoją kopię wartości konfiguracyjnych w różnych skryptach bash, manifestach wdrożeniowych itp. Ta zdecentralizowana konfiguracja prowadzi do następującego:
- Drift konfiguracji: Bez jednego, centralnego źródła prawdy, łatwo o niekonsekwencje w konfiguracji między środowiskami, gdy różne zespoły wprowadzają niezależne zmiany.
- Brak widoczności: Nie ma scentralizowanego sposobu na przeglądanie, wyszukiwanie i analizowanie całego stanu konfiguracji we wszystkich usługach. To sprawia, że bardzo trudno jest zrozumieć, jak usługa jest skonfigurowana.
- Problemy z audytem: Zmiany w zmiennych środowiskowych nie są śledzone w żaden standardowy sposób, co utrudnia audytowanie tego, kto zmienił jaką konfigurację i kiedy.
- Trudności z testowaniem: Bez możliwości łatwego tworzenia migawek i udostępniania konfiguracji, zapewnienie spójnych środowisk dla rozwoju i testowania staje się niezwykle uciążliwe.
Zamiast tego rozdrobnionego podejścia, posiadanie scentralizowanego rozwiązania konfiguracyjnego pozwala zespołom zarządzać konfiguracją z jednej platformy lub repozytorium.
Buduj swoje aplikacje z użyciem zmiennych środowiskowych na długi czas
Gdy Twoja aplikacja się rozwija, zastanów się, jak możesz potrzebować bardziej zaawansowanych sposobów zarządzania jej ustawieniami konfiguracyjnymi.
To, co wydaje się proste teraz, może stać się bardziej skomplikowane później. Prawdopodobnie będziesz potrzebować lepszych sposobów na kontrolę dostępu, współdzielenie ustawień zespołu, jasne organizowanie wszystkiego i płynną aktualizację konfiguracji.
Nie zamykaj się w kącie, używając od początku tylko zmiennych środowiskowych. Musisz zaplanować, jak radzić sobie z konfiguracjami, gdy Twoje potrzeby się rozszerzą.
Podczas gdy zmienne środowiskowe są świetne do obsługi danych skoncentrowanych na środowisku, takich jak dane uwierzytelniające, nazwy baz danych, lokalne adresy IP itp., chcesz stworzyć system, który stosuje solidne zasady, takie jak bezpieczeństwo, możliwość współdzielenia, organizacja i zdolność do szybkiego dostosowywania się do zmian.
Alternatywy, które omówiliśmy, takie jak użycie dedykowanego pliku konfiguracyjnego lub usługi, posiadają cenne funkcje, które są zgodne z tymi zasadami. To pomoże ci szybko się poruszać, nie zwalniając tempa.