Fri. Jan 24th, 2025

Series Ansible – Bài 4 – Ứng dụng Ansible để cài đặt WordPress

By admin Apr 5, 2024
Ansibe

Ở các bài trước mình đã giới thiệu với các bạn về Ansiblecách sử dụng và viết một Ansible playbook. Nếu các bạn chưa đọc các bài viết này các bạn có thể đọc lại các bài viết đó tại đây.
Trong bài viết này mình sẽ thực hành ứng dụng của Ansible khi setup một trang web WordPress nhé.

Mô hình sử dụng trong bài.

  • Server Ansible Control Node
  • Web Server
  • Nginx Load Balance
Ansible

Quy hoạch xác định các roles cần thiết trong ansible.

Đầu tiên trước khi bắt đầu chúng ta cần xác định chúng ta sẽ cần thiết lập những gì cho mô hình này. Ở đây mình sẽ sử dụng  Apache để chạy website wordpress và sử dụng Nginx để thiết lập Reverproxy và caching các file tĩnh. Vậy chúng ta sẽ thống kê như sau:

 –  Đầu tiên setup LAMP stack để chạy wordpress.

–  Thiết lập Vhost cho domain và tiến hành  cài đặt wordpress cho domain đó.

– Cài đặt Nginx làm loadblance 

– Cài đặt Vhost để biến nginx thành reverse proxy và cache server,.

– Tất nhiên một trang wbe sẽ không thể thiếu được SSL để bảo mật hơn.

Sau khi thống kê thì ta sẽ có một tree map cho dự án như sau:

				
					├── certbot
│   ├── README.md
│   ├── handlers
│   │   └── main.yml
│   └── tasks
│       └── main.yml
├── inventory.ini
├── loadbalance
│   ├── README.md
│   ├── handlers
│   │   └── main.yml
│   └── tasks
│       └── main.yml
├── nginx_config
│   ├── conf
│   │   ├── cdn.conf
│   │   ├── header.conf
│   │   ├── proxy_cache.conf
│   │   └── proxy_pass.conf
│   ├── nginx.conf
│   └── systctl.conf
├── playbook.yml
├── setup_lamp
│   ├── README.md
│   ├── handlers
│   │   └── main.yml
│   └── tasks
│       └── main.yml
├── setup_wordpress
│   ├── README.md
│   ├── handlers
│   │   └── main.yml
│   ├── tasks
│   │   └── main.yml
│   └── templates
│       ├── apache.conf.j2
│       └── wp-config.php.j2
├── vars
│   └── default.yml
└── vhost-nginx
    ├── README.md
    ├── handlers
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    └── templates
        └── nginx_vhost.conf.j2
				
			

Tiến hành viết playbook.

Trong bài này mình sẽ sử dụng roles để viết một ansible play book cho nên mỗi bước được đề ra trong phần 1 sẽ được setup thành 1 roles.
Một số modules mình sử dụng trong dự án này như sau: 

Đầu tiên chúng ta sẽ bắt đầu với bước 1 setup LAMP stack.


Cơ bản setup lamp stack chúng ta cần cài các thành phần như apache, mysql, php và php extention.

				
					---
# tasks file for setup_lamp
- name: Install prerequisites
  apt: name=aptitude update_cache=yes state=latest force_apt_get=yes
  tags: [ system ]

- name: Install LAMP Packages
  apt: name={{ item }} update_cache=yes state=latest
  loop: [ 'apache2', 'mysql-server', 'python3-pymysql', 'php', 'php-mysql', 'libapache2-mod-php' ]
  tags: [ system ]

- name: Install PHP Extensions
  apt: name={{ item }} update_cache=yes state=latest
  loop: "{{ php_modules }}"
  tags: [ system ]

- name: Set the root password
  mysql_user:
    name: root
    password: "{{ mysql_root}}"
    login_unix_socket: /var/run/mysqld/mysqld.sock
  tags: [ mysql, mysql-root ]

- name: Remove all anonymous user accounts
  mysql_user:
    name: ''
    host_all: yes
    state: absent
    login_user: root
    login_password: "{{ mysql_root_password }}"
  tags: [ mysql ]

- name: Remove the MySQL test database
  mysql_db:
    name: test
    state:reloaded
    login_user: root
    login_password: "{{ mysql_root_password }}"
  tags: [ mysql ]

				
			

Bước 2 chúng ta cần setup một Vhost apache và install word press cho domain đó.

Đầu tiên chúng ta tạo file main dành cho task của roles setup_wordpress như sau.

				
					---
# tasks file for setup_wordpress
# Apache Config vhost
- name: Create document root
  file:
   path: "/var/www/{{ http_host }}"
   state: directory
   owner: "www-data"
   group: "www-data"
   mode: '0755'
  tags: [ apache ]

- name: Set up Apache VirtualHost
  template:
   src: "apache.conf.j2"
   dest: "/etc/apache2/sites-available/{{ http_conf }}"
  notify: Reload Apache
  tags: [ apache ]

- name: Enable rewrite module
  shell: /usr/sbin/a2enmod rewrite
  notify: Reload Apache
  tags: [ apache ]

- name: Enable new site
  shell: /usr/sbin/a2ensite {{ http_conf }}
  notify: Reload Apache
  tags: [ apache ]

- name: Disable default Apache site
  shell: /usr/sbin/a2dissite 000-default.conf
  notify: Restart Apache
  tags: [ apache ]
# Setup Database for WordPress
- name: Creates database for WordPress
  mysql_db:
   name: "{{mysql_user}}"
   state: present
   login_user: root
   login_password: "{{ mysql_root_password }}"
  tags: [ mysql ]

- name: Create MySQL user for WordPress
  mysql_user:
   name: "{{ mysql_user }}"
   password: "{{ mysql_password }}"
   priv: "{{ mysql_user }}.*:ALL"
   state: present
   login_user: root
   login_password: "{{ mysql_root_password }}"
  tags: [ mysql ]

# UFW Configuration
- name: "UFW - Allow HTTP on port {{ http_port }}"
  ufw:
   rule: allow
   port: "{{ http_port }}"
   proto: tcp
  tags: [ system ]
# WordPress Configuration
- name: Download and unpack latest WordPress
  unarchive:
   src: https://wordpress.org/latest.tar.gz
   dest: "/var/www/{{ http_host }}"
   remote_src: yes
   creates: "/var/www/{{ http_host }}/wordpress"
  tags: [ wordpress ]
- name: Set ownership
  file:
   path: "/var/www/{{ http_host }}"
   state: directory
   recurse: yes
   owner: www-data
   group: www-data
  tags: [ wordpress ]
- name: Set permissions for directories
  shell: "/usr/bin/find /var/www/{{ http_host }}/wordpress/ -type d -exec chmod 750 {} \\;"
  tags: [ wordpress ]
- name: Set permissions for files
  shell: "/usr/bin/find /var/www/{{ http_host }}/wordpress/ -type f -exec chmod 640 {} \\;"
  tags: [ wordpress ]
- name: Set up wp-config
  template:
   src: "wp-config.php.j2"
   dest: "/var/www/{{ http_host }}/wordpress/wp-config.php"
  tags: [ wordpress ]


				
			

Kế tiếp  ta cần 2 template dành cho Vhost và wp-config.php dùng để cài đặt wordpress.

Ta tiến hành tạo hai file jira như sau.

Vhost.conf.j2

				
					<VirtualHost *:{{ http_port }}>
    ServerAdmin webmaster@localhost
    ServerName {{ http_host }}
    ServerAlias www.{{ http_host }}
    DocumentRoot /var/www/{{ http_host }}/wordpress
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    <Directory /var/www/{{ http_host }}>
          Options -Indexes
          AllowOverride All
    </Directory>

    <IfModule mod_dir.c>
        DirectoryIndex index.php index.html index.cgi index.pl  index.xhtml index.htm
    </IfModule>

</VirtualHost>

				
			

Wp-config.php.j2

				
					<?php
/**
 * The base configuration for WordPress
 *
 * The wp-config.php creation script uses this file during the
 * installation. You don't have to use the web site, you can
 * copy this file to "wp-config.php" and fill in the values.
 *
 * This file contains the following configurations:
 *
 * * MySQL settings
 * * Secret keys
 * * Database table prefix
 * * ABSPATH
 *
 * @link https://codex.wordpress.org/Editing_wp-config.php
 *
 * @package WordPress
 */

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', '{{mysql_user}}' );

/** MySQL database username */
define( 'DB_USER', '{{ mysql_user }}' );

/** MySQL database password */
define( 'DB_PASSWORD', '{{ mysql_password }}' );

/** MySQL hostname */
define( 'DB_HOST', 'localhost' );

/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );

/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

/** Filesystem access **/
define('FS_METHOD', 'direct');

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define( 'AUTH_KEY',         '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'SECURE_AUTH_KEY',  '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'LOGGED_IN_KEY',    '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'NONCE_KEY',        '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'AUTH_SALT',        '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'SECURE_AUTH_SALT', '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'LOGGED_IN_SALT',   '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'NONCE_SALT',       '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );

/**#@-*/

/**
 * WordPress Database Table prefix.
 *
 * You can have multiple installations in one database if you give each
 * a unique prefix. Only numbers, letters, and underscores please!
 */
$table_prefix = 'wp_';

/**
 * For developers: WordPress debugging mode.
 *
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
 *
 * For information on other constants that can be used for debugging,
 * visit the Codex.
 *
 * @link https://codex.wordpress.org/Debugging_in_WordPress
 */
define( 'WP_DEBUG', false );

/* That's all, stop editing! Happy publishing. */

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
        define( 'ABSPATH', dirname( __FILE__ ) . '/' );
}

/** Sets up WordPress vars and included files. */
require_once( ABSPATH . 'wp-settings.php' );

				
			

Thiết lập Loadblance

Sau khi đã cài đặt web server thành công ta có thể tiếp tục cài đặt loadbalance cho nó.

Thiết lập file task cho roles loadblance như sau:

				
					---
- name: Update repo
  apt:
    update_cache: yes
- name: Install Nginx
  apt:
    name: "{{ package }}"
    state: present
  notify: Start nginx
  vars:
    package:
      - nginx
      - nginx-extras
  tags: [Load balance]

- name: Config server
  copy:
    src: /root/wordpress/nginx_config/systctl.conf
    dest: /etc/sysctl.conf
  notify: Apply sysctl config
  tags: [Load balance]

- name: Optimize Nginx Caching Performance
  copy:
    src: /root/wordpress/nginx_config/nginx.conf
    dest: /etc/nginx/nginx.conf
  notify: Restart Nginx
  tags: [Load balance]

- name: Config CDN Option
  synchronize:
    src: /root/wordpress/nginx_config/conf/
    dest: /etc/nginx/conf
  notify: Restart Nginx
  tags: [Load balance]

				
			

Thiết lập Vhost Nginx

Sau khi đã cài đặt đầy đủ các package cần thiết cho Nginx ta cần thiết lập Vhost nginx để có  thể cài đặt được Vhost cho một domain cụ thể .

Ta sẽ thiết lập task cho Vhost Nginx như sau:

				
					---
# tasks file for vhost-nginx
- name: setup vhost for nginx
  template:
    src: nginx_vhost.conf.j2
    dest: /etc/nginx/sites-enabled/{{ nginx_host}}.conf
    owner: root
    group: root
    mode: '644'
  notify: Reload Nginx
  tags: [ vHost Nginx ]
				
			

Thiết lập SSL

Cuối cùng cũng quan trọng đó là thiết lập SSL cho web vừa khởi tạo.

				
					---
# tasks file for certbot
- name: Install Certbot
  apt:
    name: "{{package}}"
    state: present
  vars:
    package:
      - certbot
      - python3-certbot-nginx
  tags: [ Certbot ]
- name: Install SSL
  shell: certbot --nginx --non-interactive --agree-tos --email danht@vinahost.vn --domains  {{ nginx_host }}
  become: true
  notify: Reload Nginx
  tags: [ Certbot ]

				
			

Tạo Iventory và Playbook

Để playbook hoạt động ta cần cài đặt invetory và các biến mặc định truyền trong vars/default.

Inventory.

				
					[lb-server]
nginx1 ansible_host=146.196.65.12

[webserver]
server1 ansible_host=146.196.65.7

[all:vars]
ansible_user=root
ansible_ssh_private_key_file=/root/.ssh/id_rsa

				
			

default.yml

				
					---
#System Settings
php_modules: [ 'php-curl', 'php-gd', 'php-mbstring', 'php-xml', 'php-xmlrpc', 'php-soap', 'php-intl', 'php-zip' ]

#MySQL Settings
mysql_root_password: "Thanhdan1@710"
mysql_db: "wordpress"
mysql_user: "danny"
mysql_password: "Thanhdan1@710"

#HTTP Settings
http_host: "wordpress.thanhdan.name.vn"
http_conf: "wordpress.thanhdan.name.vn.conf"
http_port: "80"
backend_servers:
  - name: server1
    address: 146.196.65.7
    port: 80
load_balancing_method: round-robin
nginx_host: "wordpress.thanhdan.name.vn"
load_balancer_port: 80

				
			

Cuối cùng  ta cần tạo playbook để có thể thực hiện các quá trình trên.

				
					- name: Install WordPress For Web Server
  hosts: webserver
  become: true
  vars_files:
    - vars/default.yml
  roles:
    - setup_lamp
    - setup_wordpress
- name: Configuration LoadBalance
  hosts: lb-server
  become: true
  vars_files:
    - vars/default.yml
  roles:
    - loadbalance
    - vhost-nginx
    - certbot
~

				
			

Cuối cũng ta chạy play book để kiểm tra kết quả

				
					PLAY [Install WordPress For Web Server] *************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************
ok: [server1]

TASK [setup_lamp : Install prerequisites] ***********************************************************************************************************************************************
changed: [server1]

TASK [setup_lamp : Install LAMP Packages] ***********************************************************************************************************************************************
changed: [server1] => (item=apache2)
changed: [server1] => (item=mysql-server)
changed: [server1] => (item=python3-pymysql)
changed: [server1] => (item=php)
changed: [server1] => (item=php-mysql)
changed: [server1] => (item=libapache2-mod-php)

TASK [setup_lamp : Install PHP Extensions] **********************************************************************************************************************************************
changed: [server1] => (item=php-curl)
changed: [server1] => (item=php-gd)
changed: [server1] => (item=php-mbstring)
changed: [server1] => (item=php-xml)
changed: [server1] => (item=php-xmlrpc)
changed: [server1] => (item=php-soap)
changed: [server1] => (item=php-intl)
changed: [server1] => (item=php-zip)

TASK [setup_lamp : Set the root password] ***********************************************************************************************************************************************
[WARNING]: Option column_case_sensitive is not provided. The default is now false, so the column's name will be uppercased. The default will be changed to true in community.mysql
4.0.0.
changed: [server1]

TASK [setup_lamp : Remove all anonymous user accounts] **********************************************************************************************************************************
ok: [server1]

TASK [setup_lamp : Remove the MySQL test database] **************************************************************************************************************************************
ok: [server1]

TASK [setup_wordpress : Create document root] *******************************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Set up Apache VirtualHost] **************************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Enable rewrite module] ******************************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Enable new site] ************************************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Disable default Apache site] ************************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Creates database for WordPress] *********************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Create MySQL user for WordPress] ********************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : UFW - Allow HTTP on port 80] ************************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Download and unpack latest WordPress] ***************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Set ownership] **************************************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Set permissions for directories] ********************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Set permissions for files] **************************************************************************************************************************************
changed: [server1]

TASK [setup_wordpress : Set up wp-config] ***********************************************************************************************************************************************
changed: [server1]

RUNNING HANDLER [setup_wordpress : Reload Apache] ***************************************************************************************************************************************
changed: [server1]

RUNNING HANDLER [setup_wordpress : Restart Apache] **************************************************************************************************************************************
changed: [server1]

PLAY [Configuration LoadBalance] ********************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************
ok: [nginx1]

TASK [loadbalance : Update repo] ********************************************************************************************************************************************************
changed: [nginx1]

TASK [loadbalance : Install Nginx] ******************************************************************************************************************************************************
changed: [nginx1]

TASK [loadbalance : Config server] ******************************************************************************************************************************************************
changed: [nginx1]

TASK [loadbalance : Optimize Nginx Caching Performance] *********************************************************************************************************************************
changed: [nginx1]

TASK [loadbalance : Config CDN Option] **************************************************************************************************************************************************
[DEPRECATION WARNING]: The connection's stdin object is deprecated. Call display.prompt_until(msg) instead. This feature will be removed in version 2.19. Deprecation warnings can be
disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [nginx1]

TASK [vhost-nginx : setup vhost for nginx] **********************************************************************************************************************************************
changed: [nginx1]

TASK [certbot : Install Certbot] ********************************************************************************************************************************************************
changed: [nginx1]

TASK [certbot : Install SSL] ************************************************************************************************************************************************************
changed: [nginx1]

RUNNING HANDLER [loadbalance : Start nginx] *********************************************************************************************************************************************
ok: [nginx1]

RUNNING HANDLER [loadbalance : Restart Nginx] *******************************************************************************************************************************************
changed: [nginx1]

RUNNING HANDLER [loadbalance : Apply sysctl config] *************************************************************************************************************************************
changed: [nginx1]

RUNNING HANDLER [certbot : Reload Nginx] ************************************************************************************************************************************************
changed: [nginx1]

PLAY RECAP ******************************************************************************************************************************************************************************
nginx1                     : ok=13   changed=11   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
server1                    : ok=22   changed=19   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


				
			

Sau khi chạy thành công ta truy cập vào trang web wordpress.thanhdan.name.vn để kiểm tra sẽ thấy giao diện để cài đặt wordpress.

Ansible deloy web

Trên đây là quá trình cài đặt một website wordpress và thiết lập caching cùng load balance từ A-Z. Các file câu hình chi tiết các bạn có thể tải về tại đây.

Vậy là chúng ta đã đi gần hết chặn đường của Series này. Ở bài sau sẽ là bài cuối cũng khi mình sử dụng Ansible để cấu hình nhiều Docker Contrainer với nhau. Các bạn có thể đón xem tại Series Ansible này nhé.

Chúc các bạn thực hiện thành công !

Tài liệu tham khảo:

  • https://github.com/aleks/ansible-multi-wordpress/tree/master
  • https://jinja.palletsprojects.com/en/2.10.x/
  • https://blog.vinahost.vn/ansible-la-gi/
  • https://elroydevops.tech/cach-su-dung-ansible-infrastructure-as-code/

By admin

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *

error: Content is protected !!
Don`t copy text!