Benutzer-Werkzeuge

Webseiten-Werkzeuge


ansible

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
ansible [2023-12-15 15:53:25] manfredansible [2024-04-04 16:02:21] (aktuell) – [Wenn-Sonst] manfred
Zeile 1: Zeile 1:
 +====== Ansible ======
 +
 +  * [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html|ansible.builtin.file]]
 +  * [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html|ansible.builtin.lineinfile]]
 +  * [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/blockinfile_module.html|ansible.builtin.blockinfile]]
 +  * [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/replace_module.html|ansible.builtin.replace]]
 +  * [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html|ansible.builtin.user]]
 +  * [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/group_module.html|ansible.builtin.group]]
 +  * [[https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html|ansible.posix.authorized_key]]
 +  * [[https://docs.ansible.com/ansible/latest/collections/ansible/posix/mount_module.html|ansible.posix.mount]]
 +  * [[https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_conditionals.html|Conditionals]]
 +  * [[https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_lookups.html|Lookups]]
 +
 +<code python>
 +---
 +- name: PlayBook Betriebssystemversion anzeigen
 +  hosts: all
 +  gather_facts: yes
 +  become: true
 +  tasks:
 +
 +    - name: "jammy"
 +      ansible.builtin.debug:
 +        var: ansible_facts.lsb.codename
 +
 +    - name: "Ubuntu 22.04.4 LTS"
 +      ansible.builtin.debug:
 +        var: ansible_facts.lsb.description
 +
 +    - name: "Ubuntu"
 +      ansible.builtin.debug:
 +        var: ansible_facts.lsb.id
 +
 +    - name: "22"
 +      ansible.builtin.debug:
 +        var: ansible_facts.lsb.major_release
 +
 +    - name: "22.04"
 +      ansible.builtin.debug:
 +        var: ansible_facts.lsb.release
 +</code>
 +
 +  > ansible-playbook -i inventory.yml -l test01 playbook_update.yml
 +  > ansible-playbook -i inventory.yml -l test02 playbook_update.yml
 +
 +<file python inventory.yml>
 +---
 +servers:
 +  hosts:
 +    test01:
 +      ansible_host: 10.10.3.11
 +      become: true
 +    test02:
 +      ansible_host: 10.10.3.12
 +      become: true
 +</file>
 +
 +<file python include_variables.yml>
 +---
 +ansible_python_interpreter: "/usr/bin/python3"
 +  
 +SSHDCFG: "/etc/ssh/sshd_config"
 +
 +NTP_SERVER1: "192.168.20.5"
 +NTP_SERVER2: "10.10.11.1"
 +</file>
 +
 +<file python include_users.yml>
 +---
 +#------------------------------------------------------------------------------#
 +# SFTP-Benutzer definieren
 +#------------------------------------------------------------------------------#
 +#
 +# Der User, bei dem Gruppenname und Benutzername sind gleich, ist ein "Master",
 +# alle weiteren User, die mit dieser gleichen Gruppe angelegt werden,
 +# sind "Kunden" unterhalb dieses Masters.
 +#
 +# Wenn bei einem User der Gruppenname und der Benutzername gleich sind,
 +# dann wird sein Home-Verzeichnis ganz normal unterhalb von /home angelegt.
 +# Sind diese Namen unterschiedlich, dann wird sein Home-Verzeichnis unterhalb
 +# dessen Home-Verzeichnis angelegt, dessen Benutzername dem eigenen Gruppennamen
 +# entspricht.
 +#
 +# Ein "Master" hat kein "datadir", ein "Kunde" braucht immer ein "datadir"!
 +#
 +#------------------------------------------------------------------------------#
 +    users:
 +      - name: "sftp"
 +        gruppe: "sftp"
 +        shell: "/bin/bash"
 +        ssh_key: "{{ lookup('file', 'ssh-keys/sftp.pub') }}"
 +        password: "!"
 +        comment: "Master-User"
 +    
 +      - name: "otto"
 +        gruppe: "sftp"
 +        shell: "/bin/bash"
 +        ssh_key: "{{ lookup('file', 'ssh-keys/otto.pub') }}"
 +        password: "!"
 +        comment: "Otto der Filmemacher"
 +        datadir: "DATEN"
 +    
 +      - name: "fritz"
 +        gruppe: "sftp"
 +        shell: "/bin/bash"
 +        ssh_key: "{{ lookup('file', 'ssh-keys/fritz.pub') }}"
 +        password: "!"
 +        comment: "Fritzchen klein ging allein"
 +        datadir: "DATEN"
 +</file>
 +
 +<file python playbook_update.yml>
 +---
 +# -----------------------------------------------------------
 +# Upgrade
 +# -----------------------------------------------------------
 +- name: "Update"
 +  gather_facts: false
 +  become: true
 +  hosts: servers
 +  tasks:
 +    # -------------------------------------------------------
 +    #  IPv6 abschalten
 +    # -------------------------------------------------------
 +    - name: Deactivate ipv6 perm
 +      lineinfile:
 +        path: /etc/default/grub
 +        state: present
 +        regexp: '^GRUB_CMDLINE_LINUX='
 +        line: 'GRUB_CMDLINE_LINUX="ipv6.disable=1"'
 +
 +    - name: Deactivate ipv6 temp
 +      ansible.builtin.shell: |
 +        sysctl -w net.ipv6.conf.all.disable_ipv6=1
 +        sysctl -w net.ipv6.conf.default.disable_ipv6=1
 +        update-grub
 +        exit 0
 +      args:
 +        executable: /bin/bash
 +
 +    - name: Restart systemd-resolved
 +      service:
 +        name: systemd-resolved
 +        state: restarted
 +
 +    # -------------------------------------------------------
 +    #  apt-get dist-upgrade
 +    # -------------------------------------------------------
 +    - name: Perform a dist-upgrade.
 +      ansible.builtin.apt:
 +        upgrade: dist
 +        update_cache: yes
 +
 +    - name: Check if a reboot is required.
 +      ansible.builtin.stat:
 +        path: /var/run/reboot-required
 +        get_md5: no
 +      register: reboot_required_file
 +
 +    - name: Reboot the server (if required).
 +      ansible.builtin.reboot:
 +      when: reboot_required_file.stat.exists == true
 +
 +    - name: Remove dependencies that are no longer required.
 +      apt:
 +        autoremove: yes
 +
 +    - name: Check the Uptime of the servers
 +      shell: "uptime"
 +      register: Uptime
 +
 +    - debug: var=Uptime.stdout
 +
 +    ### TASK install basic
 +    - name: Install Tools server
 +      apt:
 +        update_cache: yes
 +        name:
 +          - systemd-timesyncd
 +          - vim
 +          - screen
 +          - mc
 +        state: present
 +</file>
 +
 +<file python playbook_add_user.yml>
 +---
 +- hosts: servers
 +  gather_facts: true
 +  become_user: root
 +  become: true
 +  tasks:
 +
 +#==============================================================================#
 +### SSHD/SFTP-Konfiguration - Anfang
 +#------------------------------------------------------------------------------#
 +### die letzte Sektion wird entfernt, weil sie immer am Ende bleiben muss
 +### und hier aber noch etwas hinzugefühgt (bzw. eingeschoben) werden soll
 +
 +    # 330 # Sicherheitssektion entfernen
 +    - name: Textblock aus der Datei entfernen
 +      ansible.builtin.blockinfile:
 +        path: "{{SSHDCFG}}"
 +        marker: "# {mark} Sicherheitssektion"
 +        block: ""
 +        state: absent
 +
 +#----------------------------------------------------------------------#
 +### Das SFTP-Sub-System mus umgestellt werden
 +
 +    - name: SFTP-User umask 0002
 +      ansible.builtin.lineinfile:
 +        path: "{{SSHDCFG}}"
 +        line: Subsystem sftp internal-sftp -u 002 -l VERBOSE
 +        create: yes
 +
 +    #--------------------------------------------------------------------------#
 +    # SFTP-Log
 +    #--------------------------------------------------------------------------#
 +    # 350 # SSHD/SFTP - überprüfen und ggf. konfigurieren
 +    - name: SFTP - logadmin einrichten
 +      ansible.builtin.lineinfile:
 +        path: "{{SSHDCFG}}"
 +        line: "{{ item }}"
 +        create: yes
 +      with_items:
 +        - '# Log internal-sftp in a separate file'
 +        - ':programname, isequal, "internal-sftp" -/var/log/sftp.log'
 +        - ':programname, isequal, "internal-sftp" ~'
 +
 +    #--------------------------------------------------------------------------#
 +    # 365 # spezieller Benutzer zum lesen von Logs
 +    - name: SFTP - SSHD-CFG für logadmin
 +      ansible.builtin.lineinfile:
 +        path: "{{SSHDCFG}}"
 +        line: "{{ item }}"
 +        create: yes
 +      with_items:
 +        - '# Create an additional socket for some of the sshd chrooted users.'
 +        - '$AddUnixListenSocket /home/logadmin/dev/log'
 +        - '#========================================================================#'
 +        - 'Match user logadmin'
 +        - '        ChrootDirectory %h'
 +        - '        X11Forwarding no'
 +        - '        AllowTcpForwarding no'
 +        - '        ForceCommand internal-sftp -l VERBOSE'
 +
 +#==============================================================================#
 +### SSHD/SFTP-Konfiguration - Mitte
 +
 +#------------------------------------------------------------------------------#
 +### Master: item['name'] == item['gruppe']
 +
 +    - name: Master-Gruppe anlegen
 +      ansible.builtin.group:
 +        name: "{{ item['gruppe'] }}"
 +        state: present
 +        local: false
 +        non_unique: false
 +      when: item['name'] == item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +    - name: Master-Benutzer anlegen
 +      ansible.builtin.user:
 +        name: "{{ item['name'] }}"
 +        group: "{{ item['gruppe'] }}"
 +        home: "/home/{{ item['name'] }}"
 +        comment: "{{ item['comment'] }}"
 +        password: "{{ item.password | default('!') }}"
 +        state: present
 +        umask: 0002
 +        append: false
 +        create_home: true
 +        generate_ssh_key: false
 +        local: false
 +        non_unique: false
 +      when: item['name'] == item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +    - name: Rechte vom Master-Home-Verzeichnis setzen
 +      ansible.builtin.file:
 +        path: "/home/{{ item['name'] }}"
 +        owner: root
 +        group: root
 +        mode: '0755'
 +        recurse: false
 +        state: directory
 +      when: item['name'] == item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +    - name: Rechte vom Master-DEV-Verzeichnis setzen
 +      ansible.builtin.file:
 +        path: "/home/{{ item['name'] }}/dev"
 +        owner: root
 +        group: root
 +        mode: '0755'
 +        recurse: false
 +        state: directory
 +      when: item['name'] == item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +    - name: Rechte vom Master-SSH-Verzeichnis setzen
 +      ansible.builtin.file:
 +        path: "/home/{{ item['name'] }}/.ssh"
 +        owner: "{{ item['name'] }}"
 +        group: root
 +        mode: '0755'
 +        recurse: false
 +        state: directory
 +      when: item['name'] == item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +#------------------------------------------------------------------------------#
 +### Kunden: item['name'] != item['gruppe']
 +
 +    - name: Kunde-Benutzer anlegen
 +      ansible.builtin.user:
 +        name: "{{ item['name'] }}"
 +        group: "{{ item['gruppe'] }}"
 +        home: "/home/{{ item['gruppe'] }}/{{ item['name'] }}"
 +        comment: "{{ item['comment'] }}"
 +        password: "{{ item.password | default('!') }}"
 +        state: present
 +        umask: 0002
 +        append: false
 +        create_home: true
 +        generate_ssh_key: false
 +        local: false
 +        non_unique: false
 +      when: item['name'] != item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +    - name: Rechte vom Kunden-Home-Verzeichnis setzen
 +      ansible.builtin.file:
 +        path: "/home/{{ item['gruppe'] }}/{{ item['name'] }}"
 +        owner: root
 +        group: root
 +        mode: '0755'
 +        recurse: false
 +        state: directory
 +      when: item['name'] != item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +    - name: Rechte vom Kunden-DEV-Verzeichnis setzen
 +      ansible.builtin.file:
 +        path: "/home/{{ item['gruppe'] }}/{{ item['name'] }}/dev"
 +        owner: root
 +        group: root
 +        mode: '0755'
 +        recurse: false
 +        state: directory
 +      when: item['name'] != item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +    - name: Rechte vom Kunden-SSH-Verzeichnis setzen
 +      ansible.builtin.file:
 +        path: "/home/{{ item['gruppe'] }}/{{ item['name'] }}/.ssh"
 +        owner: "{{ item['name'] }}"
 +        group: root
 +        mode: '0755'
 +        recurse: false
 +        state: directory
 +      when: item['name'] != item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +    - name: Rechte vom Kunden-DATADIR-Verzeichnis setzen
 +      ansible.builtin.file:
 +        path: "/home/{{ item['gruppe'] }}/{{ item['name'] }}/{{ item['datadir'] }}"
 +        owner: "{{ item['name'] }}"
 +        group: "{{ item['gruppe'] }}"
 +        mode: '0755'
 +        recurse: false
 +        state: directory
 +      when: item['name'] != item['gruppe']
 +      with_items:
 +        - "{{ users }}"
 +
 +#------------------------------------------------------------------------------#
 +### Alle Benutzer
 +
 +    - name: SSH-Schlüssel ablegen
 +      authorized_key:
 +        user: "{{ item['name'] }}"
 +        key: "{{ item['ssh_key'] }}"
 +        state: present
 +      with_items:
 +        - "{{ users }}"
 +
 +#==============================================================================#
 +### SSHD/SFTP-Konfiguration - Ende
 +#------------------------------------------------------------------------------#
 +    #--------------------------------------------------------------------------#
 +    # Sicherheitssektion
 +
 +    - name: "Textblock an die Datei anhängen / der muß immer ganz unten in der Datei sein"
 +      ansible.builtin.blockinfile:
 +        path: "{{SSHDCFG}}"
 +        marker: "# {mark} Sicherheitssektion"
 +        block: "#------------------------------------------------------------------------------#\nMatch group !root,!admin,*\n\t
 +                ChrootDirectory /tmp\n\t
 +                X11Forwarding no\n\t
 +                AllowTcpForwarding no\n\t
 +                ForceCommand internal-sftp -l VERBOSE\n#------------------------------------------------------------------------------#"
 +        state: present
 +
 +    #--------------------------------------------------------------------------#
 +    - name: Restart sshd
 +        service:
 +          name: sshd
 +          state: restarted
 +          enabled: true
 +</file>
 +
 +
 +
 +===== File =====
 +
 +<code python>
 +---
 +- name: Dateien und Verzeichnisse löschen
 +  file:
 +    path:  "{{ item }}"
 +    state: absent
 +  with_items:
 +    - /eine/datei.txt
 +    - /ein/verzeichnis/
 +</code>
 +
 +<code python>
 +---
 +# Inhalte von einem Verzeichnis löschen; z.B. von einem Mount-Point
 +- block:
 +  - name: Dateien im Verzeichnis einlesen
 +    find:
 +      paths: "/etc/nginx/modules-enabled"
 +      hidden: True
 +      recurse: True
 +    register: collected_files
 +
 +  - name: Sym-Links im Verzeichnis einlesen
 +    find:
 +      paths: "/etc/nginx/modules-enabled"
 +      hidden: True
 +      recurse: True
 +      file_type: link
 +    register: collected_link
 +
 +  - name: Unterverzeichnisse einlesen
 +    find:
 +      paths: "/etc/nginx/modules-enabled"
 +      hidden: True
 +      recurse: True
 +      file_type: directory
 +    register: collected_directories
 +
 +  - name: entferne Dateien und Unterverzeichnisse aus dem Verzeichnis
 +    file:
 +      path: "{{ item.path }}"
 +      state: absent
 +    with_items: >
 +      {{
 +        collected_files.files
 +        + collected_link.files
 +        + collected_directories.files
 +      }}
 +</code>
 +
 +
 +===== LineInFile =====
 +
 +<code python>
 +---
 +# -----------------------------------------------------------
 +# Tests
 +# -----------------------------------------------------------
 +- name: "Install Squid on remote hosts"
 +  gather_facts: false
 +  become: true
 +  hosts: servers
 +  vars_files:
 +    - include_variables.yml
 +
 +  # https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html#examples
 +  tasks:
 +    - name: Add a line to a file if the file does not exist, without passing regexp
 +      ansible.builtin.lineinfile:
 +        path: /tmp/testfile
 +        line: 192.168.1.99 foo.lab.net foo
 +        create: yes
 +</code>
 +
 +
 +===== BlockInFile =====
 +
 +[[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/blockinfile_module.html]]
 +
 +<code python>
 +- name: Insert/Update HTML surrounded by custom markers after <body> line
 +  ansible.builtin.blockinfile:
 +    path: /var/www/html/index.html
 +    marker: "<!-- {mark} ANSIBLE MANAGED BLOCK -->"
 +    insertafter: "<body>"
 +    block: |
 +      <h1>Welcome to {{ ansible_hostname }}</h1>
 +      <p>Last updated on {{ ansible_date_time.iso8601 }}</p>
 +</code>
 +
 +<code python>
 +- name: Remove HTML as well as surrounding markers
 +  ansible.builtin.blockinfile:
 +    path: /var/www/html/index.html
 +    marker: "<!-- {mark} ANSIBLE MANAGED BLOCK -->"
 +    block: ""
 +</code>
 +
 +<code python>
 +    - name: Textblock aus der Datei entfernen
 +      ansible.builtin.blockinfile:
 +        path: /tmp/test.txt
 +        marker: "# {mark} Sicherheitssektion"
 +        block: ""
 +        state: absent
 +</code>
 +
 +<file bash /tmp/test.txt>
 +aaa
 +bbb
 +ccc
 +# BEGIN Sicherheitssektion
 +ddd
 +eee
 +fff
 +# END Sicherheitssektion
 +</file>
 +
 +
 +===== Wenn-Sonst =====
 +
 +Wenn die Major-Versionsnummer eine "22" (von "Ubuntu 22.04") ist, dann bleibt der Wert in der Variable ''php_version'' auf "8.1", sonst wird er mit "7.2" überschrieben:
 +  ### OS-Schalter
 +- name: Ubuntu 22.04 LTS
 +  set_fact:
 +    php_version: "8.1"
 +    percona_repo_version: "80"
 +  when:
 +    ansible_facts.lsb.major_release == "22"
 +
 +
 +===== cut / split =====
 +
 +[[https://www.middlewareinventory.com/blog/ansible-split-examples/]]
 +
 +  ### ein einfaches Beispiel, hier wird die Zeichenkette einer E-Mail beim ''@'' getrennt
 +  ---
 +  - name: Ansible Split Example 1
 +    hosts: localhost
 +    tasks:
 +      - name: Split Simple String Example
 +        debug: msg={{ 'sarav@gritfy.com'|split('@')}}
 +
 +  ### in diesem Beispiel wird eine Zeichenkette bei bestimmten Zeichen (-) getrennt
 +  ---
 +  - name: Ansible Split Example 2
 +    hosts: localhost
 +    vars:
 +      var1: dos-e1-south-209334567829102380
 +    tasks:
 +      - set_fact:
 +          var2: "{{ var1.split('-') }}"
 +      - debug:
 +          msg: "{{ var2.0 }}-{{ var2.1 }}-{{ var2.2 }}"
 +
 +  ### in diesem Beispiel wird alles nach dem letzten Trennzeichen (-), einschließlich des Trennzeiches selbst, per RegEx entfernt
 +  ---
 +  - name: Ansible Split Example 3
 +    hosts: localhost
 +    vars:
 +      var: dos-e1-south-209334567829102380
 +    tasks:
 +      - debug:
 +          msg: '{{ var | regex_replace("^(.*)-[^-]+$", "\\1") }}'
 +
 +Die Ausgaben von Beispiel 2 und 3 sind identisch und lauten: ''%%    "msg": "dos-e1-south"%%''
 +
 +  Erklärung der im 3. Beispiel verwendeten RegEx:
 +  
 +  ^(.*)
 +  behalte alles vom Beginn im Zwischenspeicher (1. Zwischenspeicher)
 +  
 +  -[^-]+$
 +  finde das "-", welches von einer Zeichenkette gefolgt wird, die kein "-" enthält (kurz gesagt: finde das letzte "-") samt der Zeichen bis zum Zeilenende
 +  
 +  \\1
 +  ersetze die Zeichenkette durch den Inhalt aus dem 1. Zwischenspeicher
 +
 +  ### man kann auch mehrere Zeichenketten mit einem Spaltentrenner (-) wieder zu einer einzigen Zeichenkette zusammensetzen
 +      - debug:
 +          msg: "{{ var2[0:3] | join('-') }}"
 +
 +  ### in diesem Beispiel wird eine Datei eingelesen, zeilenweise bearbeitet und die einzelnen Zeilen werden beim '':'' getrennt und der Inhalt der ersten Spalte wird ausgegeben
 +  ---
 +  - name: Ansible Split Example 4
 +    hosts: localhost
 +    vars: 
 +      - usernames : []
 +    tasks:
 +      - name: print only domain names from Email IDs with Split
 +        set_fact:        
 +          usernames: '{{ usernames + [ item | split(":") | first ] }}'
 +        loop: "{{ lookup('file', '/etc/passwd').splitlines() | select('match','^(?!#)')}}"
 +        
 +      - debug: var=usernames
 +
 +
 +===== SED / regex_replace =====
 +
 +[[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/replace_module.html]]
 +
 +<code python>
 +    - name: Replace old hostname with new hostname (requires Ansible >= 2.4)
 +      ansible.builtin.replace:
 +        path: /etc/hosts
 +        regexp: '(\s+)old\.host\.name(\s+.*)?$'
 +        replace: '\1new.host.name\2'
 +</code>
 +
 +<code python>
 +    - name: Supports a validate command
 +      ansible.builtin.replace:
 +        path: /etc/apache/ports
 +        regexp: '^(NameVirtualHost|Listen)\s+80\s*$'
 +        replace: '\1 127.0.0.1:8080'
 +        validate: '/usr/sbin/apache2ctl -f %s -t'
 +</code>
 +