Terraform, todo lo que necesitas saber para comenzar a usar nuestros Módulos
Tags: beginners, tutorial, devops, spanish
Published: 2022-02-03 23:10:53

**Los módulos en Terraform** son una colección de recursos que se pueden vincular o simplemente crear individualmente. Cuando llamamos a un módulo, estamos llamando a un archivo con una serie de recursos y algunos parámetros, los cuales necesitamos especificar o bien en el propio recurso o en otro archivo que almacene nuestras variables.

**¿Por qué usar Terraform?**

- Es una herramienta muy útil para desarrollar, cambiar y tener una versión de nuestra infraestructura de manera eficiente y segura.

- Es una herramienta que permite definir infraestructura como código y habilita cambiar y hacer un seguimiento de la infraestructura con facilidad.

- Es independiente de la plataforma o ‘cloud agnostic’ y permite trabajar con múltiples proveedores cloud.

**¿Qué necesitamos para este laboratorio?**

- Terraform instalado. En este caso, ejecutamos la v.1.0.0

- En nuestro caso, utilizamos AWS como nuestro proveedor de servicios en la nube, por lo que necesitamos un usuario con acceso mediante programación. 

- Tu editor de código preferido.

Por lo general, primero deberíamos configurar un módulo Terraform para el "backend" con nuestros parámetros requeridos o simplemente obtener algún módulo oficial de la red. En nuestro caso, estamos usando un módulo propio con un Bucket S3 Y DynamonDB , por lo tanto, especificamos qué parámetros queremos en nuestro módulo.

> **¿Qué es un backend? ¿Y el tfstate?**
El tfstate es el fichero donde se guardan los datos con los recursos que hemos ido creando con nuestro código en Terraform. El backend es donde decidimos guardar ese archivo/s.

**Este módulo de Terraform implementa los recursos necesarios para almacenar el estado de Terraform en AWS.**
** Esto incluye**

- Amazon S3 Bucket

- DynamoDB Table

¡Empecemos!

Creamos una carpeta modules y luego terraform-aws-s3-backend

```
└── modules
    └── terraform-aws-s3-backend 
```

Vamos a definir las variables que necesitamos, en este caso necesitamos el nombre de buckets3 y el de la dynamondb

**variables.tf**

```
variable "s3_bucket" {
  type        = string
  description = <<-EOF
  Name of the Amazon S3 bucket to store Terraform state.
  EOF
}

variable "dynamodb_table" {
  type        = string
  description = <<-EOF
  Name of the DynamoDB table to store Terraform state lock.
  EOF
}
```

ahora vamos a definir nuestros recursos para ser usado como backend 

**main.tf**

```
# -----------------------------------------------------------------------------
# AMAZON S3 BUCKET y DYNAMODB TABLE PARA TERRAFORM STATE
# Este módulo de Terraform despliega los recursos necesarios para almacenar Los estados de Terraform en AWS
# estado en AWS.
# INCLUYE:
#   * Amazon S3 Bucket
#   * DynamoDB Table
# -----------------------------------------------------------------------------

terraform {
  required_version = ">= 1.0.0"
}

# -----------------------------------------------------------------------------
# S3 BUCKET
# 
# -----------------------------------------------------------------------------
resource "aws_s3_bucket" "s3_bucket" {
  bucket = var.s3_bucket

  # El propietario obtiene FULL_CONTROL. Nadie más tiene derechos de acceso(default).
  acl = "private"

  versioning {
    enabled = true
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
#Prevenimos explícitamente la destrucción usando terraform. true|false
  lifecycle {
    prevent_destroy = true
  }
}

# -----------------------------------------------------------------------------
# DYNAMODB TABLE
# 
# -----------------------------------------------------------------------------
resource "aws_dynamodb_table" "dynamodb_table" {
  name = var.dynamodb_table
  billing_mode   = "PROVISIONED"
  read_capacity  = 1
  write_capacity = 1
  hash_key = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}
```

y por supuesto la salida.

**output.tf**

```
# -----------------------------------------------------------------------------
# OUTPUTS
# -----------------------------------------------------------------------------
output "s3_bucket" {
  value       = aws_s3_bucket.s3_bucket.id
  description = "El nombre del S3 bucket"
}

output "dynamodb_table" {
  value       = aws_dynamodb_table.dynamodb_table.id
  description = "El nombre del DynamoDB table"
}
```

**Ahora como probamos nuestro modulo**

creamos una carpeta por ejemplo **example** para hacer la llamada, cabe destacar que podemos almacenar todos nuestros módulos y poder hacer las distintas llamadas, muchas cosas por hacer.

dentro del directorio **example**
creamos el archivo **main.tf**

```
# -----------------------------------------------------------------------------
# AMAZON S3 BUCKET - DYNAMODB TABLE TERRAFORM STATE
# -----------------------------------------------------------------------------
provider "aws" {
  region = "us-east-1"
}

#Acá un punto clave le estamos dando la ruta donde esta nuestro modulo, también podemos llamar a un repo donde podría servir como banco de módulos

module "s3_backend" {
  source         = "../../terraform-aws-s3-backend"
  s3_bucket      = "tf-roxsross-s3-bucket"
  dynamodb_table = "tf-roxsross-dynamodb-table"
}
```
y ademas nuestra salida **output.tf**

```
# -----------------------------------------------------------------------------
# OUTPUTS
# -----------------------------------------------------------------------------
output "s3_bucket" {
  value       = module.s3_backend.s3_bucket
  description = <<-EOF
  el nombre del S3 bucket para almacenar el estado de Terraform
  EOF
}

output "dynamodb_table" {
  value       = module.s3_backend.dynamodb_table
  description = <<-EOF
  el nombre de la DynamoDB table para almacenar el estado de Terraform
  EOF
}
```

```
.
└── modules
    └── terraform-aws-s3-backend
        ├── example
        │   ├── main.tf
        │   └── output.tf
        ├── main.tf
        ├── output.tf
        └── variables.tf
```


Y por último, desplegar nuestro módulo con los comandos terraform init, terraform plan y terraform apply.

**y no te olvides del terraform validate , para validar que todo este okey**

![terraform validate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zo9deg7ztl1ppxokf95.png)
 
Terraform plan

```
terraform plan -out plan.out
```

![Terraform plan](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ol7kw3c1ca5pxsaunm4.png)
 
y Aplicamos!!

```
terraform apply "plan.out"
```

![terraform apply](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gs5o91zjljh4r4pm5q3w.png)
 

En este post, hemos visto cómo desplegar un Bucket S3/dynamodb “backend” Recuerda visitar la documentación oficial de Terraform para seguir aprendiendo sobre los módulos, recursos y sus parámetros.

y estamos en AWS 

![AWS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shsmkph22lu1yid12ya5.png)
 
**y un bonus track **

Recuerden utilizar herramientas para escanear vulnerabilidades en nuestros módulos.

voy a usar https://snyk.io/

con la CLI   
`snyk iac
    Find security issues in Infrastructure as Code files.`


```
snyk iac test terraform-aws-s3-backend/
```
![snyk iac test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vixt85ny3s1dbh7ncmia.png)
 

![RoxsRoss](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48pxubnlq3pujewfangk.png)

Repositorio Github ->>>> [https://github.com/roxsross/modules-roxsross-tf](https://github.com/roxsross/modules-roxsross-tf)