Terraform y LocalStack
Si trabajas con DevOps, redes, sistemas o cloud, probablemente ya escuchaste hablar de Terraform. Esta herramienta se volvió casi obligatoria para quien quiere automatizar infraestructura de forma simple y escalable.
Pero existe una barrera para mucha gente: ¿cómo practicar sin gastar dinero en nube pública? El co$$to de jugar en la cloud puede ser alto. Basta olvidar una VM encendida para percibir lo rápido que llega la cuenta. Es ahí donde entra la combinación Terraform + LocalStack.
Usar los dos juntos es una excelente forma de entrenar infraestructura como código (IaC) sin gastar nada. Como LocalStack es open source y puede instalarse vía containers, consigues crear un escenario realista de nube privada para experimentar recursos como redes, máquinas virtuales y volúmenes. Esto elimina gastos en cloud pública y viabiliza el aprendizaje de forma accesible.
Otra gran ventaja es que el combo permite simular flujos muy próximos a los entornos de producción. Escribes el código Terraform, lo aplicas en LocalStack y ves los recursos siendo aprovisionados en la práctica. Así, resulta fácil entender conceptos como versionado, modularización, gestión de estado y automatización de infraestructura. Es un aprendizaje práctico, que va más allá de la teoría, acelera la curva de conocimiento y además ayuda a perder el miedo de crear y destruir recursos sin preocupación.
Preparé un lab basado en Docker Compose y voy a mostrar cómo usar Terraform para aprovisionar una instancia en LocalStack (y también comparar con AWS).
Organización de los archivos
Antes de empezar, para mantener el laboratorio organizado y fácil de entender, es importante seguir una estructura de directorio como la descrita abajo. El archivo docker-compose.yml debe quedar en la raíz del proyecto, pues es quien levanta todo el ambiente de containers. Los archivos de Terraform quedan dentro de la carpeta terraform/, separando lo que es infraestructura de la orquestación de containers. Dentro de esa carpeta, el provider.tf se usa para configurar el proveedor (como LocalStack o AWS) y el main.tf concentra la definición de los recursos que serán creados. Esa organización simple hace el lab más legible, modular y fácil de mantener.
├── docker-compose.yml
├── terraform/
├── main.tf
├── provider.tf
Docker Compose
Docker Compose va a ser la base para crear los ambientes y ejecutar el script terraform y una instancia de LocalStack para simular un provider de cloud.
Archivo: docker-compose.yml
1version: '3.8'
2
3services:
4 localstack:
5 container_name: localstack
6 image: localstack/localstack:latest
7 ports:
8 - "4566:4566"
9 - "4510-4559:4510-4559"
10 environment:
11 - EDGE_PORT=4566
12 - AWS_DEFAULT_REGION=us-east-1
13 - AWS_ACCESS_KEY_ID=test
14 - AWS_SECRET_ACCESS_KEY=test
15 - SERVICES=ec2
16 - DEBUG=1
17 - DATA_DIR=/tmp/localstack/data
18 - DOCKER_HOST=unix:///var/run/docker.sock
19 - HOST_TMP_FOLDER=/var/lib/localstack
20 volumes:
21 - localstack_data:/var/lib/localstack
22 - "/var/run/docker.sock:/var/run/docker.sock"
23 networks:
24 - terraform
25
26 terraform:
27 image: hashicorp/terraform:1.6
28 container_name: terraform
29 working_dir: /workspace
30 volumes:
31 - ./terraform:/workspace
32 networks:
33 - terraform
34 depends_on:
35 - localstack
36 entrypoint: ["tail", "-f", "/dev/null"]
37
38
39volumes:
40 localstack_data:
41
42networks:
43 terraform:
44 name: terraform
Para crear el ambiente basta con ejecutar
docker compose up -d --build
LocalStack Cloud Provider
En Terraform, un provider (proveedor) es el componente responsable de hacer el puente entre los scripts Terraform y el servicio que quieres gestionar; en el caso de esta explicación es LocalStack. Cada provider es como si fuera un plugin que traduce los comandos de Terraform en llamadas a la API de la plataforma que estás usando.
Ejemplo práctico: si quieres crear una instancia en AWS, necesitas el provider “aws”. Si quieres crear una red en LocalStack, usas el provider “localstack”. Y así sucesivamente, ¿captaste?
Mira la config de nuestro lab:
Archivo: terraform/provider.tf
1terraform {
2 required_providers {
3 aws = {
4 source = "hashicorp/aws"
5 version = "~> 5.0"
6 }
7 }
8}
9
10provider "aws" {
11 access_key = "test"
12 secret_key = "test"
13 region = "us-east-1"
14 s3_use_path_style = true
15 skip_credentials_validation = true
16 skip_metadata_api_check = true
17 skip_requesting_account_id = true
18
19 endpoints {
20 s3 = "http://localstack:4566"
21 ec2 = "http://localstack:4566"
22 }
23}
Terraform script
Un script Terraform es un archivo o un conjunto de archivos de configuración escritos en HCL (HashiCorp Configuration Language) que describen la infraestructura que deseas crear o gestionar.
En vez de crear recursos manualmente en un panel de cloud, escribes ese script diciendo, por ejemplo, “quiero una VM con tal red y tal disco”. Terraform lee el script, compara con el estado actual de la infraestructura y ejecuta los cambios necesarios para dejar todo igual a lo que fue definido en el código. Es la base del concepto de infraestructura como código (IaC).
El script de abajo crea una VM en AWS; para Terraform eso es un recurso llamado “aws_instance”, mira los pasos de cómo crearla.
Archivo: terraform/main.tf
1# Buscar a última AMI Amazon Linux 2
2data "aws_ami" "amazon_linux" {
3 most_recent = true
4
5 filter {
6 name = "name"
7 values = ["amzn2-ami-hvm-*-x86_64-gp2"]
8 }
9
10 owners = ["amazon"]
11}
12
13# Criar uma instância EC2
14resource "aws_instance" "exemplo_ec2" {
15 ami = data.aws_ami.amazon_linux.id
16 instance_type = "t2.micro"
17
18 tags = {
19 Name = "Infraascode.com.br - Terraform"
20 }
21}
Iniciando Terraform
El comando terraform init sirve para inicializar un directorio de trabajo de Terraform, preparando todo para que puedas usar tus scripts. Descarga e instala los providers necesarios (como AWS, Azure, LocalStack, etc.), configura el backend de almacenamiento del estado (si lo hubiera) y valida la estructura inicial de los archivos; en resumen, es el primer paso obligatorio antes de correr cualquier otro comando, pues garantiza que el ambiente esté listo para ejecutar el plan y aplicar la infraestructura.
1 $ terraform init
2
3Initializing the backend...
4
5Initializing provider plugins...
6- Finding hashicorp/aws versions matching "~> 5.0"...
7- Installing hashicorp/aws v5.100.0...
8- Installed hashicorp/aws v5.100.0 (signed by HashiCorp)
9
10Terraform has created a lock file .terraform.lock.hcl to record the provider
11selections it made above. Include this file in your version control repository
12so that Terraform can guarantee to make the same selections by default when
13you run "terraform init" in the future.
14
15Terraform has been successfully initialized!
16
17You may now begin working with Terraform. Try running "terraform plan" to see
18any changes that are required for your infrastructure. All Terraform commands
19should now work.
20
21If you ever set or change modules or backend configuration for Terraform,
22rerun this command to reinitialize your working directory. If you forget, other
23commands will detect it and remind you to do so if necessary.
Verificando el plan de ejecución
El comando terraform plan sirve para mostrar, de forma previa, lo que Terraform va a hacer antes de aplicar los cambios en tu infraestructura. Compara lo que está definido en tus archivos de configuración con el estado actual y genera un “plan de ejecución”, indicando qué recursos serán creados, alterados o destruidos. Esto ayuda a revisar y validar los cambios antes de ejecutarlos, evitando sorpresas o errores.
1terraform plan -out=infraascode_com_br
2data.aws_ami.amazon_linux: Reading...
3data.aws_ami.amazon_linux: Read complete after 2s [id=ami-04681a1dbd79675a5]
4
5Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
6 + create
7
8Terraform will perform the following actions:
9
10 # aws_instance.exemplo_ec2 will be created
11 + resource "aws_instance" "exemplo_ec2" {
12 + ami = "ami-04681a1dbd79675a5"
13 + arn = (known after apply)
14 + associate_public_ip_address = (known after apply)
15 + availability_zone = (known after apply)
16 + instance_type = "t2.micro"
17 + tags = {
18 + "Name" = "Infraascode.com.br - Terraform"
19 }
20 + tags_all = {
21 + "Name" = "Infraascode.com.br - Terraform"
22 }
23 + id = (known after apply)
24 + public_ip = (known after apply)
25 + private_ip = (known after apply)
26 }
27
28Plan: 1 to add, 0 to change, 0 to destroy.
29
30───────────────────────────────────────────────────────────────────────────────
31
32Saved the plan to: infraascode_com_br
33
34To perform exactly these actions, run the following command to apply:
35 terraform apply "infraascode_com_br"
Terraform apply
El comando terraform apply se usa para ejecutar los cambios descritos en los archivos de configuración, aplicando en la infraestructura todo lo que fue planeado en el terraform plan. Crea, altera o remueve recursos de acuerdo con el código y solo finaliza cuando la infraestructura está en el estado deseado. En otras palabras, es el comando que transforma tu código Terraform en recursos reales funcionando en el ambiente definido, en nuestro caso LocalStack.
1 $terraform apply infraascode_com_br
2aws_instance.exemplo_ec2: Creating...
3aws_instance.exemplo_ec2: Still creating... [10s elapsed]
4aws_instance.exemplo_ec2: Creation complete after 10s [id=i-50b40c581c4dad9b4]
5
6Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Verificando el resultado
El comando terraform state list sirve para exhibir todos los recursos que Terraform está gestionando en el archivo de estado (terraform.tfstate). Muestra la lista de los objetos conocidos por Terraform, como VMs, redes, discos o cualquier otro recurso creado. Esto es útil para verificar lo que ya fue aprovisionado, confirmar nombres correctos de recursos e incluso para depurar situaciones en que el código y la infraestructura parecen no estar alineados.
1terraform state list
2data.aws_ami.amazon_linux
3aws_instance.exemplo_ec2
4/workspace/# terraform state show aws_instance.exemplo_ec2
5# aws_instance.exemplo_ec2:
6resource "aws_instance" "exemplo_ec2" {
7 ami = "ami-04681a1dbd79675a5"
8 arn = "arn:aws:ec2:us-east-1::instance/i-50b40c581c4dad9b4"
9 associate_public_ip_address = true
10 availability_zone = "us-east-1a"
11 disable_api_stop = false
12 disable_api_termination = false
13 ebs_optimized = false
14 get_password_data = false
15 hibernation = false
16 id = "i-50b40c581c4dad9b4"
17 instance_initiated_shutdown_behavior = "stop"
18 instance_state = "running"
19 instance_type = "t2.micro"
20 ipv6_address_count = 0
21 ipv6_addresses = []
22 monitoring = false
23 placement_partition_number = 0
24 primary_network_interface_id = "eni-697884262d742bf4f"
25 private_dns = "ip-10-75-171-105.ec2.internal"
26 private_ip = "10.75.171.105"
27 public_dns = "ec2-54-214-150-17.compute-1.amazonaws.com"
28 public_ip = "54.214.150.17"
29 secondary_private_ips = []
30 security_groups = []
31 source_dest_check = true
32 subnet_id = "subnet-777fbdb4bbd4df236"
33 tags = {
34 "Name" = "Infraascode.com.br - Terraform"
35 }
36 tags_all = {
37 "Name" = "Infraascode.com.br - Terraform"
38 }
39 tenancy = "default"
40 user_data_replace_on_change = false
41 vpc_security_group_ids = []
42
43 metadata_options {
44 http_endpoint = "enabled"
45 http_protocol_ipv6 = "disabled"
46 http_put_response_hop_limit = 1
47 http_tokens = "optional"
48 instance_metadata_tags = "disabled"
49 }
50
51 root_block_device {
52 delete_on_termination = true
53 device_name = "/dev/sda1"
54 encrypted = false
55 iops = 0
56 tags = {}
57 tags_all = {}
58 throughput = 0
59 volume_id = "vol-22f90e0fe787def16"
60 volume_size = 8
61 volume_type = "gp2"
62 }
63}
Resumiendo
Jugar con Terraform y LocalStack en un ambiente de LAB abre un abanico de posibilidades para quien quiere aprender infraestructura como código sin depender de la nube pública y sin preocuparse por los costos. Puedes probar la creación de máquinas virtuales, redes, volúmenes y simular flujos de producción de forma segura, rápida y controlada. Esa libertad de experimentar da confianza para entender conceptos de automatización, versionado y modularización sin miedo de “romper” nada crítico.
Además, el lab con Terraform y LocalStack es una excelente manera de descubrir nuevas funcionalidades, crear escenarios diferentes y evolucionar tus habilidades de forma práctica. En cada prueba ganas un poco más de experiencia y te acercas a lo que encontrarás en ambientes de empresas. Es una inversión en aprendizaje que acelera tu curva de evolución y te prepara para los desafíos.
¡Un abrazo!
¡Larga y próspera vida a todos!
Referencias
Entre em contato:
NewsLetter - https://engineeringmanager.com.br/Linkdin - linkedin.com/in/leonardoml/
Twitter: @infraascode_br
Te convido a ver os outros posts do blog Infra-as-Code garanto que tem coisas legais lá!!
|
|
