Systémový přístup k proměnným v Ansible

přípustný kódový styl devops

Ahoj! Jmenuji se Denis Kaljužnyj Pracuji jako inženýr v oddělení automatizace vývojových procesů. Každý den se na stovky serverů kampaní zavádějí nové sestavení aplikací. A v tomto článku sdílím své zkušenosti s používáním Ansible pro tyto účely.

Tato příručka nabízí způsob, jak uspořádat proměnné v nasazení. Tato příručka je určena pro ty, kteří již používají role ve svých učebnicích a čtou Osvědčené postupyale narazil na podobné problémy:

  • Po nalezení proměnné v kódu není možné okamžitě pochopit, za co je zodpovědná;
  • Existuje několik rolí a proměnné musí být spojeny s jednou hodnotou, ale to nefunguje;
  • Máte potíže vysvětlit ostatním, jak funguje logika proměnných ve vašich příručkách

S těmito problémy jsme se setkali na projektech v naší společnosti, v důsledku čehož jsme dospěli k pravidlům pro formátování proměnných v našich playbookech, která tyto problémy do jisté míry vyřešila.

Systémový přístup k proměnným v Ansible

Proměnné v rolích

Role je samostatný objekt systému nasazení. Jako každý objekt systému musí mít rozhraní pro interakci se zbytkem systému. Takovým rozhraním jsou proměnné role.

Vezměte si například roli api, který na server nainstaluje aplikaci Java. Jaké má proměnné?

Systémový přístup k proměnným v Ansible

Proměnné role lze rozdělit do 2 typů podle typu:

1. Свойства
    a) независимые от среды
    б) зависимые от среды
2. Связи
    a) слушатели 
    б) запросы внутри системы
    в) запросы в среду

Variabilní vlastnosti jsou proměnné, které definují chování role.

Dotazové proměnné jsou proměnné, jejichž hodnota se používá k označení zdrojů mimo roli.

Variabilní posluchači jsou proměnné, jejichž hodnota se používá k vytvoření dotazovaných proměnných.

Na druhou stranu 1a, 2a, 2b jsou proměnné, které nezávisí na prostředí (železo, externí zdroje atd.) a lze je vyplnit výchozími hodnotami v roli defaults. Proměnné jako 1.ba 2.c však nelze vyplnit jinými hodnotami než „příklad“, protože se budou měnit od stojanu k stojanu v závislosti na prostředí.

styl kódu

  • Název proměnné musí začínat názvem role. Díky tomu bude v budoucnu snadné zjistit, z jaké role proměnná pochází a za co je zodpovědná.
  • Při používání proměnných v rolích musíte dbát na dodržování principu zapouzdření a používat proměnné definované buď v roli samotné, nebo v rolích, na kterých závisí ta aktuální.
  • Vyhněte se používání slovníků pro proměnné. Ansible vám neumožňuje pohodlně přepsat jednotlivé hodnoty ve slovníku.

    Příklad špatné proměnné:

    myrole_user:
        login: admin
        password: admin

    Zde je login střední proměnnou a heslo je závislou proměnnou. Ale
    protože jsou spojeny do slovníku, budete jej muset specifikovat celý
    Vždy. Což je velmi nepohodlné. Lepší takto:

    myrole_user_login: admin
    myrole_user_password: admin

Proměnné v příručkách nasazení

Při sestavování deployment playbooku (dále jen playbook) se držíme pravidla, že by měl být umístěn v samostatném úložišti. Stejně jako role: každá ve svém vlastním gitovém úložišti. To vám umožní uvědomit si, že role a playbook jsou různé nezávislé objekty systému nasazení a změny v jednom objektu by neměly ovlivnit provoz druhého. Toho je dosaženo změnou výchozích hodnot proměnných.

Při kompilaci playbooku, shrnuto, je možné přepsat výchozí hodnoty proměnných rolí na dvou místech: v proměnných playbooku a v proměnných inventáře.

mydeploy                        # Каталог деплоя
├── deploy.yml                  # Плейбук деплоя
├── group_vars                  # Каталог переменных плейбука
│   ├── all.yml                 # Файл для переменных связи всей системы
│   └── myapi.yml               # Файл переменных свойств группы myapi
└── inventories                 #
    └── prod                    # Каталог окружения prod
        ├── prod.ini            # Инвентори файл
        └── group_vars          # Каталог для переменных инвентори
            └── myapi           #
                ├── vars.yml    # Средозависимые переменные группы myapi
                └── vault.yml   # Секреты (всегда средозависимы) *

* - Proměnné a Vaulty

Rozdíl je v tom, že při volání playbooků umístěných na stejné úrovni se vždy používají proměnné playbooku. To znamená, že tyto proměnné jsou skvělé pro změnu výchozích hodnot proměnných, které nezávisí na prostředí. Naopak proměnné inventáře budou použity pouze pro konkrétní prostředí, což je ideální pro proměnné specifické pro prostředí.

Je důležité si uvědomit, že priorita proměnných vám nedovolí předefinovat proměnné nejprve v proměnných playbooku a poté samostatně ve stejném inventáři.

To znamená, že již v této fázi se musíte rozhodnout, zda je proměnná závislá na prostředí nebo ne, a umístit ji na správné místo.

Například v jednom projektu byla proměnná zodpovědná za povolení SSL po dlouhou dobu závislá na prostředí, protože jsme na jednom stánku nemohli povolit SSL z důvodů, které jsme nemohli ovlivnit. Poté, co jsme tento problém vyřešili, stal se nezávislým na médiu a přesunul se do proměnných playbooku.

Proměnné vlastností pro skupiny

Rozšiřme náš model na obrázku 1 přidáním 2 skupin serverů s odlišnou Java aplikací, ale s odlišným nastavením.

Systémový přístup k proměnným v Ansible

Představte si, jak bude hrací příručka vypadat v tomto případě:

- hosts: myapi
  roles:
    - api

- hosts: bbauth
  roles:
    - auth

- hosts: ghauth
  roles:
    - auth

V playbooku máme tři skupiny, takže se doporučuje vytvořit co nejvíce souborů skupin v proměnných inventáře group_vars a proměnných playbooku najednou. Jeden soubor skupiny je v tomto případě popis jedné součásti vaší aplikace v playbooku. Když otevřete soubor skupiny v proměnných playbooku, okamžitě uvidíte všechny rozdíly oproti výchozímu chování rolí přiřazených skupině. V inventárních proměnných: rozdíly v chování skupin od stánku k stánku.

Styl kódu

  • Pokuste se vůbec nepoužívat proměnné host_vars, protože nepopisují systém, ale pouze speciální případ, který v dlouhodobém horizontu povede k otázkám: "Proč se tento hostitel liší od ostatních?", odpověď na kterou je není vždy snadné najít.

Propojit proměnné

To je však o proměnných vlastností, ale co o proměnných odkazu?
Jejich rozdíl je v tom, že musí mít stejnou hodnotu v různých skupinách.

Na začátku bylo myšlenku použijte monstrózní konstrukci formuláře:
hostvars[groups['bbauth'][0]]['auth_bind_port'], ale bylo okamžitě opuštěno
protože má nedostatky. Za prvé, objemnost. Za druhé, závislost na konkrétním hostiteli ve skupině. Za třetí je nutné před zahájením nasazení shromáždit fakta od všech hostitelů, pokud nechceme dostat nedefinovanou chybu proměnné.

V důsledku toho bylo rozhodnuto použít proměnné propojení.

Propojit proměnné jsou proměnné, které patří do playbooku a jsou potřebné k propojení systémových objektů.

Proměnné odkazu jsou vyplněny obecnými systémovými proměnnými group_vars/all/vars a jsou tvořeny odstraněním všech proměnných posluchače z každé skupiny a přidáním názvu skupiny, ze které byl posluchač odebrán, na začátek proměnné.

Je tak zajištěna jednotnost a neprolínání jmen.

Zkusme svázat proměnné z výše uvedeného příkladu:

Systémový přístup k proměnným v Ansible

Představte si, že máme proměnné, které na sobě závisí:

# roles/api/defaults:
# Переменная запроса
api_auth1_address: "http://example.com:80"
api_auth2_address: "http://example2.com:80"

# roles/auth/defaults:
# Переменная слушатель
auth_bind_port: "20000"

Dejme to do společných proměnných group_vars/all/vars všechny posluchače a k názvu přidejte název skupiny:

# group_vars/all/vars
bbauth_auth_bind_port: "20000"
ghauth_auth_bind_port: "30000"

# group_vars/bbauth/vars
auth_bind_port: "{{ bbauth_auth_bind_port }}"

# group_vars/ghauth/vars
auth_bind_port: "{{ ghauth_auth_bind_port }}"

# group_vars/myapi/vars
api_auth1_address: "http://{{ bbauth_auth_service_name }}:{{ bbauth_auth_bind_port }}"
api_auth2_address: "http://{{ ghauth_auth_service_name }}:{{ ghauth_auth_bind_port }}"

Nyní změnou hodnoty konektoru budeme mít jistotu, že požadavek půjde na stejný port.

Styl kódu

  • Vzhledem k tomu, že role a skupiny jsou různé systémové objekty, musí mít různé názvy, aby proměnné odkazu přesně ukazovaly, že patří do určité skupiny serverů, a nikoli do role v systému.

Soubory prostředí

Role mohou používat soubory, které se liší prostředí od prostředí.

Příkladem takových souborů jsou certifikáty SSL. Uložte je jako text
v proměnné není příliš pohodlné. Cestu k nim je ale vhodné uložit do proměnné.

Použijeme například proměnnou api_ssl_key_file: "/path/to/file".

Protože je zřejmé, že se certifikát klíče bude měnit z prostředí do prostředí, jedná se o proměnnou závislou na prostředí, což znamená, že by měla být umístěna v souboru
group_vars/myapi/vars inventář proměnných a obsahují hodnotu „například“.

Nejpohodlnějším způsobem je v tomto případě umístit soubor klíče do repozitáře playbooku podél cesty
files/prod/certs/myapi.key, pak hodnota proměnné bude:
api_ssl_key_file: "prod/certs/myapi.key". Pohodlí spočívá v tom, že lidé zodpovědní za nasazení systému na konkrétním stojanu mají také své vyhrazené místo v úložišti pro ukládání svých souborů. Zároveň zůstává možnost zadat absolutní cestu k certifikátu na serveru, v případě, že certifikáty dodává jiný systém.

Více stojanů v jednom prostředí

Často je potřeba rozmístit několik téměř stejných stojanů ve stejném prostředí s minimálními rozdíly. V tomto případě rozdělujeme proměnné závislé na prostředí na ty, které se v tomto prostředí nemění, a ty, které se mění. A ten druhý vyjmeme přímo do samotných souborů inventáře. Po této manipulaci je možné vytvořit další inventář přímo v adresáři prostředí.

Znovu použije inventář group_vars a také bude moci předefinovat některé proměnné přímo pro sebe.

Konečná adresářová struktura pro projekt nasazení:

mydeploy                        # Каталог деплоя
├── deploy.yml                  # Плейбук деплоя
├── files                       # Каталог для файлов деплоя
│   ├── prod                    # Католог для средозависимых файлов стенда prod
│   │   └── certs               # 
│   │       └── myapi.key       #
│   └── test1                   # Каталог для средозависимых файлов стенда test1
├── group_vars                  # Каталог переменных плейбука
│   ├── all.yml                 # Файл для переменных связи всей системы
│   ├── myapi.yml               # Файл переменных свойств группы myapi
│   ├── bbauth.yml              # 
│   └── ghauth.yml              #
└── inventories                 #
    ├── prod                    # Каталог окружения prod
    │   ├── group_vars          # Каталог для переменных инвентори
    │   │   ├── myapi           #
    │   │   │   ├── vars.yml    # Средозависимые переменные группы myapi
    │   │   │   └── vault.yml   # Секреты (всегда средозависимы)
    │   │   ├── bbauth          # 
    │   │   │   ├── vars.yml    #
    │   │   │   └── vault.yml   #
    │   │   └── ghauth          #
    │   │       ├── vars.yml    #
    │   │       └── vault.yml   #
    │   └── prod.ini            # Инвентори стенда prod
    └── test                    # Каталог окружения test
        ├── group_vars          #
        │   ├── myapi           #
        │   │   ├── vars.yml    #
        │   │   └── vault.yml   #
        │   ├── bbauth          #
        │   │   ├── vars.yml    #
        │   │   └── vault.yml   #
        │   └── ghauth          #
        │       ├── vars.yml    #
        │       └── vault.yml   #
        ├── test1.ini           # Инвентори стенда test1 в среде test
        └── test2.ini           # Инвентори стенда test2 в среде test

Shrnutí

Po uspořádání proměnných v souladu s článkem: každý soubor s proměnnými odpovídá za konkrétní úkol. A protože soubor má určité úkoly, bylo možné určit osobu odpovědnou za správnost každého souboru. Například vývojář nasazení systému se stává zodpovědným za správné vyplnění proměnných playbooku, zatímco správce, jehož stojan je popsán v inventáři, je přímo zodpovědný za vyplnění inventáře proměnných.

Role se staly samostatnou vývojovou jednotkou s vlastním rozhraním, což vývojáři rolí umožnilo spíše vyvíjet funkce než přizpůsobovat roli systému. Tento problém se týkal zejména společných rolí pro všechny systémy v kampani.

Správci systému již nemusí rozumět kódu nasazení. Vše, co je od nich vyžadováno pro úspěšné nasazení, je vyplnit soubory proměnných prostředí.

Literatura

  1. Документация

Autor

Kaljužnyj Denis Alexandrovič

Zdroj: www.habr.com

Přidat komentář