Системски пристап кон променливите во Ansible

ansible devops codestyle

Еј! Моето име е Денис Каљужни Работам како инженер во одделот за автоматизација на развојниот процес. Секој ден, нови изданија на апликации се пренесуваат на стотици сервери за кампањи. И во оваа статија, го споделувам моето искуство за користење на Ansible за овие цели.

Овој водич нуди начин да се организираат променливи во распоредување. Овој водич е дизајниран за оние кои веќе користат улоги во нивните игротеки и читаат Најдобри практикино наидува на слични проблеми:

  • Откако пронајдов променлива во кодот, невозможно е веднаш да се разбере за што е одговорна;
  • Има неколку улоги и променливите треба да се поврзат со една вредност, но тоа не функционира;
  • Имате потешкотии да им објасните на другите како функционира логиката на променливите во вашите книги

Овие проблеми ги наидовме на проекти во нашата компанија, како резултат на што дојдовме до правилата за форматирање на променливите во нашите книги, што донекаде ги реши овие проблеми.

Системски пристап кон променливите во Ansible

Променливи во улоги

Улогата е посебен објект на системот за распоредување. Како и секој објект на системот, тој мора да има интерфејс за интеракција со остатокот од системот. Променливите на улоги се таков интерфејс.

Земете ја, на пример, улогата api, кој инсталира Java апликација на серверот. Какви променливи има?

Системски пристап кон променливите во Ansible

Променливите на улоги можат да се поделат на 2 вида по тип:

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

Променливи својства се променливи кои го дефинираат однесувањето на улогата.

Променливи за пребарување се променливи чија вредност се користи за означување на ресурси надвор од улогата.

Променливи слушатели се променливи чија вредност се користи за формирање на променливи за барање.

Од друга страна, 1a, 2a, 2b се променливи кои не зависат од околината (железо, надворешни ресурси, итн.) и можат да се пополнат со стандардни вредности во стандардната улога. Сепак, променливите како 1.b и 2.c не можат да се пополнат со други вредности освен „пример“, бидејќи тие ќе се менуваат од стој до стој во зависност од околината.

стил на код

  • Името на променливата мора да започне со името на улогата. Ова ќе го олесни во иднина да се открие од каква улога е променливата и за што е одговорна.
  • Кога користите променливи во улоги, мора да внимавате да го следите принципот на инкапсулација и да користите променливи дефинирани или во самата улога или во улогите од кои зависи моменталната.
  • Избегнувајте користење речници за променливи. Ansible не ви дозволува практично да ги отфрлите поединечните вредности во речник.

    Пример за лоша променлива:

    myrole_user:
        login: admin
        password: admin

    Овде, најавувањето е средна променлива, а лозинката е зависната променлива. Но
    бидејќи тие се комбинирани во речник, ќе треба да го наведете во целост
    Секогаш. Што е многу незгодно. Подобро вака:

    myrole_user_login: admin
    myrole_user_password: admin

Променливи во книшките за распоредување

При составувањето на имплементацијата за распоредување (во натамошниот текст: Playbook), се придржуваме до правилото дека треба да се стави во посебно складиште. Исто како и улогите: секоја во своето складиште за git. Ова ви овозможува да сфатите дека улогите и книгата за игри се различни независни објекти на системот за распоредување и промените во еден објект не треба да влијаат на работата на другиот. Ова се постигнува со менување на стандардните вредности на променливите.

При составување книга за игри, да резимираме, можно е да се отфрлат стандардните вредности на променливите за улоги на две места: во променливите на книгата за игри и во променливите за залихи.

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

* - Променливи и сводови

Разликата е во тоа што променливите на Playbook секогаш се користат кога се повикуваат Playbook лоцирани на исто ниво со неа. Ова значи дека овие променливи се одлични за менување на стандардните вредности на променливите кои не зависат од околината. Спротивно на тоа, променливите за залиха ќе се користат само за одредена средина, која е идеална за променливи специфични за околината.

Важно е да се напомене дека предноста на променливата нема да ви дозволи да ги редефинирате променливите прво во променливите на Playbook, а потоа одделно во истиот инвентар.

Ова значи дека веќе во оваа фаза треба да одлучите дали променливата зависи од околината или не и да ја поставите на вистинското место.

На пример, во еден проект, променливата одговорна за овозможување на SSL беше зависна од околината долго време, бидејќи не можевме да овозможиме SSL од причини надвор од наша контрола на една од штандовите. Откако го решивме овој проблем, тој стана средно независен и се пресели во променливите на Playbook.

Променливи на својства за групи

Ајде да го прошириме нашиот модел на Слика 1 со додавање на 2 групи сервери со различна Java апликација, но со различни поставки.

Системски пристап кон променливите во Ansible

Замислете како ќе изгледа книгата за игри во овој случај:

- hosts: myapi
  roles:
    - api

- hosts: bbauth
  roles:
    - auth

- hosts: ghauth
  roles:
    - auth

Имаме три групи во Playbook, па затоа се препорачува да креирате што повеќе групни датотеки во променливите на залихите на group_vars и променливите на плејбук одеднаш. Една групна датотека во овој случај е описот на една компонента од вашата апликација во Playbook. Кога ќе ја отворите групната датотека во променливите на Playbook, веднаш ги гледате сите разлики од стандардното однесување на улогите доделени на групата. Во променливите на залихите: разлики во однесувањето на групата од штанд до штанд.

стил на код

  • Обидете се да не користите променливи host_vars воопшто, бидејќи тие не го опишуваат системот, туку само посебен случај, што на долг рок ќе доведе до прашања: „Зошто овој хост е различен од останатите?“, чиј одговор е не е секогаш лесно да се најде.

Поврзете ги променливите

Сепак, тоа е за променливите на својствата, но што е со променливите за врски?
Нивната разлика е во тоа што тие мора да имаат иста вредност во различни групи.

На почетокот имаше идеја користете монструозна конструкција на формата:
hostvars[groups['bbauth'][0]]['auth_bind_port'], но веднаш беше напуштен
затоа што има недостатоци. Прво, обемноста. Второ, зависност од одреден домаќин во групата. Трето, потребно е да се соберат факти од сите хостови пред да се започне со распоредувањето, доколку не сакаме да добиеме недефинирана променлива грешка.

Како резултат на тоа, беше одлучено да се користат променливи за врски.

Поврзете ги променливите се променливи кои припаѓаат на Playbook и се потребни за поврзување на системските објекти.

Променливите за врски се пополнети во општи системски променливи group_vars/all/vars и се формираат со отстранување на сите променливи на слушателот од секоја група и додавање на името на групата од која е отстранет слушателот на почетокот на променливата.

На тој начин се обезбедува униформност и непресекување на имињата.

Ајде да се обидеме да ги поврземе променливите од примерот погоре:

Системски пристап кон променливите во Ansible

Замислете дека имаме променливи кои зависат една од друга:

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

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

Да го ставиме во заеднички променливи group_vars/all/vars сите слушатели и додајте го името на групата во името:

# 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 }}"

Сега, со промена на вредноста на конекторот, ќе бидеме сигурни дека барањето ќе оди на истата порта.

стил на код

  • Бидејќи улогите и групите се различни системски објекти, тие треба да имаат различни имиња, така што променливите за врска точно ќе покажат дека припаѓаат на одредена серверска група, а не на улога во системот.

Датотеки за животна средина

Улогите може да користат датотеки што се разликуваат од средина до средина.

SSL сертификатите се пример за такви датотеки. Чувајте ги како текст
во променлива не е многу погодно. Но, погодно е да се складира патеката до нив во променлива.

На пример, ја користиме променливата api_ssl_key_file: "/path/to/file".

Бидејќи е очигледно дека клучниот сертификат ќе се менува од средина до средина, ова е променлива зависна од околината, што значи дека треба да се наоѓа во датотеката
group_vars/myapi/vars инвентар на променливи и ја содржи вредноста „на пример“.

Најзгодниот начин во овој случај е да ја ставите датотеката со клучеви во складиштето на Playbook долж патеката
files/prod/certs/myapi.key, тогаш вредноста на променливата ќе биде:
api_ssl_key_file: "prod/certs/myapi.key". Погодноста лежи во фактот што луѓето одговорни за распоредување на системот на одреден штанд имаат и свое посебно место во складиштето за складирање на нивните датотеки. Во исто време, останува можно да се одреди апсолутната патека до сертификатот на серверот, во случај сертификатите да се испорачуваат од друг систем.

Повеќе штандови во една средина

Честопати има потреба да се распоредат неколку речиси идентични штандови во иста средина со минимални разлики. Во овој случај, ние ги делиме променливите зависни од околината на оние што не се менуваат во оваа средина и оние што се менуваат. И ние го вадиме второто директно во самите датотеки со залихи. По оваа манипулација, станува возможно да се создаде друг инвентар директно во директориумот на животната средина.

Ќе го користи повторно инвентарот group_vars и исто така ќе може да редефинира некои променливи директно за себе.

Конечната структура на директориумот за проектот за распоредување:

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

Сумирање

По организирањето на променливите во согласност со статијата: секоја датотека со променливи е одговорна за одредена задача. И бидејќи датотеката има одредени задачи, стана можно да се додели лице одговорно за точноста на секоја датотека. На пример, развивачот на распоредувањето на системот станува одговорен за правилно пополнување на променливите на playbook, додека администраторот, чиј штанд е опишан во пописот, е директно одговорен за пополнување на пописот на променливите.

Улогите станаа автономна развојна единица со свој интерфејс, дозволувајќи му на развивачот на улоги да развива карактеристики наместо да ја приспособува улогата да одговара на системот. Ова прашање беше особено точно за заедничките улоги за сите системи во кампањата.

Системските администратори повеќе не треба да го разбираат кодот за распоредување. Сè што се бара од нив за успешно распоредување е да ги пополнат датотеките со променливите на околината.

Литература

  1. документација

Автор

Каљужни Денис Александрович

Извор: www.habr.com

Додадете коментар