Sådan oprettes anvendelige stykker og playbøger - Del 5


I denne del 5 af Ansible Series vil vi forklare, hvordan man opretter Ansible Plays og Playbooks ved hjælp af Ansible-moduler.

Ansible skibe med enkeltstående scripts kaldet moduler, der bruges i playbøger til udførelse af specialiserede opgaver på eksterne noder.

Moduler er nyttige til automatisering af opgaver som pakkehåndtering, arkivering og kopiering af filer for blot at nævne nogle få. De giver dig mulighed for at foretage tweaks på konfigurationsfiler og administrere enheder såsom routere, switche, load balancere, firewalls og en række andre enheder.

Formålet med dette underemne er at give dig et overblik over forskellige opgaver, der kan udføres af Ansible-moduler:

Pakkehåndtering i Linux

Pakkehåndtering er en af de mest vigtige og hyppige opgaver, der udføres af systemadministratorer. Ansible leveres med moduler, der hjælper dig med at udføre pakkehåndteringsopgaver både i RedHat- og Debian-baserede systemer.

De er relativt lette at gætte. Der er apt-modulet til APT-pakkehåndtering til Debian-baseret, det gamle yum-modul til YUM-pakkehåndtering og dnf-modul forbundet med nyere RHEL-distributioner.

Nedenfor er et par eksempler på, hvordan modulerne kan bruges i en playbook:

---
- name: install Apache webserver
  hosts: webservers

  tasks:
       - name: install httpd
         dnf:  
          name: httpd  
          State: latest
---
- name: install Apache webserver
  hosts: databases

  tasks:
       - name: install Apache webserver
         apt:  
          name: apache2  
          State: latest

Servicemodul

Servicemodulet giver systemadministratorer mulighed for at starte, stoppe, opdatere, opgradere og genindlæse tjenester på systemet.

---
- name: Start service httpd, if not started
  service:
    name: httpd
    state: started
---
- name: Stop service httpd
  service:
    name: httpd
    state: stopped
---
- name: Restart network service for interface eth0
  service:
    name: network
    state: restarted
    args: enp2s0

Kopier modul

Som navnet antyder, kopierer modulet kopierede filer fra et sted på den eksterne maskine til en anden placering på den samme maskine.

---
- name: Copy file with owner and permissions
  copy:
    src: /etc/files/tecmint.conf
    dest: /srv/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: '0644'

Playbook kopierer konfigurationsfilen tecmint.conf fra/etc/files/directory til/srv/directory som tecmint-bruger med 0644 tilladelser.

Tilladelser kan også repræsenteres ved hjælp af symbolsk repræsentation som vist i sidste linje.

---
- name: Copy file with owner and permissions
  copy:
    src: /etc/files/tecmint.conf
    dest: /srv/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: u=rw, g=r, o=r

Tilladelserne i det foregående eksempel kan repræsenteres som vist på den sidste linje. Brugeren tildeles læse- og skrivetilladelser, gruppen tildeles skrivetilladelser, og resten af verden tildeles læsetilladelser.

Filmodul

Filmodulet bruges til at udføre mange filhandlinger, herunder oprettelse af filer og mapper, tildeling af filtilladelser og indstilling af symlinks.

---
- name: Change file ownership, group, and permissions
  file:
    path: /etc/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: '0644'

Ovenstående afspilning opretter en fil kaldet tecmint.conf i/etc-katalogindstillingsrettighederne til 0644.

---
- name: Remove file (delete file)
  file:
    path: /etc/tecmint.conf
    state: absent

Dette fjerner eller sletter filen tecmint.conf.

---
- name: create a directory if it doesn’t exist
  file:
    path: /etc/mydirectory
    State: directory
    mode: '0777'

Dette opretter en mappe i/etc-indstillingsrettighederne til 0777.

---
- name: Recursively deleting a  directory
  file:
    path: /etc/tecmint.conf
    state: absent

Ovenstående afspilning sletter rekursivt en mappe.

Lineinfile-modul

Lineinfile-modulet er nyttigt, når du vil ændre en enkelt linje i en fil. Det kan erstatte en eksisterende linje.

---
 - name: Ensure SELinux is set to enforcing mode
  lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: SELINUX=disabled

Afspilningen ovenfor indstiller SELINUX-værdien til deaktiveret.

SELINUX=disabled
---
- name: Add a line to a file if the file does not exist, without         passing regexp
  lineinfile:
    path: /etc/hosts
    line: 10.200.50.51 linux-console.net
    create: yes

Dette tilføjer posten 10.200.50.51 linux-console.net til filen/etc/hosts.

Arkivmodul

Et arkivmodul bruges til oprettelse af et komprimeret arkiv med en enkelt eller flere filer. Det antages, at kompressionskilden eksisterer, er til stede på måldestinationen. Efter arkivering kan kildefilen senere slettes eller fjernes ved hjælp af udsagnet remove = True .

- name: Compress directory /path/to/tecmint_dir/ into /path/to/tecmint.tgz
  archive:
    path: /path/to/tecmint_dir
    dest: /path/to/tecmint.tgz

This compresses the /path/to/tecmint_dir  directory to /path/to/tecmint.tgz
- name: Compress regular file /path/to/tecmint into /path/to/foo.gz and remove it
  archive:
    path: /path/to/tecmint
    dest: /path/to/tecmint.tgz
    remove: yes

I ovenstående afspilning slettes kildefilen/stien/til/tecmint, når arkiveringen er afsluttet.

- name: Create a bz2 archive of /path/to/tecmint
  archive:
    path: /path/to/tecmint
    format: bz2

Dette opretter en komprimeret fil i bz2-format fra/stien/til/tecmint-filen.

Git-modul

Modulet administrerer git-checkouts af softwarelagre.

- git:
    repo: 'https://foosball.example.org/path/to/repo.git'
    dest: /srv/checkout
    version: release-0.22

Kommandomodul

Et af de mest anvendte moduler, kommandomodulet tager kommandonavnet og senere efterfulgt af en liste med argumenter. Kommandoen sendes på samme måde, som du skriver en Linux-shell.

- name: Executing a command using the command module
  command: cat helloworld.txt
---
 - name: Check the remote host uptime
    hosts: servers
    tasks:
      - name: Execute the Uptime command over Command module
        register: uptimeoutput
        command: "uptime"

- debug:
          var: uptimeoutput.stdout_lines

Kommandomodulet henter oppetiden for eksterne servere.

Variabler til at hente resultaterne af kørende kommandoer

Ansible playbooks bruges normalt til at udføre opgaver på administrerede værter uden at vise output på kommandolinjen. Der er dog tilfælde, at du muligvis bliver bedt om at fange output eller resultater. I dette afsnit gennemgår vi, hvordan du kan optage output fra en playbook i en variabel og senere vise den.

Et ansible register bruges til at registrere en opgaves output og gemme det som en variabel. Variablen indeholder derefter opgavens stdout.

Lad os for eksempel antage, at du vil kontrollere diskbrug af administrerede noder i respektive rodmapper ved hjælp af kommandoen df -Th/. Du skal bruge 'command' -modulet til at definere kommandoen og 'register' for at gemme std-output i en variabel.

For at få vist kommandoen bruger du 'debug' -modulet sammen med stdout-returværdien.

---

 - hosts: all
   become: yes

   tasks:
     - name: Execute /boot usage on Hosts
       command: 'df -Th /'
       register: df

     - debug: var=df.stdout

Lad os nu køre playbook. I dette tilfælde har vi navngivet vores playbook check_disk_space.yml.

# ansible-playbook check_disk_space.yml

Som du har set, er produktionen sammenblandet og gør det svært at følge med.

For at justere output og gøre det lettere at læse skal du erstatte stdout-returværdien med stdout_lines.

---

 - hosts: all
   become: yes

   tasks:
     - name: Execute /boot usage on Hosts
       command: 'df -Th /'
       register: df

     - debug: var=df.stdout_lines

Brug Conditionals til at kontrollere Play Execution

Ligesom i programmeringssprog bruges betingede udsagn, når mere end et resultat er muligt. Lad os se på nogle af de almindeligt anvendte betingede udsagn i Ansible playbooks.

Nogle gange vil du måske udføre opgaver på bestemte noder og ikke andre. Betingelsen 'when' er ret nem at bruge og implementere i en playbook. Når du bruger 'når' -sætningen, skal du blot erklære tilstanden ved siden af klausulen som vist:

when: condition

Når betingelsen er opfyldt, udføres opgaven på fjernsystemet.

Lad os se et par eksempler:

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian”

Stykket ovenfor installerer Nginx webserver på værter, der kører Debian-familien af distroer.

Du kan også bruge operatoren ELLER og AND sammen med den når den betingede erklæring.

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian” and
           ansible_distribution_version == “18.04”

Når du bruger OG -operatøren, skal begge udsagn være opfyldt, for at opgaven skal udføres.

Afspilningen ovenfor installerer Nginx på noder, der kører en Debian-familie af OS, som er version 18.04. Dette vil åbenbart være Ubuntu 18.04.

Med operatøren ELLER udføres opgaven, hvis en af betingelserne er opfyldt.

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian” or
	      Ansible_os_family == “SUSE”

Afspilningen ovenfor installerer Nginx-webservere på enten Debian- eller SUSE-familien af OS eller dem begge.

BEMÆRK: Sørg altid for at bruge det dobbelte ligestillingstegn == , når du tester en tilstand.

Betingelser i løkker

Betingelser kan også bruges i en løkke. Sig for eksempel, at du har en liste over flere pakker, der skal installeres på eksterne noder.

I playbooken nedenfor har vi et array kaldet pakker, der indeholder en liste over pakker, der skal installeres. Disse opgaver udføres efter hinanden, hvis den krævede klausul er indstillet til Sand.

---
 - name: Install Software packages
    hosts: all
    vars:
	packages:
    • name: nginx
required: True
    • name: mysql
required: True
    • name: apache
required: False



   tasks:
    • name: Install “{{ item.name }}”on Debian
apt: 
 name: “{{ item.name }}”
 state: present 
When: item.required == True
loop: “{{ packages }}”  

Konfigurer fejlhåndtering

Nogle gange mislykkes opgaver, når der køres playbøger. Lad os antage, at du kører 5 opgaver på 3 servere som vist i playbook nedenfor. Hvis der opstår en fejl på opgave 3 (Start af MySQL) på server 2, stopper Ansible med at udføre de resterende opgaver på server 2 og forsøger at fuldføre de resterende opgaver på resten af serverne.

---
 - name: Install Software packages
   hosts: server1, server2, server3
   tasks:
- name: Install dependencies
<< some code >>

- name: Install MySQL database
<< some code >>

- name: Start MySQL
<< some code >>

- name: Install Nginx
<< some code >>

- name: Start Nginx
<< some code >>

Hvis du f.eks. Vil have konsistens i udførelsen af playbook, skal du stoppe eksekveringen af en playbook, hvis en af serverne mislykkes, skal du tilføje indstillingen.

---
 - name: Install Software packages
   hosts: server1, server2, server3
   any_errors_fatal:  true
   tasks:

På denne måde, hvis en opgave mislykkes på en server, stopper Ansible udførelsen af hele playbook på alle serverne og afslutter.

Hvis du vil have, at playbook ignorerer fejlene og fortsætter med at udføre det resterende sæt opgaver, skal du bruge alternativet ignore_errors: True.

---
 - name: Install Software packages
   hosts: server1, server2, server3
   tasks:
- name: Install dependencies
<< some code >>
     ignore_errors: True

Opret Playbooks for at konfigurere systemer til en bestemt tilstand

I dette afsnit ser vi på nogle ekstra muligheder, der er tilgængelige, når du kører en playbook.

Lad os begynde med indstillingen Kontroller eller Tørkørsel. Indstillingen tørkørsel eller kontroltilstand bruges, når du kører en playbook til at kontrollere, om der opstår fejl, og om der er ændringer, der vil blive foretaget på de administrerede værter. Det foretager dog ingen ændringer i fjernknudepunkterne.

For eksempel for at tørre en playbook kaldet httpd.yml , der installerer og starter Apache-webserverkørslen:

# ansible-playbook httpd.yml --check

Den anden mulighed, vi skal se på, er indstillingen --start-at-task . Dette bruges, når du angiver navnet på den opgave, som playbook skal begynde eller starte med.

Lad os tage et eksempel: Playbook nedenfor udelukker 2 opgaver: Det første play installerer Apache-webserveren og det andet installerer htop-værktøjet.

---
 - name: Install httpd

   hosts: all
   tasks:
    yum:	 
name: httpd
     state: Installed

- name: Install htop

      yum:  
      name: htop
      state: started

Hvis du vil springe over installationen af Apache-webserver og i stedet installere køreprogrammet htop:

# ansible-playbook playbook.yml --start-at-task “Install htop”

Endelig kan du tagge dine opgaver eller afspilninger ved at tilføje tagsindstillingen til din playbook som vist. Dette er praktisk, når du har en ganske stor playbook, og du vil køre specifikke opgaver fra hele playbook.

---
 - name: Install httpd
   tags: Install and start
   hosts: all
   tasks:
    yum:	 
name: httpd
     state: Installed

   tags: Install

    • service: 
name: httpd
state: started
# ansible-playbook playbook.yml -tags "Install"

For at udelade tags skal du bruge indstillingerne --skip-tags som vist.

# ansible-playbook playbook.yml --skip-tags "Install"

I dette emne tog vi dig gennem de almindeligt anvendte moduler i Ansible, hvordan du henter stdout fra udførelsen af en playbook til analyse, ved hjælp af betingelser i playbook og hvordan man håndterer fejl, der kan opstå, når du kører opgaver. Endelig genoptog vi konfigurationen af playbooks, og hvordan du kan bruge yderligere muligheder til at bestemme, hvilke opgaver der skal køres, hvis du ikke har til hensigt at køre hele playbook.