Cómo importar infraestructura existente a Terraform con Terraformer
En este artículo, te cuento sobre esta excelente herramienta para importar infraestructura existente a Terraform.
Hace un tiempo, en la serie que llamé Terraform Essentials, en el último capítulo, les mostré cómo importar infraestructura existente, pero había una limitación que tiene y es que no genera los archivos .tf sino que guarda todo en un .tfstate.
Gracias a Dios existe el Open Source y un montón de gente buena que comparte las soluciones que inventa para que las limitaciones que pueda tener una herramienta, desaparezcan.
Así que el día de hoy, les voy a hablar sobre una herramienta llamada Terraformer, la misma es capaz de importar la infraestructura existente y guardarla en archivos.tf, soporta un montón de proveedores, por supuesto es gratuita y la misma fue creada por el equipo SRE de Waze.
Empecemos
Terraformer, básicamente lo que hace y de una manera muy sencilla es leer toda la infraestructura que tenemos en cualquier proveedor soportado y generar los archivos .tf, de esta manera, vamos a poder gestionar, no solo la nueva infraestructura, sino la existente, a través de Terraform.
Nota: Terraform debe estar instalado en la misma máquina donde correrá Terraformer.
Nota 2: Por el momento, Terraform es capaz de funcionar con Terraform 0.12.x, se están haciendo trabajos para ser compatibles con última versión.
Instalación
Vamos a instalar Terraformer. Para eso, debemos clonar el repositorio del proyecto:
$ git clone https://github.com/GoogleCloudPlatform/terraformer.git
Entramos al directorio
$ cd terraformer
Si no tenés golang instalado, debemos hacerlo, para eso ejecutaremos:
$ sudo apt install golang-go
Una vez instalado, vamos a correr...
$ go mod download
Luego tenemos que "buildear" Terraformer para todos los proveedores o para el cual queramos trabajar. Si usas varios proveedores, podes bajar todos los complementos corriendo:
$ sudo go build -v
O, si, como en este caso que les voy a mostrar solo importas infraestructura de DigitalOcean, podes correrlo así:
$ sudo go run build/main.go digitalocean
Tené en cuenta que haciéndolo así 👆, el ejecutable te va a quedar como terraform-digitalocean.
Por último movemos el ejecutable a la carpeta /usr/local/bin:
$ sudo cp terraformer-digitalocean /usr/local/bin
La instalación estaría pronta, podemos ejecutar lo siguiente para ver si ejecuta bien.
$ terraformer-digitalocean
La devolución sería algo como esto:
Usage:
[command]
Available Commands:
help Help about any command
import Import current state to Terraform configuration
plan Plan to import current state to Terraform configuration
version Print the version number of Terraformer
Flags:
-h, --help help for this command
-v, --version version for this command
Una vez instalado, comenzamos a ajustar algunas cosillas para importar...
Importación
Como les comenté más arriba, voy a importar la infra que tengo corriendo en DigitalOcean, en este momento no es mucha más que nombres de dominio, pero tranquilamente se puede usar para importar droplets u otros recursos y no solo desde DigitalOcean.
Vamos a crear una carpeta llamada ¨do¨:
$ mkdir do && cd do
Vamos a generar un archivo llamado init.tf, en el mismo definiremos el proveedor al cual queremos conectarnos, en este caso será DigitalOcean, así que mi archivo se ve algo así:
$ vim init.tf
provider "digitalocean" {}
Pasamos nuestra API key de DigitalOcean como variable de entorno. La misma la pueden generar desde aquí:
$ export DIGITALOCEAN_TOKEN=<api-key>
Luego debemos iniciar el plugin de DigitalOcen para Terraform, así que ejecutaremos:
$ terraform init
El output de este comando se deberá ver algo así:
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "digitalocean" (terraform-providers/digitalocean) 1.22.2...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.digitalocean: version = "~> 1.22"
Warning: registry.terraform.io: For users on Terraform 0.13 or greater, this provider has moved to digitalocean/digitalocean. Please update your source in required_providers.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
A partir de aquí, podemos comenzar a importar nuestra infraestructura.
Para hacerlo, debemos invocar el ejecutable, la acción, el provider y el recurso. Por ejemplo, en mi caso para importar los dominios y sus registros, corrí lo siguiente:
$ terraformer-digitalocean import digitalocean plan -r domain
El output de eso fue todo esto:
Lo siguiente que veremos es que generó una carpeta llamada ¨generated¨, entraremos ahí, luego habrá otra con el nombre del proveedor, en este caso DigitalOcean, el recurso que importamos y adentro los archivos .tf con su respectivo .tfstate.
drwxrwxr-x 2 ubuntu ubuntu 4096 Oct 2 11:00 ./
drwxrwxr-x 4 ubuntu ubuntu 4096 Oct 2 11:06 ../
-rwxrwxr-x 1 ubuntu ubuntu 935 Oct 2 11:00 domain.tf*
-rwxrwxr-x 1 ubuntu ubuntu 10707 Oct 2 11:00 outputs.tf*
-rwxrwxr-x 1 ubuntu ubuntu 52 Oct 2 11:00 provider.tf*
-rwxrwxr-x 1 ubuntu ubuntu 23260 Oct 2 11:00 record.tf*
-rwxrwxr-x 1 ubuntu ubuntu 132703 Oct 2 11:00 terraform.tfstate*
Si abro el archivo domain.tf, que es el que más me interesa, veo que me trajo todos los dominios:
resource "digitalocean_domain" "tfer--cduser-002E-com" {
name = "cduser.com"
}
resource "digitalocean_domain" "tfer--cloudforgood-002E-xyz" {
name = "cloudforgood.xyz"
}
resource "digitalocean_domain" "tfer--en-002E-cduser-002E-com" {
name = "en.cduser.com"
}
resource "digitalocean_domain" "tfer--incusdrive-002E-com" {
name = "incusdrive.com"
}
Ahora, vos me dirás pero importar recurso por recurso no es para nada eficiente y lo que te respondo es: tenés razón, pero Terraformer puede importar proyectos enteros. En mi caso pude importar todo un proyecto de DigitalOcean con sus dominios, spaces y droplets. Lo que si, es que debemos definir todos los recursos en la misma "orden":
terraformer-digitalocean import digitalocean -r droplet,ssh_key,volume,project <id-proyecto>
Para ir cerrando
Como ven, no es nada del otro mundo importar infra a Terraform con Terraformer.
Tengan en cuenta lo que les mencione más arriba con respecto a la versión de Terraform y también que la cantidad de proveedores es un poco más limitada, acá pueden ver la lista de los que están soportados en este momento:
Espero que les haya servido y como siempre digo, cualquier duda o consulta, no duden en dejar un comentario.