5/5 - (1 vote)

This article is a tutorial that is intended for novice system administrators, so experienced professionals can safely skip it. The publication is a continuation of a series of educational articles here , here .

In this article, we will practice writing an Ansible role to automatically raise a web server.

So, as I mentioned in the first part , any ansible-role writing is accompanied by a plan. This plan should include everything that will need to be installed and configured.

If we consider all the points in one article, then the material turns out to be too voluminous – in fact, that is why it was decided to divide it into two parts. Here is our plan, in which the first three points that we completed in the first part are crossed out :

  1. Point 1. Initial server setup.
  2. Point 2. Installing LEMP.
  3. Item 3. Rights and user.
  4. Step 4. Setting up LEMP.
  5. Item 5. Transfer of site code and database.
  6. Item 6. Testing.
  7. Item 7. Bottom line.

In this article, we will complete the remaining four steps. So, at the moment in the /var/ansible directory is:

.

├── hosts.txt

├── LEMP

│ ├──defaults

│ │ └── main.yml

│ ├── files

│ ├── handlers

│ │ └── main.yml

│ ├── meta

│ │ └── main.yml

│ ├── README.md

│ ├── tasks

│ │ ├── apache2_install.yml

│ │ ├── default_settings.yml

│ │ ├── default_user_settings.yml

│ │ ├── exim4_install.yml

│ │ ├── main.yml

│ │ ├── mysql_install.yml

│ │ └── nginx_install.yml

│ ├── templates

│ ├── tests

│ │ ├── inventory

│ │ └── test.yml

│ └── vars

│ └── main.yml

└── playbook.yml

Item 4. Initial server setup.

At this stage, we will configure the following services:

  1. php
  2. nginx
  3. mysql
  4. apache2
  5. exim4

php setup.

The first step is to install php on the remote server. To do this, create an empty file /var/ansible/LEMP/taskscalled php.yml. We use the apt module .

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
cd /var/ansible/LEMP/tasks
touch php.yml
cd /var/ansible/LEMP/tasks touch php.yml
cd /var/ansible/LEMP/tasks
touch php.yml

We add:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: install php
apt: name={{ item }} update_cache=yes state=latest
with_items:
- git
- php
- php-curl
- php-gd
- php-mbstring
- php-xml
- php-xmlrpc
- php-soap
- php-intl
- php-zip
- name: install php apt: name={{ item }} update_cache=yes state=latest with_items: - git - php - php-curl - php-gd - php-mbstring - php-xml - php-xmlrpc - php-soap - php-intl - php-zip
- name: install php
  apt: name={{ item }} update_cache=yes state=latest
  with_items:
  - git
  - php
  - php-curl
  - php-gd
  - php-mbstring
  - php-xml
  - php-xmlrpc
  - php-soap
  - php-intl
  - php-zip
  1. with_items : – create an array of variables from the packages we need.
  2. name={{ item }} – here we use the item array to install php modules. apt will run until it has installed all the packages in the item array.

Don’t forget to include the new yml file in main.yml.

Add to main.yml.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#####install php
- include_tasks: php.yml
#####install php - include_tasks: php.yml
#####install php
  - include_tasks: php.yml

For php we will need to pass a php.ini file.

Create a php directory and a php-ansible.ini file in /var/ansible/LEMP/files/.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
cd /var/ansible/LEMP/files/
mkdir php
touch php/php.ini
cd /var/ansible/LEMP/files/ mkdir php touch php/php.ini
cd /var/ansible/LEMP/files/
mkdir php
touch php/php.ini

Insert into the php-ansible.ini file, after [PHP], any configuration you need:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[PHP]
[PHP]
[PHP]

Next, you need to transfer this file to /etc/php/7.3/apache2/. It will be automatically loaded and applied after restarting the php interpreter. In this case it is apache2.

Open the php.yml file in jobs (/var/ansible/LEMP/tasks/php.yml)and add file copy and apache2 reload.

We add:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: copy config
copy:
src: php/php-ansible.ini
dest: /etc/php/7.3/apache2
- name: restart apache2
service:
name: apache2
state: restarted
- name: copy config copy: src: php/php-ansible.ini dest: /etc/php/7.3/apache2 - name: restart apache2 service: name: apache2 state: restarted
- name: copy config
  copy:
    src: php/php-ansible.ini
    dest: /etc/php/7.3/apache2

- name: restart apache2
  service:
    name: apache2
    state: restarted

Setting up nginx.

  1. To configure, we need to transfer the nginx configuration files:
    1. nginx.conf
    2. site configuration. domain_name.conf.
  2. Enable site.
  3. Reload nginx.

Let’s go to the directory /var/ansible/LEMP/files.

Create an nginx directory.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
mkdir nginx
cd nginx/
mkdir nginx cd nginx/
mkdir nginx
cd nginx/

In the nginx directory, you need to create 2 files: nginx.conf and domain_name.conf .

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
touch nginx.conf domain_name.conf
touch nginx.conf domain_name.conf
touch nginx.conf domain_name.conf
  1. nginx.conf must be passed to the nginx root directory
  2. domain_name.conf needs to be passed to sites-available.

In nginx.conf we insert the configuration from our previous article .

The domain_name.conf is the configuration from our previous article .

After adding the configuration, go to ./tasks/nginx_install.yml.

We transfer the configuration to the remote server using the copy and file module .

We add:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: Copy config.
copy:
src: nginx/nginx.conf
dest: /etc/nginx/nginx.conf
- name: Copy domain_name config
copy:
src: nginx/domain_name.conf
dest: /etc/nginx/sites-available/domain_name.conf
- name: enable site domain_name
file:
src: /etc/nginx/sites-available/domain_name.conf
dest: /etc/nginx/sites-enabled/domain_name.conf
state: link
- name: restart nginx
service:
name: nginx
state: restarted
- name: Copy config. copy: src: nginx/nginx.conf dest: /etc/nginx/nginx.conf - name: Copy domain_name config copy: src: nginx/domain_name.conf dest: /etc/nginx/sites-available/domain_name.conf - name: enable site domain_name file: src: /etc/nginx/sites-available/domain_name.conf dest: /etc/nginx/sites-enabled/domain_name.conf state: link - name: restart nginx service: name: nginx state: restarted
  - name: Copy config.
    copy:
      src: nginx/nginx.conf
      dest: /etc/nginx/nginx.conf

  - name: Copy domain_name  config
    copy:
      src: nginx/domain_name.conf
      dest: /etc/nginx/sites-available/domain_name.conf

  - name: enable site domain_name
    file:
      src: /etc/nginx/sites-available/domain_name.conf
      dest: /etc/nginx/sites-enabled/domain_name.conf
      state: link

  - name: restart nginx
    service:
      name: nginx
      state: restarted
  1. src – file in ./files directory;
  2. dest – the address where the file is stored on the remote server.

Let’s run and check:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
TASK [LEMP : include_tasks] *************************************************************************************************************************************************************************************
included: /var/ansible/LEMP/tasks/nginx_install.yml for ansible2
TASK [LEMP : Install nginx] *************************************************************************************************************************************************************************************
ok: [ansible2]
TASK [LEMP : Copy config.] **************************************************************************************************************************************************************************************
changed: [ansible2]
TASK [LEMP : Copy domain_name config] **************************************************************************************************************************************************************************
changed: [ansible2]
TASK [LEMP : enable site domain_name] ***************************************************************************************************************************************************************************
changed: [ansible2]
PLAY RECAP ******************************************************************************************************************************************************************************************************
ansible2 : ok=4 changed=3 unreachable=0 failed=0
TASK [LEMP : include_tasks] ************************************************************************************************************************************************************************************* included: /var/ansible/LEMP/tasks/nginx_install.yml for ansible2 TASK [LEMP : Install nginx] ************************************************************************************************************************************************************************************* ok: [ansible2] TASK [LEMP : Copy config.] ************************************************************************************************************************************************************************************** changed: [ansible2] TASK [LEMP : Copy domain_name config] ************************************************************************************************************************************************************************** changed: [ansible2] TASK [LEMP : enable site domain_name] *************************************************************************************************************************************************************************** changed: [ansible2] PLAY RECAP ****************************************************************************************************************************************************************************************************** ansible2 : ok=4 changed=3 unreachable=0 failed=0
TASK [LEMP : include_tasks] *************************************************************************************************************************************************************************************
included: /var/ansible/LEMP/tasks/nginx_install.yml for ansible2
TASK [LEMP : Install nginx] *************************************************************************************************************************************************************************************
ok: [ansible2]
TASK [LEMP : Copy config.] **************************************************************************************************************************************************************************************
changed: [ansible2]
TASK [LEMP : Copy domain_name  config] **************************************************************************************************************************************************************************
changed: [ansible2]
TASK [LEMP : enable site domain_name] ***************************************************************************************************************************************************************************
changed: [ansible2]
PLAY RECAP ******************************************************************************************************************************************************************************************************
ansible2                   : ok=4    changed=3    unreachable=0    failed=0

nginx config added.

Outcome:

  1. The nginx configuration and domain_name are passed.
  2. A symbolic link is created in sites-enabled.
  3. The service is restarted.

mysql setup.

You need to create a mysql.cnf configuration file and then transfer it to a remote server.

Create mysql directory in /var/ansible/LEMP/files.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
cd /var/ansible/LEMP/files
mkdir mysql
cd mysql/
touch mysql.cnf
cd /var/ansible/LEMP/files mkdir mysql cd mysql/ touch mysql.cnf
cd /var/ansible/LEMP/files
mkdir mysql
cd mysql/
touch mysql.cnf

Insert after [mysqld] the configuration you need.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[mysqld]
[mysqld]
[mysqld]

Open ansible mysql configuration file/var/ansible/LEMP/tasks/mysql_install.yml

We transfer the configuration file to the remote server and restart mysql.

We add:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: Copy config
copy:
src: mysql/mysql.cnf
dest: /etc/mysql/mysql.conf.d/mysql.cnf
- name: restart mysql
service:
name: mysql
state: restarted
- name: Copy config copy: src: mysql/mysql.cnf dest: /etc/mysql/mysql.conf.d/mysql.cnf - name: restart mysql service: name: mysql state: restarted
  - name: Copy config
    copy:
      src: mysql/mysql.cnf
      dest: /etc/mysql/mysql.conf.d/mysql.cnf

  - name: restart mysql
    service:
      name: mysql
      state: restarted

Outcome:

  1. Restart the mysql service.
  2. mysql setup is complete.

apache2 setup.

We do similar actions as in nginx

Need to transfer

  1. apache2.conf
  2. domain_name.conf
  3. ports.conf

We create a directory and the above listed files in the directory /var/ansible/LEMP/files.

Configurations for apache2 and domain_name can be taken from the following articles:

  1. apache2.conf configuration
  2. configuration  domain_name.conf .

We configure apache2 to work on port 81. Add configuration for ports.conf:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Listen 81
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
Listen 81 <IfModule ssl_module> Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule>
Listen 81
<IfModule ssl_module>
         Listen 443
</IfModule>

<IfModule mod_gnutls.c>
         Listen 443
</IfModule>

Next we go to/var/ansible/LEMP/tasks/apache2_install.yml

We add:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: copy config
copy:
src: apache2/apache2.conf
dest: /etc/apache2/apache2.conf
- name: copy domain_name config
copy:
src: apache2/domain_name.conf
dest: /etc/apache2/sites-available/domain_name.conf
- name: enable site domain_name
file:
src: /etc/apache2/sites-available/domain_name.conf
dest: /etc/apache2/sites-enabled/domain_name.conf
state: link
- name: copy ports
copy:
src: apache2/ports.conf
dest: /etc/apache2/ports.conf
- name: restart apache2
service:
name: apache2
state: restarted
- name: copy config copy: src: apache2/apache2.conf dest: /etc/apache2/apache2.conf - name: copy domain_name config copy: src: apache2/domain_name.conf dest: /etc/apache2/sites-available/domain_name.conf - name: enable site domain_name file: src: /etc/apache2/sites-available/domain_name.conf dest: /etc/apache2/sites-enabled/domain_name.conf state: link - name: copy ports copy: src: apache2/ports.conf dest: /etc/apache2/ports.conf - name: restart apache2 service: name: apache2 state: restarted
 - name: copy config
    copy:
      src: apache2/apache2.conf
      dest: /etc/apache2/apache2.conf

  - name: copy domain_name config
    copy:
      src: apache2/domain_name.conf
      dest: /etc/apache2/sites-available/domain_name.conf

  - name: enable site domain_name
    file:
      src: /etc/apache2/sites-available/domain_name.conf
      dest: /etc/apache2/sites-enabled/domain_name.conf
      state: link

  - name: copy ports
    copy:
      src: apache2/ports.conf
      dest: /etc/apache2/ports.conf

  - name: restart apache2
    service:
      name: apache2
      state: restarted

Outcome:

  1. Transferring configuration files;
  2. Restart the apache2 service.

Setting up exim4.

Necessary:

  1. Upload configuration file /etc/exim4/update-exim4.conf.conf;
  2. Reload exim4.

Create an exim4 directory and update-exim4.conf.conf file in /var/ansible/LEMP/files.

Add to the exim4 configuration file:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# /etc/exim4/update-exim4.conf.conf
#
# Edit this file and /etc/mailname by hand and execute update-exim4.conf
# yourself or use 'dpkg-reconfigure exim4-config'
#
# Please note that this is _not_ a dpkg-conffile and that automatic changes
# to this file might happen. The code handling this will honor your local
# changes, so this is usually fine, but will break local schemes that mess
# around with multiple versions of the file.
#
# update-exim4.conf uses this file to determine variable values to generate
# exim configuration macros for the configuration file.
#
# Most settings found in here do have corresponding questions in the
# Debconf configuration, but not all of them.
#
# This is a Debian specific file
dc_eximconfig_configtype='local'
dc_other_hostnames='domain_name'
dc_local_interfaces='127.0.0.1 ; ::1'
dc_readhost=''
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost=''
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname=''
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'
# /etc/exim4/update-exim4.conf.conf # # Edit this file and /etc/mailname by hand and execute update-exim4.conf # yourself or use 'dpkg-reconfigure exim4-config' # # Please note that this is _not_ a dpkg-conffile and that automatic changes # to this file might happen. The code handling this will honor your local # changes, so this is usually fine, but will break local schemes that mess # around with multiple versions of the file. # # update-exim4.conf uses this file to determine variable values to generate # exim configuration macros for the configuration file. # # Most settings found in here do have corresponding questions in the # Debconf configuration, but not all of them. # # This is a Debian specific file dc_eximconfig_configtype='local' dc_other_hostnames='domain_name' dc_local_interfaces='127.0.0.1 ; ::1' dc_readhost='' dc_relay_domains='' dc_minimaldns='false' dc_relay_nets='' dc_smarthost='' CFILEMODE='644' dc_use_split_config='false' dc_hide_mailname='' dc_mailname_in_oh='true' dc_localdelivery='mail_spool'
# /etc/exim4/update-exim4.conf.conf
#
# Edit this file and /etc/mailname by hand and execute update-exim4.conf
# yourself or use 'dpkg-reconfigure exim4-config'
#
# Please note that this is _not_ a dpkg-conffile and that automatic changes
# to this file might happen. The code handling this will honor your local
# changes, so this is usually fine, but will break local schemes that mess
# around with multiple versions of the file.
#
# update-exim4.conf uses this file to determine variable values to generate
# exim configuration macros for the configuration file.
#
# Most settings found in here do have corresponding questions in the
# Debconf configuration, but not all of them.
#
# This is a Debian specific file
dc_eximconfig_configtype='local'
dc_other_hostnames='domain_name'
dc_local_interfaces='127.0.0.1 ; ::1'
dc_readhost=''
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost=''
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname=''
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'

Add the desired configuration to this file.

(/var/ansible/LEMP/tasks/exim4_install.yml)Add “copy file” and “reload exim4” to the configuration file.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: copy config
copy:
src: exim4/update-exim4.conf.conf
dest: /etc/exim4/update-exim4.conf.conf
- name: restart exim4
service:
name: exim4
state: restarted
- name: copy config copy: src: exim4/update-exim4.conf.conf dest: /etc/exim4/update-exim4.conf.conf - name: restart exim4 service: name: exim4 state: restarted
  - name: copy config
    copy:
      src: exim4/update-exim4.conf.conf
      dest: /etc/exim4/update-exim4.conf.conf

  - name: restart exim4
    service:
      name: exim4
      state: restarted

The configuration for exim4 is ready.

Structure of files directory with configuration:

├── files

│ ├── apache2

│ │ ├── apache2.conf

│ │ ├── domain_name.conf

│ │ └── ports.conf

│ ├── exim4

│ │ └── update-exim4.conf.conf

│ ├── mysql

│ │ └── mysql.cnf

│ ├── nginx

│ │ ├── domain_name.conf

│ │ └── nginx.conf

│ └── PHP

│ └── php-ansible.ini

At the moment, the configuration of services is completed. If you need to upload or change additional files, you can also add and change them using the above method.

Item 5. Transfer of site code and database.

At this point, you need to move the site dump to load it into the database and transfer the site code.

We will need 2 directories in the files directory.

It:

  1. mysql_dump – site dump directory;
  2. data – directory with code.

First, add the platform code to the /data.

In our case, the site code will be the wordpress installer .

Next, transfer the dump of your database to the directory /mysql_dump.

Create a new yml file called file.yml at /var/ansible/LEMP/tasks/.

Include it in main.yml

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
####add_site_file
- include_tasks: file.yml
####add_site_file - include_tasks: file.yml
  ####add_site_file
  - include_tasks: file.yml

Add a task to it:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: copy file domain_name
copy:
src: data/
dest: /var/www/domain_name/data/
owner: domain_name
group: domain_name
- name: copy dump
copy:
src: mysql_dump/dump.sql
dest: /tmp/dump.sql
- name: mysql_dump
mysql_db:
name: domain_name_db
state: import
target: /tmp/dump.sql
login_user: root
login_password: "{{ mysql_root_password }}"
- name: copy file domain_name copy: src: data/ dest: /var/www/domain_name/data/ owner: domain_name group: domain_name - name: copy dump copy: src: mysql_dump/dump.sql dest: /tmp/dump.sql - name: mysql_dump mysql_db: name: domain_name_db state: import target: /tmp/dump.sql login_user: root login_password: "{{ mysql_root_password }}"
  - name: copy file domain_name
    copy:
      src: data/
      dest: /var/www/domain_name/data/
      owner: domain_name
      group: domain_name

  - name: copy dump
    copy:
      src: mysql_dump/dump.sql
      dest: /tmp/dump.sql

  - name: mysql_dump
    mysql_db:
      name: domain_name_db
      state: import
      target: /tmp/dump.sql
      login_user: root
      login_password: "{{ mysql_root_password }}"

In order to load the dump into the database, the mysql_db module is used.

Site files and dump were moved to the server.

Item 6. Testing.

At the moment the directory structure looks like this:
.
├── hosts.txt
├── LEMP
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── apache2
│ │ │ ├── apache2.conf
│ │ │ ├── mysql
_
_
_
_
_
_ cnf
│ │ ├── mysql_dump
│ │ │ └── dump.sql │ │
├── nginx
│ │ │ ├── ─ php-ansible.ini │ ├── handlers

│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── README.md
│ ├── tasks
│ │ ├── apache2_install.yml
│ │ ├── default_settings.yml
│ │ ├── default_user_settings.yml
│ │ ├── exim4_install.yml
│ │ ├── file.yml
│ │ ├── main.yml
│ │ ├── mysql_install.yml
│ │ ├── nginx_install.yml
│ ── php.yml
│ ├── templates
│ ├── tests
│ │ ├── inventory
│ │ └── test.yml
│ └── vars
│ └── main.yml
├── php.ini
├── playbook.retry
└── playbook.yml

Task configuration in .tasks directory:

apache2_install.yml :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: Install apache2
apt:
name: apache2
state: latest
- name: copy config
copy:
src: apache2/apache2.conf
dest: /etc/apache2/apache2.conf
- name: copy domain_name config
copy:
src: apache2/domain_name.conf
dest: /etc/apache2/sites-available/domain_name.conf
- name: copy ports
copy:
src: apache2/ports.conf
dest: /etc/apache2/ports.conf
- name: restart apache2
service:
name: apache2
state: restarted
- name: Install apache2 apt: name: apache2 state: latest - name: copy config copy: src: apache2/apache2.conf dest: /etc/apache2/apache2.conf - name: copy domain_name config copy: src: apache2/domain_name.conf dest: /etc/apache2/sites-available/domain_name.conf - name: copy ports copy: src: apache2/ports.conf dest: /etc/apache2/ports.conf - name: restart apache2 service: name: apache2 state: restarted
  - name: Install apache2
    apt:
      name: apache2
      state: latest

  - name: copy config
    copy:
      src: apache2/apache2.conf
      dest: /etc/apache2/apache2.conf

  - name: copy domain_name config
    copy:
      src: apache2/domain_name.conf
      dest: /etc/apache2/sites-available/domain_name.conf

  - name: copy ports
    copy:
      src: apache2/ports.conf
      dest: /etc/apache2/ports.conf

  - name: restart apache2
    service:
      name: apache2
      state: restarted

default_settings.yml :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: update repo.
shell: apt update
- name: install default app.
shell:
cmd: "apt install -y dirmngr mc iotop htop telnet tcpdump nmap curl hexedit sudo zip unzip patch pwgen vim less parted subversion ntp bzip2 lsof strace mutt s-nail ncdu smartmontools tree dnsutils logrotate rsyslog"
- name: time
shell:
cmd: "timedatectl set-timezone {{time_zone}}"
- name: locale settings
shell:
cmd: 'locale-gen {{locale1}} && update-locale LANG={{locale2}} LC_TIME="{{locale1}}"'
- name: hostname
shell:
cmd: "hostnamectl set-hostname {{DOMAIN_NAME}}"
- name: update repo. shell: apt update - name: install default app. shell: cmd: "apt install -y dirmngr mc iotop htop telnet tcpdump nmap curl hexedit sudo zip unzip patch pwgen vim less parted subversion ntp bzip2 lsof strace mutt s-nail ncdu smartmontools tree dnsutils logrotate rsyslog" - name: time shell: cmd: "timedatectl set-timezone {{time_zone}}" - name: locale settings shell: cmd: 'locale-gen {{locale1}} && update-locale LANG={{locale2}} LC_TIME="{{locale1}}"' - name: hostname shell: cmd: "hostnamectl set-hostname {{DOMAIN_NAME}}"
  - name: update repo.
    shell: apt update

  - name: install default app.
    shell:
      cmd: "apt install -y dirmngr mc iotop htop telnet tcpdump nmap curl hexedit sudo zip unzip patch pwgen vim less parted subversion ntp bzip2 lsof strace mutt s-nail ncdu smartmontools tree dnsutils logrotate rsyslog"

  - name: time
    shell:
      cmd: "timedatectl set-timezone {{time_zone}}"

  - name: locale settings
    shell:
      cmd: 'locale-gen {{locale1}} && update-locale LANG={{locale2}} LC_TIME="{{locale1}}"'

  - name: hostname
    shell:
      cmd: "hostnamectl set-hostname {{DOMAIN_NAME}}"

default_user_settings.yml :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: add group
group:
name: "{{ DOMAIN_NAME }}"
state: present
gid: "{{ Group_GID }}"
- name: add user
user:
name: "{{ DOMAIN_NAME }}"
password: "{{ user_password | password_hash('sha512') }}"
uid: "{{ User_uid }}"
group: "{{ DOMAIN_NAME }}"
state: present
update_password: on_create
home: "/var/www/{{ DOMAIN_NAME }}"
shell: /bin/bash
- name: create home directory
file:
path: "/var/www/{{ DOMAIN_NAME }}"
owner: "{{ DOMAIN_NAME }}"
group: "{{ DOMAIN_NAME }}"
mode: 0751
state: directory
- name: create other directory
file:
path: "/var/www/{{ DOMAIN_NAME }}/data"
owner: "{{ DOMAIN_NAME }}"
group: "{{ DOMAIN_NAME }}"
mode: 0755
state: directory
- name: create other directory
file:
path: "/var/www/{{ DOMAIN_NAME }}/log"
owner: "{{ DOMAIN_NAME }}"
group: "{{ DOMAIN_NAME }}"
mode: 0755
state: directory
- name: create other directory
file:
path: "/var/www/{{ DOMAIN_NAME }}/sess"
owner: "{{ DOMAIN_NAME }}"
group: "{{ DOMAIN_NAME }}"
mode: 0755
state: directory
- name: create other directory
file:
path: "/var/www/{{ DOMAIN_NAME }}/tmp"
owner: "{{ DOMAIN_NAME }}"
group: "{{ DOMAIN_NAME }}"
mode: 0755
state: directory
- name: create other directory
file:
path: "/var/www/{{ DOMAIN_NAME }}/upload"
owner: "{{ DOMAIN_NAME }}"
group: "{{ DOMAIN_NAME }}"
mode: 0755
state: directory
- name: create other directory
file:
path: "/var/www/{{ DOMAIN_NAME }}/log/apache2"
owner: "{{ DOMAIN_NAME }}"
group: "{{ DOMAIN_NAME }}"
mode: 0755
state: directory
- name: create other directory
file:
path: "/var/www/{{ DOMAIN_NAME }}/log/nginx"
owner: "{{ DOMAIN_NAME }}"
group: "{{ DOMAIN_NAME }}"
mode: 0755
state: directory
- name: add group group: name: "{{ DOMAIN_NAME }}" state: present gid: "{{ Group_GID }}" - name: add user user: name: "{{ DOMAIN_NAME }}" password: "{{ user_password | password_hash('sha512') }}" uid: "{{ User_uid }}" group: "{{ DOMAIN_NAME }}" state: present update_password: on_create home: "/var/www/{{ DOMAIN_NAME }}" shell: /bin/bash - name: create home directory file: path: "/var/www/{{ DOMAIN_NAME }}" owner: "{{ DOMAIN_NAME }}" group: "{{ DOMAIN_NAME }}" mode: 0751 state: directory - name: create other directory file: path: "/var/www/{{ DOMAIN_NAME }}/data" owner: "{{ DOMAIN_NAME }}" group: "{{ DOMAIN_NAME }}" mode: 0755 state: directory - name: create other directory file: path: "/var/www/{{ DOMAIN_NAME }}/log" owner: "{{ DOMAIN_NAME }}" group: "{{ DOMAIN_NAME }}" mode: 0755 state: directory - name: create other directory file: path: "/var/www/{{ DOMAIN_NAME }}/sess" owner: "{{ DOMAIN_NAME }}" group: "{{ DOMAIN_NAME }}" mode: 0755 state: directory - name: create other directory file: path: "/var/www/{{ DOMAIN_NAME }}/tmp" owner: "{{ DOMAIN_NAME }}" group: "{{ DOMAIN_NAME }}" mode: 0755 state: directory - name: create other directory file: path: "/var/www/{{ DOMAIN_NAME }}/upload" owner: "{{ DOMAIN_NAME }}" group: "{{ DOMAIN_NAME }}" mode: 0755 state: directory - name: create other directory file: path: "/var/www/{{ DOMAIN_NAME }}/log/apache2" owner: "{{ DOMAIN_NAME }}" group: "{{ DOMAIN_NAME }}" mode: 0755 state: directory - name: create other directory file: path: "/var/www/{{ DOMAIN_NAME }}/log/nginx" owner: "{{ DOMAIN_NAME }}" group: "{{ DOMAIN_NAME }}" mode: 0755 state: directory
  - name: add group
    group:
      name: "{{ DOMAIN_NAME }}"
      state: present
      gid: "{{ Group_GID }}"

  - name: add user
    user:
      name: "{{ DOMAIN_NAME }}"
      password: "{{ user_password | password_hash('sha512') }}"
      uid: "{{ User_uid }}"
      group: "{{ DOMAIN_NAME }}"
      state: present
      update_password: on_create
      home: "/var/www/{{ DOMAIN_NAME }}"
      shell: /bin/bash

  - name: create home directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0751
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/data"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/log"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/sess"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/tmp"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/upload"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/log/apache2"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/log/nginx"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

exim4_install.yml :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: Install exim4
apt:
name: exim4
state: latest
- name: copy config
copy:
src: exim4/update-exim4.conf.conf
dest: /etc/exim4/update-exim4.conf.conf
- name: restart exim4
service:
name: exim4
state: restarted
- name: Install exim4 apt: name: exim4 state: latest - name: copy config copy: src: exim4/update-exim4.conf.conf dest: /etc/exim4/update-exim4.conf.conf - name: restart exim4 service: name: exim4 state: restarted
  - name: Install exim4
    apt:
      name: exim4
      state: latest

  - name: copy config
    copy:
      src: exim4/update-exim4.conf.conf
      dest: /etc/exim4/update-exim4.conf.conf

  - name: restart exim4
    service:
      name: exim4
      state: restarted

main.yml :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# - include_tasks: default_settings.yml
#####install mysql
# - include_tasks: mysql_install.yml
#####install nginx
# - include_tasks: nginx_install.yml
#####install apache2
# - include_tasks: apache2_install.yml
#####install exim4
# - include_tasks: exim4_install.yml
#####default user settings
# - include_tasks: default_user_settings.yml
#####install php
# - include_tasks: php.yml
#####copy file domain_name
- include_tasks: file.yml
# - include_tasks: default_settings.yml #####install mysql # - include_tasks: mysql_install.yml #####install nginx # - include_tasks: nginx_install.yml #####install apache2 # - include_tasks: apache2_install.yml #####install exim4 # - include_tasks: exim4_install.yml #####default user settings # - include_tasks: default_user_settings.yml #####install php # - include_tasks: php.yml #####copy file domain_name - include_tasks: file.yml
#  - include_tasks: default_settings.yml
  #####install mysql
#  - include_tasks: mysql_install.yml
  #####install nginx
#  - include_tasks: nginx_install.yml
  #####install apache2
#  - include_tasks: apache2_install.yml
  #####install exim4
#  - include_tasks: exim4_install.yml
  #####default user settings
#  - include_tasks: default_user_settings.yml
  #####install php
#  - include_tasks: php.yml
  #####copy file domain_name
  - include_tasks: file.yml

mysql_install.yml:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: add mysql repo
get_url:
url: https://dev.mysql.com/get/mysql-apt-config_0.8.6-1_all.deb
dest: "/tmp"
mode: 0440
- name: install mysql repo
apt: "deb=/tmp/mysql-apt-config_0.8.6-1_all.deb"
become: true
- name: add key mysql and update repo
shell: "apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29 && apt update"
- name: install python-mysqldb
apt:
name: python-mysqldb
state: present
update_cache: yes
- name: check latest version of mysql 5.7
command: bash -c "apt-cache showpkg mysql-server|grep 5.7|head -1|cut -d' ' -f1"
register: latestmysql57
- debug: msg="{{ latestmysql57.stdout }}"
- name: install mysql 57
apt:
name: mysql-server={{ latestmysql57.stdout }}
state: present
update_cache: yes
- name: update mysql root password for all root accounts
become: true
mysql_user:
name: root
host: "{{ item }}"
password: "{{ mysql_root_password }}"
login_user: root
login_password: 12345
check_implicit_admin: yes
priv: "*.*:ALL,GRANT"
state: present
with_items:
- 127.0.0.1
- ::1
- localhost
- name: Create a new database with name 'DOMAIN_NAME_DB'
mysql_db:
login_user: root
login_password: "{{ mysql_root_password }}"
name: "{{name_db}}"
state: present
- name: add user DOMAIN_NAME_USR
mysql_user:
login_user: root
login_password: "{{ mysql_root_password }}"
host: localhost
name: "{{user_db}}"
password: "{{password_user_db}}"
priv: '{{name_db}}.*:ALL,GRANT'
state: present
- name: Copy config
copy:
src: mysql/mysql.cnf
dest: /etc/mysql/mysql.conf.d/mysql.cnf
- name: restart mysql
service:
name: mysql
state: restarted
- name: add mysql repo get_url: url: https://dev.mysql.com/get/mysql-apt-config_0.8.6-1_all.deb dest: "/tmp" mode: 0440 - name: install mysql repo apt: "deb=/tmp/mysql-apt-config_0.8.6-1_all.deb" become: true - name: add key mysql and update repo shell: "apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29 && apt update" - name: install python-mysqldb apt: name: python-mysqldb state: present update_cache: yes - name: check latest version of mysql 5.7 command: bash -c "apt-cache showpkg mysql-server|grep 5.7|head -1|cut -d' ' -f1" register: latestmysql57 - debug: msg="{{ latestmysql57.stdout }}" - name: install mysql 57 apt: name: mysql-server={{ latestmysql57.stdout }} state: present update_cache: yes - name: update mysql root password for all root accounts become: true mysql_user: name: root host: "{{ item }}" password: "{{ mysql_root_password }}" login_user: root login_password: 12345 check_implicit_admin: yes priv: "*.*:ALL,GRANT" state: present with_items: - 127.0.0.1 - ::1 - localhost - name: Create a new database with name 'DOMAIN_NAME_DB' mysql_db: login_user: root login_password: "{{ mysql_root_password }}" name: "{{name_db}}" state: present - name: add user DOMAIN_NAME_USR mysql_user: login_user: root login_password: "{{ mysql_root_password }}" host: localhost name: "{{user_db}}" password: "{{password_user_db}}" priv: '{{name_db}}.*:ALL,GRANT' state: present - name: Copy config copy: src: mysql/mysql.cnf dest: /etc/mysql/mysql.conf.d/mysql.cnf - name: restart mysql service: name: mysql state: restarted
  - name: add mysql repo
    get_url:
      url: https://dev.mysql.com/get/mysql-apt-config_0.8.6-1_all.deb
      dest: "/tmp"
      mode: 0440

  - name: install mysql repo
    apt: "deb=/tmp/mysql-apt-config_0.8.6-1_all.deb"
    become: true

  - name: add key mysql and update repo
    shell: "apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29 && apt update"

  - name: install python-mysqldb
    apt:
      name: python-mysqldb
      state: present
      update_cache: yes

  - name: check latest version of mysql 5.7
    command: bash -c "apt-cache showpkg mysql-server|grep 5.7|head -1|cut -d' ' -f1"
    register: latestmysql57
  - debug: msg="{{ latestmysql57.stdout }}"

  - name: install mysql 57
    apt:
      name: mysql-server={{ latestmysql57.stdout }}
      state: present
      update_cache: yes

  - name: update mysql root password for all root accounts
    become: true
    mysql_user:
      name: root
      host: "{{ item }}"
      password: "{{ mysql_root_password }}"
      login_user: root
      login_password: 12345
      check_implicit_admin: yes
      priv: "*.*:ALL,GRANT"
      state: present
    with_items:
      - 127.0.0.1
      - ::1
      - localhost

  - name: Create a new database with name 'DOMAIN_NAME_DB'
    mysql_db:
      login_user: root
      login_password: "{{ mysql_root_password }}"
      name: "{{name_db}}"
      state: present

  - name: add user DOMAIN_NAME_USR
    mysql_user:
      login_user: root
      login_password: "{{ mysql_root_password }}"
      host: localhost
      name: "{{user_db}}"
      password: "{{password_user_db}}"
      priv: '{{name_db}}.*:ALL,GRANT'
      state: present

  - name: Copy config
    copy:
      src: mysql/mysql.cnf
      dest: /etc/mysql/mysql.conf.d/mysql.cnf

  - name: restart mysql
    service:
      name: mysql
      state: restarted

nginx_install.yml :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: Install nginx
apt:
name: nginx
state: latest
- name: Copy config.
copy:
src: nginx/nginx.conf
dest: /etc/nginx/nginx.conf
- name: Copy domain_name config
copy:
src: nginx/domain_name.conf
dest: /etc/nginx/sites-available/domain_name.conf
- name: enable site domain_name
file:
src: /etc/nginx/sites-available/domain_name.conf
dest: /etc/nginx/sites-enabled/domain_name.conf
state: link
- name: restart nginx
service:
name: nginx
state: restarted
- name: Install nginx apt: name: nginx state: latest - name: Copy config. copy: src: nginx/nginx.conf dest: /etc/nginx/nginx.conf - name: Copy domain_name config copy: src: nginx/domain_name.conf dest: /etc/nginx/sites-available/domain_name.conf - name: enable site domain_name file: src: /etc/nginx/sites-available/domain_name.conf dest: /etc/nginx/sites-enabled/domain_name.conf state: link - name: restart nginx service: name: nginx state: restarted
  - name: Install nginx
    apt:
      name: nginx
      state: latest

  - name: Copy config.
    copy:
      src: nginx/nginx.conf
      dest: /etc/nginx/nginx.conf

  - name: Copy domain_name  config
    copy:
      src: nginx/domain_name.conf
      dest: /etc/nginx/sites-available/domain_name.conf

  - name: enable site domain_name
    file:
      src: /etc/nginx/sites-available/domain_name.conf
      dest: /etc/nginx/sites-enabled/domain_name.conf
      state: link

  - name: restart nginx
    service:
      name: nginx
      state: restarted

php.yml :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- name: install php
apt: name={{ item }} update_cache=yes state=latest
with_items:
- git
- php
- php-curl
- php-gd
- php-mbstring
- php-xml
- php-xmlrpc
- php-soap
- php-intl
- php-zip
- name: copy config
copy:
src: php/php-ansible.ini
dest: /etc/php/7.3/apache2
- name: restart apache2
service:
name: apache2
state: restarted
- name: install php apt: name={{ item }} update_cache=yes state=latest with_items: - git - php - php-curl - php-gd - php-mbstring - php-xml - php-xmlrpc - php-soap - php-intl - php-zip - name: copy config copy: src: php/php-ansible.ini dest: /etc/php/7.3/apache2 - name: restart apache2 service: name: apache2 state: restarted
- name: install php
  apt: name={{ item }} update_cache=yes state=latest
  with_items:
  - git
  - php
  - php-curl
  - php-gd
  - php-mbstring
  - php-xml
  - php-xmlrpc
  - php-soap
  - php-intl
  - php-zip

- name: copy config
  copy:
    src: php/php-ansible.ini
    dest: /etc/php/7.3/apache2

- name: restart apache2
  service:
    name: apache2
    state: restarted

Variable file /var/ansible/LEMP/vars/main.yml:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
DOMAIN_NAME: domain_name
locale1: ru_RU.UTF-8
locale2: en_US.UTF-8
time_zone: Europe/Moscow
User_uid: 10000
Group_GID: 10000
user_password: password
mysql_root_password: password
name_db: domain_name_db
user_db: domain_name_usr
password_user_db: password
DOMAIN_NAME: domain_name locale1: ru_RU.UTF-8 locale2: en_US.UTF-8 time_zone: Europe/Moscow User_uid: 10000 Group_GID: 10000 user_password: password mysql_root_password: password name_db: domain_name_db user_db: domain_name_usr password_user_db: password
DOMAIN_NAME: domain_name
locale1: ru_RU.UTF-8
locale2: en_US.UTF-8
time_zone: Europe/Moscow
User_uid: 10000
Group_GID: 10000
user_password: password
mysql_root_password: password
name_db: domain_name_db
user_db: domain_name_usr
password_user_db: password

For testing, we go to a remote server. Add to /etc/hostsrecord like:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
127.0.0.1 domain_name.com
127.0.0.1 domain_name.com
127.0.0.1 domain_name.com

Checking the status of services:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
systemctl status nginx apache2 mysql exim4
systemctl status nginx apache2 mysql exim4
systemctl status nginx apache2 mysql exim4

If all services are working, we make a request to the site using curl.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# curl -LI domain_name.com
HTTP/1.1 302 Found
Server: nginx
Date: Wed, 29 Jun 2022 11:32:10 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Keep-Alive: timeout=15
Location: http://domain_name.com/wp-admin/setup-config.php
HTTP/1.1 200
Server: nginx
Date: Wed, 29 Jun 2022 11:32:10 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Keep-Alive: timeout=15
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
# curl -LI domain_name.com HTTP/1.1 302 Found Server: nginx Date: Wed, 29 Jun 2022 11:32:10 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Keep-Alive: timeout=15 Location: http://domain_name.com/wp-admin/setup-config.php HTTP/1.1 200 Server: nginx Date: Wed, 29 Jun 2022 11:32:10 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Keep-Alive: timeout=15 Expires: Wed, 11 Jan 1984 05:00:00 GMT Cache-Control: no-cache, must-revalidate, max-age=0
# curl -LI domain_name.com
HTTP/1.1 302 Found
Server: nginx
Date: Wed, 29 Jun 2022 11:32:10 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Keep-Alive: timeout=15
Location: http://domain_name.com/wp-admin/setup-config.php

HTTP/1.1 200
Server: nginx
Date: Wed, 29 Jun 2022 11:32:10 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Keep-Alive: timeout=15
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0

Everything is working! Next, you need to configure the site in the web interface.

Item 7. Bottom line.

Well, here we are and got acquainted with Ansible and the basic modules that are most often used in its work. Of course, this ansible role is not ideal, and was created only for learning. This mini-course will be enough to understand how ansible works at a basic level.