# Aprovisionar Azure SQL Server y Bases de Datos con Terraform
## Introducción
Azure SQL Database es un servicio de base de datos relacional como servicio (DBaaS) que se ejecuta en la nube de Azure. Proporciona un motor de base de datos SQL completamente administrado, lo que permite a las empresas centrarse en la creación de aplicaciones sin preocuparse por la infraestructura subyacente. La **infraestructura como código (IaC)** es fundamental en este contexto, ya que permite a los desarrolladores definir y gestionar la infraestructura mediante código, lo que mejora la consistencia y la reproducibilidad.
Este tutorial se centrará en cómo aprovisionar un **Servidor SQL de Azure** y bases de datos utilizando **Terraform**. Aprenderás a crear un servidor SQL, bases de datos, y configurar reglas de firewall y autenticación de Azure Active Directory (AAD). Los casos de uso incluyen la creación de entornos de desarrollo, pruebas, y producción de aplicaciones que dependen de bases de datos SQL.
## Prerequisitos
Antes de comenzar, asegúrate de cumplir con los siguientes requisitos:
- [Terraform CLI](https://www.terraform.io/downloads.html) instalado en tu máquina.
- Una cuenta activa de [Azure](https://azure.microsoft.com/free/).
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) instalado y configurado.
- Un [principal de servicio de Azure](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal) con permisos para crear recursos en la suscripción de Azure.
## Conceptos Fundamentales
- **Servidor SQL de Azure**: Un servidor lógico que alberga bases de datos SQL.
- **Base de datos**: Instancia específica de almacenamiento de datos dentro del servidor SQL.
- **Reglas de firewall**: Configuraciones que determinan qué direcciones IP pueden acceder al servidor SQL.
- **Autenticación AAD**: Permite el uso de credenciales de Azure Active Directory para acceder a las bases de datos.
La administración del estado en Terraform es crítica. Terraform mantiene un archivo de estado que rastrea los recursos que ha creado. Esto permite a Terraform aplicar cambios incrementales y evitar la recreación innecesaria de recursos.
| Término | Descripción |
|--------------------------|-----------------------------------------------------|
| `azurerm_sql_server` | Recurso que representa un servidor SQL de Azure. |
| `azurerm_sql_database` | Recurso que representa una base de datos en SQL. |
| `azurerm_mssql_firewall_rule` | Reglas que controlan el acceso al servidor SQL. |
## Sintaxis del Recurso
### Recurso: `azurerm_sql_server`
```hcl
resource "azurerm_sql_server" "example" {
name = var.sql_server_name
resource_group_name = azurerm_resource_group.example.name
location = var.location
version = "12.0"
administrator_login = var.administrator_login
administrator_login_password = var.administrator_login_password
tags = var.tags
}
Tabla de Argumentos
| Argumento | Descripción |
|---|---|
name |
Nombre del servidor SQL. |
resource_group_name |
Nombre del grupo de recursos donde se ubicará. |
location |
Ubicación del servidor SQL. |
version |
Versión del motor de base de datos (ej. "12.0"). |
administrator_login |
Nombre de usuario del administrador. |
| `administrator_login_password | Contraseña del administrador. |
tags |
Etiquetas para clasificar el recurso. |
Ejemplos Prácticos
1. Crear un Servidor SQL Básico
resource "azurerm_resource_group" "example" {
name = "mi-grupo-recursos"
location = "East US"
}
resource "azurerm_sql_server" "example" {
name = "mi-servidor-sql"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "12.0"
administrator_login = "admin_user"
administrator_login_password = "P@ssword1234"
}
2. Crear una Base de Datos SQL
resource "azurerm_sql_database" "example" {
name = "mi-base-datos"
resource_group_name = azurerm_resource_group.example.name
server_name = azurerm_sql_server.example.name
sku {
name = "S0"
tier = "Standard"
capacity = 10
}
}
3. Configurar una Regla de Firewall
resource "azurerm_mssql_firewall_rule" "example" {
name = "mi-regla-firewall"
resource_group_name = azurerm_resource_group.example.name
server_name = azurerm_sql_server.example.name
start_ip_address = "0.0.0.0"
end_ip_address = "255.255.255.255"
}
4. Activar Autenticación AAD
resource "azurerm_sql_active_directory_administrator" "example" {
server_name = azurerm_sql_server.example.name
resource_group_name = azurerm_resource_group.example.name
login = "aad_user@domain.com"
object_id = "12345678-1234-1234-1234-123456789012"
}
5. Crear Varias Bases de Datos
resource "azurerm_sql_database" "example" {
count = 3
name = "mi-base-datos-${count.index + 1}"
resource_group_name = azurerm_resource_group.example.name
server_name = azurerm_sql_server.example.name
sku {
name = "S0"
tier = "Standard"
capacity = 10
}
}
6. Manejo de Variables
variable "sql_server_name" {
type = string
default = "mi-servidor-sql"
}
variable "location" {
type = string
default = "East US"
}
variable "administrator_login" {
type = string
default = "admin_user"
}
variable "administrator_login_password" {
type = string
default = "P@ssword1234"
}
variable "tags" {
type = map(string)
default = {
Environment = "Development"
Project = "Terraform"
}
}
7. Outputs
output "sql_server_name" {
value = azurerm_sql_server.example.name
}
output "database_name" {
value = azurerm_sql_database.example.name
}
8. Inicializar y Aplicar Terraform
# Inicializar Terraform
terraform init
# Crear un plan
terraform plan -out main.tfplan
# Aplicar el plan
terraform apply main.tfplan
Casos de Uso del Mundo Real
- Entornos de Desarrollo: Provisionar servidores SQL y bases de datos para entornos de desarrollo y pruebas de aplicaciones.
- Migraciones: Migrar bases de datos on-premises a Azure utilizando Terraform para mantener la configuración y el estado.
- Despliegue de Aplicaciones en Producción: Automatizar el aprovisionamiento de bases de datos para aplicaciones críticas en producción, asegurando configuraciones consistentes y seguras.
Mejores Prácticas
- Gestión del Estado: Usa un backend remoto como Azure Storage para almacenar el estado de Terraform de manera segura.
- Seguridad: No hardcodear contraseñas en el código. Usa variables de entorno o servicios como Azure Key Vault.
- Modularización: Divide la configuración en módulos reutilizables para facilitar el mantenimiento y la escalabilidad.
- Convenciones de Nomenclatura: Usa nombres claros y consistentes para recursos y variables para facilitar la identificación.
- Versiones de Proveedores: Especifica versiones de proveedores en el archivo
versions.tfpara evitar problemas de compatibilidad.
Errores Comunes
Error: "Error creating SQL Server: ...":
- Causa: Las credenciales de administrador no cumplen con las políticas de complejidad de Azure.
- Solución: Asegúrate de que la contraseña cumpla con los requisitos de Azure.
Error: "Resource not found: ...":
- Causa: El grupo de recursos no existe o no se ha creado.
- Solución: Verifica que el grupo de recursos se haya creado antes de referenciarlo.
Error: "IP address range is not valid":
- Causa: Las direcciones IP en la regla de firewall no son válidas.
- Solución: Asegúrate de que las direcciones IP estén en el formato correcto.
Error: "The requested resource is in use":
- Causa: Intentas eliminar un recurso que aún está en uso.
- Solución: Verifica que no haya dependencias activas antes de eliminar recursos.
Recursos Relacionados
| Recurso | Descripción |
|---|---|
| azurerm_sql_server | Documentación del recurso para SQL Server. |
| azurerm_sql_database | Documentación del recurso para bases de datos. |
| azurerm_mssql_firewall_rule | Documentación sobre reglas de firewall. |
| Terraform en Azure | Guía general sobre el uso de Terraform en Azure. |
Script Completo de Infraestructura
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "mi-grupo-recursos"
location = "East US"
}
resource "azurerm_sql_server" "example" {
name = "mi-servidor-sql"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "12.0"
administrator_login = "admin_user"
administrator_login_password = "P@ssword1234"
}
resource "azurerm_sql_database" "example" {
name = "mi-base-datos"
resource_group_name = azurerm_resource_group.example.name
server_name = azurerm_sql_server.example.name
sku {
name = "S0"
tier = "Standard"
capacity = 10
}
}
resource "azurerm_mssql_firewall_rule" "example" {
name = "mi-regla-firewall"
resource_group_name = azurerm_resource_group.example.name
server_name = azurerm_sql_server.example.name
start_ip_address = "0.0.0.0"
end_ip_address = "255.255.255.255"
}
output "sql_server_name" {
value = azurerm_sql_server.example.name
}
output "database_name" {
value = azurerm_sql_database.example.name
}
Conclusión
En este tutorial, hemos aprendido cómo aprovisionar un servidor SQL de Azure y bases de datos utilizando Terraform. La implementación de IaC no solo facilita el despliegue de recursos, sino que también asegura que los entornos sean reproducibles y gestionables. Como siguiente paso, considera explorar más sobre la automatización de despliegues y la integración de Terraform con otros servicios de Azure.
Referencias
This tutorial is structured to provide a comprehensive guide on provisioning Azure SQL Server and Databases with Terraform, utilizing practical examples and best practices, while ensuring clarity and accessibility for developers.