Importar Infraestructura a Terraform paso a paso — Step by Step

Importar Infraestructura a Terraform paso a paso — Step by Step

Level 100

En este articulo, aprenderá formas de importar recursos de la nube preexistentes antes de continuar desarrollando IaC en Terraform.

Esta guía le proporcionará un escenario de importación de IaC al que suelen enfrentarse los equipos que empiezan a adoptar Terraform para sus operaciones.

Documentación oficial

¿Por qué importar?

La infraestructura como código (de aquí en adelante la llamaremos IaC) es una nueva forma de gestionar los recursos de TI que ha demostrado su eficacia en entornos que integran infraestructura en la nube y contenerización. Gracias a su flexibilidad, control de la calidad y precio accesible ha logrado irrumpir en un ecosistema en el que la complejidad y la variedad de herramientas para desarrolladores están ganando terreno.

La falta de recursos humanos y la pronunciada curva de aprendizaje que implica el uso de Terraform hacen que los equipos comiencen a utilizar la infraestructura de la nube directamente a través de sus respectivas consolas web.

Future Trends in Infrastructure as Code (IAC) | by A. Yigit Ogun |  DevOps.dev

De hecho, cualquier tipo de método IaC (CloudFormation, Azure ARM, Pulumi, etc.) requiere cierta capacitación y experiencia en el manejo de escenarios en tiempo real. Las cosas se complican especialmente cuando se trata de conceptos como estados "tfstate" y backends remotos.

En el peor de los casos, puedes perder el archivo terraform.tfstate . Afortunadamente, puedes usar la función de importación para reconstruirlo.

iron man - Create meme / Meme Generator - Meme-arsenal.com

La importación de Terraform "terraform import" facilita la obtención de los recursos de la nube bajo la gestión de Terraform.

import es un comando CLI de Terraform que se utiliza para leer la infraestructura del mundo real y actualizar el estado, de modo que se puedan aplicar futuras actualizaciones al mismo conjunto de infraestructura a través de IaC.

La funcionalidad de importación ayuda a actualizar el estado localmente y no crea la configuración correspondiente automáticamente.

Sin embargo, el equipo de Terraform está trabajando arduamente para mejorar esta función en próximas versiones.

Importación fácil

Para comprender por qué necesitamos importar recursos de la nube, comencemos importando de un recurso simple:

La instancia EC2 en AWS.

Supongo que la instalación y configuración de Terraform de las credenciales de AWS en AWS CLI ya se encuentra en la maquina fisica.

No entraremos en detalles sobre eso en este tutorial. Para importar un recurso simple a Terraform, siga la guía paso a paso.

1. Prepare la instancia EC2

Suponiendo que la instalación de Terraform y la configuración de las credenciales de AWS en AWS CLI ya se realizan localmente, comience importando un recurso en AWS: la instancia EC2 en AWS.

Por lograr el objetivo de esta guia, crearemos un recurso a mano desde la consola para luego importarlo.

Terraform: crear una instancia EC2 en una VPC existente

Continúe y aprovisione una instancia EC2 en su cuenta de AWS. Aquí están los detalles del ejemplo de la instancia EC2 así creada:

Nombre: ec2-terraform
ID de instancia: i-001e797e05799bf0b
Tipo: t2.micro
ID de VPC: vpc-xxxxxx

2. Crear el main.tf y establezca la configuración del proveedor "AWS"

El objetivo de este paso es importar esta instancia EC2 a nuestra configuración de Terraform. En la ruta deseada, cree main.tf y configure el provider AWS . El archivo debería verse como el siguiente.

Importación de una instancia EC2 a la configuración de Terraform:

// Configuración del proveedor 
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

Ejecute terraform init para inicializar los modulos de terraform.

A continuación se muestra el resultado de una inicialización exitosa.

Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.16.1...
- Installed hashicorp/aws v5.16.1 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

3. Definir la configuración para el recurso que quieres importar

Como se mencionó anteriormente, la importación de Terraform no genera los archivos de configuración por sí sola. Por lo tanto, debe crear manualmente la configuración correspondiente para la instancia EC2. Esto no necesita muchos argumentos ya que tendremos que agregarlos o modificarlos cuando importemos la instancia EC2 a nuestro archivo de estado "tfstate".

Sin embargo, si no le importa no ver resultados coloridos en la CLI, puede comenzar a agregar todos los argumentos que conoce.

Pero este no es un enfoque infalible, porque normalmente la infraestructura que tengas que importar no la habrás creado tú.

Por lo tanto, de todos modos es mejor saltarse algunos argumentos .

En un momento veremos cómo ajustar nuestra configuración para reflejar el recurso exacto.

Por ahora, agregue el main.tfcon la configuración del EC2.

Por ejemplo, he usado la siguiente configuración.

La única razón por la que he incluido amiun instance_type es que son los argumentos requeridos para aws_instance

resource "aws_instance" "ec2" {
 ami           = "unknown"
 instance_type = "unknown"
}

4. Importar

Piense en ello como si el recurso de la nube (instancia EC2) y su correspondiente configuración estuvieran disponibles en nuestros archivos. Todo lo que queda por hacer es mapear. Lo hacemos ejecutando el comando de importación de la siguiente manera.

terraform import aws_instance.ec2 <Instance ID>

Un resultado exitoso debería verse así:

aws_instance.ec2: Importing from ID "i-001e797e05799bf0b"...
aws_instance.ec2: Import prepared!
  Prepared aws_instance for import
aws_instance.ec2: Refreshing state... [id=i-001e797e05799bf0b]
Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

El comando anterior asigna la aws_instance.ec2la configuración a la instancia EC2 utilizando el ID.

.
├── main.tf
└── terraform.tfstate

Por mapeo quiero decir que el archivo de estado "tfstate" ahora "conoce" la existencia de la instancia EC2 con el ID dado.

El archivo tfstate contiene información sobre cada atributo de esta instancia EC2, ya que lo obtuvo mediante el comando de importación.

5. Revisa resultado y luego ejecuta el plan

Tenga en cuenta que el directorio ahora también contiene terraform.tfstate. Este archivo se generó después de que el comando de importación se ejecutara correctamente. Tómese un momento para revisar el contenido de este archivo.

{
  "version": 4,
  "terraform_version": "1.5.0",
  "serial": 1,
  "lineage": "b8aed583-dc66-53e6-b39f-c7bad0b4ef4b",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "aws_instance",
      "name": "ec2",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "ami": "ami-053b0d53c279acc90",
            "arn": "arn:aws:ec2:us-east-1:459137896070:instance/i-001e797e05799bf0b",
            "associate_public_ip_address": true,
            "availability_zone": "us-east-1c",

En este momento nuestra configuración no refleja todos los atributos.

Cualquier intento de realizar plan y el apply fallará porque no hemos ajustado los valores de sus atributos.

Para cerrar la brecha en los archivos de configuración y archivos de estado "tfstate" ejecute terraform plany observe el resultado.

# aws_instance.ec2 must be replaced
-/+ resource "aws_instance" "ec2" {
      ~ ami                                  = "ami-053b0d53c279acc90" -> "unknown" # forces replacement
      ~ arn                                  = "arn:aws:ec2:us-east-1:459137896070:instance/i-001e797e05799bf0b" -> (known after apply)
      ~ associate_public_ip_address          = true -> (known after apply)
      ~ availability_zone                    = "us-east-1c" -> (known after apply)
      ~ cpu_core_count                       = 1 -> (known after apply)
      ~ cpu_threads_per_core                 = 1 -> (known after apply)
      ~ disable_api_stop                     = false -> (known after apply)

El plan indica que intentaría reemplazar la instancia EC2.

Pero esto va completamente en contra de nuestro propósito.

The Terrors and Joys of Terraform | by Driven by Code | Driven by Code |  Medium

Podríamos hacerlo de todos modos simplemente sin preocuparnos por los recursos existentes y creando nuevos recursos mediante la configuración.

La buena noticia es que Terraform ha tomado nota de la existencia de una instancia EC2 asociada a su estado.

6. Ajustando la configuración para evitar el replace [Reemplazo]

En este punto, es importante comprender que el terraform.tfstate es una referencia para Terraform. Todas sus operaciones futuras se realizan teniendo en cuenta este archivo.

Se debe concentrar en no reemplazar la instancia EC2, sino en alinear la configuración para evitar el reemplazo.

Con el tiempo, alcanzarías un estado de 0 diferencia.

Observe el resultado del plan y encuentre todos los atributos que causan el reemplazo.

Cambie el valor de ami "unknown" a lo que está resaltado en el resultado del plan y ejecútelo terraform plan nuevamente.

Observe el resultado.

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place
# aws_instance.ec2 will be updated in-place
  ~ resource "aws_instance" "ec2" {
        id                                   = "i-001e797e05799bf0b"
      ~ tags                                 = {
          - "Name" = "ec2-terraform" -> null
        }
      ~ tags_all                             = {
          - "Name" = "ec2-terraform"
        } -> (known after apply)
      + user_data_replace_on_change          = false
        # (30 unchanged attributes hidden)

        # (8 unchanged blocks hidden)
    }

Esta vez el plan no indica el reemplazo de la instancia EC2. Si obtiene el mismo resultado, podrá importar parcialmente nuestro recurso en la nube . Actualmente se encuentra en un estado de riesgo reducido: si aplicamos la configuración ahora, el recurso no será reemplazado, pero algunos atributos cambiarán.

7. Mejore la configuración para evitar reemplazos

Si queremos lograr un estado de diferencia 0, debe alinear su bloque de recursos aún más. El resultado del plan resalta los cambios de atributos mediante ~. También indica la diferencia en los valores.

Por ejemplo, resalta el cambio en el valor de tipo_instancia de "t2.micro" a "unknown".

En otras palabras, si el valor de instance_typehubiera sido “t2.micro”, Terraform NO habría solicitado un cambio.

De manera similar, también puede ver que hay cambios en las etiquetas "tags" . Cambiemos la configuración.

El aws_instance debería tener el siguiente aspecto:

resource "aws_instance" "ec2" {
  ami           = "ami-053b0d53c279acc90"
  instance_type = "t2.micro"
  tags = {
    "Name" : "ec2-terraform"
  }
}

Ejecute terraform plannuevamente y observe el resultado.

aws_instance.ec2: Refreshing state... [id=i-001e797e05799bf0b]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are
needed.

Si obtiene el mismo resultado, felicidades

ya que ha importado con éxito un recurso de nube a su configuración de Terraform.

Ahora es posible gestionar esta configuración a través de Terraform directamente, sin sorpresas.

Review: Testing Terraform Infrastructure-as-code with Unit tests & BDD e2e  with checkov and compliance-testing | by Jaroslav Pantsjoha | ITNEXT

Como quedaría el main.tf

El Bonus Track con Terraformer

¿Pero qué pasa si ya tienes alguna infraestructura y quieres migrarla al código?

U otro caso: siempre creaste los monitores Datadog manualmente y ahora quieres administrarlos como un código.

Existe una herramienta que podría ayudarte con eso. Terraformer : una herramienta CLI que genera archivos tf/ jsony tfstatebasados ​​en la infraestructura existente.

https://github.com/GoogleCloudPlatform/terraformer

Resumen

Terraform nos permite de una forma declarativa construir y mantener la definición de nuestra infraestructura como si de código se tratase. Su potencia y capacidad de adaptación a múltiples entornos y necesidades hace que se especialmente interesante en entornos muy dinámicos, cambiantes y con distintos entornos de ejecución (on-premises, cloud o híbrido).