Ansible之剧本和角色

playbook剧本

YAML简介

YAML(YAML Ain't Markup Language的缩写)是一种人类可读的完整的数据序列化语言。

YAML 官网首页就很 YAML,这很有意思。 The Official YAML Web Site

通常用作软件的配置文件;

YAML基本语法规则(基于显式指示符的表示范围的Flow Style):

  • 流序列:以逗号分隔的列表形式写入,并置于方括号[]内;

  • 流映射:以逗号分隔的列表形式写入,并置于大括号{}内;

YAML支持3种基本数据类型:

  • 标量(Scalar):原子数据类型,如:字符串(String)、数字(Numbers)、布尔值(Boolean)和空值(null)等;

  • 序列(Sequence):节点列表,类似某些编程语言的数组(Array)、列表(List)等;

  • 映射(Mapping):节点到节点的映射,键值对,类似某些编程语言的哈希(Hash)、哈希映射(Hash Map)、字典(Dict)、对象(Objects)等;

与许多编程语言不同,键key可以是序列或映射。 一个YAML文件或流可以包含多个文档Documents 文档可以显式地以---开头(可选的)。在规范中称此为指令结束标记,但实际使用中更多称为文档开始标记; 文档可以显式地以...结尾(可选的)。在规范中称此为文档结束标记,如果文档没有指令,可以省略---,仅用...来分割多个文档; 如果YAML文件或流仅包含一个文档,那么--- ...可以省略

YAML支持两个指令: 版本指令:指令放在---之前行,如 %YAML 1.2 用于告知 YAML 处理器使用哪个版本处理当前文档; 标签指令:为用户提供自定义处理程序的速记标记的方法,一般很少使用

  • yaml格式:以.yaml或者.yml结尾

 root@server-21:~# cat /etc/netplan/00-installer-config.yaml
 # This is the network config written by 'subiquity'
 network:
   ethernets:
     ens33:
       dhcp4: no
       dhcp6: no
       addresses: [192.168.221.21/24]
       gateway4: 192.168.221.2
       nameservers:
         addresses: [114.114.114.114,8.8.8.8]
   version: 2

yaml格式要求:

1.严格区分大小写

2.缩进统一,同一级别配置要对齐

  • 缩进不允许使用Tab制表符,只允许使用空格字符;

  • 缩进的空格数不重要,但官方推荐使用2个空格字符;

  • 冒号后面至少要有一个空格

Ansible案例

前提条件:Ubuntu配置好四台设备

 # 前提是每台机子都apt update
 192.168.221.120   manage01
 192.168.221.21   node1
 192.168.221.22   node2
 192.168.221.23   node3
 #(仅管理机)
 # ssh免密(输入yes和密码)
 ssh-keygen
 ssh-copy-id root@node1
 ssh-copy-id root@node2
 ssh-copy-id root@node3
 #下载ansible
 apt update
 apt install ansible
 #查看版本
 ansible --version
 #创建ansible
 mkdir /etc/ansible
 cd /etc/ansible
 vim hosts
 --------------------------------------------
 [group1]
 node1    # 对应 /etc/hosts 中的 192.168.221.21
 node2    # 对应 192.168.221.22
 node3    # 对应 192.168.221.23
 --------------------------------------------
 # ping节点
 ansible -m ping group1
 node3 | SUCCESS => {
     "ansible_facts": {
         "discovered_interpreter_python": "/usr/bin/python3"
     },
     "changed": false,
     "ping": "pong"
 }
 node1 | SUCCESS => {
     "ansible_facts": {
         "discovered_interpreter_python": "/usr/bin/python3"
     },
     "changed": false,
     "ping": "pong"
 }
 node2 | SUCCESS => {
     "ansible_facts": {
         "discovered_interpreter_python": "/usr/bin/python3"
     },
     "changed": false,
     "ping": "pong"
 }

案例一:playbook部署LNMP环境

 # Ubuntu部署LNMP环境
 vim lnmp.yaml
 ---
 - name: 部署LNMP环境
   hosts: group1
   become: true
   tasks:
     - name: 安装Nginx
       apt:
         name: nginx
         state: present
     - name: 安装MySQL服务器
       apt:
         name: mysql-server
         state: present
     - name: 安装PHP及相关扩展
       apt:
         name: "{{ packages }}"
         state: present
       vars:
         packages:
           - php-fpm
           - php-mysql
           - php-cli
           - php-gd
           - php-curl
           - php-mbstring
     - name: 启动并启用Nginx服务
       service:
         name: nginx
         state: started
         enabled: true
     - name: 启动并启用MySQL服务
       service:
         name: mysql
         state: started
         enabled: true
     - name: 启动并启用PHP-FPM服务
       service:
         name: php8.1-fpm
         state: started
         enabled: true
 # 执行剧本
 # 执行剧本但不真正生效,用于检测脚本是否正确
 ansible-playbook -C lnmp.yaml
 # 正常执行剧本
 ansible-playbook lnmp.yaml

课后练习:

1.Ansible剧本配Yum源或APT源(Ubuntu已完成,Centos未尝试)

 vim apt.yml
 ---
 - name: 配置Yum/APT软件源
   hosts: node1
   become: yes
   gather_facts: yes
   
   vars:
     # 通用配置
     use_mirrors: true
     backup_existing: true
     
     # Yum源配置
     yum_mirror_url: "https://mirrors.aliyun.com"
     centos_mirror: "{{ yum_mirror_url }}/centos"
     epel_mirror: "{{ yum_mirror_url }}/epel"
     
     # APT源配置
     apt_mirror_url: "http://mirrors.aliyun.com"
     ubuntu_mirror: "{{ apt_mirror_url }}/ubuntu"
     debian_mirror: "{{ apt_mirror_url }}/debian"
 ​
   tasks:
     - name: 检测操作系统家族
       fail:
         msg: "不支持的操作系统: {{ ansible_distribution }}"
       when: >
         ansible_os_family != "RedHat" and
         ansible_os_family != "Debian"
 ​
     # RedHat系列配置块
     - name: 为RedHat系统备份现有repo文件
       block:
         - name: 备份整个repo目录
           command: >
             mv /etc/yum.repos.d /etc/yum.repos.d.backup_{{ ansible_date_time.epoch }}
           when: backup_existing
         
         - name: 创建新的repo目录
           file:
             path: /etc/yum.repos.d
             state: directory
             mode: '0755'
         
         - name: 配置CentOS基础源
           copy:
             dest: /etc/yum.repos.d/CentOS-Base.repo
             mode: '0644'
             content: |
               # CentOS-Base.repo
               [base]
               name=CentOS-$releasever - Base
               baseurl={{ centos_mirror }}/$releasever/os/$basearch/
               gpgcheck=1
               gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{ ansible_distribution_major_version }}
 ​
               [updates]
               name=CentOS-$releasever - Updates
               baseurl={{ centos_mirror }}/$releasever/updates/$basearch/
               gpgcheck=1
               gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{ ansible_distribution_major_version }}
 ​
               [extras]
               name=CentOS-$releasever - Extras
               baseurl={{ centos_mirror }}/$releasever/extras/$basearch/
               gpgcheck=1
               gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{ ansible_distribution_major_version }}
 ​
               [centosplus]
               name=CentOS-$releasever - Plus
               baseurl={{ centos_mirror }}/$releasever/centosplus/$basearch/
               gpgcheck=1
               enabled=0
               gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-{{ ansible_distribution_major_version }}
         
         - name: 配置EPEL源
           copy:
             dest: /etc/yum.repos.d/epel.repo
             mode: '0644'
             content: |
               [epel]
               name=Extra Packages for Enterprise Linux $releasever - $basearch
               baseurl={{ epel_mirror }}/$releasever/$basearch
               enabled=1
               gpgcheck=0
               
         - name: 清理Yum缓存
           command: yum clean all
         
         - name: 更新Yum缓存
           command: yum makecache
       when: ansible_os_family == "RedHat"
 ​
     # Debian系列配置块
     - name: 为Debian系统配置APT源
       block:
         - name: 备份现有sources.list
           command: >
             cp /etc/apt/sources.list /etc/apt/sources.list.backup_{{ ansible_date_time.epoch }}
           when: backup_existing
         
         - name: 配置Ubuntu源
           copy:
             dest: /etc/apt/sources.list
             mode: '0644'
             content: |
               # Ubuntu sources list
               deb {{ ubuntu_mirror }}/ {{ ansible_distribution_release }} main restricted universe multiverse
               deb {{ ubuntu_mirror }}/ {{ ansible_distribution_release }}-security main restricted universe multiverse
               deb {{ ubuntu_mirror }}/ {{ ansible_distribution_release }}-updates main restricted universe multiverse
               deb {{ ubuntu_mirror }}/ {{ ansible_distribution_release }}-backports main restricted universe multiverse
           when: ansible_distribution == "Ubuntu"
         
         - name: 配置Debian源
           copy:
             dest: /etc/apt/sources.list
             mode: '0644'
             content: |
               # Debian sources list
               deb {{ debian_mirror }}/ {{ ansible_distribution_release }} main contrib non-free
               deb {{ debian_mirror }}/ {{ ansible_distribution_release }}-updates main contrib non-free
               deb {{ debian_mirror }}/ {{ ansible_distribution_release }}-security main contrib non-free
           when: ansible_distribution == "Debian"
         
         - name: 更新APT缓存
           apt:
             update_cache: yes
             cache_valid_time: 3600
       when: ansible_os_family == "Debian"
 ​
     # 验证配置
     - name: 验证RedHat系统软件源配置
       command: yum repolist
       register: yum_repos
       when: ansible_os_family == "RedHat"
     
     - name: 显示Yum仓库列表
       debug:
         msg: "Yum仓库配置成功,共 {{ yum_repos.stdout_lines[-1] }} 个仓库"
       when: ansible_os_family == "RedHat"
     
     - name: 验证Debian系统软件源配置
       command: apt-cache policy
       register: apt_sources
       when: ansible_os_family == "Debian"
     
     - name: 显示APT配置状态
       debug:
         msg: "APT源配置成功,缓存已更新"
       when: ansible_os_family == "Debian"

2.Ansible剧本修改IP地址与主机名(没出错但也没生效)

 ---
 - name: 配置Ubuntu系统网络和主机名
   hosts: node1
   become: true
   gather_facts: true
 ​
   vars:
     # 网络配置
     new_ip_address: "192.168.221.100"
     new_netmask: "255.255.255.0"
     new_gateway: "192.168.221.2"
     new_dns_servers:
       - "8.8.8.8"
       - "8.8.4.4"
     network_interface: "ens33"  # 必须根据实际情况修改!
     
     # 主机名配置
     new_hostname: "ubuntu-server"
     new_domain: "local.lan"
     
     # 备份配置
     backup_files: true
 ​
   tasks:
     - name: 显示当前系统信息
       debug:
         msg: |
           当前系统信息:
           主机名: {{ ansible_hostname }}
           IP地址: {{ ansible_default_ipv4.address }}
           网卡: {{ ansible_default_ipv4.interface }}
           所有网卡: {{ ansible_interfaces }}
 ​
     - name: 检测实际网卡名称
       shell: ip -o link show | awk -F': ' '{print $2}' | grep -v lo
       register: network_interfaces
       changed_when: false
 ​
     - name: 显示检测到的网卡
       debug:
         msg: "系统检测到的网卡: {{ network_interfaces.stdout_lines }}"
 ​
     - name: 备份原始主机名配置
       copy:
         src: /etc/hostname
         dest: /etc/hostname.backup_{{ ansible_date_time.epoch }}
         remote_src: true
         backup: "{{ backup_files }}"
       when: backup_files
 ​
     - name: 备份原始hosts文件
       copy:
         src: /etc/hosts
         dest: /etc/hosts.backup_{{ ansible_date_time.epoch }}
         remote_src: true
         backup: "{{ backup_files }}"
       when: backup_files
 ​
     - name: 备份原始网络配置
       copy:
         src: "{{ item }}"
         dest: "{{ item }}.backup_{{ ansible_date_time.epoch }}"
         remote_src: true
         backup: "{{ backup_files }}"
       loop: "{{ query('fileglob', '/etc/netplan/*.yaml') + query('fileglob', '/etc/netplan/*.yml') }}"
       ignore_errors: yes
       when: backup_files
 ​
     - name: 修改主机名
       hostname:
         name: "{{ new_hostname }}"
 ​
     - name: 更新hosts文件中的主机名
       blockinfile:
         path: /etc/hosts
         marker: "# {mark} ANSIBLE MANAGED BLOCK - Hostname"
         block: |
           127.0.0.1 localhost
           127.0.1.1 {{ new_hostname }}.{{ new_domain }} {{ new_hostname }}
           
           # IPv6配置
           ::1 localhost ip6-localhost ip6-loopback
           ff02::1 ip6-allnodes
           ff02::2 ip6-allrouters
         state: present
 ​
     - name: 获取当前Netplan配置文件
       find:
         paths: /etc/netplan
         patterns: "*.yaml,*.yml"
         file_type: file
       register: netplan_files
 ​
     - name: 显示找到的Netplan文件
       debug:
         msg: "找到的Netplan配置文件: {{ netplan_files.files | map(attribute='path') | list }}"
 ​
     - name: 禁用其他Netplan配置(避免冲突)
       file:
         path: "{{ item }}"
         state: absent
       loop: "{{ netplan_files.files | map(attribute='path') | list }}"
       when: item != '/etc/netplan/99-static-ip.yaml'
 ​
     - name: 配置静态IP地址
       copy:
         dest: "/etc/netplan/99-static-ip.yaml"
         content: |
           network:
             version: 2
             renderer: networkd
             ethernets:
               {{ network_interface }}:
                 dhcp4: no
                 dhcp6: no
                 addresses:
                   - {{ new_ip_address }}/24
                 routes:
                   - to: default
                     via: {{ new_gateway }}
                 nameservers:
                   addresses: [{{ new_dns_servers | join(', ') }}]
         mode: '0644'
 ​
     - name: 验证Netplan配置语法
       command: netplan generate
       changed_when: false
 ​
     - name: 应用网络配置
       command: netplan apply
 ​
     - name: 重启网络服务
       systemd:
         name: systemd-networkd
         state: restarted
       when: ansible_distribution == 'Ubuntu'
 ​
     - name: 等待网络服务稳定
       wait_for_connection:
         timeout: 60
 ​
     - name: 强制系统重启(确保所有更改生效)
       reboot:
         msg: "应用网络和主机名配置后重启"
         connect_timeout: 5
         reboot_timeout: 300
         pre_reboot_delay: 0
         post_reboot_delay: 30
 ​
     - name: 验证新的主机名(重启后)
       shell: hostname
       register: hostname_check
       changed_when: false
 ​
     - name: 验证新的IP地址(重启后)
       shell: |
         ip addr show {{ network_interface }} 2>/dev/null | grep "inet " | awk '{print $2}' || echo "未配置"
       register: ip_check
       changed_when: false
 ​
     - name: 显示最终配置结果
       debug:
         msg: |
           🎉 系统配置完成!
           
           最终配置信息:
           设置的主机名: {{ new_hostname }}
           实际主机名: {{ hostname_check.stdout | default('未知') }}
           设置的IP地址: {{ new_ip_address }}
           实际IP地址: {{ ip_check.stdout | default('未知') }}
           网卡接口: {{ network_interface }}
           
           如果配置不正确,请检查:
           1. 网卡名称是否正确
           2. IP地址是否在正确的网段
           3. 网关地址是否正确

3.Ansible剧本实现系统优化:设置时区、时间同步、更新软件、关闭防火墙、SELinux

第一个剧本:设置时区

 ### 设置时区
 vim time.yml
 ---
 - name: 设置时区
   hosts: node1
   become: yes
   tasks:
     - name: Set timezone to Asia/Shanghai
       timezone:
         name: Asia/Shanghai

第二个实验:时间同步

 ### 时间同步
 ---
 - name: 基础时间同步配置
   hosts: group1
   become: yes
   gather_facts: yes
 ​
   vars:
     ntp_servers: ["ntp.aliyun.com", "ntp1.aliyun.com"]
 ​
   tasks:
     - name: 设置时区
       timezone:
         name: Asia/Shanghai
 ​
     - name: 安装chrony (RedHat)
       package: name=chrony state=present
       when: ansible_os_family == "RedHat"
 ​
     - name: 安装chrony (Debian)
       package: name=chrony state=present
       when: ansible_os_family == "Debian"
 ​
     - name: 配置chrony服务
       systemd:
         name: "{{ 'chronyd' if ansible_os_family == 'RedHat' else 'chrony' }}"
         state: started
         enabled: yes
 ​
     - name: 显示当前时间
       command: date
       register: current_time
       changed_when: false
 ​
     - name: 显示配置结果
       debug:
         msg: "时间同步配置完成!当前时间: {{ current_time.stdout }}"

还没有写:更新软件、关闭防火墙、SELinux

4.Ansible剧本安装单机LNMP、LNMT(案例一已完成LNMP,LNMT还未排完错)

 ---
 - name: 部署LNMT环境
   hosts: node1
   become: true
   gather_facts: true
 ​
   vars:
     # Tomcat配置
     tomcat_version: 9
     java_package: "openjdk-11-jdk"
     
     # 数据库配置 - 生产环境请务必修改这些密码!
     mysql_root_password: "root123"
     mysql_app_database: "mysql"
     mysql_app_user: "root"
     mysql_app_password: "root123"
     
     # 应用配置
     app_context_path: "/myapp"
     tomcat_manager_user: "admin"
     tomcat_manager_password: "admin123!"
     
     # 网络配置
     server_host: "localhost"
 ​
   tasks:
     - name: 检查系统版本
       debug:
         msg: "检测到系统: {{ ansible_distribution }} {{ ansible_distribution_version }}"
 ​
     - name: 更新软件包缓存
       apt:
         update_cache: yes
         cache_valid_time: 3600
 ​
     - name: 安装基础依赖
       apt:
         name: "{{ item }}"
         state: present
       loop:
         - curl
         - wget
         - vim
         - unzip
 ​
     - name: 安装Nginx
       apt:
         name: nginx
         state: present
 ​
     - name: 安装MySQL服务器
       apt:
         name: "{{ item }}"
         state: present
       loop:
         - mysql-server
         - mysql-client
         - python3-pymysql
 ​
     - name: 安装Java环境
       apt:
         name: "{{ java_package }}"
         state: present
 ​
     - name: 设置Java环境变量
       lineinfile:
         path: /etc/environment
         line: "JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64"
         state: present
 ​
     - name: 安装Tomcat
       apt:
         name: "{{ item }}"
         state: present
       loop:
         - "tomcat{{ tomcat_version }}"
         - "tomcat{{ tomcat_version }}-admin"
         - "tomcat{{ tomcat_version }}-docs"
         - "tomcat{{ tomcat_version }}-examples"
 ​
     - name: 等待MySQL服务启动
       systemd:
         name: mysql
         state: started
       register: mysql_service_result
 ​
     - name: 安全配置MySQL(使用debconf设置root密码)
       debconf:
         name: mysql-server
         question: mysql-server/root_password
         value: "{{ mysql_root_password }}"
         vtype: password
 ​
     - name: 确认MySQL root密码
       debconf:
         name: mysql-server
         question: mysql-server/root_password_again
         value: "{{ mysql_root_password }}"
         vtype: password
 ​
     - name: 重新配置MySQL
       shell: dpkg-reconfigure -f noninteractive mysql-server
       when: mysql_service_result.changed
       
     - name: 安装PyMySQL模块
       pip:
         name: PyMySQL
         state: present
       become: yes
 ​
     - name: 创建应用数据库
       mysql_db:
         name: "{{ mysql_app_database }}"
         state: present
         login_user: root
         login_password: "{{ mysql_root_password }}"
       ignore_errors: yes
 ​
     - name: 创建应用数据库用户
       mysql_user:
         name: "{{ mysql_app_user }}"
         host: localhost
         password: "{{ mysql_app_password }}"
         priv: "{{ mysql_app_database }}.*:ALL"
         state: present
         login_user: root
         login_password: "{{ mysql_root_password }}"
       ignore_errors: yes
 ​
     - name: 确保Tomcat webapps目录存在
       file:
         path: "/var/lib/tomcat{{ tomcat_version }}/webapps/ROOT"
         state: directory
         owner: tomcat
         group: tomcat
         mode: '0755'
         recurse: yes
 ​
     - name: 创建测试JSP页面
       copy:
         dest: "/var/lib/tomcat{{ tomcat_version }}/webapps/ROOT/index.jsp"
         content: |
           <%@ page contentType="text/html;charset=UTF-8" language="java" %>
           <!DOCTYPE html>
           <html>
           <head>
               <title>LNMT环境测试</title>
           </head>
           <body>
               <h1>✅ LNMT环境部署成功!</h1>
               <p>服务器时间: <%= new java.util.Date() %></p>
               <p>Java版本: <%= System.getProperty("java.version") %></p>
               <p>Tomcat版本: <%= application.getServerInfo() %></p>
               <p>服务器: <%= request.getServerName() %>:<%= request.getServerPort() %></p>
               
               <h2>数据库连接测试</h2>
               <%
                 try {
                   Class.forName("com.mysql.cj.jdbc.Driver");
                   out.println("<p style='color: green;'>✅ MySQL驱动加载成功</p>");
                 } catch (Exception e) {
                   out.println("<p style='color: red;'>❌ MySQL驱动加载失败: " + e.getMessage() + "</p>");
                 }
               %>
           </body>
           </html>
         owner: tomcat
         group: tomcat
         mode: '0644'
 ​
     - name: 配置Tomcat用户权限
       copy:
         dest: "/etc/tomcat{{ tomcat_version }}/tomcat-users.xml"
         content: |
           <?xml version='1.0' encoding='utf-8'?>
           <tomcat-users xmlns="http://tomcat.apache.org/xml"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                         xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
                         version="1.0">
             <role rolename="manager-gui"/>
             <role rolename="admin-gui"/>
             <role rolename="manager-script"/>
             <user username="{{ tomcat_manager_user }}"
                   password="{{ tomcat_manager_password }}"
                   roles="manager-gui,admin-gui,manager-script"/>
           </tomcat-users>
         owner: tomcat
         group: tomcat
         mode: '0640'
       notify: 重启Tomcat服务
 ​
     - name: 允许外部访问Tomcat管理界面
       lineinfile:
         path: "/etc/tomcat{{ tomcat_version }}/server.xml"
         regexp: '<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve"'
         line: '<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve"'
         state: present
       notify: 重启Tomcat服务
 ​
     - name: 配置Nginx代理Tomcat
       copy:
         dest: /etc/nginx/sites-available/tomcat
         content: |
           server {
               listen 80;
               server_name {{ server_host }};
               
               # 静态文件缓存
               location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
                   expires 1y;
                   add_header Cache-Control "public, immutable";
               }
               
               # API代理
               location {{ app_context_path }}/ {
                   proxy_pass http://localhost:8080{{ app_context_path }}/;
                   proxy_set_header Host $host;
                   proxy_set_header X-Real-IP $remote_addr;
                   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                   proxy_set_header X-Forwarded-Proto $scheme;
                   proxy_connect_timeout 30s;
                   proxy_read_timeout 60s;
               }
               
               # 根路径代理
               location / {
                   proxy_pass http://localhost:8080/;
                   proxy_set_header Host $host;
                   proxy_set_header X-Real-IP $remote_addr;
                   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                   proxy_set_header X-Forwarded-Proto $scheme;
               }
               
               # Tomcat管理界面
               location /manager/ {
                   proxy_pass http://localhost:8080/manager/;
                   proxy_set_header Host $host;
                   proxy_set_header X-Real-IP $remote_addr;
                   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                   proxy_set_header X-Forwarded-Proto $scheme;
               }
           }
         mode: '0644'
       notify: 重新加载Nginx配置
 ​
     - name: 启用Nginx Tomcat站点
       file:
         src: /etc/nginx/sites-available/tomcat
         dest: /etc/nginx/sites-enabled/tomcat
         state: link
       notify: 重新加载Nginx配置
 ​
     - name: 禁用Nginx默认站点
       file:
         path: /etc/nginx/sites-enabled/default
         state: absent
       notify: 重新加载Nginx配置
 ​
     - name: 配置防火墙规则
       ufw:
         rule: allow
         port: "{{ item }}"
         proto: tcp
       loop:
         - 80
         - 8080
         - 3306
       ignore_errors: yes
 ​
     - name: 启动并启用服务
       systemd:
         name: "{{ item }}"
         state: started
         enabled: true
       loop:
         - nginx
         - mysql
         - "tomcat{{ tomcat_version }}"
 ​
     - name: 等待服务启动完成
       wait_for:
         port: "{{ item }}"
         delay: 10
         state: started
         timeout: 120
       loop:
         - 80
         - 8080
         - 3306
 ​
     - name: 验证服务状态
       shell: systemctl is-active {{ item }}
       register: service_status
       changed_when: false
       loop:
         - nginx
         - mysql
         - "tomcat{{ tomcat_version }}"
 ​
     - name: 显示部署摘要
       debug:
         msg: |
           🎉 LNMT环境部署完成!
 ​
           
           服务状态:
           Nginx: {{ service_status.results[0].stdout }}
           MySQL: {{ service_status.results[1].stdout }}
           Tomcat: {{ service_status.results[2].stdout }}
           
           访问地址:
           🌐 网站: http://{{ ansible_default_ipv4.address }}:80
           🚀 Tomcat直接访问: http://{{ ansible_default_ipv4.address }}:8080
           📊 Tomcat管理: http://{{ ansible_default_ipv4.address }}:8080/manager/html
           
           安全信息:
           🔑 Tomcat管理员: {{ tomcat_manager_user }} / {{ tomcat_manager_password }}
           🔒 MySQL root密码: {{ mysql_root_password }}
           💾 应用数据库: {{ mysql_app_database }} (用户: {{ mysql_app_user }})
 ​
   handlers:
     - name: 重新加载环境变量
       command: source /etc/environment
       changed_when: false
       
     - name: 重启Tomcat服务
       systemd:
         name: "tomcat{{ tomcat_version }}"
         state: restarted
 ​
     - name: 重新加载Nginx配置
       systemd:
         name: nginx
         state: reloaded

5.Ansible剧本安装集群:MySQL主从、Redis哨兵(未完成)


Ansible-role角色

1、核心

  • 将剧本根据功能进行拆分成不同组件;

  • 每个组件只完成一项简单任务;

  • 复杂任务通过组合多个组件来实现;

2、优缺点

  • 优点:灵活、低耦合、高复用;

  • 缺点:编写的复杂性高,对技术要求高;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值