====== 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]] --- - 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 > ansible-playbook -i inventory.yml -l test01 playbook_update.yml > ansible-playbook -i inventory.yml -l test02 playbook_update.yml --- servers: hosts: test01: ansible_host: 10.10.3.11 become: true test02: ansible_host: 10.10.3.12 become: true --- ansible_python_interpreter: "/usr/bin/python3" SSHDCFG: "/etc/ssh/sshd_config" NTP_SERVER1: "192.168.20.5" NTP_SERVER2: "10.10.11.1" --- #------------------------------------------------------------------------------# # 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" --- # ----------------------------------------------------------- # 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 --- - 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 ===== --- - name: Dateien und Verzeichnisse löschen file: path: "{{ item }}" state: absent with_items: - /eine/datei.txt - /ein/verzeichnis/ --- # 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 }} ===== LineInFile ===== --- # ----------------------------------------------------------- # 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 ===== BlockInFile ===== [[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/blockinfile_module.html]] - name: Insert/Update HTML surrounded by custom markers after line ansible.builtin.blockinfile: path: /var/www/html/index.html marker: "" insertafter: "" block: |

Welcome to {{ ansible_hostname }}

Last updated on {{ ansible_date_time.iso8601 }}

- name: Remove HTML as well as surrounding markers ansible.builtin.blockinfile: path: /var/www/html/index.html marker: "" block: "" - name: Textblock aus der Datei entfernen ansible.builtin.blockinfile: path: /tmp/test.txt marker: "# {mark} Sicherheitssektion" block: "" state: absent aaa bbb ccc # BEGIN Sicherheitssektion ddd eee fff # END Sicherheitssektion ===== 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]] - 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' - 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'