使用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