Aproximació del sistema a les variables a Ansible

estil de codi de devops ansible

Ei! El meu nom és Denis Kalyuzhny Treballo com a enginyer al departament d'automatització de processos de desenvolupament. Cada dia, es distribueixen noves compilacions d'aplicacions a centenars de servidors de campanyes. I en aquest article, comparteixo la meva experiència d'utilitzar Ansible per a aquests propòsits.

Aquesta guia ofereix una manera d'organitzar les variables en un desplegament. Aquesta guia està dissenyada per a aquells que ja utilitzen rols als seus llibres de jocs i llegeixen Millors pràctiquesperò tenint problemes similars:

  • Després d'haver trobat una variable al codi, és impossible entendre immediatament de què és responsable;
  • Hi ha diversos rols, i les variables s'han d'associar amb un valor, però no funciona;
  • Tenir dificultats per explicar als altres com funciona la lògica de les variables dels teus llibres de jugades

Ens hem trobat amb aquests problemes en projectes de la nostra empresa, com a resultat de la qual cosa hem arribat a les regles de format de variables en els nostres llibres de jugades, que en certa mesura resolen aquests problemes.

Aproximació del sistema a les variables a Ansible

Variables en els rols

Un rol és un objecte del sistema de desplegament independent. Com qualsevol objecte del sistema, ha de tenir una interfície per interactuar amb la resta del sistema. Les variables de rol són aquesta interfície.

Preneu, per exemple, el paper api, que instal·la una aplicació Java al servidor. Quines variables té?

Aproximació del sistema a les variables a Ansible

Les variables de rol es poden dividir en 2 tipus per tipus:

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

Propietats variables són variables que defineixen el comportament d'un rol.

Consulta variables són variables el valor de les quals s'utilitza per designar recursos externs al rol.

Oients variables són variables el valor de les quals s'utilitza per formar variables de consulta.

D'altra banda, 1a, 2a, 2b són variables que no depenen de l'entorn (ferro, recursos externs, etc.) i que es poden omplir amb valors per defecte en el rol per defecte. Tanmateix, variables com 1.b i 2.c no es poden omplir amb valors que no siguin 'exemple', ja que canviaran d'estand a peu en funció de l'entorn.

estil de codi

  • El nom de la variable ha de començar pel nom del rol. D'aquesta manera, serà més fàcil esbrinar en el futur de quina funció és la variable i de quina és la responsable.
  • Quan utilitzeu variables en rols, heu d'assegurar-vos de seguir el principi d'encapsulació i utilitzar variables definides ja sigui en el propi rol o en els rols dels quals depèn l'actual.
  • Eviteu utilitzar diccionaris per a variables. Ansible no us permet substituir convenientment valors individuals en un diccionari.

    Un exemple de variable dolenta:

    myrole_user:
        login: admin
        password: admin

    Aquí, l'inici de sessió és la variable mediana i la contrasenya és la variable dependent. Però
    com que es combinen en un diccionari, l'hauràs d'especificar íntegrament
    Sempre. La qual cosa és molt incòmode. Millor d'aquesta manera:

    myrole_user_login: admin
    myrole_user_password: admin

Variables en llibres de jocs de desplegament

Quan compilem un llibre de jocs de desplegament (d'ara endavant anomenat llibre de jocs), ens adherim a la regla que s'ha de col·locar en un repositori separat. Igual que els rols: cadascun al seu propi repositori git. Això us permet adonar-vos que els rols i el llibre de jocs són diferents objectes independents del sistema de desplegament, i els canvis en un objecte no haurien d'afectar el funcionament de l'altre. Això s'aconsegueix canviant els valors per defecte de les variables.

En compilar un llibre de jugades, per resumir, és possible anul·lar els valors predeterminats de les variables de rol en dos llocs: a les variables del llibre de jocs i a les variables d'inventari.

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

* - Variables i Voltes

La diferència és que les variables del llibre de jugades sempre s'utilitzen quan es crida a llibres de jocs situats al mateix nivell amb ell. Això vol dir que aquestes variables són ideals per canviar els valors predeterminats de variables que no depenen de l'entorn. Per contra, les variables d'inventari només s'utilitzaran per a un entorn concret, la qual cosa és ideal per a variables específiques de l'entorn.

És important tenir en compte que la precedència de variables no us permetrà redefinir les variables primer a les variables del llibre de jocs i després per separat al mateix inventari.

Això vol dir que ja en aquesta etapa cal decidir si la variable depèn de l'entorn o no i col·locar-la al lloc correcte.

Per exemple, en un projecte, la variable responsable d'habilitar SSL va dependre de l'entorn durant molt de temps, ja que no vam poder habilitar SSL per motius aliens al nostre control en un dels estands. Després de solucionar aquest problema, es va convertir en un mitjà independent i es va passar a les variables del llibre de jocs.

Variables de propietat per a grups

Ampliem el nostre model de la figura 1 afegint 2 grups de servidors amb una aplicació Java diferent, però amb configuracions diferents.

Aproximació del sistema a les variables a Ansible

Imagineu com serà el llibre de jugades en aquest cas:

- hosts: myapi
  roles:
    - api

- hosts: bbauth
  roles:
    - auth

- hosts: ghauth
  roles:
    - auth

Tenim tres grups al llibre de jugades, per la qual cosa es recomana crear tants fitxers de grup en variables d'inventari group_vars i variables de llibre de jocs alhora. En aquest cas, un fitxer de grup és la descripció d'un component de la vostra aplicació al llibre de jugades. Quan obriu el fitxer de grup a les variables del llibre de jocs, veureu immediatament totes les diferències respecte al comportament predeterminat dels rols assignats al grup. En variables d'inventari: diferències en el comportament del grup d'estand a estand.

Estil de codi

  • Intenteu no utilitzar en absolut les variables host_vars, ja que no descriuen el sistema, sinó només un cas especial, que a la llarga portarà a preguntes: "Per què aquest host és diferent de la resta?", La resposta a la qual és no sempre és fàcil de trobar.

Variables d'enllaç

Tanmateix, es tracta de variables de propietat, però què passa amb les variables d'enllaç?
La seva diferència és que han de tenir el mateix valor en diferents grups.

Al principi n'hi havia la idea utilitzeu una construcció monstruosa de la forma:
hostvars[groups['bbauth'][0]]['auth_bind_port'], però immediatament va ser abandonat
perquè té defectes. En primer lloc, el volum. En segon lloc, la dependència d'un amfitrió específic del grup. En tercer lloc, cal recollir dades de tots els hosts abans d'iniciar el desplegament, si no volem obtenir un error de variable no definit.

Com a resultat, es va decidir utilitzar variables d'enllaç.

Variables d'enllaç són variables que pertanyen al llibre de jugades i són necessàries per enllaçar objectes del sistema.

Les variables d'enllaç s'emplenen a les variables generals del sistema group_vars/all/vars i es formen eliminant totes les variables d'oient de cada grup i afegint el nom del grup del qual s'ha eliminat l'oient al començament de la variable.

Així, s'assegura la uniformitat i la no intersecció de noms.

Intentem lligar variables de l'exemple anterior:

Aproximació del sistema a les variables a Ansible

Imagineu que tenim variables que depenen les unes de les altres:

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

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

Posem-ho en variables comunes group_vars/all/vars tots els oients i afegeix el nom del grup al nom:

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

Ara, canviant el valor del connector, estarem segurs que la sol·licitud anirà al mateix port.

Estil de codi

  • Com que els rols i els grups són objectes de sistema diferents, han de tenir noms diferents perquè les variables d'enllaç mostrin amb precisió que pertanyen a un grup de servidors específic i no a un rol del sistema.

Fitxers d'entorn

Els rols poden utilitzar fitxers que difereixen d'un entorn a un altre.

Els certificats SSL són un exemple d'aquests fitxers. Emmagatzemeu-los com a text
en una variable no és molt convenient. Però és convenient emmagatzemar el camí cap a ells dins d'una variable.

Per exemple, fem servir la variable api_ssl_key_file: "/path/to/file".

Com que és obvi que el certificat de clau canviarà d'un entorn a un altre, aquesta és una variable depenent de l'entorn, el que significa que s'ha de localitzar al fitxer
group_vars/myapi/vars inventari de variables i continguin el valor "per exemple".

La manera més convenient en aquest cas és posar el fitxer de claus al dipòsit del llibre de jocs al llarg del camí
files/prod/certs/myapi.key, aleshores el valor de la variable serà:
api_ssl_key_file: "prod/certs/myapi.key". La comoditat rau en el fet que les persones responsables de desplegar el sistema en un estand concret també tenen el seu propi lloc dedicat al repositori per emmagatzemar els seus fitxers. Al mateix temps, segueix sent possible especificar la ruta absoluta al certificat al servidor, en cas que els certificats siguin subministrats per un altre sistema.

Múltiples estands en un entorn

Sovint hi ha la necessitat de desplegar diversos estands gairebé idèntics al mateix entorn amb diferències mínimes. En aquest cas, dividim les variables dependents de l'entorn en les que no canvien dins d'aquest entorn i les que ho fan. I traiem aquest últim directament als mateixos fitxers d'inventari. Després d'aquesta manipulació, és possible crear un altre inventari directament al directori de l'entorn.

Reutilitzarà l'inventari group_vars i també podrà redefinir algunes variables directament per si mateix.

L'estructura de directoris final per al projecte de desplegament:

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

Resumint

Després d'organitzar les variables d'acord amb l'article: cada fitxer amb variables és responsable d'una tasca concreta. I com que el fitxer té determinades tasques, es va poder assignar una persona responsable de la correcció de cada fitxer. Per exemple, el desenvolupador del desplegament del sistema es fa responsable de l'ompliment correcte de les variables del llibre de jugades, mentre que l'administrador, el suport del qual es descriu a l'inventari, és el responsable directament d'omplir l'inventari de variables.

Els rols es van convertir en una unitat de desenvolupament autònoma amb la seva pròpia interfície, la qual cosa va permetre al desenvolupador de rols desenvolupar funcions en lloc d'adaptar la funció per adaptar-se al sistema. Aquest problema era especialment cert per als rols comuns de tots els sistemes d'una campanya.

Els administradors del sistema ja no necessiten entendre el codi de desplegament. Tot el que se'ls requereix per a un desplegament satisfactori és omplir els fitxers de variables d'entorn.

Literatura

  1. Registres

Autor

Kalyuzhny Denis Alexandrovich

Font: www.habr.com

Afegeix comentari