基于 Ansible 与 Jinja2 模板的 LNMP 环境及 WordPress 自动化部署实践

使用JINJA2模板部署文件

示例 1:用模板部署 Web 服务器主页(显示主机名)

复制代码
 #1. 编写部署剧本(playbook.yml)
 [lyk@controller web 09:33:33]$ vim playbook.yml 
  ---      
   2 - name: Enable intranet services
   3   hosts: node1
   4   tasks: 
   5     - name: ensure latest version of httpd
   6       yum:
   7         name: httpd
   8         state: latest
   9          
  10     - name: test html page is installed
  11       template:
  12         src: index.html.ja
  13         dest: /var/www/html/index.html                                     
  14          
  15     - name: httpd enabled and running
  16       service:
  17         name: httpd
  18         enabled: true
  19         state: restarted
  20 ...      
 ​
 #2. 编写 Jinja2 模板(index.html.ja)
 [lyk@controller web 09:42:20]$ vim index.html.ja
   1 Welcome to {{ ansible_fqdn }}     
   
 #3. 执行部署并验证  
  lyk@controller web 09:44:02]$ ansible-playbook playbook.yml 
  
  
 [lyk@controller web 09:44:16]$ curl http://node1/.
 Welcome to node1.lyk.cloud
 [lyk@controller web 09:44:59]$ curl http://node1/
 Welcome to node1.lyk.cloud
 [lyk@controller web 09:45:17]$ cat index.html.ja 
 Welcome to {{ ansible_fqdn }}
 ​
 ​
 ​
 [lyk@controller web 09:46:38]$ curl http://node1/
 Welcome to node1.lyk.cloud
 [lyk@controller web 09:47:55]$ curl http://node2/
 Hello World From node2
 [lyk@controller web 09:47:58]$ curl http://node3/
 Hello World From node3
 [lyk@controller web 09:48:01]$ curl http://node4/
 Hello World From node4
 ​

示例 2:用模板配置 SSH 服务(自定义端口、权限等)

复制代码
  [lyk@controller web 09:51:20]$ vim playbook.yml 
  
   1 ---      
   2 - name: config sshd service
   3   hosts: node1
   4   vars:  
   5     ssh_port: 1022
   6     root_allowed: "yes"
   7     groups_allowed: wheel
   8     passwords_allowed: "yes"
   9     ansible_managed: "Ansible managed"
  10   tasks: 
  11     - name: config sshd service
  12       template:
  13         src: sshd_config.j2
  14         dest: /root/sshd_config    
  
  
 --剧本内容是告诉 Ansible 在node1上做三件事:
 --安装 / 更新 httpd(Apache Web 服务器);
 --用模板文件index.html.ja生成/var/www/html/index.html(网站主页);
 --启动并开机自启 httpd 服务。
  
  #2. 编写 Jinja2 模板(index.html.ja)
  [lyk@controller web 09:51:49]$ vim sshd_config.j2
   1 # {{ ansible_managed }}
   2 # DO NOT MAKE LOCAL MODIFICATIONS TO THIS FILE AS THEY WILL BE LOST
   3 Port {{ ssh_port }}
   4 ListenAddress {{ ansible_facts['default_ipv4']['address'] }}
   5  
   6 HostKey /etc/ssh/ssh_host_rsa_key
   7 HostKey /etc/ssh/ssh_host_ecdsa_key
   8 HostKey /etc/ssh/ssh_host_ed25519_key
   9 SyslogFacility AUTHPRIV
  10 PermitRootLogin  {{ root_allowed }}
  11 AllowGroups {{ groups_allowed }}
  12  
  13 AuthorizedKeysFile      /etc/.rht_authorized_keys .ssh/authorized_keys
  14 PasswordAuthentication {{ passwords_allowed }}  
  
 --模板里写的是Welcome to {{ ansible_fqdn }},其中{{ ansible_fqdn }}是 ---Ansible 的内置变量,代表 “受管主机的完整主机名”(比如node1.lyk.cloud)。
 --作用:用模板生成的主页会自动替换变量,显示目标主机自己的完整主机名。
  
  [lyk@controller web 09:51:04]$ ansible-playbook playbook.yml 
 ​

Jinja2 模板语法

for 语句
复制代码
 [lyk@controller web 10:34:01]$ vim playbook.yml 
 ​
   1 ---                        
   2 - name: test template      
   3   hosts: node1             
   4   vars:                    
   5     users:                 
   6       - tom                
   7       - jack               
   8       - Snoopy             
   9       - lucky              
  10   tasks:                   
  11     - name: test template  
  12       template:            
  13         src: testfile.j2   
  14         dest: /tmp/testfile                                             
  15 ... 
  
  
  [lyk@controller web 10:48:50]$ vim testfile.j2
  
   1 {% for user in users %}                                                 
   2 username is {{ user }}
   3 {% endfor %}
 ​
 ​
 [lyk@controller web 11:01:37]$ ansible-playbook playbook.yml 
 ​
 ​
 #node1查看
 [lyk@node1 ~ 09:05:58]$ cat /tmp/testfile
 username is tom
 username is jack
 username is Snoopy
 username is lucky
 ​

基于 Ansible 的 LNMP 环境自动化部署与 WordPress 搭建

复制代码
 #1. 准备工作:复制和清理目录
 lyk@controller ~ 13:47:02]$ cp -r web lnmp
 [lyk@controller ~ 13:52:05]$ cd lnmp/
 [lyk@controller lnmp 13:52:33]$ rm -fr *
 ​
 #2. 复制核心配置文件
 [lyk@controller lnmp 13:52:50]$ cp ../web/ansible.cfg .
 [lyk@controller lnmp 13:53:17]$ cp ../web/inventory .
 ​
 #3. 编辑主机清单(inventory)
 [lyk@controller lnmp 13:53:44]$ vim inventory 
 ​
   1 [lnmps]
   2 lnmp ansible_host=node1
   3      
   4 [controllers]
   5 controller
   6      
   7 [dev]
   8 node1
   9      
  10 [test]
  11 node2
  12      
  13 [prod]
  14 node3
  15 node4 
  
 #4. 编写部署剧本(deploy_lnmp.yml) 
  [lyk@controller lnmp 13:55:16]$ vim deploy_lnmp.yml
 ---
 - name: deploy mariadb
   hosts: lnmp
   tasks:
     # 安装数据库
     - name: install mariadb-server
       yum:
         name: 
           - mariadb-server
           - python2-PyMySQL
         state: present
 ​
     # 启动服务
     - name: enable and start mariadb
       service:
        name: mariadb
        enabled: yes
        state: started
 ​
     # 设置 root 密码
     - name: set root@localhost password
       shell: mysqladmin password {{ mysql_root_password }}
       ignore_errors: yes
 ​
     - name: set root password
       mysql_user:
         name: root
         password: "{{ mysql_root_password }}"
         host: "{{ item }}"
         state: present
         login_user: root
         login_password: "{{ mysql_root_password }}"
       with_items:
         - "{{ ansible_fqdn }}"
         - 127.0.0.1
         - ::1
     
   # 删除匿名用户
     - name: delete user anonymous
       mysql_user:
         name: ""
         host_all: yes
         state: absent
         login_user: root
         login_password: "{{ mysql_root_password }}"
         #login_unix_socket: /var/lib/mysql/mysql.sock
 ​
 ​
     # 删除测试数据库
     - name: delete database test
       mysql_db:
         name: test
         state: absent
         login_user: root
         login_password: "{{ mysql_root_password }}"
 ​
 ​
 - name: prepare db for webapp
   hosts: lnmp
   tasks:
     # 创建新用户
     - name: create user {{ user }}
       mysql_user:
         name: "{{ app_user }}"
         password: "{{ app_password }}"
         host: "{{ app_host }}"
         priv: "{{ app_priv }}"
         state: present
         login_user: root
         login_password: "{{ mysql_root_password }}"
 ​
     # 创建新库
     - name: create database db_name
       mysql_db:
         name: "{{ db_name }}"
         state: present
         login_user: root
         login_password: "{{ mysql_root_password }}"
 ​
 - name: deploy web server
   hosts: lnmp
   tasks:
     - name: install nginx
       yum:
         name: nginx
         state: present
     # 启动服务
     - name: enable and start nginx
       service:
        name: nginx
        enabled: yes
        state: started
     - name: prepare test file for web server
       copy:
         content: hello world from nginx
         dest: /usr/share/nginx/html/index.html
 ​
 - name: php
   hosts: lnmp
   tasks:
     - name: install php
       yum:
         name: php,php-fpm,php-mysqlnd
         state: present
     - name: modify running user for php
       lineinfile:
         path: /etc/php-fpm.d/www.conf
         regexp: "{{ item}} = "
         line: "{{ item }} = nginx"
       loop:
         - user
         - group
     # 启动服务
     - name: enable and start php-fpm.service
       service:
        name: php-fpm
        enabled: yes
        state: restarted
     - name: config php for nginx
       copy:
         src: php.conf
         dest: /etc/nginx/default.d/php.conf
     - name: restart nginx
       service:
        name: nginx
        state: restarted
 ​
 - name: deploy web app
   hosts: lnmp
   vars:
     blog_vhost: blog.lyk.cloud
   tasks:
     - name: prepare vhost for wordpress
       template:
         src: vhost-wordpress.conf.j2
         dest: /etc/nginx/conf.d/vhost-wordpress.conf
     - name: create /usr/share/nginx/html/{{ blog_vhost }}
       file:
         path: /usr/share/nginx/html/{{ blog_vhost }}
         state: directory
     - name: Unarchive a wordpress file 
       unarchive:
         src: wordpress-4.9.4-zh_CN.zip
         dest: /usr/share/nginx/html/{{ blog_vhost }}/
         owner: nginx
         group: nginx
     - name: restart nginx
       service:
        name: nginx
        state: restarted
        
 ​
 --部署 MariaDB(数据库):安装数据库软件、启动服务、设置 root 密码、删除默认的匿名用户和测试库(安全加固)。
 --准备数据库(给 Web 应用用):创建一个专用的数据库用户(比如wordpress)和数据库(比如webapp),让 Web 程序能连接数据库。
 --部署 Nginx(Web 服务器):安装 Nginx、启动服务,先放一个简单的 “hello world” 页面测试。
 --部署 PHP:安装 PHP 及相关组件(处理动态网页),配置 PHP 和 Nginx 配合工作(让 Nginx 遇到.php文件时交给 PHP 处理)。
 --部署 Web 应用(WordPress):配置 Nginx 虚拟主机(让blog.lyk.cloud这个域名指向 WordPress)、创建网站目录、解压 WordPress 程序包并设置权限。
 ​
 ​
 # 5. 创建变量文件(存密码和配置)      
 [lyk@controller lnmp 13:58:00]$ mkdir host_vars
 [lyk@controller lnmp 13:58:32]$ mkdir host_vars/lnmp
 [lyk@controller lnmp 13:58:52]$ vim hostvars/lnmp/vaults.yml
 ​
   1 mysql_root_password: lyk@123
   2 app_user: wordpress                                                           
   3 app_password: lyk@123
   4 app_host: '%'      
   5 app_priv: '*.*:ALL'
 ​
 --里面存的是 “敏感变量”(需要加密的信息):
 --mysql_root_password: lyk@123:数据库 root 用户的密码。
 --app_user: wordpress:给 Web 应用用的数据库用户名。
 --app_password: lyk@123:Web 应用用户的密码。
 --这些信息不能明文存,所以后面会加密。
 ​
 #db_name: webapp:给 Web 应用用的数据库名字  
 [lyk@controller lnmp 14:05:58]$ vim hostvars/lnmp/vars.yml
   1 db_name: webapp  
   
 #6. 配置 PHP 和 Nginx 配合 
 [lyk@controller lnmp 14:07:41]$ vim php.conf  
   1 location ~ \.php$ {
   2     try_files $uri =404;
   3     fastcgi_pass 127.0.0.1:9000;
   4     fastcgi_index index.php;
   5     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
   6     include fastcgi_params;
   7 }   
   
 #拖入wordpress-4.9.4-zh_CN.zip
 [lyk@controller lnmp 14:10:49]$ rz -E
 rz waiting to receive.
 ​
 [lyk@controller lnmp 14:10:58]$ ls
 ansible.cfg      hostvars   php.conf
 deploy_lnmp.yml  inventory  wordpress-4.9.4-zh_CN.zip
 ​
 [lyk@controller lnmp 14:11:41]$ unzip wordpress-4.9.4-zh_CN.zip 
 ​
 [lyk@controller lnmp 14:12:02]$ ls
 ansible.cfg      hostvars   php.conf   wordpress-4.9.4-zh_CN.zip
 deploy_lnmp.yml  inventory  wordpress
 ​
 #7. 准备 WordPress 程序
 [lyk@controller lnmp 14:12:21]$ ls wordpress
 index.php        wp-blog-header.php    wp-includes        wp-settings.php
 license.txt      wp-comments-post.php  wp-links-opml.php  wp-signup.php
 readme.html      wp-config-sample.php  wp-load.php        wp-trackback.php
 wp-activate.php  wp-content            wp-login.php       xmlrpc.php
 wp-admin         wp-cron.php           wp-mail.php
 ​
 #8.到nginx里面复制模板到vhost-wordpress.conf.j2, 配置 Nginx 虚拟主机(域名对应网站)
 [lyk@controller web 11:00:26]$ sudo yum install -y nginx
 [lyk@controller web 14:15:30]$ vim /etc/nginx/nginx.conf
 ​
 [lyk@controller lnmp 14:12:39]$ vim vhost-wordpress.conf.j2
 ​
   1  server {
   2      listen       80;
   3      server_name  {{ blog_vhost }};
   4      root         /usr/share/nginx/html/{{ blog_vhost }}/wordpress;
   5      index index.php;
   6    
   7      # Load configuration files for the default server block.
   8      include /etc/nginx/default.d/*.conf;
   9      
  10      # log file
  11      access_log  /var/log/nginx/access-{{ blog_vhost }}.log;
  12      error_log /var/log/nginx/error-{{ blog_vhost }}.log;
  13  }   
  
 ​
 #9. 加密敏感信息(保护密码)
 [lyk@controller lnmp 14:19:13]$ ansible-vault encrypt hostvars/lnmp/vaults.yml
 New Vault password:              ##lyk@123
 Confirm New Vault password:      ##lyk@123
 Encryption successful
 [lyk@controller lnmp 14:21:48]$ echo lyk@123 > secret.txt
 ​
 ​
 #编辑 Ansible 配置文件,添加vault_password_file=./secret.txt,告诉 Ansible:“解密vaults.yml时,自动从secret.txt读密码”(不用手动输入)
 [lyk@controller lnmp 14:22:30]$ vim ansible.cfg 
   1 [defaults]
   2 remote_user = lyk
   3 inventory = ./inventory
   4 #roles_path =./roles
   5 #collections_paths =./collections                                               
   6 vault_password_file=./secret.txt
   7  
   8 [privilege_escalation]
   9 become = True
  10 become_user = root
  11 become_method = sudo
  12 become_ask_pass = False
 ​
 #测试解密查看vaults.yml,确认加密正常(能看到解密后的密码)
 [lyk@controller lnmp 14:27:07]$ ansible-vault view hostvars/lnmp/vaults.yml 
 mysql_root_password: lyk@123
 app_user: wordpress
 app_password: lyk@123
 app_host: '%'
 app_priv: '*.*:ALL'
 ​
 ​
 [lyk@controller lnmp 14:28:55]$ mv hostvars/ host_vars
 ​
 #10. 目标主机(node1)的清理工作
 [lyk@node1 ~ 14:31:56]$ systemctl status httpd
 ● httpd.service - The Apache HTTP Server
    Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
    Active: active (running) since 一 2025-08-18 09:44:16 CST; 4h 47min ago          ##running导致nginx不能使用
      Docs: man:httpd(8)
 #关闭
 [lyk@node1 ~ 14:33:41]$ sudo systemctl disable httpd --now
 ​
 #清除之前数据库密码
 [root@node1 ~ 15:41:29]# systemctl stop mariadb
 [root@node1 ~ 15:41:37]# rm -fr /var/lib/mysql/*
 ​
 ​
 [lyk@controller lnmp 14:38:27]$ ansible-playbook deploy_lnmp.yml 
 ​

登录网页

复制代码
 #  C:\Windows\System32\drivers\etc添加
 10.1.8.11 blog.lyk.cloud
 #浏览器输入
 blog.lyk.cloud
相关推荐
wdxylb36 分钟前
云原生俱乐部-RH134知识点总结(1)
linux·云原生
王者鳜錸1 小时前
PYTHON让繁琐的工作自动化-猜数字游戏
python·游戏·自动化
黑客影儿1 小时前
Kali Linux 环境中的系统配置文件与用户配置文件大全
linux·运维·程序人生·安全·网络安全·系统安全·学习方法
岚天start1 小时前
Linux系统网络排查工具总结
linux·运维·网络·监控·扫描·连通性·流量
风静雪冷2 小时前
grep命令要点、详解和示例
linux
我是哈哈hh2 小时前
【MySQL】在UBuntu环境安装以及免密码登录入门
linux·数据库·mysql·ubuntu
LKAI.3 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
知白守黑2673 小时前
Linux磁盘阵列
linux·运维·服务器
维尔切4 小时前
Linux中基于Centos7使用lamp架构搭建个人论坛(wordpress)
linux·运维·架构