¿Se pregunta qué es Terraform? Averigüémoslo.
Infraestructura como código (IaC) es una terminología muy extendida entre los profesionales de DevOps. Es el proceso de gestión y aprovisionamiento de toda la infraestructura de TI (comprende tanto las máquinas físicas como las virtuales) mediante archivos de definición legibles por máquina. Es un enfoque de ingeniería de software hacia las operaciones. Ayuda a automatizar el centro de datos completo mediante el uso de scripts de programación.
Con todas las características que ofrece la Infraestructura como Código, tiene múltiples retos:
- Necesidad de aprender a codificar
- Desconocimiento del impacto del cambio.
- Necesidad de revertir el cambio
- No puede realizar un seguimiento de los cambios
- No puede automatizar un recurso
- Múltiples entornos para la infraestructura
Terraform se ha creado para resolver estos retos.
Terraform es una herramienta de código abierto de infraestructura como código desarrollada por HashiCorp. Se utiliza para definir y aprovisionar la infraestructura completa utilizando un lenguaje declarativo fácil de aprender.
Es una herramienta de aprovisionamiento de infraestructuras en la que puede almacenar la configuración de su infraestructura en la nube como códigos. Es muy similar a herramientas como CloudFormation, que utilizaría para automatizar su infraestructura de AWS, pero sólo puede utilizarla en AWS. Con Terraform, puede utilizarla también en otras plataformas en la nube.
A continuación se enumeran algunas de las ventajas de utilizar Terraform.
- Realiza la orquestación, no sólo la gestión de la configuración
- Soporta múltiples proveedores como AWS, Azure, GCP, DigitalOcean y muchos más
- Proporciona una infraestructura inmutable en la que la configuración cambia sin problemas
- Utiliza un lenguaje fácil de entender, HCL (lenguaje de configuración de HashiCorp)
- Fácilmente portable a cualquier otro proveedor
- Soporta arquitectura de sólo cliente, por lo que no necesita gestión de configuración adicional en un servidor
Conceptos básicos de Terraform
A continuación se detallan los conceptos/terminologías centrales utilizados en Terraform:
- Variables: También utilizadas como variables de entrada, son pares clave-valor utilizados por los módulos de Terraform para permitir la personalización.
- Proveedor: Es un plugin para interactuar con APIs de servicio y acceder a sus recursos relacionados.
- Módulo: Es una carpeta con plantillas Terraform donde se definen todas las configuraciones
- Estado: Consiste en información almacenada en caché sobre la infraestructura gestionada por Terraform y las configuraciones relacionadas.
- Recursos: Se refiere a un bloque de uno o más objetos de infraestructura (instancias de computación, redes virtuales, etc.), que se utilizan en la configuración y gestión de la infraestructura.
- Fuente dedatos: La implementan los proveedores para devolver información sobre objetos externos a terraform.
- Valores desalida: Son valores de retorno de un módulo terraform que pueden ser utilizados por otras configuraciones.
- Plan: Es una de las etapas en las que se determina lo que hay que crear, actualizar o destruir para pasar del estado real/actual de la infraestructura al estado deseado.
- Aplicar: Es una de las etapas donde aplica los cambios estado real/actual de la infraestructura para pasar al estado deseado.
Ciclo de vida de Terraform
El ciclo de vida de Terraform consiste en – init, plan, apply y destroy.
- Terraform init inicializa el directorio de trabajo que consta de todos los archivos de configuración
- Terraform plan se utiliza para crear un plan de ejecución para alcanzar un estado deseado de la infraestructura. Se realizan cambios en los archivos de configuración para alcanzar el estado deseado.
- Terraform apply realiza entonces los cambios en la infraestructura según lo definido en el plan, y la infraestructura llega al estado deseado.
- Terraform destroy se utiliza para eliminar todos los recursos antiguos de la infraestructura, que se marcan como contaminados tras la fase apply.
¿Cómo funciona Terraform?
Terraform tiene dos componentes principales que conforman su arquitectura:
- Terraform Core
- Proveedores
Núcleo de Terraform
El núcleo de Terraform utiliza dos fuentes de entrada para hacer su trabajo.
La primera fuente de entrada es una configuración de Terraform que usted, como usuario, configura. Aquí, usted define lo que necesita ser creado o aprovisionado. Y la segunda fuente de entrada es un estado donde terraform mantiene el estado actualizado de cómo es la configuración actual de la infraestructura.
Así pues, lo que hace terraform core es tomar la entrada y calcular el plan de lo que hay que hacer. Compara el estado, cuál es el estado actual, y cuál es la configuración que usted desea en el resultado final. Calcula lo que hay que hacer para llegar a ese estado deseado en el archivo de configuración. Calcula qué hay que crear, qué hay que actualizar, qué hay que eliminar para crear y aprovisionar la infraestructura.
Proveedores
El segundo componente de la arquitectura son los proveedores para tecnologías específicas. Puede tratarse de proveedores de nube como AWS, Azure, GCP u otra plataforma de infraestructura como servicio. También es un proveedor para componentes de más alto nivel como Kubernetes u otras herramientas de plataforma como servicio, incluso algún software como herramienta de autoservicio.
Le ofrece la posibilidad de crear infraestructuras a distintos niveles.
Por ejemplo, crear una infraestructura de AWS, luego desplegar Kubernetes sobre ella y después crear servicios/componentes dentro de ese clúster de Kubernetes.
Terraform cuenta con más de un centenar de proveedores para diferentes tecnologías, y cada proveedor permite luego al usuario de Terraform acceder a sus recursos. Así, por ejemplo, a través del proveedor de AWS, tiene acceso a cientos de recursos de AWS como instancias EC2, los usuarios de AWS, etc. Con el proveedor de Kubernetes, tiene acceso a productos básicos, recursos como servicios y despliegues y espacios de nombres, etc.
Así es como funciona Terraform, y de esta manera, intenta ayudarle a aprovisionar y cubrir la configuración completa de la aplicación, desde la infraestructura hasta la aplicación.
Hagamos algunas cosas prácticas. 👨💻
Instalaremos Terraform en Ubuntu y aprovisionaremos una infraestructura muy básica.
Instalar Terraform
Descargue el último paquete de Terraform.
Consulte la página oficial de descargas para obtener la última versión para el sistema operativo correspondiente.
geekflare@geekflare:~$ wget https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
--2020-08-14 16:55:38--
https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
Resolviendo releases.hashicorp.com (releases.hashicorp.com)... 151.101.153.183, 2a04:4e42:24::439
Conectando con releases.hashicorp.com (releases.hashicorp.com)|151.101.153.183|:443... conectado.
Solicitud HTTP enviada, esperando respuesta... 200 OK
Longitud: 34851622 (33M) [application/zip]
Guardando en: 'terraform_0.13.0_linux_amd64.zip'
terraform_0.13.0_linux_amd64.zip
100%[=================================================================>] 33.24M
90.3KB/s en 5m 28s
2020-08-14 17:01:06 (104 KB/s) - 'terraform_0.13.0_linux_amd64.zip' guardado [34851622/34851622]
Extraiga el paquete descargado.
geekflare@geekflare:~$ unzip terraform_0.13.0_linux_amd64.zip
Archive:
terraform_0.13.0_linux_amd64.zip
inflar: terraform
Mueva el archivo ejecutable terraform a la ruta que se muestra a continuación. Compruebe la versión de terraform.
geekflare@geekflare:~$ sudo mv terraform /usr/local/bin/
[sudo] contraseña para geekflare:
geekflare@geekflare:~$ terraform -v
Terraform v0.13.0
Puede ver que estos son los comandos disponibles en terraform para su ejecución.
geekflare@geekflare:~$ terraform
Uso: terraform [-version] [-help] <comando> [args]
A continuación se enumeran los comandos disponibles para su ejecución.
Los comandos más comunes y útiles se muestran primero, seguidos de
comandos menos comunes o más avanzados. Si acaba de empezar
comenzando con Terraform, quédese con los comandos comunes. Para los
otros comandos, por favor lea la ayuda y docs antes de su uso.
Comandos comunes:
apply Construye o cambia la infraestructura
console Consola interactiva para las interpolaciones de Terraform
destroy Destruye la infraestructura gestionada por Terraform
env Gestión del espacio de trabajo
fmt Reescribe los archivos de configuración al formato canónico
get Descarga e instala módulos para la configuración
graph Crear un gráfico visual de los recursos de Terraform
import Importar la infraestructura existente a Terraform
init Inicializar un directorio de trabajo de Terraform
login Obtener y guardar las credenciales para un host remoto
logout Eliminar las credenciales almacenadas localmente para un host remoto
output Leer una salida de un archivo de estado
plan Generar y mostrar un plan de ejecución
providers Imprime un árbol de los proveedores utilizados en la configuración
refresh Actualizar el archivo de estado local contra los recursos reales
mostrar Inspeccionar el estado o plan de Terraform
taint Marcar manualmente un recurso para su recreación
untaint Desmarca manualmente un recurso como manchado
validate Valida los archivos Terraform
version Imprime la versión de Terraform
workspace Gestión del espacio de trabajo
Todos los demás comandos:
0.12upgrade Reescribe el código fuente del módulo pre-0.12 para la v0.12
0.13upgrade Reescribe el código fuente del módulo pre-0.13 para la v0.13
debug Gestión de la salida de depuración (experimental)
force-unlock Desbloquear manualmente el estado de Terraform
push Comando obsoleto para Terraform Enterprise legacy (v1)
state Gestión avanzada del estado
Aprovisionar una instancia AWS EC2 utilizando Terraform
En esta demostración, voy a lanzar una nueva instancia AWS EC2 utilizando Terraform.
Cree un directorio de trabajo para esta demo de Terraform.
geekflare@geekflare:~$ mkdir terraform_demo
Vaya al directorio y cree un archivo de configuración de terraform donde defina el proveedor y los recursos para lanzar una instancia AWS EC2.
geekflare@geekflare:~$ cd terraform_demo/
geekflare@geekflare:~/terraform_demo$ gedit awsec2.tf
proveedor "aws" {
access_key = "B5KG6Fe5GUKIATUF5UD"
secret_key = "R4gb65y56GBF6765ejYSJA4YtaZ T6GY7H"
region = "us-west-2"
}
recurso "aws_instance" "terraform_demo" {
ami = "ami-0a634ae95e11c6f91"
instance_type = "t2.micro"
}
Nota: He cambiado las claves de acceso y secretas 😛, necesita utilizar las suyas propias.
De la configuración mencionada anteriormente, se puede ver que estoy mencionando el proveedor como AWS. Dentro del proveedor, estoy dando las credenciales de usuario de AWS y las regiones donde la instancia debe ser lanzada.
En recursos, estoy dando detalles de AMI de Ubuntu (ami-0a634ae95e11c6f91) y mencionando que el tipo de instancia debe ser t2.micro
Puede ver lo fácil y legible que es el archivo de configuración, incluso si no es un codificador empedernido.
terraform init
Ahora, el primer paso es inicializar terraform.
geekflare@geekflare:~/terraform_demo$ terraform init
Inicializando el backend...
Inicializando los plugins del proveedor...
- Usando hashicorp/aws v3.2.0 previamente instalado
Los siguientes proveedores no tienen ninguna restricción de versión en la configuración,
por lo que se instaló la última versión.
Para evitar actualizaciones automáticas a nuevas versiones principales que puedan contener rupturas de
cambios, recomendamos añadir restricciones de versión en un bloque required_providers
en su configuración, con las cadenas de restricción sugeridas a continuación.
* hashicorp/aws: version = "~> 3.2.0"
¡Terraform se ha inicializado con éxito!
Ya puede empezar a trabajar con Terraform. Intente ejecutar "terraform plan" para ver
cualquier cambio que se requiera para su infraestructura. Todos los comandos de Terraform
deberían funcionar ahora.
Si alguna vez establece o cambia los módulos o la configuración del backend para Terraform,
vuelva a ejecutar este comando para reinicializar su directorio de trabajo. Si lo olvida, otros
comandos lo detectarán y le recordarán que lo haga si es necesario.
plan terraform
La siguiente es la etapa de plan; creará el gráfico de ejecución para crear y aprovisionar la infraestructura.
geekflare@geekflare:~/terraform_demo$ terraform plan
Refrescando el estado de Terraform en memoria antes del plan...
El estado refrescado se utilizará para calcular este plan, pero no se
persistirá en el almacenamiento de estado local o remoto.
------------------------------------------------------------------------
Se ha generado un plan de ejecución que se muestra a continuación.
Las acciones de los recursos se indican con los siguientes símbolos:
crear
Terraform realizará las siguientes acciones:
# se creará aws_instance.terraform_demo
recurso "aws_instance" "terraform_demo" {
ami = "ami-0a634ae95e11c6f91"
arn = (conocido después de aplicar)
associate_public_ip_address = (conocido después de aplicar)
availability_zone = (conocido después de aplicar)
cpu_core_count = (conocido después de aplicar)
cpu_threads_per_core = (conocido después de aplicar)
get_password_data = false
host_id = (conocido después de aplicar)
id = (conocido después de aplicar)
instance_state = (conocido después de aplicar)
instance_type = "t2.micro"
ipv6_address_count = (conocido después de aplicar)
ipv6_addresses = (conocido después de aplicar)
key_name = (conocido después de aplicar)
outpost_arn = (conocido después de aplicar)
password_data = (conocido después de aplicar)
placement_group = (conocido después de aplicar)
primary_network_interface_id = (conocido después de la solicitud)
private_dns = (conocido después de solicitar)
private_ip = (conocido después de solicitar)
public_dns = (conocido después de solicitar)
public_ip = (conocido después de solicitar)
secondary_private_ips = (conocido después de la solicitud)
security_groups = (conocido después de aplicar)
source_dest_check = true
subnet_id = (conocido después de aplicar)
tenancy = (conocido después de aplicar)
volume_tags = (conocido después de aplicar)
vpc_security_group_ids = (conocido después de aplicar)
ebs_block_device {
delete_on_termination = (conocido después de aplicar)
device_name = (conocido después de aplicar)
encrypted = (conocido después de aplicar)
iops = (conocido después de aplicar)
kms_key_id = (conocido después de aplicar)
snapshot_id = (conocido después de aplicar)
volume_id = (conocido después de aplicar)
volume_size = (conocido después de aplicar)
volume_type = (conocido después de aplicar)
}
dispositivo_bloque_efímero {
nombre_dispositivo = (conocido después de aplicar)
no_device = (conocido después de aplicar)
virtual_name = (conocido después de aplicar)
}
metadata_options {
http_endpoint = (conocido después de aplicar)
http_put_response_hop_limit = (conocido después de aplicar)
http_tokens = (conocido después de aplicar)
}
network_interface {
delete_on_termination = (conocido después de aplicar)
device_index = (conocido después de aplicar)
network_interface_id = (conocido después de aplicar)
}
root_block_device {
delete_on_termination = (conocido después de aplicar)
device_name = (conocido después de aplicar)
encriptado = (conocido después de aplicar)
iops = (conocido después de aplicar)
kms_key_id = (conocido después de aplicar)
volume_id = (conocido después de aplicar)
volume_size = (conocido después de aplicar)
volume_type = (conocido después de aplicar)
}
}
Plan: 1 para añadir, 0 para cambiar, 0 para destruir.
------------------------------------------------------------------------
Nota: No especificó un parámetro "-out" para guardar este plan, por lo que Terraform
no puede garantizar que se realicen exactamente estas acciones si
"terraform apply" se ejecuta posteriormente.
terraform aplicar
La etapa apply ejecutará el archivo de configuración y lanzará una instancia AWS EC2. Cuando ejecute el comando apply, le preguntará «¿Desea realizar estas acciones?», deberá escribir sí y pulsar enter.
geekflare@geekflare:~/terraform_demo$ terraform apply
Se ha generado un plan de ejecución que se muestra a continuación.
Las acciones de recursos se indican con los siguientes símbolos:
crear
Terraform realizará las siguientes acciones:
# se creará aws_instance.terraform_demo
recurso "aws_instance" "terraform_demo" {
ami = "ami-0a634ae95e11c6f91"
arn = (conocido después de aplicar)
associate_public_ip_address = (conocido después de aplicar)
availability_zone = (conocido después de aplicar)
cpu_core_count = (conocido después de aplicar)
cpu_threads_per_core = (conocido después de aplicar)
get_password_data = false
host_id = (conocido después de aplicar)
id = (conocido después de aplicar)
instance_state = (conocido después de aplicar)
instance_type = "t2.micro"
ipv6_address_count = (conocido después de aplicar)
ipv6_addresses = (conocido después de aplicar)
key_name = (conocido después de aplicar)
outpost_arn = (conocido después de aplicar)
password_data = (conocido después de aplicar)
placement_group = (conocido después de aplicar)
primary_network_interface_id = (conocido después de la solicitud)
private_dns = (conocido después de solicitar)
private_ip = (conocido después de solicitar)
public_dns = (conocido después de solicitar)
public_ip = (conocido después de solicitar)
secondary_private_ips = (conocido después de la solicitud)
security_groups = (conocido después de aplicar)
source_dest_check = true
subnet_id = (conocido después de aplicar)
tenancy = (conocido después de aplicar)
volume_tags = (conocido después de aplicar)
vpc_security_group_ids = (conocido después de aplicar)
ebs_block_device {
delete_on_termination = (conocido después de aplicar)
device_name = (conocido después de aplicar)
encrypted = (conocido después de aplicar)
iops = (conocido después de aplicar)
kms_key_id = (conocido después de aplicar)
snapshot_id = (conocido después de aplicar)
volume_id = (conocido después de aplicar)
volume_size = (conocido después de aplicar)
volume_type = (conocido después de aplicar)
}
dispositivo_bloque_efímero {
nombre_dispositivo = (conocido después de aplicar)
no_device = (conocido después de aplicar)
virtual_name = (conocido después de aplicar)
}
metadata_options {
http_endpoint = (conocido después de aplicar)
http_put_response_hop_limit = (conocido después de aplicar)
http_tokens = (conocido después de aplicar)
}
network_interface {
delete_on_termination = (conocido después de aplicar)
device_index = (conocido después de aplicar)
network_interface_id = (conocido después de aplicar)
}
root_block_device {
delete_on_termination = (conocido después de aplicar)
device_name = (conocido después de aplicar)
encriptado = (conocido después de aplicar)
iops = (conocido después de aplicar)
kms_key_id = (conocido después de aplicar)
volume_id = (conocido después de aplicar)
volume_size = (conocido después de aplicar)
volume_type = (conocido después de aplicar)
}
}
Plan: 1 para añadir, 0 para cambiar, 0 para destruir.
¿Desea realizar estas acciones?
Terraform realizará las acciones descritas anteriormente.
Sólo se aceptará el "sí" para aprobar.
Introduzca un valor: sí
aws_instance.terraform_demo: Creando...
aws_instance.terraform_demo: Aún creando... [10s transcurridos]
aws_instance.terraform_demo: Aún creando... [20s transcurridos]
aws_instance.terraform_demo: Aún creando... [30s transcurridos]
aws_instance.terraform_demo: Todavía creando... [40s elapsed]
aws_instance.terraform_demo: Creación completada tras 44s [id=i-0eec33286ea4b0740]
¡Aplicación completada! Recursos: 1 añadido, 0 modificado, 0 destruido.
Vaya a su panel de control de AWS EC2 y verá que se ha creado una nueva instancia con el id de instancia mencionado al final del comando apply.
Ha lanzado con éxito una instancia AWS EC2 utilizando Terraform.
terraform destroy
Por último, si desea eliminar la infraestructura, debe ejecutar el comando destroy.
geekflare@geekflare:~/terraform_demo$ terraform destroy
aws_instance.terraform_demo: Refrescando estado... [id=i-0eec33286ea4b0740]
Se ha generado un plan de ejecución que se muestra a continuación.
Las acciones de recursos se indican con los siguientes símbolos:
- destruir
Terraform realizará las siguientes acciones:
# aws_instance.terraform_demo será destruido
- recurso "aws_instance" "terraform_demo" {
- ami = "ami-0a634ae95e11c6f91" -> null
- arn = "arn:aws:ec2:us-west-2:259212389929:instance/i-0eec33286ea4b0740" -> null
- associate_public_ip_address = true -> null
- availability_zone = "us-west-2c" -> null
- cpu_core_count = 1 -> null
- cpu_threads_per_core = 1 -> null
- disable_api_termination = false -> null
- ebs_optimized = false -> null
- get_password_data = false -> null
- hibernation = false -> null
- id = "i-0eec33286ea4b0740" -> null
- instance_state = "running" -> null
- instance_type = "t2.micro" -> null
- ipv6_address_count = 0 -> null
- ipv6_addresses = [] -->
null
- monitorización = false -> null
- primary_network_interface_id = "eni-02a46f2802fd15634" -> null
- private_dns = "ip-172-31-13-160.us-west-2.compute.internal" -> null
- private_ip = "172.31.13.160" -> null
- public_dns = "ec2-34-221-77-94.us-oeste-2.compute.amazonaws.com" -> null
- public_ip = "34.221.77.94" -> null
- secondary_private_ips = [] -> null
- grupos_seguridad = [
- "por defecto
] -> null
- source_dest_check = true -> null
- subnet_id = "subred-5551200c" -> null
- etiquetas = {} -> null
- tenancy = "default" -> null
- volume_tags = {} -> null
- vpc_security_group_ids = [
- "sg-b5b480d1",
] -> null
- especificación_créditos {
- cpu_credits = "standard" -> null
}
- metadata_options {
- http_endpoint = "enabled" -> null
- http_put_response_hop_limit = 1 -> null
- http_tokens = "opcional" -> null
}
- root_block_device {
- delete_on_termination = true -> null
- nombre_dispositivo = "/dev/sda1" -> null
- encriptado = false -> null
- iops = 100 -> null
- volume_id = "vol-0be2673afff6b1a86" -> null
- volume_size = 8 -> null
- tipo_volumen = "gp2" -> null
}
}
Plan: 0 para añadir, 0 para modificar, 1 para destruir.
¿Realmente quiere destruir todos los recursos?
Terraform destruirá toda su infraestructura gestionada, como se muestra arriba.
No se puede deshacer. Sólo se aceptará un "sí" para confirmar.
Introduzca un valor: sí
aws_instance.terraform_demo: Destroying... [id=i-0eec33286ea4b0740]
aws_instance.terraform_demo: Aún destruyendo... [id=i-0eec33286ea4b0740, 10s transcurridos]
aws_instance.terraform_demo: Aún destruyendo... [id=i-0eec33286ea4b0740, 20s transcurridos]
aws_instance.terraform_demo: Aún destruyendo... [id=i-0eec33286ea4b0740, 30s transcurridos]
aws_instance.terraform_demo: Destrucción completada tras 34s
¡Destrucción completada! Recursos: 1 destruido.
Si vuelve a comprobar el panel de EC2, verá que la instancia se ha terminado.
Conclusión
Creo que lo anterior le da una idea para empezar con Terraform. Siga adelante y pruebe el ejemplo que acabo de mostrar.
También debería echar un vistazo a estos programas de automatización de infraestructuras.
Si usted está interesado en aprender más, entonces yo sugeriría comprobar Aprendizaje DevOps con Terraform curso.