I’m going to automate configuration of simple microservice architecture application by using Ansible Playbook and Vagrant.
Create 3 roles for this archtecture
1. Frontend
2. Backend
3. Database
Ansible-Galaxy Create Backend Role
ansible-galaxy role init backend
# name of the role(folder) created in my local machine
tree backend/
#tell anislble to role (folder) use playbook
tutorial.yaml
---
- hosts: backend
vars:
backend_user: backend
backend_folder: /backend
tasks:
- name: include nodejs role
include_role:
name: nodejs
- name: Include the backend role
include_role:
name: backend
- hosts: frontend
tasks:
- name: include nodejs role
include_role:
name: nodejs
- name: include the frontend role
include_role:
name: frontend
- hosts: database
tasks:
- name: include the database role
include_role:
name: database
backend/tasks/main.yaml
---
- name: Create User
become: true
user:
name: "{{ backend_user}}"
- name: Create a directory if it doesn't exist
become: true
ansible.builtin.file:
path: "{{ backend_folder}}"
state: directory
owner: "{{ backend_user }}"
mode: '0755'
- name: acl package installation
become: true
package:
name: acl
state: present
- name: Clone git repo
become: true
become_user: "{{ backend_user }}"
git:
repo: https://github.com/bezkoder/nodejs-express-sequelize-mysql.git
force: yes
dest: /home{{ backend_folder }}/backend
- name: Install pacakages for the backend app
become: true
become_user: "{{ backend_user }}"
community.general.npm:
path: /home{{ backend_folder }}/backend
- name: Update DB configuration
become: true
template:
src: db.config.js.j2
dest: /home{{ backend_folder }}/backend/app/config/db.config.js
- name: tutorials service file
become: true
template:
src: tutorials.service.j2
dest: /etc/systemd/system/tutorials.service
- name: restart service
become: true
systemd:
daemon_reload: yes
name: tutorials
state: started
enabled: yes
- name: restart service
become: true
systemd:
name: tutorials
state: restarted
backend/defaults/main.yaml
---
# defaults file for backend
backend_db_host: 192.168.150.12
backend_db_name: tutorials
backend_db_user: backend
backend_db_password: acit4640
backend/template/db.config.js.j2
module.exports = {
HOST: "{{ backend_db_host }}",
USER: "{{ backend_db_user }}",
PASSWORD: "{{ backend_db_password }}",
DB: "{{ backend_db_name }}",
dialect: "mysql",
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
};
backend/template/tutorials.service.js
[Unit]
Description=Tutorials backend
After=network.target
[Service]
WorkingDirectory=/home/{{ backend_user }}/backend
Type=simple
User={{ backend_user }}
ExecStart=/usr/bin/node /home/{{ backend_user }}/backend/server.js
Restart=always
[Install]
WantedBy=multi-user.target
Ansible-Galaxy Create Nodejs Role
ansible-galaxy role init nodejs
# name of the role(folder) created in my local machine
nodejs/tasks/main.yml
---
# tasks file for nodejs
- name: nodejs Installation
get_url:
url: https://deb.nodesource.com/setup_14.x
dest: /home/vagrant/nodesource_install_script
register: download_nodejs_script
- name: Run the installation script
become: true
command: bash /home/vagrant/nodesource_install_script
when: download_nodejs_script.changed
- name: Make sure NodeJS is installed
become: true
package:
name: nodejs
Ansible-Galaxy Create Frontend Role
ansible-galaxy role init trontend
# name of the role(folder) created in my local machine
Frontend/tasks/main.yml
---
- name: run apt-get update
become: true
apt:
upgrade: yes
update_cache: yes
- name: Install nginx
become: true
package:
name: nginx
state: present
- name: Git Clone
git:
repo: https://github.com/bezkoder/react-crud-web-api.git
force: yes
dest: /home/vagrant{{ http_static_dir }}
- name: Install packages
npm:
path: /home/vagrant{{ http_static_dir }}
state: latest
- name: Run npm run-script build
shell:
cmd: npm run-script build
chdir: /home/vagrant{{ http_static_dir }}
- name: http-common.js modification
replace:
path: /home/vagrant/{{http_static_dir}}/src/http-common.js
regexp: 'baseURL: "http://localhost:8080/api"'
replace: 'baseURL: "{{ http_api_location}}"'
- name: nginx default file modification
become: true
template:
force: yes
src: default.j2
dest: /etc/nginx/sites-available/default
register: default
- name: enable nginx and run
become: true
systemd:
name: nginx
enabled: yes
state: started
- name: restart nginx
become: true
systemd:
name: nginx
state: restarted
when: default.changed
Frontend/defaults/main.yml
---
# defaults file for frontend
http_static_dir: "/frontend"
http_api_location : "/api"
http_backend_url: "http://192.168.150.10:8080"
Frontend/templates/default.js
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or WordPress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /home/vagrant{{ http_static_dir}}/build;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass {{ http_backend_url}};
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /www;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
Ansible-Galaxy Create Database Role
ansible-galaxy role init database
# name of the role(folder) created in my local machine
database/tasks/main.yml
---
- name: run apt-get update
become: true
apt:
upgrade: yes
update_cache: yes
- name: install MySQL
become: true
package:
name: mysql-server
state: present
- name: Install pymysql
become: true
pip:
name: pymysql
state: present
- name: Install python3-pip
become: true
package:
name: python3-pip
state: present
- name: Install python3-mysqldb
become: true
apt:
name: python3-mysqldb
state: present
- name: Run pymysql and create database
become: true
mysql_db:
name: "{{ backend_db_name }}"
state: present
check_implicit_admin: yes
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: CREATE USER backend
become: true
mysql_user:
name: "{{ backend_db_user}}"
password: "{{ backend_db_password }}"
priv: "{{ backend_db_name }}.*:ALL"
state: present
check_implicit_admin: yes
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: change mysqld.cnf bind-address
become: true
replace:
path: /etc/mysql/mysql.conf.d/mysqld.cnf
regexp: '127.0.0.1'
replace: '0.0.0.0'
register: mysqld_cnf
- name: Enable MySQL and Run
become: true
systemd:
name: mysql
enabled: yes
state: started
- name: restart MySQL service
become: true
systemd:
name: mysql
state: restarted
when: mysqld_cnf.changed
database/defaults/main.yml
---
# defaults file for database
backend_db_name: tutorials
backend_db_user: backend
backend_db_password: acit4640
Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.boot_timeout = 60000
config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.linked_clone = true
vb.customize [ "modifyvm", :id, "--uartmode1", "disconnected" ]
end
config.vm.define "backend" do |backend|
backend.vm.provider "virtualbox" do |vb|
vb.name = "BACKEND"
end
backend.vm.network "private_network", ip: "192.168.150.10"
backend.vm.network "forwarded_port", guest: 80, host: 8090
backend.vm.provision "ansible" do |ansible|
ansible.playbook = "tutorials.yaml"
end
end
config.vm.define "frontend" do |frontend|
frontend.vm.provider "virtualbox" do |vb|
vb.name = "FRONTEND"
end
frontend.vm.network "private_network", ip: "192.168.150.11"
frontend.vm.network "forwarded_port", guest: 80, host: 8080
frontend.vm.provision "ansible" do |ansible|
ansible.playbook = "tutorials.yaml"
end
end
config.vm.define "database" do |database|
database.vm.provider "virtualbox" do |vb|
vb.name = "DATABASE"
end
database.vm.network "private_network", ip: "192.168.150.12"
database.vm.network "forwarded_port", guest: 3306, host: 12002
database.vm.provision "ansible" do |ansible|
ansible.playbook = "tutorials.yaml"
end
end
end
Run Vagrantfile
vagrant up
vagrant provision
Great blog! Is your theme custom made or did you download it from somewhere? A theme like yours with a few simple tweeks would really make my blog shine. Please let me know where you got your design. Many thanks
Aw, this was a really good post. Taking the time and actual effort to generate a superb article… but what can I say… I procrastinate a lot and don’t manage to get nearly anything done.