Systeminställning till variabler i Ansible

ansible devops codestyle

Hallå! Mitt namn är Denis Kalyuzhny Jag arbetar som ingenjör på avdelningen för utvecklingsprocessautomation. Varje dag rullas nya applikationsbyggen ut till hundratals kampanjservrar. Och i den här artikeln delar jag med mig av min erfarenhet av att använda Ansible för dessa ändamål.

Den här guiden erbjuder ett sätt att organisera variabler i en distribution. Den här guiden är designad för dig som redan använder roller i sina spelböcker och läser Bästa metodermen stöter på liknande problem:

  • Efter att ha hittat en variabel i koden är det omöjligt att omedelbart förstå vad den är ansvarig för;
  • Det finns flera roller, och variablerna måste associeras med ett värde, men det fungerar inte;
  • Har svårt att förklara för andra hur logiken i variablerna i dina spelböcker fungerar

Vi stötte på dessa problem i projekt i vårt företag, vilket ledde till att vi kom till reglerna för formatering av variabler i våra spelböcker, vilket till viss del löste dessa problem.

Systeminställning till variabler i Ansible

Variabler i roller

En roll är ett separat Deployment System Object. Som alla objekt i systemet måste det ha ett gränssnitt för att interagera med resten av systemet. Rollvariabler är ett sådant gränssnitt.

Ta till exempel rollen api, som installerar en Java-applikation på servern. Vilka variabler har den?

Systeminställning till variabler i Ansible

Rollvariabler kan delas in i två typer efter typ:

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

Variabla egenskaper är variabler som definierar en rolls beteende.

Frågevariabler är variabler vars värde används för att ange resurser utanför rollen.

Varierande lyssnare är variabler vars värde används för att bilda frågevariabler.

Å andra sidan är 1a, 2a, 2b variabler som inte är beroende av miljön (järn, externa resurser etc.) och kan fyllas med standardvärden i standardrollen. Variabler som 1.b och 2.c kan dock inte fyllas med andra värden än "exempel", eftersom de kommer att förändras från stativ till stativ beroende på miljön.

kodstil

  • Namnet på variabeln måste börja med rollens namn. Detta kommer att göra det enkelt att i framtiden ta reda på vilken roll variabeln kommer från och vad den är ansvarig för.
  • När du använder variabler i roller måste du vara säker på att följa principen om inkapsling och använda variabler definierade antingen i själva rollen eller i de roller som den aktuella beror på.
  • Undvik att använda ordböcker för variabler. Ansible låter dig inte enkelt åsidosätta individuella värden i en ordbok.

    Ett exempel på en dålig variabel:

    myrole_user:
        login: admin
        password: admin

    Här är inloggning medianvariabeln och lösenord är den beroende variabeln. Men
    eftersom de är kombinerade till en ordbok måste du ange den i sin helhet
    Alltid. Vilket är väldigt obekvämt. Bättre så här:

    myrole_user_login: admin
    myrole_user_password: admin

Variabler i distributionsspelböcker

När vi kompilerar en distributionsspelbok (hädanefter kallad en spelbok) följer vi regeln att den ska placeras i ett separat arkiv. Precis som roller: var och en i sitt eget git-förråd. Detta gör att du kan inse att rollerna och spelboken är olika oberoende objekt i distributionssystemet, och ändringar i ett objekt bör inte påverka driften av det andra. Detta uppnås genom att ändra standardvärdena för variablerna.

När du kompilerar en playbook, för att sammanfatta, är det möjligt att åsidosätta standardvärdena för rollvariabler på två ställen: i playbook-variabler och i inventeringsvariabler.

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

* - Variabler och valv

Skillnaden är att playbook-variabler alltid används när man anropar playbooks som ligger på samma nivå som den. Detta betyder att dessa variabler är bra för att ändra standardvärdena för variabler som inte är beroende av miljön. Omvänt kommer inventeringsvariabler endast att användas för en viss miljö, vilket är idealiskt för miljöspecifika variabler.

Det är viktigt att notera att variabelprioritet inte tillåter dig att omdefiniera variabler först i playbook-variabler och sedan separat i samma inventering.

Det betyder att du redan i detta skede behöver ta ställning till om variabeln är miljöberoende eller inte och placera den på rätt plats.

Till exempel i ett projekt var variabeln som ansvarade för att aktivera SSL miljöberoende under lång tid, eftersom vi inte kunde aktivera SSL av skäl utanför vår kontroll vid en av montrarna. Efter att vi åtgärdat det här problemet blev det mediumoberoende och flyttade till playbook-variabler.

Egenskapsvariabler för grupper

Låt oss utöka vår modell i figur 1 genom att lägga till 2 grupper av servrar med en annan Java-applikation, men med olika inställningar.

Systeminställning till variabler i Ansible

Föreställ dig hur spelboken kommer att se ut i det här fallet:

- hosts: myapi
  roles:
    - api

- hosts: bbauth
  roles:
    - auth

- hosts: ghauth
  roles:
    - auth

Vi har tre grupper i playbook, så det rekommenderas att skapa så många gruppfiler i group_vars inventeringsvariabler och playbook-variabler samtidigt. En gruppfil i det här fallet är beskrivningen av en komponent i din applikation i spelboken. När du öppnar gruppfilen i playbook-variablerna ser du omedelbart alla skillnader från standardbeteendet för rollerna som tilldelats gruppen. I lagervariabler: skillnader i gruppbeteende från monter till monter.

Kodstil

  • Försök att inte använda host_vars-variabler alls, eftersom de inte beskriver systemet, utan bara ett specialfall, vilket i det långa loppet kommer att leda till frågor: "Varför är denna värd annorlunda än resten?", Svaret på vilket är inte alltid lätt att hitta.

Länkvariabler

Det handlar dock om egenskapsvariabler, men hur är det med länkvariabler?
Deras skillnad är att de måste ha samma värde i olika grupper.

I början fanns det idé använd en monstruös konstruktion av formen:
hostvars[groups['bbauth'][0]]['auth_bind_port'], men det övergavs omedelbart
eftersom det har brister. Först, skrymmande. För det andra beroendet av en specifik värd i gruppen. För det tredje är det nödvändigt att samla in fakta från alla värdar innan vi startar distributionen, om vi inte vill få ett odefinierat variabelfel.

Som ett resultat beslutades det att använda länkvariabler.

Länkvariabler är variabler som hör till spelboken och som behövs för att länka systemobjekt.

Länkvariabler fylls i i allmänna systemvariabler group_vars/all/vars och bildas genom att ta bort alla lyssnarvariabler från varje grupp och lägga till namnet på gruppen från vilken lyssnaren togs bort i början av variabeln.

Därmed säkerställs enhetligheten och icke-korsningen av namn.

Låt oss försöka binda variabler från exemplet ovan:

Systeminställning till variabler i Ansible

Föreställ dig att vi har variabler som är beroende av varandra:

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

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

Låt oss lägga det i vanliga variabler group_vars/all/vars alla lyssnare och lägg till namnet på gruppen till namnet:

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

Nu, genom att ändra värdet på kontakten, kommer vi att vara säkra på att begäran kommer att gå till samma plats där porten är placerad.

Kodstil

  • Eftersom roller och grupper är olika objekt i systemet måste du ha olika namn på dem, då kommer länkvariablerna korrekt att visa att de tillhör en specifik grupp av servrar, och inte till en roll i systemet.

Miljöfiler

Roller kan använda filer som skiljer sig från miljö till miljö.

SSL-certifikat är ett exempel på sådana filer. Lagra dem som text
i en variabel är inte särskilt bekvämt. Men det är bekvämt att lagra sökvägen till dem i en variabel.

Vi använder till exempel variabeln api_ssl_key_file: "/path/to/file".

Eftersom det är uppenbart att nyckelcertifikatet kommer att ändras från miljö till miljö är detta en miljöberoende variabel, vilket betyder att den ska finnas i filen
group_vars/myapi/vars inventering av variabler, och innehåller värdet "till exempel".

Det bekvämaste sättet i det här fallet är att lägga nyckelfilen i playbook-förrådet längs vägen
files/prod/certs/myapi.key, då blir variabelns värde:
api_ssl_key_file: "prod/certs/myapi.key". Bekvämligheten ligger i det faktum att de personer som ansvarar för att distribuera systemet på en viss monter också har sin egen dedikerade plats i förvaret för att lagra sina filer. Samtidigt är det fortfarande möjligt att ange den absoluta sökvägen till certifikatet på servern, om certifikaten levereras av ett annat system.

Flera montrar i en miljö

Ofta finns det behov av att placera ut flera nästan identiska montrar i samma miljö med minimala skillnader. I det här fallet delar vi in ​​miljöberoende variabler i de som inte förändras inom den här miljön och de som gör det. Och vi tar ut det senare direkt i själva inventeringsfilerna. Efter denna manipulation blir det möjligt att skapa ytterligare en inventering direkt i miljökatalogen.

Den kommer att återanvända group_vars-inventeringen och även kunna omdefiniera vissa variabler direkt för sig själv.

Den slutliga katalogstrukturen för distributionsprojektet:

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

Summering

Efter att ha organiserat variablerna i enlighet med artikeln: varje fil med variabler är ansvarig för en specifik uppgift. Och eftersom filen har vissa uppgifter blev det möjligt att tilldela en person som ansvarar för att varje fil är korrekt. Till exempel blir utvecklaren av systemimplementeringen ansvarig för korrekt fyllning av playbook-variablerna, medan administratören, vars ställning beskrivs i inventeringen, är direkt ansvarig för att fylla i inventeringen av variabler.

Roller blev en fristående utvecklingsenhet med ett eget gränssnitt, vilket gjorde det möjligt för rollutvecklaren att utveckla funktioner snarare än att skräddarsy rollen för att passa systemet. Det här problemet gällde särskilt gemensamma roller för alla system i en kampanj.

Systemadministratörer behöver inte längre förstå distributionskoden. Allt som krävs av dem för en framgångsrik distribution är att fylla i filerna med miljövariabler.

Litteratur

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

Författare

Kalyuzhny Denis Alexandrovich

Källa: will.com

Lägg en kommentar