Demonstração de escalonamento horizontal no Aria Automation com NSX e Ansible – parte 2
No artigo demonstração de escalonamento horizontal no Aria Automation com NSX e Ansible, detalho bem o processo de construção do blueprint, bem como algumas particularidades. Agora serei mais breve, basicamente vou demonstrar novamente o escalonamento horizontal com balanceador de carga do NSX e Ansible, mas o resultado final será uma aplicação específica. É interessante realizar construções para aplicações específicas pelo fato de já ter um padrão pré-definido e com isso conseguimos evitar a generalização do blueprint.
A aplicação em questão trata-se do Homer Web, onde basicamente precisamos de um ou mais servidores web conectados em um balanceador de carga na porta 80. Estes servidores terão 1 GB de RAM e 1 vCPU e irão rodar Apache e PHP. No mesmo blueprint, teremos o servidor de banco de dados que será uma unica máquina com 2 GB de RAM e 2 vCPU. Neste servidor irá rodar o MySQL.
Todos os dados da aplicação serão armazenados no servidor MySQL, ou seja, a quantidade de servidores web pode crescer ou diminuir de forma rápida e simplificada conforme a necessidade.
Agora vem a mágia de não ser um blueprint genérico, ou seja, eu já sei previamente muita coisa e por isso não preciso solicitar estas informações para o usuário. Por exemplo, já sei o tamanho que as instâncias web e de banco de dados precisam ter, já sei a porta, protocolo e algoritmo do balanceador de carga, etc. Enfim, já falei demais. Vamos ao código do blueprint:
name: Homer Web
version: 1
inputs:
vm_environment:
type: string
title: Environment
oneOf:
- title: Production
const: prod
- title: Development
const: dev
vm_web_instances:
type: integer
title: Web Server Instances
default: 2
resources:
network_web:
type: Cloud.NSX.Network
properties:
networkType: existing
constraints:
- tag: ${'environment:' + (input.vm_environment)}
- tag: service:web
- tag: network:nsx
network_db:
type: Cloud.NSX.Network
properties:
networkType: existing
constraints:
- tag: ${'environment:' + (input.vm_environment)}
- tag: service:db
- tag: network:nsx
ansible_web:
type: Cloud.Ansible
dependsOn:
- vm_db
ignoreChanges: true
properties:
count: ${input.vm_web_instances}
host: ${resource.vm_web.*}
groups:
- vra_web
osType: linux
account: Caverna Ansible
username: root
password: ${secret.caverna-linux}
hostVariables:
database_ip: ${resource.vm_db.address}
playbooks:
provision:
- /etc/ansible/playbooks/install-homer-web.yml
ansible_db:
type: Cloud.Ansible
ignoreChanges: true
properties:
host: ${resource.vm_db.*}
groups:
- vra_db
osType: linux
account: Caverna Ansible
username: root
password: ${secret.caverna-linux}
playbooks:
provision:
- /etc/ansible/playbooks/install-homer-db.yml
hostVariables:
database_ip: ${resource.vm_db.address}
security_web:
type: Cloud.SecurityGroup
properties:
securityGroupType: existing
constraints:
- tag: security:web
security_db:
type: Cloud.SecurityGroup
properties:
securityGroupType: existing
constraints:
- tag: security:db
vm_web:
type: Cloud.vSphere.Machine
dependsOn:
- vm_db
allocatePerInstance: true
properties:
name: CAV-P-WEB-
image: Ubuntu 22.04
cpuCount: 1
totalMemoryMB: 1024
constraints:
- tag: ${'environment:' + (input.vm_environment)}
- tag: service:web
networks:
- network: ${resource.network_web.id}
assignment: static
securityGroups:
- ${resource.security_web.id}
count: ${input.vm_web_instances}
vm_db:
type: Cloud.vSphere.Machine
properties:
name: CAV-P-DB-
image: Ubuntu 22.04
cpuCount: 2
totalMemoryMB: 2048
constraints:
- tag: ${'environment:' + (input.vm_environment)}
- tag: service:db
networks:
- network: ${resource.network_db.id}
assignment: static
securityGroups:
- ${resource.security_db.id}
lb_web:
type: Cloud.NSX.LoadBalancer
properties:
name: CAV-P-WEB-LB-
network: ${resource.network_web.id}
instances: ${resource.vm_web[*].id}
internetFacing: false
routes:
- instancePort: 80
instanceProtocol: TCP
port: 80
protocol: TCP
algorithm: ROUND_ROBIN
constraints:
- tag: nsx:lb-01
Vou compartilhar os playbooks do Ansible também. Estes playbooks são responsáveis por instalar e configurar os servidores web e de banco de dados. Abaixo vemos o playbook install-homer-db.yml. Este playbook instala o MySQL, cria um banco de dados, uma tabela, um usuário e por fim reinicia o serviço do MySQL.
- name: "Install MySQL - Homer Web"
hosts: all
become: yes
tasks:
- name: "Install latest version of MySQL"
apt:
name: mysql-server
update_cache: yes
state: latest
- name: "Install PyMySQL"
apt:
name: python3-pymysql
state: present
- name: "Create a MySQL database"
mysql_db:
name: homer_db
state: present
login_host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: "Create a table"
mysql_query:
login_host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
query: "CREATE TABLE IF NOT EXISTS homer_db.thumbs (code INT AUTO_INCREMENT PRIMARY KEY, status VARCHAR(50), date TIMESTAMP DEFAULT CURRENT_TIMESTAMP);"
- name: "Create a MySQL user"
mysql_user:
name: homer
password: homerJayS123
priv: '*.*:ALL'
host: '%'
state: present
login_host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: "Grant privileges to the user on the database"
mysql_user:
name: homer
priv: 'homer_db.*:ALL'
host: '%'
state: present
login_host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: "Update MySQL configuration to allow external connections"
lineinfile:
path: /etc/mysql/mysql.conf.d/mysqld.cnf
regexp: '^bind-address\s*='
line: 'bind-address = {{ database_ip }}'
- name: "Restart MySQL service"
service:
name: mysql
state: restarted
Já o playbook install-homer-web.yml é responsável por instalar o Apache e PHP, além de obter a aplicação do github e configura-la no diretório do Apache. É interessante observar a parte que é configurado o endereço IP do banco de dados, pois isso é uma variável do Ansible que configuramos dinamicamente no blueprint.
- name: "Install Apache and PHP - Homer Web"
hosts: all
become: yes
tasks:
- name: "Install latest version of Apache"
apt: name=apache2 update_cache=yes state=latest
- name: "Install latest version of PHP"
apt: name=php update_cache=yes state=latest
- name: "Install latest version of PHP MySQL"
apt: name=php-mysql update_cache=yes state=latest
- name: "Restart Apache service"
service: name=apache2 state=restarted
- name: "Remove index.html file"
file:
path: "/var/www/html/index.html"
state: absent
- name: "Clone repository"
git:
repo: "https://github.com/ricardoconzatti/demo.git"
dest: "/tmp/homer-web"
- name: "Copy files to Apache folder"
shell: cp -r /tmp/homer-web/homer-web-v2/* /var/www/html/
- name: "Change connection database file"
shell: echo '<?php $dbcon = mysqli_connect("{{ database_ip }}", "homer", "homerJayS123", "homer_db"); ?>' > /var/www/html/cnx.php
Agora vou solicitar este item de catálogo. Apenas seleciono o ambiente de produção e inicialmente com duas instâncias web.
Após o deployment com sucesso, basta abrir o endereço do balanceador de carga no navegador e voilà. It’s alive!
Agora poderia atualizar o deployment aumentando ou diminuindo a quantidade de servidores web para atender a demanda.
Deixei todos os arquivos no github. É isso aí, pessoal. Até a próxima!




