//修改主机名
[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-hostshosts (3):192.168.183.135192.168.183.136192.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 firewalldhosts: alltasks:- name: disabled selinuxlineinfile: path: /etc/selinux/configregexp: '^SELINUX='line: SELINUX=disabled- name: disabled firewalldservice: name: firewalldstate: stoppedenabled: no- name: Deploy the nginx servicehosts: 192.168.183.135vars_files: - /etc/ansible/playbooks/lnmp/vars/nginx_test.ymltasks: - name: Create the nginx useruser: name: nginxsystem: yescreate_home: noshell: /sbin/nologinstate: present- name: Create the nginx directoryfile: path: "{{ install_dir }}"state: directoryowner: nginxgroup: nginxrecurse: yes- name: Install dependenciesyum: name=pcre-devel,openssl,openssl-devel,gd-devel,gcc,gcc-c++,vim,wget,make state=present- name: Download the nginx packagecopy: src: /opt/{{ package_nginx }}.tar.gzdest: /opt/- name: Unzip the nginx packageunarchive: src: /opt/{{ package_nginx }}.tar.gzdest: /usr/local/remote_src: yes- name: Configure and make installshell: 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 Variablescopy: dest: /etc/profile.d/nginx.shcontent: export PATH={{ install_dir }}/sbin:$PATH- name: Write nginx service filecopy: dest: /usr/lib/systemd/system/nginx.servicecontent: |[Unit]Description=nginx server daemonAfter=network.target[Service]Type=forkingExecStart={{ install_dir }}/sbin/nginxExecStop={{ install_dir }}/sbin/nginx -s stopExecReload=/bin/kill -HUP \$MAINPID[Install]WantedBy=multi-user.target- name: Start the nginx serviceservice:name: nginxstate: startedenabled: yes- name: Deploy mysqlhosts: 192.168.183.136vars_files: - /etc/ansible/playbooks/lnmp/vars/mysql_test.ymltasks:- name: Create a mysql useruser: name: mysqlsystem: yescreate_home: noshell: /sbin/nologinstate: present- name: Download and Unzip the mysql packageunarchive: src: /opt/{{ package_mysql }}.tar.gzdest: "{{ unzip_dir }}"- name: Mysql Soft linksfile: src: "{{ unzip_dir }}{{ package_mysql }}"dest: "{{ install_dir }}"state: link- name: Change the owner of the owner groupfile: path: "{{ install_dir }}"owner: mysqlgroup: mysqlstate: directoryrecurse: yes- name: Include Soft linksfile: src: "{{ install_dir }}/include"dest: /usr/include/mysqlstate: link- name: Configuring environment Variablescopy: dest: /etc/ld.so.conf.d/mysql.confcontent: "{{ install_dir }}/lib/"- name: Configuring environment Variables mysql.shcopy: dest: /etc/profile.d/mysql.shcontent: export PATH={{ install_dir }}/bin:$PATH- name: Create a data directoryfile: path: "{{ data_dir }}"owner: mysqlgroup: mysqlstate: directoryrecurse: yes- name: Initializing the databaseshell: cat /tmp/pass || mysqld --initialize --user mysql --datadir {{ data_dir }} &> /tmp/pass- name: Generating configuration filescopy: dest: /etc/my.cnfcontent: | [mysqld]basedir = {{ install_dir }}datadir = {{ data_dir }}socket = /tmp/mysql.sockport = 3306pid-file = {{ data_dir }}/mysql.piduser = mysqlskip-name-resolve- name: mysqld service filecopy: dest: /usr/lib/systemd/system/mysqld.servicecontent: |[Unit]Description=mysqld server daemonAfter=network.target[Service]Type=forkingExecStart={{ install_dir }}/support-files/mysql.server startExecStop={{ install_dir }}/support-files/mysql.server stopExecReload=/bin/kill -HUP $MAINPID[Install]WantedBy=multi-user.target- name: reload daemonshell: systemctl daemon-reload- name: Start the mysqld serviceservice: name: mysqldstate: startedenabled: yes- name: Install PHPhosts: 192.168.183.137vars_files: - /etc/ansible/playbooks/lnmp/vars/php_test.ymltasks: - name: Download and Unzip the PHP packageunarchive: src: /opt/{{ package_php }}.tar.gzdest: /usr/local/- name: Install dependenciesyum: 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 installshell: 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 Variablescopy: dest: /etc/profile.d/php8.shcontent: export PATH={{ install_dir }}/bin:$PATH- name: Copy Configuration file startup scriptcopy: src: "{{ install_dir }}/etc/php-fpm.conf.default"dest: "{{ install_dir }}/etc/php-fpm.conf"remote_src: yes- name: Copy Configuration file startup scriptcopy: 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 filecopy: dest: /usr/lib/systemd/system/php.servicecontent: |[Unit]Description=phpAfter=network.target[Service]Type=forkingExecStart={{ install_dir }}/sbin/php-fpmExecStop=ps -ef |grep php|grep -v grep|awk '{print $2}' |xargs kill -9ExecReload=/bin/kill -HUP $MAINPID[Install]WantedBy=multi-user.target- name: Start the PHP serviceservice: name: phpstate: startedenabled: yes- name: Create index.php filecopy: dest: /var/index.phpcontent: |- name: Exposing php Portslineinfile: path: "{{ install_dir }}/etc/php-fpm.d/www.conf"regexp: '^listen = 'line: listen = 192.168.183.137:9000- name: Connect the nginxlineinfile: 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 serviceservice: name: phpstate: restarted- name: Create index.php file in nginxhosts: 192.168.183.135vars_files: - /etc/ansible/playbooks/lnmp/vars/nginx_test.ymltasks: - name: Backup nginxcopy: src: "{{ install_dir }}/conf/nginx.conf"dest: "{{ install_dir }}/conf/nginx.conf-bak"remote_src: yes- name: Generate a new nginxcopy: src: /etc/ansible/playbooks/lnmp/nginx.confdest: "{{ install_dir }}/conf/nginx.conf"- name: Restart the nginx serviceservice: name: nginxstate: restarted
在执行playbook之前,最好要进行验证,确保其内容的语法正确无误。ansible-playbook命令提供了一个–syntax-check选项,可用于验证playbook的语法。
[root@ansible playbooks]# ansible-playbook --syntax-check lnmp.ymlplaybook: lnmp.yml
执行playbook。
[root@ansible lnmp]# ansible-playbook lnmp.yml
访问时需确保selinux状态为disabled状态。
//查看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