diff --git a/.woodpecker.yml b/.woodpecker.yml index b33d751..e97a28f 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -13,7 +13,11 @@ steps: image: python:3.11-slim commands: - pip install --no-cache-dir ansible - - ansible-playbook playbook/playbook.yml --check --list-tasks + - echo "$ANSIBLE_VAULT_PASSWORD" > .vault_pass + - ansible-galaxy collection install -r playbook/requirements.yml --force + - ansible-playbook playbook/playbook.yml --check --list-tasks \ + --vault-password-file .vault_pass -i 'localhost,' -c local -e 'gather_facts=false' + secrets: [ANSIBLE_VAULT_PASSWORD] run_preflight: when: @@ -21,7 +25,11 @@ steps: image: python:3.11-slim commands: - pip install --no-cache-dir ansible - - ansible-playbook playbook/playbook.yml --tags preflight -l pdp-portal --ask-vault-pass + - echo "$ANSIBLE_VAULT_PASSWORD" > .vault_pass + - ansible-galaxy collection install -r playbook/requirements.yml --force + - ansible-playbook playbook/playbook.yml --tags preflight -l pdp-portal \ + --vault-password-file .vault_pass + secrets: [ANSIBLE_VAULT_PASSWORD] run_patch: when: @@ -29,5 +37,8 @@ steps: image: python:3.11-slim commands: - pip install --no-cache-dir ansible + - echo "$ANSIBLE_VAULT_PASSWORD" > .vault_pass - ansible-galaxy collection install -r playbook/requirements.yml --force - - ansible-playbook playbook/playbook.yml -l pdp-portal -e "target_clm_version=prod-2024-06" --ask-vault-pass + - ansible-playbook playbook/playbook.yml -l pdp-portal -e "target_clm_version=prod-2024-06" \ + --vault-password-file .vault_pass + secrets: [ANSIBLE_VAULT_PASSWORD] diff --git a/ansible.cfg b/ansible.cfg index 448b7b3..27026ed 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,7 +1,7 @@ [defaults] inventory = playbook/servicenow_inventory.yml roles_path = playbook/roles -collections_paths = ~/.ansible/collections:./collections +collections_path = ~/.ansible/collections:./collections host_key_checking = False retry_files_enabled = False stdout_callback = yaml diff --git a/playbook/inventory_apps b/playbook/inventory_apps index 4a53391..f7e1872 100644 --- a/playbook/inventory_apps +++ b/playbook/inventory_apps @@ -22,7 +22,7 @@ app_mail=git-app@example.com # Optional: Gruppen für Umgebungen #[dev:children] #pdp-portal -git +#git #[prod:children] #confluence diff --git a/playbook/roles/compliance_check/tasks/main.yml b/playbook/roles/compliance_check/tasks/main.yml index bd76e38..418cab5 100644 --- a/playbook/roles/compliance_check/tasks/main.yml +++ b/playbook/roles/compliance_check/tasks/main.yml @@ -1,18 +1,21 @@ --- -- name: Compliance-Check: Führe OpenSCAP-Scan durch (sofern installiert) - shell: oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_standard --results {{ log_dir }}/oscap_result_{{ inventory_hostname }}.xml /usr/share/xml/scap/ssg/content/ssg-$(lsb_release -si | tr '[:upper:]' '[:lower:]')-ds.xml +- name: "Compliance-Check: Führe OpenSCAP-Scan durch (sofern installiert)" + ansible.builtin.shell: >- + oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_standard + --results {{ log_dir }}/oscap_result_{{ inventory_hostname }}.xml + /usr/share/xml/scap/ssg/content/ssg-$(lsb_release -si | tr '[:upper:]' '[:lower:]')-ds.xml register: oscap_result ignore_errors: true changed_when: false -- name: Compliance-Check: Führe Lynis-Scan durch (sofern installiert) - shell: lynis audit system --quiet --logfile {{ log_dir }}/lynis_{{ inventory_hostname }}.log +- name: "Compliance-Check: Führe Lynis-Scan durch (sofern installiert)" + ansible.builtin.shell: lynis audit system --quiet --logfile {{ log_dir }}/lynis_{{ inventory_hostname }}.log register: lynis_result ignore_errors: true changed_when: false - name: Sende Compliance-Report an Linux-Admins - mail: + community.general.mail: host: "localhost" port: 25 to: "{{ linux_admins_mail }}" diff --git a/playbook/roles/post_upgrade/tasks/main.yml b/playbook/roles/post_upgrade/tasks/main.yml index cb48ff2..c6a06ec 100644 --- a/playbook/roles/post_upgrade/tasks/main.yml +++ b/playbook/roles/post_upgrade/tasks/main.yml @@ -1,17 +1,17 @@ --- - name: Reboot nach Upgrade (optional) - reboot: + ansible.builtin.reboot: msg: "Reboot nach Auto-Upgrade" pre_reboot_delay: 60 when: reboot_after_upgrade tags: reboot -- name: Health-Check: Prüfe, ob kritische Dienste laufen - service_facts: +- name: "Health-Check: Prüfe, ob kritische Dienste laufen" + ansible.builtin.service_facts: tags: health - name: Prüfe Status der kritischen Dienste - assert: + ansible.builtin.assert: that: - "(services[item].state == 'running') or (services[item].state == 'started')" fail_msg: "Kritischer Dienst {{ item }} läuft nicht!" diff --git a/playbook/roles/preflight_check/tasks/main.yml b/playbook/roles/preflight_check/tasks/main.yml index 7f3c41c..f3dc0c3 100644 --- a/playbook/roles/preflight_check/tasks/main.yml +++ b/playbook/roles/preflight_check/tasks/main.yml @@ -1,14 +1,14 @@ --- -- name: Prüfe, ob aktueller Zeitpunkt im Maintenance-Window liegt - set_fact: +- name: "Prüfe, ob aktueller Zeitpunkt im Maintenance-Window liegt" + ansible.builtin.set_fact: now: "{{ lookup('pipe', 'date +%H:%M') }}" window_start: "{{ maintenance_window_start }}" window_end: "{{ maintenance_window_end }}" changed_when: false tags: preflight -- name: Maintenance-Window-Check (Abbruch, wenn außerhalb) - fail: +- name: "Maintenance-Window-Check (Abbruch, wenn außerhalb)" + ansible.builtin.fail: msg: "Aktuelle Zeit {{ now }} liegt außerhalb des Maintenance-Windows ({{ window_start }} - {{ window_end }}). Upgrade wird abgebrochen!" when: >- ( @@ -18,14 +18,14 @@ ) tags: preflight -- name: Prüfe freien Speicherplatz auf / (mind. 5GB empfohlen) - stat: +- name: "Prüfe freien Speicherplatz auf / (mind. 5GB empfohlen)" + ansible.builtin.stat: path: / register: root_stat tags: preflight - name: Warnung bei zu wenig Speicherplatz - assert: + ansible.builtin.assert: that: - root_stat.stat.avail_bytes > 5368709120 fail_msg: "Wenig freier Speicherplatz auf /: {{ root_stat.stat.avail_bytes | human_readable }} (mind. 5GB empfohlen)" @@ -33,7 +33,7 @@ tags: preflight - name: Prüfe Erreichbarkeit von SUSE Manager - uri: + ansible.builtin.uri: url: "{{ suma_api_url }}" method: GET validate_certs: no @@ -45,7 +45,7 @@ tags: preflight - name: Warnung, wenn SUSE Manager nicht erreichbar - assert: + ansible.builtin.assert: that: - suma_reachable.status is defined and suma_reachable.status == 200 fail_msg: "SUSE Manager API nicht erreichbar!" @@ -53,14 +53,14 @@ tags: preflight - name: Prüfe, ob VMware-Snapshot-Modul verfügbar ist - shell: "python3 -c 'import pyVmomi'" + ansible.builtin.shell: "python3 -c 'import pyVmomi'" register: pyvmomi_check ignore_errors: true changed_when: false tags: preflight - name: Warnung, wenn pyVmomi nicht installiert ist - assert: + ansible.builtin.assert: that: - pyvmomi_check.rc == 0 fail_msg: "pyVmomi (VMware-Modul) nicht installiert!" @@ -68,7 +68,7 @@ tags: preflight - name: Prüfe, ob aktueller SUSE Manager Channel synchronisiert ist - uri: + ansible.builtin.uri: url: "{{ suma_api_url }}" method: POST body_format: json @@ -91,7 +91,7 @@ tags: preflight - name: Hole Channel-Details für Ziel-CLM-Version - uri: + ansible.builtin.uri: url: "{{ suma_api_url }}" method: POST body_format: json @@ -114,7 +114,7 @@ tags: preflight - name: Prüfe Channel-Sync-Status - assert: + ansible.builtin.assert: that: - suma_channel_details.json.result.last_sync is defined fail_msg: "Channel {{ target_clm_version }} ist nicht synchronisiert!" @@ -122,7 +122,7 @@ tags: preflight - name: Slack-Benachrichtigung bei kritischen Fehlern (Beispiel) - slack: + community.general.slack: token: "{{ slack_token | default('xoxb-...') }}" msg: "[CRITICAL] Fehler beim Preflight-Check auf {{ inventory_hostname }}: {{ ansible_failed_result.msg | default('Unbekannter Fehler') }}" channel: "#linux-admins" diff --git a/playbook/roles/smoke_tests/tasks/main.yml b/playbook/roles/smoke_tests/tasks/main.yml index c85b2bc..b45e8bc 100644 --- a/playbook/roles/smoke_tests/tasks/main.yml +++ b/playbook/roles/smoke_tests/tasks/main.yml @@ -1,27 +1,26 @@ ---- - name: Prüfe, ob HTTP-Service installiert ist (Apache/Nginx) - stat: + ansible.builtin.stat: path: /usr/sbin/httpd register: apache_check ignore_errors: true - name: Prüfe, ob Nginx installiert ist - stat: + ansible.builtin.stat: path: /usr/sbin/nginx register: nginx_check ignore_errors: true -- name: Smoke-Test: Prüfe HTTP-Endpoint (nur wenn Web-Server installiert) - uri: +- name: "Smoke-Test: Prüfe HTTP-Endpoint (nur wenn Web-Server installiert)" + ansible.builtin.uri: url: "{{ smoke_test_url | default('http://localhost') }}" status_code: 200 - return_content: no + return_content: false register: http_result ignore_errors: true when: apache_check.stat.exists or nginx_check.stat.exists -- name: Smoke-Test: Prüfe offenen Port (optional) - wait_for: +- name: "Smoke-Test: Prüfe offenen Port (optional)" + ansible.builtin.wait_for: port: "{{ smoke_test_port | default(80) }}" host: "{{ smoke_test_host | default('localhost') }}" timeout: 5 @@ -29,41 +28,41 @@ ignore_errors: true - name: Prüfe, ob MySQL/MariaDB installiert ist - stat: + ansible.builtin.stat: path: /usr/bin/mysql register: mysql_check ignore_errors: true -- name: Smoke-Test: Prüfe Datenbankverbindung (nur wenn MySQL installiert) - shell: "echo 'select 1' | mysql -h {{ smoke_test_db_host | default('localhost') }} -u {{ smoke_test_db_user | default('root') }} --password={{ smoke_test_db_pass | default('') }} {{ smoke_test_db_name | default('') }}" +- name: "Smoke-Test: Prüfe Datenbankverbindung (nur wenn MySQL installiert)" + ansible.builtin.shell: "echo 'select 1' | mysql -h {{ smoke_test_db_host | default('localhost') }} -u {{ smoke_test_db_user | default('root') }} --password={{ smoke_test_db_pass | default('') }} {{ smoke_test_db_name | default('') }}" register: db_result ignore_errors: true when: mysql_check.stat.exists and smoke_test_db_host is defined - name: Prüfe, ob Oracle installiert ist - stat: + ansible.builtin.stat: path: /u01/app/oracle/product register: oracle_check ignore_errors: true -- name: Oracle DB: Finde alle Oracle SIDs (nur wenn Oracle installiert) - shell: | +- name: "Oracle DB: Finde alle Oracle SIDs (nur wenn Oracle installiert)" + ansible.builtin.shell: | ps -ef | grep -E "ora_pmon_[A-Z0-9_]+" | grep -v grep | awk '{print $NF}' | sed 's/ora_pmon_//' register: oracle_sids changed_when: false ignore_errors: true when: oracle_check.stat.exists -- name: Oracle DB: Finde alle Oracle Listener (nur wenn Oracle installiert) - shell: | +- name: "Oracle DB: Finde alle Oracle Listener (nur wenn Oracle installiert)" + ansible.builtin.shell: | ps -ef | grep -E "tnslsnr" | grep -v grep | awk '{print $NF}' | sed 's/tnslsnr//' register: oracle_listeners changed_when: false ignore_errors: true when: oracle_check.stat.exists -- name: Oracle DB: Prüfe alle gefundenen SIDs (nur wenn Oracle installiert) - shell: | +- name: "Oracle DB: Prüfe alle gefundenen SIDs (nur wenn Oracle installiert)" + ansible.builtin.shell: | export ORACLE_HOME={{ item.oracle_home | default('/u01/app/oracle/product/19.0.0/dbhome_1') }} export PATH=$ORACLE_HOME/bin:$PATH export ORACLE_SID={{ item.sid }} @@ -76,8 +75,8 @@ ignore_errors: true when: oracle_check.stat.exists and oracle_sids.stdout_lines | length > 0 -- name: Oracle DB: Prüfe alle gefundenen Listener (nur wenn Oracle installiert) - shell: | +- name: "Oracle DB: Prüfe alle gefundenen Listener (nur wenn Oracle installiert)" + ansible.builtin.shell: | export ORACLE_HOME={{ item.oracle_home | default('/u01/app/oracle/product/19.0.0/dbhome_1') }} export PATH=$ORACLE_HOME/bin:$PATH lsnrctl status {{ item.listener }} @@ -86,8 +85,8 @@ ignore_errors: true when: oracle_check.stat.exists and oracle_listeners.stdout_lines | length > 0 -- name: Oracle DB: Logge Oracle-Check-Ergebnisse (nur wenn Oracle installiert) - copy: +- name: "Oracle DB: Logge Oracle-Check-Ergebnisse (nur wenn Oracle installiert)" + ansible.builtin.copy: content: | Oracle DB Check für {{ inventory_hostname }} Zeit: {{ ansible_date_time.iso8601 }} @@ -100,7 +99,7 @@ when: oracle_check.stat.exists - name: Smoke-Test Ergebnis zusammenfassen - debug: + ansible.builtin.debug: msg: - "HTTP-Test: {{ http_result.status | default('NOT INSTALLED') }}" - "Port-Test: {{ port_result.state | default('FAILED') }}" diff --git a/playbook/roles/vmware_snapshot/tasks/main.yml b/playbook/roles/vmware_snapshot/tasks/main.yml index b62d9e4..0e3ccc3 100644 --- a/playbook/roles/vmware_snapshot/tasks/main.yml +++ b/playbook/roles/vmware_snapshot/tasks/main.yml @@ -1,6 +1,6 @@ --- - name: Erstelle VMware Snapshot vor Upgrade - vmware_guest_snapshot: + community.vmware.vmware_guest_snapshot: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_user }}" password: "{{ vcenter_password }}" @@ -20,23 +20,23 @@ delay: 10 - name: Logge Fehler bei Snapshot-Erstellung - copy: + ansible.builtin.copy: content: "Snapshot-Fehler: {{ snapshot_result.msg | default('Unbekannter Fehler') }}" dest: "{{ log_dir }}/snapshot_error_{{ inventory_hostname }}.log" when: snapshot_result is failed - name: Setze Rollback-Flag, falls Snapshot-Erstellung fehlschlägt - set_fact: + ansible.builtin.set_fact: rollback: true when: snapshot_result is failed - name: Breche Playbook ab, wenn Snapshot-Erstellung fehlschlägt - fail: + ansible.builtin.fail: msg: "Snapshot-Erstellung fehlgeschlagen, Upgrade wird abgebrochen! Siehe Log: {{ log_dir }}/snapshot_error_{{ inventory_hostname }}.log" when: snapshot_result is failed -- name: Rollback: Setze VM auf Snapshot zurück (nur bei Fehler und wenn aktiviert) - vmware_guest_snapshot: +- name: "Rollback: Setze VM auf Snapshot zurück (nur bei Fehler und wenn aktiviert)" + community.vmware.vmware_guest_snapshot: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_user }}" password: "{{ vcenter_password }}" @@ -50,7 +50,7 @@ delegate_to: localhost - name: Lösche VMware Snapshot nach erfolgreichem Patchlauf (optional) - vmware_guest_snapshot: + community.vmware.vmware_guest_snapshot: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_user }}" password: "{{ vcenter_password }}"