<h1 style="color:#0055A4;">Ampliación de SSOO</h1>
<h3 style="color:#b0b0b0;">Nginx - Ansible - Terraform</h3>
---
# Fases
1. Servidor web con `nginx`
1.1 `Despliegue` con Terraform
1.2 `Aprovisionamiento` con Ansible
2. Servidor de aplicaciones
3. Autoescalado
4. DNS
5. SSL/TLS
---
# Nginx
----
## Usos y conceptos
- Servidor web (estáticos)
- Proxy directo
- Proxy inverso
- Balanceo de carga
- Gateway protocols
----
## Instalación de nginx
```bash
apt-get install nginx
```
## Configuración básica
```bash
/etc/nginx/
├── nginx.conf # Configuración principal
├── sites-available/ # Sitios disponibles
├── sites-enabled/ # Sitios habilitados
└── conf.d/ # Configuraciones adicionales
```
----
Un escenario típico puede ser utilizar `nginx` como un balanceador de carga que distribuye dicha carga entre 10 ó 100 instancias de `nginx` configurado como servidor web o servidor de aplicaciones
¿Creamos las máquinas una a una en la consola?
---
# Terraform
Terraform es una herramienta de **infraestructura como código** (Infrastructure as Code, IaC) desarrollada por HashiCorp. Permite **definir, planificar y crear infraestructura de manera declarativa** usando archivos de configuración.
----
## Componentes principales
```
Terraform Core
├── Configuration Files (.tf)
├── State Files (.tfstate)
├── Providers (Plugins)
└── Resources
```
## Flujo de Trabajo
1. **Write**: Escribir configuración en archivos .tf
2. **Plan**: `terraform plan` para ver cambios
3. **Apply**: `terraform apply` para crear/modificar recursos
4. **Destroy**: `terraform destroy` para eliminar recursos
----
```hcl
# Configuración del proveedor
provider "google" {
project = "aso-git"
region = "europe-west1"
}
```
----
## Tipos de Bloques
- **Provider**: Configuración del proveedor
- **Resource**: Define un recurso de infraestructura
- **Data Source**: Obtiene información de recursos existentes
- **Variable**: Define variables de entrada
- **Locals**: Define valores locales reutilizables
- **Output**: Define valores de salida
- **Module**: Agrupa recursos relacionados
- **Terraform**: Configura comportamiento de Terraform
- **Backend**: Define dónde almacenar el estado
----
Creemos nuestro servidor web con Terraform
Note:
- Acuérdate de añadir la regla del FW para HTTP
- Explicar `destroy`
----
Escalemos a 5 servidores
----
El aprovisionamiento lo hemos hecho con un script asociado a la máquina, pero esta es una solución muy limitada.
¿y si cada máquina tiene que asumir un rol diferente?
---
# Ansible
Ansible es una herramienta de automatización de infraestructura que permite **configurar y gestionar** sistemas de manera automatizada. Utiliza un lenguaje declarativo basado en YAML para definir tareas y configuraciones.
----
### Características Principales
- **Agentless**: No requiere agentes instalados en los sistemas objetivo
- **Idempotente**: Ejecutar múltiples veces produce el mismo resultado
- **Declarativo**: Define el estado deseado, no los pasos
- **Multi-plataforma**: Soporta múltiples sistemas operativos
- **Lenguaje simple**: Usa YAML, fácil de leer y escribir
----
### Componentes Principales
```
Ansible Control Node
├── Inventory (Hosts)
├── Playbooks (.yml)
├── Roles
├── Modules
└── Plugins
```
### Flujo de Trabajo
1. **Inventory**: Define los hosts objetivo
2. **Playbook**: Define las tareas a ejecutar
3. **Execution**: Ansible se conecta a los hosts y ejecuta tareas
4. **Reporting**: Muestra resultados de la ejecución
----
¿Cómo generar el inventario después de haber creado la infraestructura con Terraform?
<code>gcloud compute instances list</code>
... pero solo las etiquetadas como `web-server`
`--filter="tags.items:web-server"`
... y mejor en JSON
`--format=JSON`
... para quedarme con las IPs
`| jq '.[].networkInterfaces.[].accessConfigs[0].natIP'`
----
Escribamos un script bash para generar `inventory.ini`
----
Hagamos algunas pruebas:
- `ansible-inventory -i inventory.ini --list`
- `ansible web_servers -m ping -i inventory.ini`
- `ansible web_servers -m shell -a 'df -h'`
- `ansible web_servers -m shell -a 'whoami'`
----
## Playbooks
Los playbooks son archivos YAML que definen las tareas que Ansible debe ejecutar en los hosts.
----
### Estructura básica de un playbook
```yaml
- name: Configurar servidor web
hosts: web_servers
become: yes
tasks:
- name: Ping my webservers
ping:
- name: Print a message
debug:
msg: "Hello Ansible"
```
1. **name**: Descripción del playbook
2. **hosts**: Grupos de hosts objetivo
3. **become**: Ejecutar como root (sudo)
4. **vars**: Variables del playbook
5. **tasks**: Lista de tareas a ejecutar
----
Las tareas son acciones específicas que Ansible ejecuta en los hosts.
```yaml
- name: Descripción de la tarea
module_name:
parameter1: value1
parameter2: value2
when: condition
notify: handler_name
```
Módulos comunes:
- `apt` para instalar paquetes
- `shell` para ejecutar scripts de bash
- `systemd` para gestionar servicios
- `copy`, `file`, `template` para gestionar archivos
- `user` para gestionar usuarios
----
## Playbook for our webservers
- [ ] Definir el playbook
- [ ] Instalar `nginx`
```yml!
- name: Configurar sitio web estático con Nginx
hosts: web_servers
become: yes
tasks:
- name: Actualizar cache de paquetes
apt:
update_cache: yes
cache_valid_time: 3600
- name: Instalar nginx
apt:
name: nginx
state: present
- name: Obtener version de nginx
command: nginx -v
register: nginx_version_output
- name: Verificar version
debug:
msg: La versión es {{ nginx_version_output.stderr }}
```
----
- [X] Definir el playbook
- [x] Instalar `nginx`
- [ ] Instalar la página a servir:
- [ ] Usando variables
- [ ] Carpetas (con `loop`)
- [ ] Archivos desde templates (`index.html`)
- [ ] Configurar el site en `nginx`
----
### Definición de las variables
```yml!
- name: Configurar sitio web estático con Nginx
hosts: web_servers
become: yes
vars:
site_name: "Sitio web de ASO-GIT"
site_domain: {{ ansible_host }}
site_port: 80
site_root: /server/www/html
nginx_user: "www-data"
nginx_group: "www-data"
# Variables adicionales para las plantillas
company_name: "Universidad de Alcalá"
contact_email: "admin@{{ ansible_host }}"
contact_phone: "+34 900 123 456"
tasks:
- name: Actualizar cache de paquetes
...
```
----
### Creación de las carpetas del site
```yaml!
- name: Crear el directorio del sitio web
file:
path: "{{ site_root }}"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_group }}"
mode: "0755"
- name: Crear directorios adicionales
file:
path: "{{ site_root }}/{{ item }}"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_group }}"
mode: '0755'
loop:
- assets
- images
- javascript
```
----
### Uso de plantillas (jinja2)
`templates/index.html.js`
```html!
<body>
<div class="container">
<h1>ASO-GIT {{ site_name }}</h1>
<div class="info">
...
```
```yaml!
- name: Crear página principal del sitio desde template
template:
src: templates/index.html.j2
dest: "{{ site_root }}/index.html"
owner: "{{ nginx_user }}"
group: "{{ nginx_group }}"
mode: '0644'
```
----
- [X] Definir el playbook
- [x] Instalar `nginx`
- [X] Instalar la página a servir:
- [x] Usando variables
- [x] Carpetas (con `loop`)
- [x] Archivos desde templates (`index.html`)
- [ ] Configurar el site en `nginx`
Algunos flags útiles para `ansible-playbook`:
- `--start-at-task="Instalar nginx`
- `--diff`
----
Pero rara vez los datos que se sirven son estáticos ...
---
# Flask
## Servidores de aplicaciones
----
Flask es un framework web ligero y flexible para Python que permite crear aplicaciones web de manera rápida y sencilla. Es conocido por su simplicidad y su filosofía de "microframework" que proporciona solo lo esencial para el desarrollo web.
----
- **Ligero**: Framework minimalista
- **Flexible**: Permite personalización completa
- **Extensible**: Soporte para extensiones y middleware
- **Templates**: Sistema de plantillas integrado (Jinja2)
----
### Componentes Principales
```
Flask Application
├── Routes (Rutas)
├── Views (Vistas)
├── Templates (Plantillas)
├── Static Files (Archivos Estáticos)
├── Configuration (Configuración)
└── Extensions (Extensiones)
```
----
### Ciclo de Request-Response
1. **Request**: Cliente envía petición HTTP
2. **Routing**: Flask determina qué función manejará la petición
3. **View Function**: Función que procesa la petición
4. **Template Rendering**: Renderizado de plantillas (opcional)
5. **Response**: Respuesta HTTP enviada al cliente
----
Pero antes de poder desarrollar una aplicación Flask necesitamos instalar algunos paquetes, crear un usuario de aplicación, instalar un entorno virtual, algunas dependencias de python ...
Usemos un playbook para esto: `python-flask.yml`
----
Para hacer nuestras primeras pruebas usaremos cualquiera de los servidores web que tenemos lanzados.
----
Pero antes un pequeño truco para hacernos la vida fácil:
```bash
cd /server/flaskapp
sudo apt-get install acl
sudo setfacl -R -m user:ogarcia:rwx .
sudo setfacl -R -d -m user:ogarcia:rwx .
```
----
Ahora creamos `main.py`
```python!
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return '¡Hola, Mundo!'
if __name__ == '__main__':
app.run(debug=True)
```
```python!
@app.route('/bye')
def bye():
return '¡Bye, Mundo!'
```
`python main.app`
Usa `curl` para verificar que funciona
----
Vamos a crear ahora una serie de endpoints denominados `health endpoints`
Los health endpoints proporcionan información sobre el estado de salud de una aplicación o servicio. Estos endpoints son utilizados por sistemas de monitoreo, load balancers y orquestadores para determinar si un servicio está funcionando correctamente.
----
- **Monitorización**: Verificar el estado de la aplicación
- **Load Balancing**: Determinar si un servicio puede recibir tráfico
- **Autoescalado**: Decidir cuándo escalar o desescalar servicios
- **Recuperación**: Detectar y recuperar servicios fallidos
- **Observabilidad**: Proporcionar métricas de salud del sistema
----
### Tipos de health endpoints
----
### Liveness Probe
**Propósito**: Determinar si la aplicación está ejecutándose y respondiendo.
**Características**:
- Verifica que el proceso esté activo
- No debe depender de servicios externos
- Debe responder rápidamente
- Indica si la aplicación necesita ser reiniciada
----
### Readiness Probe
**Propósito**: Determinar si la aplicación está lista para recibir tráfico.
**Características**:
- Verifica dependencias externas (BD, APIs, etc.)
- Indica si la aplicación puede procesar requests
- Puede fallar sin causar reinicio
- Usado por load balancers para routing
{"description":"Presentación de Sistemas Operativos 2025-2026.","contributors":"[{\"id\":\"93855254-5bcf-438a-b2d1-f9f805e036e4\",\"add\":15338,\"del\":4166,\"latestUpdatedAt\":1760199142731}]","slideOptions":"{}","lang":"es-ES","title":"nginx ansible and terraform"}