rebecca 3574b47a5f Initialize infrastructure maintenance scripts with Ansible playbooks
Add Ansible-based maintenance scripts for infrastructure operations:
- CVE scanner using NIST NVD database
- Package update checker with OpenAI risk assessment
- Docker cleanup playbook
- Log archiver for rotated logs
- Disk space analyzer

Supports Ubuntu 20.04/22.04/24.04, Debian 11/12/13, and Alpine Linux
2026-01-22 10:37:08 -03:00

111 lines
4.0 KiB
YAML

---
- name: Identify Packages with CVE Vulnerabilities
hosts: all
gather_facts: true
vars:
cve_nvd_api_url: "https://services.nvd.nist.gov/rest/json/cves/2.0"
output_file: "/tmp/cve_report_{{ ansible_date_time.iso8601_basic_short }}.json"
results_per_page: 2000
tasks:
- name: Detect OS family and set package manager
set_fact:
pkg_mgr: "{{ 'apt' if ansible_os_family == 'Debian' else 'apk' if ansible_os_family == 'Alpine' else 'unknown' }}"
- name: Ensure required packages are installed
package:
name:
- curl
- jq
state: present
- name: Get installed packages with versions (Debian/Ubuntu)
command: dpkg-query -W -f='${Package}\t${Version}\n'
register: installed_packages_debian
changed_when: false
when: ansible_os_family == 'Debian'
- name: Get installed packages with versions (Alpine)
command: apk info -vv
register: installed_packages_alpine
changed_when: false
when: ansible_os_family == 'Alpine'
- name: Parse package list into dictionary
set_fact:
package_dict: "{{ installed_packages_debian.stdout | default('') | split('\n') | select('match', '^.+\t.+$') | map('regex_replace', '^(.+?)\\t(.+)$', '{\"name\": \"\\1\", \"version\": \"\\2\"}') | map('from_json') | list }}"
when: ansible_os_family == 'Debian'
- name: Parse Alpine package list into dictionary
set_fact:
package_dict: "{{ installed_packages_alpine.stdout | default('') | split('\n') | select('match', '^.+-.+$') | map('regex_replace', '^(.+?)-([0-9].+)$', '{\"name\": \"\\1\", \"version\": \"\\2\"}') | map('from_json') | list }}"
when: ansible_os_family == 'Alpine'
- name: Query NVD CVE database for each package
uri:
url: "{{ cve_nvd_api_url }}"
method: GET
return_content: true
validate_certs: false
headers:
User-Agent: "Ansible-CVE-Scanner/1.0"
register: nvd_response
failed_when: false
until: nvd_response.status == 200
retries: 3
delay: 2
- name: Extract CVE data from NVD response
set_fact:
cve_data: "{{ nvd_response.content | from_json | json_query('vulnerabilities[*]') }}"
when: nvd_response.status == 200
- name: Match CVEs with installed packages
set_fact:
cve_findings: >-
{{ cve_findings | default([]) +
[{
'package': item.package_name,
'version': item.version,
'cves': cve_data | selectattr('cve.id', 'defined') |
selectattr('cve.descriptions[*].value', 'contains', item.package_name) |
map(attribute='cve') | list,
'hostname': ansible_hostname,
'ip_address': ansible_default_ipv4.address,
'os': ansible_distribution + ' ' + ansible_distribution_version,
'scan_date': ansible_date_time.iso8601
}]
}}
loop: "{{ package_dict }}"
loop_control:
loop_var: item
vars:
package_name: "{{ item.name }}"
version: "{{ item.version }}"
- name: Filter packages with CVEs
set_fact:
affected_packages: "{{ cve_findings | selectattr('cves', 'defined') | selectattr('cves', 'length', 'gt', 0) | list }}"
- name: Generate CVE report JSON
copy:
dest: "{{ output_file }}"
content: "{{ affected_packages | to_json(indent=2) }}"
mode: '0600'
- name: Display CVE summary
debug:
msg: "Found {{ affected_packages | length }} packages with CVEs. Report saved to {{ output_file }}"
- name: Return CVE findings
set_fact:
cve_report:
hostname: ansible_hostname
ip_address: ansible_default_ipv4.address
os: ansible_distribution + ' ' + ansible_distribution_version
total_packages: package_dict | length
packages_with_cves: affected_packages | length
findings: affected_packages
scan_date: ansible_date_time.iso8601
report_file: output_file