package services // PlaybookTemplate Playbook模板定义 type PlaybookTemplate struct { ID string `json:"id"` Name string `json:"name"` Category string `json:"category"` Description string `json:"description"` Icon string `json:"icon"` Content string `json:"content"` Tags []string `json:"tags"` } // TemplateCategory 模板分类 type TemplateCategory struct { ID string `json:"id"` Name string `json:"name"` Icon string `json:"icon"` Count int `json:"count"` } // GetTemplateCategories 获取所有模板分类 func GetTemplateCategories() []TemplateCategory { cats := map[string]TemplateCategory{} for _, t := range GetPlaybookTemplates() { c, ok := cats[t.Category] if !ok { c = TemplateCategory{ID: t.Category, Name: categoryNames[t.Category], Icon: categoryIcons[t.Category]} } c.Count++ cats[t.Category] = c } var result []TemplateCategory // 按固定顺序输出 order := []string{"system", "web", "database", "container", "devops", "security", "monitoring"} for _, id := range order { if c, ok := cats[id]; ok { result = append(result, c) } } return result } var categoryNames = map[string]string{ "system": "系统管理", "web": "Web服务", "database": "数据库", "container": "容器化", "devops": "DevOps", "security": "安全加固", "monitoring": "监控告警", } var categoryIcons = map[string]string{ "system": "🖥️", "web": "🌐", "database": "🗄️", "container": "🐳", "devops": "🔧", "security": "🔒", "monitoring": "📊", } // GetPlaybookTemplates 获取所有Playbook模板 func GetPlaybookTemplates() []PlaybookTemplate { return []PlaybookTemplate{ // ===== 系统管理 ===== { ID: "update-packages", Name: "系统包更新", Category: "system", Description: "自动更新系统软件包,支持Debian/RedHat系列", Icon: "📦", Tags: []string{"update", "apt", "yum"}, Content: `--- - name: 系统包更新 hosts: "{{ target_hosts | default('all') }}" become: yes vars: update_cache: yes upgrade_type: dist # dist(完整升级) 或 safe(安全升级) tasks: - name: 更新apt缓存 apt: update_cache: yes when: ansible_os_family == "Debian" - name: 升级所有包(Debian) apt: upgrade: "{{ upgrade_type }}" autoremove: yes autoclean: yes when: ansible_os_family == "Debian" - name: 更新yum缓存 yum: update_cache: yes when: ansible_os_family == "RedHat" - name: 升级所有包(RedHat) yum: name: "*" state: latest when: ansible_os_family == "RedHat" - name: 检查是否需要重启 stat: path: /var/run/reboot-required register: reboot_required when: ansible_os_family == "Debian" - name: 提示重启 debug: msg: "⚠️ 系统需要重启以完成更新" when: ansible_os_family == "Debian" and reboot_required.stat.exists `, }, { ID: "check-system", Name: "系统信息采集", Category: "system", Description: "采集操作系统、硬件、网络等详细信息", Icon: "🔍", Tags: []string{"info", "facts", "inventory"}, Content: `--- - name: 系统信息采集 hosts: "{{ target_hosts | default('all') }}" gather_facts: yes tasks: - name: 操作系统信息 debug: msg: | ══════════ 系统信息 ══════════ 主机名: {{ ansible_facts['hostname'] }} 系统: {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }} 内核: {{ ansible_facts['kernel'] }} 架构: {{ ansible_facts['architecture'] }} CPU: {{ ansible_facts['processor_vcpus'] }} vCPUs 内存: {{ (ansible_facts['memtotal_mb'] / 1024) | round(2) }} GB IP: {{ ansible_facts['default_ipv4']['address'] | default('N/A') }} ═══════════════════════════════ - name: 磁盘使用 shell: df -h | grep -E '^/dev/' register: disk_info - name: 显示磁盘 debug: msg: "{{ disk_info.stdout_lines }}" - name: 运行时间 shell: uptime -p register: uptime_info - name: 显示运行时间 debug: msg: "运行时间: {{ uptime_info.stdout }}" `, }, { ID: "check-resources", Name: "资源监控检查", Category: "system", Description: "检查CPU/内存/磁盘使用率,超阈值告警", Icon: "📈", Tags: []string{"monitor", "cpu", "memory", "disk"}, Content: `--- - name: 资源监控检查 hosts: "{{ target_hosts | default('all') }}" gather_facts: yes vars: warn_threshold: 80 crit_threshold: 90 tasks: - name: 获取CPU使用率 shell: top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1 register: cpu_result changed_when: false - name: 获取内存使用率 shell: free | grep Mem | awk '{printf "%.0f", $3/$2*100}' register: mem_result changed_when: false - name: 获取磁盘使用率 shell: df -h / | tail -1 | awk '{print $5}' | tr -d '%' register: disk_result changed_when: false - name: 显示资源报告 debug: msg: | ═══════ {{ inventory_hostname }} 资源报告 ═══════ CPU 使用率: {{ cpu_result.stdout }}% 内存使用率: {{ mem_result.stdout }}% 磁盘使用率: {{ disk_result.stdout }}% 告警阈值: {{ warn_threshold }}% / 严重: {{ crit_threshold }}% ═══════════════════════════════════════ - name: 严重告警 fail: msg: "🚨 严重: {{ inventory_hostname }} 资源使用率超过 {{ crit_threshold }}%" when: > (cpu_result.stdout | int >= crit_threshold) or (mem_result.stdout | int >= crit_threshold) or (disk_result.stdout | int >= crit_threshold) `, }, { ID: "log-cleanup", Name: "日志清理", Category: "system", Description: "清理系统日志、临时文件,释放磁盘空间", Icon: "🧹", Tags: []string{"cleanup", "log", "disk"}, Content: `--- - name: 日志清理 hosts: "{{ target_hosts | default('all') }}" become: yes vars: log_retention_days: 30 tmp_retention_days: 7 tasks: - name: 清理journal日志 shell: journalctl --vacuum-time={{ log_retention_days }}d register: journal_result changed_when: "'Vacuuming' in journal_result.stdout" - name: 清理旧日志文件 find: paths: /var/log patterns: "*.gz,*.old,*.[0-9]" age: "{{ log_retention_days }}d" register: old_logs - name: 删除旧日志 file: path: "{{ item.path }}" state: absent loop: "{{ old_logs.files }}" - name: 清理临时文件 find: paths: /tmp age: "{{ tmp_retention_days }}d" register: tmp_files - name: 删除临时文件 file: path: "{{ item.path }}" state: absent loop: "{{ tmp_files.files }}" ignore_errors: yes - name: 清理apt缓存 apt: autoclean: yes when: ansible_os_family == "Debian" - name: 显示磁盘空间 shell: df -h / register: disk_after - name: 清理完成 debug: msg: "{{ disk_after.stdout_lines }}" `, }, { ID: "time-sync", Name: "时间同步(NTP)", Category: "system", Description: "配置NTP时间同步,确保集群时间一致", Icon: "⏰", Tags: []string{"ntp", "time", "chrony"}, Content: `--- - name: 时间同步配置 hosts: "{{ target_hosts | default('all') }}" become: yes vars: ntp_servers: - ntp.aliyun.com - ntp1.aliyun.com - pool.ntp.org tasks: - name: 安装chrony package: name: chrony state: present - name: 配置NTP服务器 lineinfile: path: /etc/chrony.conf regexp: "^server " line: "server {{ item }} iburst" create: yes loop: "{{ ntp_servers }}" - name: 启动chrony service: name: chronyd state: started enabled: yes - name: 验证时间同步 shell: chronyc tracking register: chrony_status changed_when: false - name: 显示同步状态 debug: msg: "{{ chrony_status.stdout_lines }}" `, }, // ===== Web服务 ===== { ID: "deploy-nginx", Name: "部署Nginx", Category: "web", Description: "安装配置Nginx,支持自定义站点和反向代理", Icon: "🌐", Tags: []string{"nginx", "web", "proxy"}, Content: `--- - name: 部署Nginx hosts: "{{ target_hosts | default('all') }}" become: yes vars: nginx_worker_processes: auto nginx_worker_connections: 1024 server_name: localhost listen_port: 80 proxy_pass: "" root_dir: /var/www/html tasks: - name: 安装Nginx package: name: nginx state: present - name: 创建网站目录 file: path: "{{ root_dir }}" state: directory owner: www-data group: www-data mode: '0755' when: ansible_os_family == "Debian" - name: 创建网站目录(RedHat) file: path: "{{ root_dir }}" state: directory owner: nginx group: nginx mode: '0755' when: ansible_os_family == "RedHat" - name: 部署默认页面 copy: content: | {{ server_name }}

Deployed by Ansible Deploy

Server: {{ inventory_hostname }}

dest: "{{ root_dir }}/index.html" when: proxy_pass == "" - name: 配置Nginx站点 copy: content: | server { listen {{ listen_port }}; server_name {{ server_name }}; {% if proxy_pass != "" %} location / { proxy_pass {{ proxy_pass }}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } {% else %} root {{ root_dir }}; index index.html; location / { try_files $uri $uri/ =404; } {% endif %} } dest: /etc/nginx/conf.d/{{ server_name }}.conf notify: Reload Nginx - name: 启动Nginx service: name: nginx state: started enabled: yes handlers: - name: Reload Nginx service: name: nginx state: reloaded `, }, { ID: "deploy-apache", Name: "部署Apache", Category: "web", Description: "安装配置Apache HTTP Server", Icon: "🪶", Tags: []string{"apache", "httpd", "web"}, Content: `--- - name: 部署Apache hosts: "{{ target_hosts | default('all') }}" become: yes vars: server_name: localhost listen_port: 80 document_root: /var/www/html tasks: - name: 安装Apache(Debian) apt: name: apache2 state: present when: ansible_os_family == "Debian" - name: 安装Apache(RedHat) yum: name: httpd state: present when: ansible_os_family == "RedHat" - name: 创建网站目录 file: path: "{{ document_root }}" state: directory mode: '0755' - name: 部署测试页面 copy: content: "

Apache on {{ inventory_hostname }}

" dest: "{{ document_root }}/index.html" - name: 启动Apache(Debian) service: name: apache2 state: started enabled: yes when: ansible_os_family == "Debian" - name: 启动Apache(RedHat) service: name: httpd state: started enabled: yes when: ansible_os_family == "RedHat" `, }, // ===== 数据库 ===== { ID: "deploy-mysql", Name: "部署MySQL", Category: "database", Description: "安装MySQL/MariaDB,配置root密码和基础优化", Icon: "🐬", Tags: []string{"mysql", "mariadb", "database"}, Content: `--- - name: 部署MySQL hosts: "{{ target_hosts | default('all') }}" become: yes vars: mysql_root_password: "ChangeMe@2024" mysql_port: 3306 mysql_max_connections: 500 mysql_datadir: /var/lib/mysql tasks: - name: 安装MySQL(Debian) apt: name: - mysql-server - mysql-client - python3-pymysql state: present when: ansible_os_family == "Debian" - name: 安装MariaDB(RedHat) yum: name: - mariadb-server - mariadb - python3-PyMySQL state: present when: ansible_os_family == "RedHat" - name: 启动MySQL service: name: "{{ 'mysql' if ansible_os_family == 'Debian' else 'mariadb' }}" state: started enabled: yes - name: 设置root密码 shell: | mysql -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password }}'; FLUSH PRIVILEGES;" ignore_errors: yes no_log: true - name: 优化配置 copy: content: | [mysqld] port = {{ mysql_port }} max_connections = {{ mysql_max_connections }} datadir = {{ mysql_datadir }} innodb_buffer_pool_size = 256M character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 dest: /etc/mysql/conf.d/optimize.cnf when: ansible_os_family == "Debian" notify: Restart MySQL - name: 验证MySQL shell: mysql -u root -p{{ mysql_root_password }} -e "SELECT VERSION();" register: mysql_version changed_when: false no_log: true - name: 显示版本 debug: msg: "MySQL版本: {{ mysql_version.stdout_lines[-1] | default('unknown') }}" handlers: - name: Restart MySQL service: name: "{{ 'mysql' if ansible_os_family == 'Debian' else 'mariadb' }}" state: restarted `, }, { ID: "deploy-redis", Name: "部署Redis", Category: "database", Description: "安装Redis,配置密码、内存限制和持久化", Icon: "🔴", Tags: []string{"redis", "cache", "database"}, Content: `--- - name: 部署Redis hosts: "{{ target_hosts | default('all') }}" become: yes vars: redis_port: 6379 redis_password: "ChangeMe@2024" redis_maxmemory: "512mb" redis_maxmemory_policy: allkeys-lru redis_bind: "0.0.0.0" tasks: - name: 安装Redis package: name: redis-server state: present when: ansible_os_family == "Debian" - name: 安装Redis(RedHat) yum: name: redis state: present when: ansible_os_family == "RedHat" - name: 配置Redis lineinfile: path: /etc/redis/redis.conf regexp: "{{ item.regexp }}" line: "{{ item.line }}" loop: - { regexp: '^bind ', line: 'bind {{ redis_bind }}' } - { regexp: '^port ', line: 'port {{ redis_port }}' } - { regexp: '^requirepass ', line: 'requirepass {{ redis_password }}' } - { regexp: '^maxmemory ', line: 'maxmemory {{ redis_maxmemory }}' } - { regexp: '^maxmemory-policy ', line: 'maxmemory-policy {{ redis_maxmemory_policy }}' } notify: Restart Redis - name: 启动Redis service: name: "{{ 'redis-server' if ansible_os_family == 'Debian' else 'redis' }}" state: started enabled: yes - name: 验证Redis shell: redis-cli -a {{ redis_password }} ping register: redis_ping changed_when: false no_log: true - name: 显示状态 debug: msg: "Redis状态: {{ redis_ping.stdout }}" handlers: - name: Restart Redis service: name: "{{ 'redis-server' if ansible_os_family == 'Debian' else 'redis' }}" state: restarted `, }, { ID: "deploy-postgresql", Name: "部署PostgreSQL", Category: "database", Description: "安装PostgreSQL,配置用户和基础优化", Icon: "🐘", Tags: []string{"postgresql", "postgres", "database"}, Content: `--- - name: 部署PostgreSQL hosts: "{{ target_hosts | default('all') }}" become: yes vars: postgres_version: "15" postgres_password: "ChangeMe@2024" postgres_port: 5432 postgres_max_connections: 200 tasks: - name: 安装PostgreSQL(Debian) apt: name: - postgresql - postgresql-contrib - python3-psycopg2 state: present when: ansible_os_family == "Debian" - name: 安装PostgreSQL(RedHat) yum: name: - postgresql-server - postgresql-contrib - python3-psycopg2 state: present when: ansible_os_family == "RedHat" - name: 初始化数据库(RedHat) shell: postgresql-setup --initdb when: ansible_os_family == "RedHat" ignore_errors: yes - name: 启动PostgreSQL service: name: postgresql state: started enabled: yes - name: 设置postgres密码 become_user: postgres shell: psql -c "ALTER USER postgres PASSWORD '{{ postgres_password }}';" no_log: true - name: 验证安装 become_user: postgres shell: psql -c "SELECT version();" register: pg_version changed_when: false - name: 显示版本 debug: msg: "{{ pg_version.stdout_lines[0] | default('PostgreSQL installed') }}" `, }, // ===== 容器化 ===== { ID: "deploy-docker", Name: "部署Docker", Category: "container", Description: "安装Docker CE + Docker Compose,配置镜像加速", Icon: "🐳", Tags: []string{"docker", "container", "compose"}, Content: `--- - name: 部署Docker hosts: "{{ target_hosts | default('all') }}" become: yes vars: docker_mirror: "https://mirror.ccs.tencentyun.com" docker_data_root: /var/lib/docker docker_log_max_size: "100m" docker_log_max_file: "3" tasks: - name: 安装依赖(Debian) apt: name: - apt-transport-https - ca-certificates - curl - gnupg - lsb-release state: present when: ansible_os_family == "Debian" - name: 添加Docker GPG密钥 shell: | curl -fsSL https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg when: ansible_os_family == "Debian" ignore_errors: yes - name: 添加Docker仓库 shell: | echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable" > /etc/apt/sources.list.d/docker.list when: ansible_os_family == "Debian" - name: 安装Docker(Debian) apt: name: - docker-ce - docker-ce-cli - containerd.io - docker-compose-plugin state: present update_cache: yes when: ansible_os_family == "Debian" - name: 安装Docker(RedHat) yum: name: - docker - docker-compose-plugin state: present when: ansible_os_family == "RedHat" - name: 配置Docker copy: content: | { "data-root": "{{ docker_data_root }}", "registry-mirrors": ["{{ docker_mirror }}"], "log-driver": "json-file", "log-opts": { "max-size": "{{ docker_log_max_size }}", "max-file": "{{ docker_log_max_file }}" }, "storage-driver": "overlay2", "live-restore": true } dest: /etc/docker/daemon.json notify: Restart Docker - name: 启动Docker service: name: docker state: started enabled: yes - name: 添加用户到docker组 user: name: "{{ ansible_user }}" groups: docker append: yes ignore_errors: yes - name: 验证Docker shell: docker version --format '{{.Server.Version}}' register: docker_ver changed_when: false - name: 显示版本 debug: msg: "Docker版本: {{ docker_ver.stdout }}" handlers: - name: Restart Docker service: name: docker state: restarted `, }, { ID: "deploy-portainer", Name: "部署Portainer", Category: "container", Description: "部署Portainer CE容器管理面板", Icon: "🎛️", Tags: []string{"portainer", "docker", "ui"}, Content: `--- - name: 部署Portainer hosts: "{{ target_hosts | default('all') }}" become: yes vars: portainer_port: 9443 portainer_data: /opt/portainer tasks: - name: 创建数据目录 file: path: "{{ portainer_data }}" state: directory - name: 拉取并启动Portainer shell: | docker volume create portainer_data docker run -d \ -p 8000:8000 \ -p {{ portainer_port }}:9443 \ --name portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:latest register: portainer_result ignore_errors: yes - name: 显示访问地址 debug: msg: "Portainer已部署: https://{{ ansible_host | default(inventory_hostname) }}:{{ portainer_port }}" `, }, // ===== DevOps ===== { ID: "deploy-nodejs", Name: "部署Node.js", Category: "devops", Description: "安装Node.js + PM2进程管理器", Icon: "💚", Tags: []string{"nodejs", "npm", "pm2"}, Content: `--- - name: 部署Node.js hosts: "{{ target_hosts | default('all') }}" become: yes vars: node_version: "20" install_pm2: true tasks: - name: 安装NodeSource仓库 shell: | curl -fsSL https://deb.nodesource.com/setup_{{ node_version }}.x | bash - when: ansible_os_family == "Debian" - name: 安装Node.js(Debian) apt: name: nodejs state: present update_cache: yes when: ansible_os_family == "Debian" - name: 安装Node.js(RedHat) yum: name: nodejs state: present when: ansible_os_family == "RedHat" - name: 安装PM2 npm: name: pm2 global: yes when: install_pm2 - name: 设置PM2开机启动 shell: pm2 startup systemd -u {{ ansible_user }} --hp /home/{{ ansible_user }} when: install_pm2 ignore_errors: yes - name: 验证安装 shell: node --version && npm --version register: node_ver changed_when: false - name: 显示版本 debug: msg: "{{ node_ver.stdout_lines }}" `, }, { ID: "deploy-python-app", Name: "部署Python应用", Category: "devops", Description: "配置Python环境 + Gunicorn + Systemd服务", Icon: "🐍", Tags: []string{"python", "gunicorn", "flask", "django"}, Content: `--- - name: 部署Python应用 hosts: "{{ target_hosts | default('all') }}" become: yes vars: app_name: myapp app_dir: /opt/myapp python_version: python3 venv_dir: /opt/myapp/venv gunicorn_port: 8000 gunicorn_workers: 4 app_user: www-data tasks: - name: 安装Python和依赖 package: name: - "{{ python_version }}" - "{{ python_version }}-venv" - python3-pip state: present - name: 创建应用目录 file: path: "{{ app_dir }}" state: directory owner: "{{ app_user }}" mode: '0755' - name: 创建虚拟环境 shell: "{{ python_version }} -m venv {{ venv_dir }}" args: creates: "{{ venv_dir }}/bin/activate" - name: 安装Gunicorn pip: name: gunicorn virtualenv: "{{ venv_dir }}" - name: 创建Systemd服务 copy: content: | [Unit] Description={{ app_name }} Gunicorn Service After=network.target [Service] User={{ app_user }} WorkingDirectory={{ app_dir }} ExecStart={{ venv_dir }}/bin/gunicorn --workers {{ gunicorn_workers }} --bind 0.0.0.0:{{ gunicorn_port }} app:app Restart=always [Install] WantedBy=multi-user.target dest: /etc/systemd/system/{{ app_name }}.service notify: Restart App - name: 启动服务 systemd: name: "{{ app_name }}" state: started enabled: yes daemon_reload: yes handlers: - name: Restart App systemd: name: "{{ app_name }}" state: restarted daemon_reload: yes `, }, { ID: "backup-data", Name: "数据备份", Category: "devops", Description: "定时备份指定目录到本地或远程", Icon: "💾", Tags: []string{"backup", "cron", "archive"}, Content: `--- - name: 数据备份 hosts: "{{ target_hosts | default('all') }}" become: yes vars: backup_source: /data backup_dest: /backup backup_retention_days: 7 backup_hour: "2" backup_minute: "0" tasks: - name: 创建备份目录 file: path: "{{ backup_dest }}" state: directory mode: '0700' - name: 创建备份脚本 copy: content: | #!/bin/bash DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="{{ backup_dest }}/backup_${DATE}.tar.gz" tar -czf "$BACKUP_FILE" {{ backup_source }} 2>/dev/null find {{ backup_dest }} -name "backup_*.tar.gz" -mtime +{{ backup_retention_days }} -delete echo "Backup completed: $BACKUP_FILE" dest: /usr/local/bin/backup.sh mode: '0755' - name: 配置定时任务 cron: name: "daily-backup" hour: "{{ backup_hour }}" minute: "{{ backup_minute }}" job: "/usr/local/bin/backup.sh >> /var/log/backup.log 2>&1" - name: 立即执行一次备份 shell: /usr/local/bin/backup.sh register: backup_result - name: 备份结果 debug: msg: "{{ backup_result.stdout }}" `, }, // ===== 安全加固 ===== { ID: "security-hardening", Name: "安全加固", Category: "security", Description: "SSH加固、防火墙配置、禁用root远程登录", Icon: "🔒", Tags: []string{"security", "ssh", "firewall", "hardening"}, Content: `--- - name: 安全加固 hosts: "{{ target_hosts | default('all') }}" become: yes vars: ssh_port: 22 disable_root_login: true enable_firewall: true allowed_ssh_users: [] tasks: - name: 修改SSH端口 lineinfile: path: /etc/ssh/sshd_config regexp: "^#?Port " line: "Port {{ ssh_port }}" notify: Restart SSH - name: 禁用root登录 lineinfile: path: /etc/ssh/sshd_config regexp: "^#?PermitRootLogin " line: "PermitRootLogin no" when: disable_root_login notify: Restart SSH - name: 禁用密码认证(仅密钥) lineinfile: path: /etc/ssh/sshd_config regexp: "^#?PasswordAuthentication " line: "PasswordAuthentication no" notify: Restart SSH - name: 设置SSH超时 lineinfile: path: /etc/ssh/sshd_config regexp: "^#?ClientAliveInterval " line: "ClientAliveInterval 300" notify: Restart SSH - name: 安装UFW(Debian) apt: name: ufw state: present when: ansible_os_family == "Debian" and enable_firewall - name: 配置UFW规则 shell: | ufw allow {{ ssh_port }}/tcp ufw allow 80/tcp ufw allow 443/tcp ufw --force enable when: ansible_os_family == "Debian" and enable_firewall - name: 安装fail2ban package: name: fail2ban state: present ignore_errors: yes - name: 启动fail2ban service: name: fail2ban state: started enabled: yes ignore_errors: yes - name: 加固完成 debug: msg: "✅ 安全加固完成 - SSH端口: {{ ssh_port }}, Root登录: {{ '禁用' if disable_root_login else '允许' }}" handlers: - name: Restart SSH service: name: "{{ 'ssh' if ansible_os_family == 'Debian' else 'sshd' }}" state: restarted `, }, { ID: "ssl-cert", Name: "SSL证书部署", Category: "security", Description: "使用Certbot自动申请Let's Encrypt证书", Icon: "📜", Tags: []string{"ssl", "https", "certbot", "letsencrypt"}, Content: `--- - name: SSL证书部署 hosts: "{{ target_hosts | default('all') }}" become: yes vars: domain: example.com email: admin@example.com webroot: /var/www/html tasks: - name: 安装Certbot package: name: - certbot - python3-certbot-nginx state: present - name: 申请证书 shell: | certbot certonly --webroot -w {{ webroot }} \ -d {{ domain }} \ --email {{ email }} \ --agree-tos --non-interactive args: creates: /etc/letsencrypt/live/{{ domain }}/fullchain.pem - name: 配置自动续期 cron: name: "certbot-renew" hour: "3" minute: "30" job: "certbot renew --quiet --post-hook 'systemctl reload nginx'" - name: 证书信息 shell: openssl x509 -in /etc/letsencrypt/live/{{ domain }}/fullchain.pem -noout -dates register: cert_info changed_when: false ignore_errors: yes - name: 显示证书 debug: msg: "{{ cert_info.stdout_lines | default(['证书已申请']) }}" `, }, // ===== 监控告警 ===== { ID: "deploy-node-exporter", Name: "部署Node Exporter", Category: "monitoring", Description: "部署Prometheus Node Exporter采集主机指标", Icon: "📡", Tags: []string{"prometheus", "monitoring", "exporter"}, Content: `--- - name: 部署Node Exporter hosts: "{{ target_hosts | default('all') }}" become: yes vars: exporter_version: "1.7.0" exporter_port: 9100 tasks: - name: 创建用户 user: name: node_exporter system: yes shell: /usr/sbin/nologin create_home: no - name: 下载Node Exporter get_url: url: "https://github.com/prometheus/node_exporter/releases/download/v{{ exporter_version }}/node_exporter-{{ exporter_version }}.linux-amd64.tar.gz" dest: /tmp/node_exporter.tar.gz - name: 解压 unarchive: src: /tmp/node_exporter.tar.gz dest: /tmp remote_src: yes - name: 安装二进制 copy: src: "/tmp/node_exporter-{{ exporter_version }}.linux-amd64/node_exporter" dest: /usr/local/bin/node_exporter mode: '0755' remote_src: yes - name: 创建Systemd服务 copy: content: | [Unit] Description=Node Exporter After=network.target [Service] User=node_exporter ExecStart=/usr/local/bin/node_exporter --web.listen-address=:{{ exporter_port }} Restart=always [Install] WantedBy=multi-user.target dest: /etc/systemd/system/node_exporter.service - name: 启动服务 systemd: name: node_exporter state: started enabled: yes daemon_reload: yes - name: 验证 shell: curl -s http://localhost:{{ exporter_port }}/metrics | head -5 register: metrics changed_when: false - name: 显示状态 debug: msg: "Node Exporter运行在端口 {{ exporter_port }}" `, }, { ID: "deploy-grafana", Name: "部署Grafana", Category: "monitoring", Description: "部署Grafana可视化监控面板", Icon: "📊", Tags: []string{"grafana", "dashboard", "visualization"}, Content: `--- - name: 部署Grafana hosts: "{{ target_hosts | default('all') }}" become: yes vars: grafana_port: 3000 grafana_admin_password: "admin123" tasks: - name: 安装依赖 apt: name: - apt-transport-https - software-properties-common state: present when: ansible_os_family == "Debian" - name: 添加Grafana仓库 shell: | curl -fsSL https://apt.grafana.com/gpg.key | gpg --dearmor -o /usr/share/keyrings/grafana.gpg echo "deb [signed-by=/usr/share/keyrings/grafana.gpg] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list when: ansible_os_family == "Debian" - name: 安装Grafana apt: name: grafana state: present update_cache: yes when: ansible_os_family == "Debian" - name: 配置端口 lineinfile: path: /etc/grafana/grafana.ini regexp: "^;?http_port" line: "http_port = {{ grafana_port }}" - name: 启动Grafana service: name: grafana-server state: started enabled: yes - name: 显示访问信息 debug: msg: "Grafana: http://{{ ansible_host | default(inventory_hostname) }}:{{ grafana_port }} (admin/{{ grafana_admin_password }})" `, }, // ===== 系统管理(新增) ===== { ID: "host-connectivity", Name: "主机连通性测试", Category: "system", Description: "批量检测主机SSH连通性、DNS解析、端口可达性", Icon: "🔗", Tags: []string{"ping", "connectivity", "network", "check"}, Content: `--- - name: 主机连通性测试 hosts: "{{ target_hosts | default('all') }}" gather_facts: no tasks: - name: Ansible Ping 测试 ping: register: ping_result ignore_errors: yes - name: 检测SSH端口 wait_for: host: "{{ ansible_host | default(inventory_hostname) }}" port: "{{ ansible_port | default(22) }}" timeout: 5 delegate_to: localhost register: ssh_port ignore_errors: yes - name: 检测DNS解析 shell: nslookup {{ inventory_hostname }} 2>/dev/null || host {{ inventory_hostname }} 2>/dev/null || echo "DNS解析失败" delegate_to: localhost register: dns_result changed_when: false ignore_errors: yes - name: 检测常用端口 wait_for: host: "{{ ansible_host | default(inventory_hostname) }}" port: "{{ item }}" timeout: 3 delegate_to: localhost loop: [80, 443] register: port_scan ignore_errors: yes - name: 输出连通性报告 debug: msg: | ═══════ {{ inventory_hostname }} 连通性报告 ═══════ SSH Ping: {{ '✅ 成功' if ping_result is succeeded else '❌ 失败' }} SSH 端口: {{ '✅ 开放' if ssh_port is succeeded else '❌ 不可达' }} DNS 解析: {{ dns_result.stdout | default('N/A') }} HTTP(80): {{ '✅ 开放' if port_scan.results[0] is succeeded else '❌ 关闭' }} HTTPS(443): {{ '✅ 开放' if port_scan.results[1] is succeeded else '❌ 关闭' }} ═══════════════════════════════════════ `, }, { ID: "ubuntu-multi-ip", Name: "Ubuntu 22.04 多IP配置", Category: "system", Description: "通过Netplan为Ubuntu 22.04配置多IP地址(主IP+辅助IP)", Icon: "🌐", Tags: []string{"ubuntu", "netplan", "network", "multi-ip"}, Content: `--- - name: Ubuntu 22.04 多IP地址配置 hosts: "{{ target_hosts | default('all') }}" become: yes vars: # 主网卡名称(根据实际修改) primary_nic: ens192 # 主IP配置 primary_ip: "192.168.1.100/24" primary_gateway: "192.168.1.1" primary_dns: - 223.5.5.5 - 119.29.29.29 # 辅助IP列表(可添加多个) secondary_ips: - "192.168.1.101/24" - "10.0.0.100/16" tasks: - name: 确认系统版本 assert: that: - ansible_distribution == "Ubuntu" - ansible_distribution_version is version('22.04', '>=') fail_msg: "此模板仅适用于 Ubuntu 22.04+" success_msg: "系统版本: {{ ansible_distribution }} {{ ansible_distribution_version }}" - name: 备份现有Netplan配置 shell: | mkdir -p /etc/netplan/backup cp /etc/netplan/*.yaml /etc/netplan/backup/ 2>/dev/null || true args: creates: /etc/netplan/backup - name: 生成Netplan配置 copy: content: | network: version: 2 ethernets: {{ primary_nic }}: addresses: - {{ primary_ip }} {% for ip in secondary_ips %} - {{ ip }} {% endfor %} routes: - to: default via: {{ primary_gateway }} nameservers: addresses: {% for dns in primary_dns %} - {{ dns }} {% endfor %} dest: /etc/netplan/01-multi-ip.yaml mode: '0600' register: netplan_config - name: 验证Netplan配置语法 shell: netplan try --timeout=10 environment: NETPLAN_TRY_TIMEOUT: "10" ignore_errors: yes register: netplan_try - name: 应用Netplan配置 shell: netplan apply when: netplan_config is changed - name: 等待网络恢复 wait_for: host: "{{ primary_ip | ansible.utils.ipaddr('address') }}" port: 22 timeout: 30 delegate_to: localhost when: netplan_config is changed ignore_errors: yes - name: 验证IP配置 shell: ip addr show {{ primary_nic }} | grep "inet " register: ip_verify changed_when: false - name: 显示配置结果 debug: msg: | ═══════ 多IP配置完成 ═══════ 网卡: {{ primary_nic }} 主IP: {{ primary_ip }} 网关: {{ primary_gateway }} 辅助IP: {% for ip in secondary_ips %} - {{ ip }} {% endfor %} 当前IP列表: {{ ip_verify.stdout }} ═══════════════════════════ `, }, { ID: "ipmitool-bmc", Name: "IPMI配置BMC地址", Category: "system", Description: "使用ipmitool配置服务器BMC/IPMI管理口IP地址", Icon: "🔧", Tags: []string{"ipmi", "bmc", "ipmitool", "hardware"}, Content: `--- - name: IPMI配置BMC地址 hosts: "{{ target_hosts | default('all') }}" become: yes vars: # BMC网络配置 bmc_ip: "10.10.10.100" bmc_netmask: "255.255.255.0" bmc_gateway: "10.10.10.1" # BMC用户配置 bmc_user: "admin" bmc_password: "Admin@123" bmc_channel: 1 # 是否启用DHCP(设为true则忽略上面的静态IP配置) bmc_dhcp: false tasks: - name: 安装ipmitool package: name: ipmitool state: present - name: 加载IPMI内核模块 modprobe: name: "{{ item }}" state: present loop: - ipmi_devintf - ipmi_si ignore_errors: yes - name: 查看当前BMC配置 shell: ipmitool lan print {{ bmc_channel }} register: bmc_current changed_when: false ignore_errors: yes - name: 显示当前BMC信息 debug: msg: "{{ bmc_current.stdout_lines | default(['无法读取BMC信息']) }}" - name: 设置BMC为静态IP shell: ipmitool lan set {{ bmc_channel }} ipsrc static when: not bmc_dhcp - name: 配置BMC IP地址 shell: ipmitool lan set {{ bmc_channel }} ipaddr {{ bmc_ip }} when: not bmc_dhcp - name: 配置BMC子网掩码 shell: ipmitool lan set {{ bmc_channel }} netmask {{ bmc_netmask }} when: not bmc_dhcp - name: 配置BMC默认网关 shell: ipmitool lan set {{ bmc_channel }} defgw ipaddr {{ bmc_gateway }} when: not bmc_dhcp - name: 设置BMC为DHCP模式 shell: ipmitool lan set {{ bmc_channel }} ipsrc dhcp when: bmc_dhcp - name: 配置BMC用户密码 shell: | ipmitool user set name {{ bmc_channel }} 2 {{ bmc_user }} 2>/dev/null || true ipmitool user set password 2 {{ bmc_password }} ipmitool user enable 2 ipmitool channel setaccess {{ bmc_channel }} 2 privilege=4 no_log: true ignore_errors: yes - name: 验证BMC配置 shell: ipmitool lan print {{ bmc_channel }} register: bmc_verify changed_when: false - name: 显示最终配置 debug: msg: | ═══════ BMC配置完成 ═══════ 模式: {{ 'DHCP' if bmc_dhcp else '静态IP' }} IP: {{ bmc_ip }} 掩码: {{ bmc_netmask }} 网关: {{ bmc_gateway }} 用户: {{ bmc_user }} ═══════════════════════════ {{ bmc_verify.stdout }} `, }, { ID: "apt-install", Name: "APT软件安装", Category: "system", Description: "通过apt批量安装/卸载软件包,支持指定版本和仓库", Icon: "📦", Tags: []string{"apt", "install", "package", "debian"}, Content: `--- - name: APT软件安装 hosts: "{{ target_hosts | default('all') }}" become: yes vars: # 要安装的软件包列表 packages_install: - vim - curl - wget - htop - net-tools - tree - unzip - git # 要卸载的软件包列表 packages_remove: [] # 是否更新缓存 update_cache: yes # 是否自动清理 autoremove: yes # 安装推荐包 install_recommends: no # 指定版本(可选,格式: "package=version") # 例: packages_install: ["nginx=1.18.0-0ubuntu1"] tasks: - name: 确认Debian系统 assert: that: ansible_os_family == "Debian" fail_msg: "此模板仅适用于 Debian/Ubuntu 系统" - name: 更新APT缓存 apt: update_cache: yes cache_valid_time: 3600 when: update_cache - name: 安装软件包 apt: name: "{{ packages_install }}" state: present install_recommends: "{{ install_recommends }}" register: install_result when: packages_install | length > 0 - name: 卸载软件包 apt: name: "{{ packages_remove }}" state: absent purge: yes when: packages_remove | length > 0 - name: 自动清理 apt: autoremove: yes autoclean: yes when: autoremove - name: 验证安装结果 shell: dpkg -l {{ packages_install | join(' ') }} 2>/dev/null | grep "^ii" | awk '{print $2, $3}' register: verify_result changed_when: false when: packages_install | length > 0 - name: 显示安装报告 debug: msg: | ═══════ APT安装报告 ═══════ 已安装: {{ packages_install | length }} 个包 已卸载: {{ packages_remove | length }} 个包 变更: {{ install_result.changed | default(false) }} {% if verify_result is defined and verify_result.stdout_lines is defined %} 已确认: {% for line in verify_result.stdout_lines %} ✓ {{ line }} {% endfor %} {% endif %} ═══════════════════════════ `, }, { ID: "dpkg-install", Name: "DPKG软件安装", Category: "system", Description: "通过dpkg安装本地.deb包,支持URL下载和依赖修复", Icon: "📥", Tags: []string{"dpkg", "deb", "install", "offline"}, Content: `--- - name: DPKG软件安装 hosts: "{{ target_hosts | default('all') }}" become: yes vars: # 本地deb包路径列表(服务器上的路径) local_deb_files: [] # 远程URL列表(会自动下载后安装) remote_deb_urls: [] # 下载临时目录 download_dir: /tmp/dpkg_install # 安装后是否修复依赖 fix_dependencies: yes # 是否保留下载的deb文件 keep_deb_files: no tasks: - name: 确认Debian系统 assert: that: ansible_os_family == "Debian" fail_msg: "此模板仅适用于 Debian/Ubuntu 系统" - name: 创建下载目录 file: path: "{{ download_dir }}" state: directory mode: '0755' when: remote_deb_urls | length > 0 - name: 下载远程deb包 get_url: url: "{{ item }}" dest: "{{ download_dir }}/{{ item | basename }}" mode: '0644' loop: "{{ remote_deb_urls }}" register: download_result when: remote_deb_urls | length > 0 - name: 安装本地deb包 apt: deb: "{{ item }}" state: present loop: "{{ local_deb_files }}" register: local_install when: local_deb_files | length > 0 - name: 安装下载的deb包 apt: deb: "{{ download_dir }}/{{ item | basename }}" state: present loop: "{{ remote_deb_urls }}" register: remote_install when: remote_deb_urls | length > 0 - name: 修复依赖关系 apt: update_cache: yes force_apt_get: yes shell: apt-get install -f -y when: fix_dependencies ignore_errors: yes - name: 清理下载文件 file: path: "{{ download_dir }}" state: absent when: not keep_deb_files and remote_deb_urls | length > 0 - name: 显示安装报告 debug: msg: | ═══════ DPKG安装报告 ═══════ 本地包: {{ local_deb_files | length }} 个 远程包: {{ remote_deb_urls | length }} 个 {% if local_deb_files | length > 0 %} 本地安装: {% for f in local_deb_files %} ✓ {{ f }} {% endfor %} {% endif %} {% if remote_deb_urls | length > 0 %} 远程安装: {% for u in remote_deb_urls %} ✓ {{ u | basename }} {% endfor %} {% endif %} 依赖修复: {{ '是' if fix_dependencies else '否' }} ═══════════════════════════ `, }, } }