Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 41 additions & 122 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,146 +1,65 @@
### **Infraestructura como código**
# Laboratorio de Terraform

- **Utilizar archivos de definición**: Todas las herramientas de infraestructura como código tienen un formato propio para definir la infraestructura.
- **Autodocumentación de procesos y sistemas**: Al utilizar el enfoque de infraestructura como código, podemos reutilizar el código. Es importante que este esté documentado adecuadamente para que otros usuarios comprendan el propósito y funcionamiento del módulo.
- **Versionar todo**: Esto nos permite rastrear los cambios realizados. Si se comete un error, podemos retroceder a una versión estable.
- **Preferir cambios pequeños**: Realizar cambios pequeños para evitar grandes impactos.
- **Mantener los servicios continuamente disponibles**: Garantizar la disponibilidad continua es clave en la infraestructura.
**Estudiante:** Danna Valentina López Muñoz
**Código:** A00395902
**Profesor:** Christian David Flor Astudillo
**Asignatura:** Ingeniería de Software V
**Universidad Icesi, Facultad Barberi de Ingeniería, Diseño y Ciencias Aplicadas**

### **Beneficios de la infraestructura como código**
# Contexto

- **Creación rápida y bajo demanda**: Con un único archivo de definición de infraestructura que almacena todas nuestras configuraciones, podemos crear múltiples veces la infraestructura sin necesidad de rehacer todo desde el principio.
- **Automatización**: Una vez creado el archivo de definición, podemos usar herramientas de **continuous integration** para automatizar la infraestructura.
- **Visibilidad y trazabilidad**: El versionamiento de la infraestructura como código permite una mayor visibilidad y trazabilidad, ya que todos los cambios quedan registrados.
- **Ambientes homogéneos**: Podemos crear varios ambientes a partir del mismo archivo de definición, cambiando únicamente algunos parámetros.
Durante este laboratorio se realizara el proceso de despliegue de una infraestructura en la nube de Azure usando Terraform. Lo que se busaca es incentivar la compresión de cómo la infraestructura en la nube puede ser definida, versionada y gestionada de manera declarativa, en lugar de realizar configuraciones manuales desde el portal de Azure.

---
# Pasos

### **Mejores prácticas**
## 1. Autenticación en Azure

- **Modularidad**: Es recomendable dividir la infraestructura en módulos reutilizables para facilitar su mantenimiento y escalabilidad.
- **Mantener las configuraciones centralizadas**: Utilizar variables y archivos de configuración para gestionar parámetros y evitar valores "hardcoded".
- **Manejo seguro del estado**: Almacenar el archivo `terraform.tfstate` de manera remota (por ejemplo, en un bucket S3 con bloqueo de versión) para evitar problemas en equipos distribuidos.
- **Revisiones de código y pull requests**: Antes de aplicar cambios importantes en la infraestructura, hacer revisiones mediante pull requests para asegurar que los cambios han sido revisados por otros.
Se ejecuta el comando `az login`para autenticarse y escoger la suscripción con la que se trabajara, en este caso será "Azure for Students".
![alt text](image-1.png)

### **Ambientes**
Y validamos que las configuraciones de la cuenta sean correctas con el comando `az account show`
![alt text](image.png)

Terraform permite la creación de múltiples ambientes (dev, stage, prod) con diferentes configuraciones. Puedes gestionar estos ambientes utilizando archivos `.tfvars` específicos para cada entorno.
Una vez que se ha validado que la cuenta está activa y la suscripción es la seleccionada, se puede proceder a crear el proyecto de Terraform.

- **Ambiente de desarrollo (dev)**: Se recomienda utilizar recursos más pequeños y económicos en este ambiente para reducir costos.
- **Ambiente de producción (prod)**: Aquí es importante configurar instancias y recursos con redundancia y alta disponibilidad.

Ejemplo de estructura para gestionar ambientes:
## 2. Inicialización de Terraform

```bash
├── main.tf
├── variables.tf
├── dev.tfvars
├── prod.tfvars
```
Posicionandose en la carpeta raíz del directorio, se ejecuta el comando `terraform init` que descarga proveedores, módulos y configura el backend.
![alt text](image-2.png)

Al aplicar los cambios para un ambiente en específico, puedes ejecutar:

```bash
terraform apply --var-file="dev.tfvars"
```
## 3. Añadir subscripción de azure en el provider

### **Automatización con CI/CD**
En el archivo main.tf, debajo de la línea features{} se agrega la variable subscription_id que tendrá el valor de la variable id obtenida del comando `az account show` del primer paso y validamos que la sintaxis y configuración permanezcan correctas.
![alt text](image-3.png)
![alt text](image-4.png)

Integrar Terraform en un flujo de CI/CD es una excelente práctica para automatizar la gestión de la infraestructura. Puedes utilizar herramientas como Jenkins, GitLab CI, o GitHub Actions para automatizar el proceso de despliegue y validación.
## 4. Planificación de la infraestructura

Ejemplo de un pipeline básico en GitLab CI:
Se genera un plan de ejecución con el comando `terraform plan` que compara la configuración definida en los archivos .tf con el estado real de la infraestructura existente en Azure y genera un plan de ejecución de los cambios que se llevaran a cabo al aplicar la configuración. Este paso es para verificar que los cambios en la infraestructura coincidan con el resultado esperado antes de hacer modificaciones.
![alt text](image-5.png)

```yaml
stages:
- validate
- plan
- apply
## 5. Aplicación del plan de la infraestructura

validate:
script:
- terraform init
- terraform validate
Se utiliza el comando `terraform apply` para ejecutar el plan y aplicarlo sobre la infraestructura, el comando solicita ingresar nuevamente el nombre de la función y confirmar la operación con yes, así Terraform aprovisiona los recursos en Azure según lo definido en los archivos .tf.

plan:
script:
- terraform plan
En mi caso, tuve que crear el archivo dev.tfvars para definir los nombres de los recursos y usar el comando `terraform apply --var-file="dev.tfvars` porque algunos fallaban al momento de crearse,
![alt text](image-6.png)
![alt text](image-7.png)
![alt text](image-8.png)

apply:
script:
- terraform apply --auto-approve
```
## 6. Verificación de funcionamiento

Este pipeline primero inicializa el entorno, luego valida la configuración, y finalmente aplica los cambios automáticamente.
En el portal de azure, en el apartado de grupo de recursos, se selecciona el recurso creado (en este caso se llama danna-functionapp) y se puede apreciar que contiene tres recursos; una aplicación de funciones, un plan de App Service y una cuenta de almacenamiento.
![alt text](image-9.png)

### **Seguridad**
Accedemos al url que aparece en el recurso aplicación de funciones (`https://danna-functionapp.azurewebsites.net`)
![alt text](image-11.png)

- **Manejo seguro de credenciales**: Nunca almacenar credenciales en el código fuente. Utilizar herramientas como **AWS Secrets Manager** o **HashiCorp Vault** para gestionar los secretos de manera segura.
- **Control de acceso basado en roles (IAM)**: Asignar roles y permisos específicos a los recursos de Terraform mediante políticas de IAM para restringir el acceso según sea necesario.
- **Cifrado de datos**: Utilizar cifrado en reposo y en tránsito para proteger los datos sensibles, como el uso de **KMS (Key Management Service)** de AWS.
- **Seguridad en el estado**: Si almacenas el archivo `terraform.tfstate` en un bucket S3, asegúrate de habilitar el cifrado y el control de versiones para evitar modificaciones no autorizadas.
Y vemos que está funcionando correctamente
![alt text](image-12.png)

---
Accedemos también al url que nos resulto como outputs al aplicar el plan (`https://danna-functionapp.azurewebsites.net/api/danna-functionapp`)
![alt text](image-10.png)

### **Manejo de variables en Terraform**

Para hacer escalable y reutilizable el archivo de definición de infraestructura, se recomienda no usar valores "hardcoded". Terraform permite crear variables de los siguientes tipos:

- **string**
- **number**
- **boolean**
- **map**
- **list**

Si no se declara un tipo, el valor por defecto será `string`. Sin embargo, es una buena práctica especificar el tipo de la variable.

Ejemplo de definición de variables:

```terraform
variable "ami_id" {
type = string
description = "ID de la AMI"
}

variable "instance_type" {
type = string
description = "Tipo de instancia"
}

variable "tags" {
type = map
description = "Etiquetas para la instancia"
}
```

### **Asignar valores a las variables**

Los valores de las variables se pueden asignar de tres maneras:

1. Utilizando variables de entorno.
2. Pasándolos como argumentos en la línea de comandos.
3. Mediante un archivo `.tfvars` con formato `key = value`.

Ejemplo de archivo `.tfvars`:

```terraform
ami_id = "ami-0ca0c67309196175e"
instance_type = "t2.micro"
tags = {
Name = "devops-tf"
Environment = "Dev"
}
```

Para usar este archivo con variables:

```bash
terraform apply --var-file="dev.tfvars"
```

### **Destruir la infraestructura**

Para eliminar la infraestructura creada, se puede utilizar:

```bash
terraform destroy --var-file="dev.tfvars" -auto-approve
```
Y la función de trigger responde correctamente a peticiones. Por lo que podemos concluir que se desplego de manera exitosa en Azure utilizando Terraform.
146 changes: 146 additions & 0 deletions REPO-EXPLANATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
### **Infraestructura como código**

- **Utilizar archivos de definición**: Todas las herramientas de infraestructura como código tienen un formato propio para definir la infraestructura.
- **Autodocumentación de procesos y sistemas**: Al utilizar el enfoque de infraestructura como código, podemos reutilizar el código. Es importante que este esté documentado adecuadamente para que otros usuarios comprendan el propósito y funcionamiento del módulo.
- **Versionar todo**: Esto nos permite rastrear los cambios realizados. Si se comete un error, podemos retroceder a una versión estable.
- **Preferir cambios pequeños**: Realizar cambios pequeños para evitar grandes impactos.
- **Mantener los servicios continuamente disponibles**: Garantizar la disponibilidad continua es clave en la infraestructura.

### **Beneficios de la infraestructura como código**

- **Creación rápida y bajo demanda**: Con un único archivo de definición de infraestructura que almacena todas nuestras configuraciones, podemos crear múltiples veces la infraestructura sin necesidad de rehacer todo desde el principio.
- **Automatización**: Una vez creado el archivo de definición, podemos usar herramientas de **continuous integration** para automatizar la infraestructura.
- **Visibilidad y trazabilidad**: El versionamiento de la infraestructura como código permite una mayor visibilidad y trazabilidad, ya que todos los cambios quedan registrados.
- **Ambientes homogéneos**: Podemos crear varios ambientes a partir del mismo archivo de definición, cambiando únicamente algunos parámetros.

---

### **Mejores prácticas**

- **Modularidad**: Es recomendable dividir la infraestructura en módulos reutilizables para facilitar su mantenimiento y escalabilidad.
- **Mantener las configuraciones centralizadas**: Utilizar variables y archivos de configuración para gestionar parámetros y evitar valores "hardcoded".
- **Manejo seguro del estado**: Almacenar el archivo `terraform.tfstate` de manera remota (por ejemplo, en un bucket S3 con bloqueo de versión) para evitar problemas en equipos distribuidos.
- **Revisiones de código y pull requests**: Antes de aplicar cambios importantes en la infraestructura, hacer revisiones mediante pull requests para asegurar que los cambios han sido revisados por otros.

### **Ambientes**

Terraform permite la creación de múltiples ambientes (dev, stage, prod) con diferentes configuraciones. Puedes gestionar estos ambientes utilizando archivos `.tfvars` específicos para cada entorno.

- **Ambiente de desarrollo (dev)**: Se recomienda utilizar recursos más pequeños y económicos en este ambiente para reducir costos.
- **Ambiente de producción (prod)**: Aquí es importante configurar instancias y recursos con redundancia y alta disponibilidad.

Ejemplo de estructura para gestionar ambientes:

```bash
├── main.tf
├── variables.tf
├── dev.tfvars
├── prod.tfvars
```

Al aplicar los cambios para un ambiente en específico, puedes ejecutar:

```bash
terraform apply --var-file="dev.tfvars"
```

### **Automatización con CI/CD**

Integrar Terraform en un flujo de CI/CD es una excelente práctica para automatizar la gestión de la infraestructura. Puedes utilizar herramientas como Jenkins, GitLab CI, o GitHub Actions para automatizar el proceso de despliegue y validación.

Ejemplo de un pipeline básico en GitLab CI:

```yaml
stages:
- validate
- plan
- apply

validate:
script:
- terraform init
- terraform validate

plan:
script:
- terraform plan

apply:
script:
- terraform apply --auto-approve
```

Este pipeline primero inicializa el entorno, luego valida la configuración, y finalmente aplica los cambios automáticamente.

### **Seguridad**

- **Manejo seguro de credenciales**: Nunca almacenar credenciales en el código fuente. Utilizar herramientas como **AWS Secrets Manager** o **HashiCorp Vault** para gestionar los secretos de manera segura.
- **Control de acceso basado en roles (IAM)**: Asignar roles y permisos específicos a los recursos de Terraform mediante políticas de IAM para restringir el acceso según sea necesario.
- **Cifrado de datos**: Utilizar cifrado en reposo y en tránsito para proteger los datos sensibles, como el uso de **KMS (Key Management Service)** de AWS.
- **Seguridad en el estado**: Si almacenas el archivo `terraform.tfstate` en un bucket S3, asegúrate de habilitar el cifrado y el control de versiones para evitar modificaciones no autorizadas.

---

### **Manejo de variables en Terraform**

Para hacer escalable y reutilizable el archivo de definición de infraestructura, se recomienda no usar valores "hardcoded". Terraform permite crear variables de los siguientes tipos:

- **string**
- **number**
- **boolean**
- **map**
- **list**

Si no se declara un tipo, el valor por defecto será `string`. Sin embargo, es una buena práctica especificar el tipo de la variable.

Ejemplo de definición de variables:

```terraform
variable "ami_id" {
type = string
description = "ID de la AMI"
}

variable "instance_type" {
type = string
description = "Tipo de instancia"
}

variable "tags" {
type = map
description = "Etiquetas para la instancia"
}
```

### **Asignar valores a las variables**

Los valores de las variables se pueden asignar de tres maneras:

1. Utilizando variables de entorno.
2. Pasándolos como argumentos en la línea de comandos.
3. Mediante un archivo `.tfvars` con formato `key = value`.

Ejemplo de archivo `.tfvars`:

```terraform
ami_id = "ami-0ca0c67309196175e"
instance_type = "t2.micro"
tags = {
Name = "devops-tf"
Environment = "Dev"
}
```

Para usar este archivo con variables:

```bash
terraform apply --var-file="dev.tfvars"
```

### **Destruir la infraestructura**

Para eliminar la infraestructura creada, se puede utilizar:

```bash
terraform destroy --var-file="dev.tfvars" -auto-approve
```
Binary file added image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Definición del provider que ocuparemos
provider "azurerm" {
features {}
subscription_id = "3fe0943f-dc81-4413-9048-3296332bd707"
}

# Se crea el grupo de recursos, al cual se asociarán los demás recursos
Expand All @@ -11,7 +12,7 @@ resource "azurerm_resource_group" "rg" {

# Se crea un Storage Account, para asociarlo al function app (recomendación de la documentación).
resource "azurerm_storage_account" "sa" {
name = var.name_function
name = var.storage_account_name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
Expand All @@ -21,7 +22,7 @@ resource "azurerm_storage_account" "sa" {
# Se crea el recurso Service Plan para especificar el nivel de servicio
# (por ejemplo, "Consumo", "Functions Premium" o "Plan de App Service"), en este caso "Y1" hace referencia a plan consumo
resource "azurerm_service_plan" "sp" {
name = var.name_function
name = var.service_plan_name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
os_type = "Windows"
Expand Down
19 changes: 18 additions & 1 deletion variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,25 @@ variable "name_function" {
description = "Name Function"
}

variable "resource_group_name" {
description = "Name of the Resource Group"
type = string
default = "lab-rg"
}

variable "storage_account_name" {
description = "Name of the Storage Account (lowercase, 3-24 chars, unique globally)"
type = string
}

variable "service_plan_name" {
description = "Name of the Service Plan"
type = string
default = "lab-serviceplan"
}

variable "location" {
type = string
default = "West Europe"
default = "brazilsouth"
description = "Location"
}