//修改主机名
[root@localhost ~]# hostnamectl set-hostname ansible
[root@localhost ~]# bash
//修改清单默认路径
[root@ansible ~]# vim /etc/ansible/ansible.cfg
inventory = /etc/ansible/inventory
//构建清单
[root@ansible ~]# cd /etc/ansible/
[root@ansible ansible]# touch inventory
[root@ansible ansible]# vim inventory
[root@ansible ~]# ansible all --list-hosts
hosts (3):
192.168.183.135
192.168.183.136
192.168.183.137
//设置免密登录
[root@ansible ansible]# ssh-keygen
[root@ansible ansible]# ssh-copy-id 192.168.183.135
[root@ansible ansible]# ssh-copy-id 192.168.183.136
[root@ansible ansible]# ssh-copy-id 192.168.183.137
//测试清单主机连通性
[root@ansible ansible]# ansible all -m ping
192.168.183.135 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
192.168.183.136 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
192.168.183.137 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
环境说明
主机 | IP | 版本 | 系统 |
---|---|---|---|
ansible | 192.168.183.138 | 2.9.27 | centos 8 |
nginx | 192.168.183.135 | 1.22.0 | centos 8 |
mysql | 192.168.183.136 | 5.7.38 | centos 8 |
php | 192.168.183.137 | 8.1.10 | centos 8 |
//文件结构
[root@ansible ~]# tree /etc/ansible/playbooks/lnmp/
/etc/ansible/playbooks/lnmp/
├── lnmp.yml //playbook
├── mysql_pass.yml //数据库加密文件
├── nginx.conf //nginx主配置文件
└── vars //变量目录
├── mysql_test.yml //mysql变量文件
├── nginx_test.yml //nginx变量文件
└── php_test.yml //php变量文件
1 directory, 6 files
//变量文件
[root@ansible ~]# cat /etc/ansible/playbooks/lnmp/vars/nginx_test.yml
install_dir: /usr/local/nginx
package_nginx: nginx-1.22.0
[root@ansible ~]# cat /etc/ansible/playbooks/lnmp/vars/mysql_test.yml
package_mysql: mysql-5.7.38-linux-glibc2.12-x86_64
unzip_dir: /usr/local/
install_dir: /usr/local/mysql
data_dir: /opt/data
[root@ansible ~]# cat /etc/ansible/playbooks/lnmp/vars/php_test.yml
package_php: php-8.1.10
install_dir: /usr/local/php8
//nginx.conf文件
[root@ansible lnmp]# cat nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.php index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 192.168.183.137:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
//playbook文件
[root@ansible ~]# cat /etc/ansible/playbooks/lnmp/lnmp.yml
---
- name: Disable selinux and firewalld
hosts: all
tasks:
- name: disabled selinux
lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: SELINUX=disabled
- name: disabled firewalld
service:
name: firewalld
state: stopped
enabled: no
- name: Deploy the nginx service
hosts: 192.168.183.135
vars_files:
- /etc/ansible/playbooks/lnmp/vars/nginx_test.yml
tasks:
- name: Create the nginx user
user:
name: nginx
system: yes
create_home: no
shell: /sbin/nologin
state: present
- name: Create the nginx directory
file:
path: "{{ install_dir }}"
state: directory
owner: nginx
group: nginx
recurse: yes
- name: Install dependencies
yum: name=pcre-devel,openssl,openssl-devel,gd-devel,gcc,gcc-c++,vim,wget,make state=present
- name: Download the nginx package
copy:
src: /opt/{{ package_nginx }}.tar.gz
dest: /opt/
- name: Unzip the nginx package
unarchive:
src: /opt/{{ package_nginx }}.tar.gz
dest: /usr/local/
remote_src: yes
- name: Configure and make install
shell:
cd /usr/local/{{ package_nginx }} && \
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log && make && make install
- name: Configuring environment Variables
copy:
dest: /etc/profile.d/nginx.sh
content: export PATH={{ install_dir }}/sbin:$PATH
- name: Write nginx service file
copy:
dest: /usr/lib/systemd/system/nginx.service
content: |
[Unit]
Description=nginx server daemon
After=network.target
[Service]
Type=forking
ExecStart={{ install_dir }}/sbin/nginx
ExecStop={{ install_dir }}/sbin/nginx -s stop
ExecReload=/bin/kill -HUP \$MAINPID
[Install]
WantedBy=multi-user.target
- name: Start the nginx service
service:
name: nginx
state: started
enabled: yes
- name: Deploy mysql
hosts: 192.168.183.136
vars_files:
- /etc/ansible/playbooks/lnmp/vars/mysql_test.yml
tasks:
- name: Create a mysql user
user:
name: mysql
system: yes
create_home: no
shell: /sbin/nologin
state: present
- name: Download and Unzip the mysql package
unarchive:
src: /opt/{{ package_mysql }}.tar.gz
dest: "{{ unzip_dir }}"
- name: Mysql Soft links
file:
src: "{{ unzip_dir }}{{ package_mysql }}"
dest: "{{ install_dir }}"
state: link
- name: Change the owner of the owner group
file:
path: "{{ install_dir }}"
owner: mysql
group: mysql
state: directory
recurse: yes
- name: Include Soft links
file:
src: "{{ install_dir }}/include"
dest: /usr/include/mysql
state: link
- name: Configuring environment Variables
copy:
dest: /etc/ld.so.conf.d/mysql.conf
content: "{{ install_dir }}/lib/"
- name: Configuring environment Variables mysql.sh
copy:
dest: /etc/profile.d/mysql.sh
content: export PATH={{ install_dir }}/bin:$PATH
- name: Create a data directory
file:
path: "{{ data_dir }}"
owner: mysql
group: mysql
state: directory
recurse: yes
- name: Initializing the database
shell:
cat /tmp/pass || mysqld --initialize --user mysql --datadir {{ data_dir }} &> /tmp/pass
- name: Generating configuration files
copy:
dest: /etc/my.cnf
content: |
[mysqld]
basedir = {{ install_dir }}
datadir = {{ data_dir }}
socket = /tmp/mysql.sock
port = 3306
pid-file = {{ data_dir }}/mysql.pid
user = mysql
skip-name-resolve
- name: mysqld service file
copy:
dest: /usr/lib/systemd/system/mysqld.service
content: |
[Unit]
Description=mysqld server daemon
After=network.target
[Service]
Type=forking
ExecStart={{ install_dir }}/support-files/mysql.server start
ExecStop={{ install_dir }}/support-files/mysql.server stop
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
- name: reload daemon
shell:
systemctl daemon-reload
- name: Start the mysqld service
service:
name: mysqld
state: started
enabled: yes
- name: Install PHP
hosts: 192.168.183.137
vars_files:
- /etc/ansible/playbooks/lnmp/vars/php_test.yml
tasks:
- name: Download and Unzip the PHP package
unarchive:
src: /opt/{{ package_php }}.tar.gz
dest: /usr/local/
- name: Install dependencies
yum: name=make,libxml2-devel,openssl-devel,curl-devel,libjpeg-devel,libpng-devel,libicu-devel,freetype-devel,openldap-devel,openldap,openldap-devel,gcc,gcc-c++,sqlite-devel,libzip-devel,http://mirror.centos.org/centos/8-stream/PowerTools/x86_64/os/Packages/oniguruma-devel-6.8.2-2.el8.x86_64.rpm,openssl,libcurl-devel.x86_64,libpng.x86_64,libpng-devel.x86_64,freetype-devel
- name: Configure and make install
shell:
cd /usr/local/{{ package_php }} && \
./configure --prefix={{ install_dir }} --with-config-file-path=/usr/local/php/etc --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --enable-fpm --enable-static --enable-sockets --with-zip --enable-calendar --enable-bcmath --enable-mbstring --with-zlib --with-iconv=/usr/local/libiconv --enable-gd --enable-mbstring --with-curl --with-freetype --disable-ipv6 --disable-debug --with-openssl --enable-intl --enable-opcach --with-iconv && make && make install
- name: Configuring environment Variables
copy:
dest: /etc/profile.d/php8.sh
content: export PATH={{ install_dir }}/bin:$PATH
- name: Copy Configuration file startup script
copy:
src: "{{ install_dir }}/etc/php-fpm.conf.default"
dest: "{{ install_dir }}/etc/php-fpm.conf"
remote_src: yes
- name: Copy Configuration file startup script
copy:
src: "{{ install_dir }}/etc/php-fpm.d/www.conf.default"
dest: "{{ install_dir }}/etc/php-fpm.d/www.conf"
remote_src: yes
- name: PHP service file
copy:
dest: /usr/lib/systemd/system/php.service
content: |
[Unit]
Description=php
After=network.target
[Service]
Type=forking
ExecStart={{ install_dir }}/sbin/php-fpm
ExecStop=ps -ef |grep php|grep -v grep|awk '{print $2}' |xargs kill -9
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
- name: Start the PHP service
service:
name: php
state: started
enabled: yes
- name: Create index.php file
copy:
dest: /var/index.php
content: |
<?php
phpinfo();
?>
- name: Exposing php Ports
lineinfile:
path: "{{ install_dir }}/etc/php-fpm.d/www.conf"
regexp: '^listen = '
line: listen = 192.168.183.137:9000
- name: Connect the nginx
lineinfile:
path: "{{ install_dir }}/etc/php-fpm.d/www.conf"
regexp: '^;listen.allowed_clients = '
line: listen.allowed_clients = 192.168.183.135
- name: Restart the PHP service
service:
name: php
state: restarted
- name: Create index.php file in nginx
hosts: 192.168.183.135
vars_files:
- /etc/ansible/playbooks/lnmp/vars/nginx_test.yml
tasks:
- name: Backup nginx
copy:
src: "{{ install_dir }}/conf/nginx.conf"
dest: "{{ install_dir }}/conf/nginx.conf-bak"
remote_src: yes
- name: Generate a new nginx
copy:
src: /etc/ansible/playbooks/lnmp/nginx.conf
dest: "{{ install_dir }}/conf/nginx.conf"
- name: Restart the nginx service
service:
name: nginx
state: restarted
在执行playbook之前,最好要进行验证,确保其内容的语法正确无误。ansible-playbook命令提供了一个–syntax-check选项,可用于验证playbook的语法。
[root@ansible playbooks]# ansible-playbook --syntax-check lnmp.yml
playbook: lnmp.yml
执行playbook。
[root@ansible lnmp]# ansible-playbook lnmp.yml
//查看mysql密码
[root@ansible ~]# ansible 192.168.183.136 -a 'cat /tmp/pass'
192.168.183.136 | CHANGED | rc=0 >>
2022-10-25T14:15:10.414652Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2022-10-25T14:15:10.616701Z 0 [Warning] InnoDB: New log files created, LSN=45790
2022-10-25T14:15:10.668312Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2022-10-25T14:15:10.672358Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 6f7a02ae-546f-11ed-a76c-000c2907de9b.
2022-10-25T14:15:10.672933Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2022-10-25T14:15:10.911035Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2022-10-25T14:15:10.911045Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2022-10-25T14:15:10.911386Z 0 [Warning] CA certificate ca.pem is self signed.
2022-10-25T14:15:10.940083Z 1 [Note] A temporary password is generated for root@localhost: spEob8CoO?sj
//写到加密yml文件中
[root@ansible ~]# echo "mysql_pass=spEob8CoO?sj" >mysql_pass.yml
//加密输入新密码
[root@ansible ~]# ansible-vault encrypt mysql_pass.yml
New Vault password:
Confirm New Vault password:
Encryption successful
//查看加密后的密码
[root@ansible ~]# cat mysql_pass.yml
$ANSIBLE_VAULT;1.1;AES256
34306262343765663234346436323663336161303432366138346530353533393035356632333366
3633613938333938663636656436613566303332353963330a353164363134343636343337333866
38376536663564646339643566653934656534633933346539346466373166623065333538356431
3362363966323365320a623364633731366334396264353933376235333965336263333761323961
64363863363438376533343437333238663430396131623239323032376435313566
//输入查看密码
[root@ansible ~]# ansible-vault view mysql_pass.yml
Vault password:
mysql_pass=spEob8CoO?sj