AWS Lambda layers v akci

V pátek se mě zákazník ptal, jak do své Lambdy dostane nějaký konfigurační soubor (bez secrets), protože ho nebaví pořád editovat hnusně dlouhé proměnné prostředí. 

A tenhle komentář fakt chápu. Není nic odpornějšího, než číst šíleně dlouhé proměnné prostředí s JSONem 🤮

Dal jsem se do hledání a tady jsou nějaké odpovědi, které přichází v úvahu.

Object storage

Tohle je asi první věc, co každého napadne. V AWS ale není žádná integrace, která by umožnila napojení souboru XYZ do této funkce. Musí to být aplikační. To znamená API call a ten znamená latency. Je to možnost, ale sáhl bych po ní asi pouze v případě, že bych musel řešit encryption at rest (S3 lze transparentně šifrovat). A i to je s otazníkem, protože na některé use cases tu máme Secrets Manager.

Co tam máme dál? 

Konfigurák ve stejném lambda layeru

lambda kód je zip. Takže do toho zipu můžeme narvat co chceme. Třeba i YAML konfigurační soubor. 

zip code.zip main config.yaml

Ve správný čas pak můžeme soubor otevřít a něco s ním udělat

	dat, err := ioutil.ReadFile("config.yaml")
	if err != nil {
		panic("shit's fucked")
	}
	fmt.Print(string(dat))

Ale v tomhle případě i změna konfiguračního souboru vyžaduje změnu celého artefaktu. Tomu se snažíme vyhýbat. Takže máme tu ještě jiné řešení?

Lambda layers

To asi není překvapení, když se ten článek takhle jmenuje, co? V každém případě, AWS Lambda má skvělou funkcionalitu, díky které můžete prostředí své funkce obohatit knihovnami a vším možným. Říká se jím layers, jsou to také jen zipy a jsou verzované. 

Když se potom přidají do funkce, tak se rozbalí do adresáře /opt. Takže řekněme, že máme konfigurační soubor config.yaml a funkci function. Takhle vytvoříme layer s konfigurací:

zip config.zip config.yaml
aws lambda publish-layer-version \
  --layer-name config \
  --compatible-runtimes go1.x \
  --zip-file fileb://./config.zip \
  --query "LayerArn" --output text

A takhle ho narveme do funkce:

aws lambda update-function-configuration \
  --function-name function \
  --layers <output z minulého snippetu>

Teď už stačí jen upravit kód z předchozí varianty a můžeme nasazovat.

	dat, err := ioutil.ReadFile("/opt/config.yaml")
	if err != nil {
		panic("shit's fucked")
	}

A tady následuje json Unmarshal atd. Však to znáte.

Lambda vrstvy možná můžou mít nějaký vliv na rychlost funkce, nenašel jsem však žádná tvrdá data, abych tady vysypal čísla. Takže si to ponecháme jako překvapení, které přijde někde v budoucnu.

Závěr

S touhle konfigurační Lambda vrstvou můžeme nezávisle nasazovat kód i konfiguraci. Nezapomínejte však, že neexistuje jeden nástroj, který by šel použít na všechny případy. Vždy, když řešíte konkrétní případ, tak sesbírejte důležité vstupy a vyberte správný nástroj pro daný úkon. A když se situace změní - změňte nástroj.

V tomhle případě budu hledat jiné řešení, až zákazník začne do YAMLu dávat secrets. Ale to nebude dnes, ani zítra a já si tak ušetřil čas, který bych jinak strávil vymýšlením over engineered mechanismu na takový primitivní úkol 😁


Máte nějaký další způsob, jak dostat konfiguraci do Lambdy? Pingněte mě na Twitteru! Možná vám za to budu líbat nohy. 

Štěpán Vraný

Jsem Systems Engineer, dělám Public Cloud a Kubernetes. Píšu o tom a ujíždím na zkoušení všech možných novinek. Taky se zajímám o DevOps a všem tlačím, že DevOps není název pozice.