El autor seleccionó la Fundación Wikimedia para recibir una donación como parte del programa Write for Donations.
Introducción
La Infraestructura como Código (IaC) es una práctica de automatización de implementación y modificaciones de infraestructura al definir los estados de los recursos y sus relaciones en código. La ejecución de ese código luego crea o modifica los recursos reales en la nube. La IaC permite a los ingenieros utilizar una herramienta de IaC como Terraform (de HashiCorp) para el aprovisionamiento de infraestructura.
Con IaC, los cambios en su infraestructura pueden pasar por el mismo proceso de revisión de código que su código de aplicación. Puede almacenar el código en control de versiones (como Git) para mantener un historial del estado de su infraestructura, y puede automatizar aún más el proceso de implementación con herramientas de nivel superior como una plataforma de desarrollador interno (IDP) de autoservicio.
Terraform es una herramienta popular de Infraestructura como Código (IaC, por sus siglas en inglés) que es independiente de la plataforma debido a su amplio soporte para muchas plataformas, incluyendo GitHub, Cloudflare y DigitalOcean. La mayoría de las configuraciones de Terraform se escriben utilizando un lenguaje declarativo llamado HashiCorp Configuration Language (HCL).
El Kit de Desarrollo en la Nube para Terraform (CDKTF) es una herramienta construida sobre Terraform que te permite definir infraestructura utilizando un lenguaje de programación familiar (como TypeScript, Python o Go) en lugar de HCL. Esta herramienta puede proporcionar una curva de aprendizaje más suave para los desarrolladores que no están familiarizados con HCL, al tiempo que permite a los desarrolladores utilizar características de programación nativas como bucles, variables y funciones.
En este tutorial, comenzarás instalando la interfaz de línea de comandos (CLI, por sus siglas en inglés) cdktf
. Luego, crearás un proyecto CDKTF en TypeScript y definirás el proyecto con dos servidores NGINX que serán balanceados por un balanceador de carga. Después, utilizarás cdktf
para implementar la infraestructura. Al final de este tutorial, tendrás un proyecto CDKTF desde el cual podrás expandir tu infraestructura.
Nota: Este tutorial ha sido probado con CDKTF 0.11.2
y Terraform 1.2.2
.
Prerrequisitos
Para completar este tutorial, necesitarás:
- A good understanding of Infrastructure-as-Code (IaC). You can learn about IaC in Infrastructure as Code Explained.
- A DigitalOcean account. If you do not have one, sign up for a new account.
- A DigitalOcean Personal Access Token, which you can create via the DigitalOcean console. Instructions on how to do that can be found at How to Generate a Personal Access Token.
- A password-less SSH key added to your DigitalOcean account. You can add that by following How To Use SSH Keys with DigitalOcean Droplets. When you add the key to your account, remember the name you give it, as you will need it in this tutorial. For CDKTF to accept the name of your key, it must start with a letter or underscore and may contain only letters, digits, underscores, and dashes.
- Terraform instalado en tu máquina local, lo cual puedes configurar con “Paso 1 – Instalar Terraform” en Cómo Usar Terraform con DigitalOcean.
- Node.js instalado en tu máquina local. Puedes encontrar instrucciones para esto en la serie Cómo Instalar Node.js y Crear un Entorno de Desarrollo Local.
- Sentirte cómodo programando con JavaScript. Para mejorar tus habilidades, revisa la serie Cómo Codificar en JavaScript.
- Sentirte cómodo usando las características básicas de TypeScript. Si no te sientes cómodo con TypeScript, la serie de tutoriales Cómo Codificar en TypeScript es un buen recurso para ponerte al día.
- A code editor or integrated development environment (IDE) that supports TypeScript. If you are not currently using one, try Visual Studio Code. You can also read up on How To Work With TypeScript in Visual Studio Code.
Paso 1 — Instalación de la CLI cdktf
Para comenzar, instalarás la herramienta de línea de comandos cdktf
.
La CLI cdktf
está disponible como un paquete NPM. Si buscas cdktf
en npmjs.com, encontrarás dos paquetes con nombres similares: cdktf
y cdktf-cli
.
Conceptualmente, CDKTF es una capa de abstracción sobre Terraform. Consta de dos partes:
-
una biblioteca que contiene un conjunto de construcciones nativas del lenguaje (como funciones y clases) para definir infraestructura. Esta parte está encapsulada dentro del paquete npm
cdktf
. Por ejemplo, puedes ver el uso de las clasesApp
yTerraformStack
del paquetecdktf
en el siguiente proyecto de muestra de CDKTF: -
Un adaptador que analiza las construcciones dentro del proyecto CDKTF y las reduce a un conjunto de documentos JSON, que luego se ingieren en Terraform de la misma manera que se ingiere HCL. Este adaptador está encapsulado en una herramienta CLI llamada
cdktf
, proporcionada por el paquetecdktf-cli
.
Para instalar la herramienta CLI cdktf
, necesitas el paquete cdktf-cli
. Puedes instalar este paquete globalmente usando npm
, yarn
, o un administrador de paquetes de tu elección.
Para instalar cdktf-cli
con npm
, ejecuta lo siguiente:
Nota: Es probable que haya una versión más nueva del paquete cdktf-cli
después de la publicación de este artículo. Puedes intentar seguir el tutorial con la última versión ejecutando npm install --global cdktf-cli@latest
en su lugar, pero ten en cuenta que algunas salidas pueden diferir ligeramente.
Alternativamente, puedes usar Homebrew en macOS o Linux para instalar la CLI cdktf
como la fórmula cdktf
:
Para verificar que la instalación haya sido exitosa, ejecuta el comando cdktf
sin argumentos:
Verás una salida similar a la siguiente:
OutputPlease pass a command to cdktf, here are all available ones:
cdktf
Commands:
cdktf init Create a new cdktf project from a template.
cdktf get Generate CDK Constructs for Terraform providers and modules.
cdktf convert Converts a single file of HCL configuration to CDK for Terraform.
cdktf deploy [stacks...] Deploy the given stacks
cdktf destroy [stacks..] Destroy the given stacks
cdktf diff [stack] Perform a diff (terraform plan) for the given stack
cdktf list List stacks in app.
cdktf login Retrieves an API token to connect to Terraform Cloud.
cdktf synth Synthesizes Terraform code for the given app in a directory.
cdktf watch [stacks..] [experimental] Watch for file changes and automatically trigger a deploy
cdktf output [stacks..] Prints the output of stacks
cdktf debug Get debug information about the current project and environment
cdktf completion generate completion script
Options:
--version Muestra el número de versión
--disable-logging No escribe archivos de registro. Soportado usando la variable de entorno CDKTF_DISABLE_LOGGING.
--disable-plugin-cache-env No establece automáticamente TF_PLUGIN_CACHE_DIR.
--log-level Qué nivel de registro debe ser escrito.
-h, --help Show help
Options can be specified via environment variables with the "CDKTF_" prefix (e.g. "CDKTF_OUTPUT")
La salida muestra los comandos disponibles. En el resto de este tutorial, ganarás experiencia usando cdktf init
, cdktf get
, cdktf deploy
y cdktf destroy
.
Ahora que has instalado el CLI cdktf
, puedes definir infraestructura escribiendo algo de código TypeScript.
Paso 2 — Creando un Nuevo Proyecto CDKTF
En este paso, utilizarás el CLI cdktf
que acabas de instalar para crear un proyecto de CDKTF de plantilla, en el que trabajarás en pasos posteriores.
Crea un directorio que albergará el proyecto CDKTF ejecutando el siguiente comando:
Luego, navega al directorio recién creado:
Usa el comando cdktf init
para crear una estructura de proyecto CDKTF en la que trabajarás:
CDKTF permite a los desarrolladores definir infraestructura utilizando TypeScript, Python, Java, C# o Go. La opción --template=typescript
le indica a cdktf
que genere la estructura de este proyecto de CDKTF utilizando TypeScript.
Terraform (y por lo tanto CDKTF) realiza un seguimiento de los recursos que administra registrando sus definiciones y estados en archivos llamados archivos de estado de Terraform. La opción --local
le indica a CDKTF que mantenga estos archivos de estado localmente en la máquina donde se ejecuta cdktf
(cada archivo sigue la estructura de nombres terraform.<stack>.tfstate
).
Después de ejecutar el comando, es posible que la interfaz de línea de comandos le pida permiso para enviar informes de fallos al equipo de CDKTF para ayudarlos a mejorar el producto:
Output? Do you want to send crash reports to the CDKTF team? See https://www.terraform.io/cdktf/create-and-deploy/configuration-file for
more information (Y/n)
Escriba Y
si desea consentir o N
si está en desacuerdo, luego presione ENTER
.
cdktf
luego creará la estructura del proyecto e instalará los paquetes. Cuando el proyecto esté estructurado, verá una salida similar a la siguiente:
Output Your cdktf typescript project is ready!
cat help Print this message
Compile:
npm run get Import/update Terraform providers and modules (you should check-in this directory)
npm run compile Compile typescript code to javascript (or "npm run watch")
npm run watch Watch for changes and compile typescript in the background
npm run build Compile typescript
Synthesize:
cdktf synth [stack] Synthesize Terraform resources from stacks to cdktf.out/ (ready for 'terraform apply')
Diff:
cdktf diff [stack] Perform a diff (terraform plan) for the given stack
Deploy:
cdktf deploy [stack] Deploy the given stack
Destroy:
cdktf destroy [stack] Destroy the stack
Test:
npm run test Runs unit tests (edit __tests__/main-test.ts to add your own tests)
npm run test:watch Watches the tests and reruns them on change
Upgrades:
npm run upgrade Upgrade cdktf modules to latest version
npm run upgrade:next Upgrade cdktf modules to latest "@next" version (last commit)
También verá algunos archivos nuevos agregados al directorio infra
. Los archivos más importantes son cdktf.json
y main.ts
.
cdktf.json
es el archivo de configuración para el proyecto de CDKTF. Si abre el archivo, mostrará algo como lo siguiente:
La propiedad app
define el comando que se ejecutará para sintetizar el código TypeScript a JSON compatible con Terraform. Esta propiedad indica que main.ts
es el punto de entrada al proyecto de CDKTF.
Si abres el archivo main.ts
, verás algo similar a lo siguiente:
En el lenguaje de CDKTF, una colección de recursos de infraestructura relacionados puede agruparse en un stack. Por ejemplo, los recursos que componen una aplicación de API, como Droplets, balanceadores de carga y registros DNS, pueden agruparse en un único stack llamado APIStack
. Cada stack mantiene su propio estado y puede ser implementado, modificado o destruido de forma independiente de otros stacks. Un uso común de los stacks es tener un stack para producción y un stack separado para desarrollo.
Una aplicación es un contenedor para múltiples stacks. Por ejemplo, una aplicación puede agrupar los stacks de varios microservicios.
El proyecto CDKTF generado en el esquema de main.ts
contiene una única clase de stack llamada MyStack
, que actualmente no define ningún recurso. Se crea una instancia de MyStack
con el nombre infra
, contenido dentro de una aplicación llamada app
. En pasos posteriores, definirás recursos de infraestructura dentro del constructor de MyStack
.
Después de crear el proyecto, el siguiente paso es configurar el proyecto CDKTF con proveedores.
Paso 3 — Instalando el Proveedor DigitalOcean
Proveedores son bibliotecas que proporcionan instrucciones a Terraform (que se utiliza bajo el capó en cdktf
) sobre cómo crear, actualizar y eliminar recursos en proveedores de nube, proveedores SaaS y otras plataformas que exponen interfaces de programación de aplicaciones (APIs). Los proveedores encapsulan la lógica de llamar a estas API upstream en funciones estándar que Terraform puede llamar.
Por ejemplo, si creara una nueva gota de DigitalOcean sin Terraform, tendría que enviar una solicitud POST
al /v2/droplets
del API de DigitalOcean. Con Terraform, en su lugar, instalaría el proveedor de DigitalOcean y definiría un recurso digitalocean_droplet
, similar al siguiente fragmento de código de muestra:
A continuación, puede utilizar la herramienta de línea de comandos cdktf
para traducir este código TypeScript en JSON compatible con Terraform y pasarlo al proveedor, que realizará las llamadas API adecuadas para crear la gota en su nombre.
Ahora que comprende qué es un proveedor, puede configurar el proveedor de DigitalOcean para su proyecto CDKTF.
Abre el archivo cdktf.json
y agrega la cadena digitalocean/digitalocean
al arreglo terraformProviders
:
digitalocean/digitalocean
es el identificador del proveedor de DigitalOcean en el Registro de Terraform.
Guarda y cierra el archivo.
A continuación, ejecuta cdktf get
para descargar e instalar el proveedor.
cdktf get
descargará el proveedor, extraerá el esquema, generará las clases TypeScript correspondientes y lo añadirá como un módulo TypeScript bajo .gen/providers/
. Esta generación automática de código te permite utilizar cualquier proveedor de Terraform y módulos HCL con CDKTF, y es cómo CDKTF puede proporcionar completado de código en editores que lo admitan.
Una vez que cdktf get
termine de ejecutarse, verás una salida similar a la siguiente:
OutputGenerated typescript constructs in the output directory: .gen
También verás un nuevo directorio llamado .gen
que contiene el código generado del proveedor.
En este paso, instalaste el proveedor digitalocean/digitalocean
en el proyecto. En el siguiente paso, configurarás el proveedor de DigitalOcean con las credenciales necesarias para autenticar el proveedor con la API de DigitalOcean.
Paso 4 — Configurando el Proveedor de DigitalOcean
En este paso, configurarás el proveedor de DigitalOcean con tu Token de Acceso Personal de DigitalOcean, lo que permite al proveedor llamar a la API de DigitalOcean en tu nombre.
Diferentes proveedores requieren y admiten credenciales diferentes para autenticarse con la API correspondiente. Para el proveedor de DigitalOcean, debes proporcionar tu Token de Acceso Personal de DigitalOcean. Puedes especificar el token al proveedor configurándolo como las variables de entorno DIGITALOCEAN_TOKEN
o DIGITALOCEAN_ACCESS_TOKEN
.
Ejecuta el siguiente comando en tu terminal para establecer la variable de entorno para esa sesión de terminal.
Nota: Al llamar a export
, estás configurando la variable de entorno solo para esa sesión de terminal. Si cierras y vuelves a abrir la terminal o ejecutas los comandos de cdktf
en una terminal diferente, deberás volver a ejecutar el comando export
para que la variable de entorno surta efecto.
A continuación, especificarás el proveedor dentro de la clase MyStack
, lo que te permitirá definir recursos proporcionados por el proveedor dentro de tu pila. Actualiza el archivo main.ts
de la siguiente manera:
El módulo para el proveedor se encuentra en ./.gen/providers/digitalocean
, el cual se generó automáticamente cuando ejecutaste cdktf get
.
Configuraste el proveedor digitalocean/digitalocean
con credenciales en este paso. A continuación, comenzarás a definir la infraestructura que forma parte del objetivo de este tutorial.
Paso 5 — Definición de Aplicaciones Web en Droplets
En este paso, definirás dos servidores NGINX, cada uno sirviendo archivos diferentes, desplegados en dos Droplets Ubuntu 20.04 idénticos.
Comienzas con la definición de los dos Droplets. Modifica main.ts
con los cambios resaltados:
Utilizas un bucle nativo de JavaScript (Array.prototype.map()
) para evitar duplicación en el código.
Al igual que si estuvieras creando el Droplet a través de la consola, hay varios parámetros que especificar:
image
– la distribución de Linux y la versión en la que se ejecutará tu Droplet.region
– el centro de datos en el que se ejecutará el Droplet.size
– la cantidad de recursos de CPU y memoria que reservarás para el Droplet.name
– un nombre único utilizado para referirse al Droplet.
Los valores para imagen
, región
y tamaño
deben ser cosas que DigitalOcean admita. Puede encontrar los valores válidos (llamados slugs) para todas las imágenes de distribución de Linux admitidas, tamaños de Droplet y regiones en la página Slugs de la API de DigitalOcean. Puede encontrar una lista completa de atributos requeridos y opcionales en la página de documentación de digitalocean_droplet
.
Agregando una Clave SSH
Como parte de los requisitos previos, cargó una clave pública SSH sin contraseña en su cuenta de DigitalOcean y anotó su nombre. Ahora usará ese nombre para recuperar el ID de la clave SSH y pasarlo a la definición de su Droplet.
Dado que la clave SSH se agregó manualmente a su cuenta de DigitalOcean, no es un recurso gestionado por su configuración actual de Terraform. Si intentara definir un nuevo recurso digitalocean_ssh_key
, creará una nueva clave SSH en lugar de usar la existente.
En su lugar, definirá un nuevo origen de datos digitalocean_ssh_key
. En Terraform, los origenes de datos se utilizan para recuperar información sobre la infraestructura que no está gestionada por la configuración actual de Terraform. En otras palabras, proporcionan una vista de solo lectura del estado de la infraestructura externa preexistente. Una vez que se define un origen de datos, puede utilizar los datos en otro lugar de su configuración de Terraform.
Todavía en main.ts
y dentro del constructor de MyStack
, defina un nuevo origen de datos DataDigitaloceanSshKey
, y pase el nombre que asignó a su clave SSH (aquí, el nombre es do_cdktf
):
Luego, actualice la definición del Droplet para incluir la clave SSH:
Una vez provisionado, puede acceder al Droplet utilizando una clave SSH privada en lugar de una contraseña.
Especificar el script de datos de usuario para instalar NGINX
Ahora ha definido dos Droplets idénticos que ejecutan Ubuntu, configurados con acceso SSH. La siguiente tarea es instalar NGINX en cada Droplet.
Cuando se crea un Droplet, una herramienta llamada CloudInit iniciará el servidor. CloudInit puede aceptar un archivo llamado datos de usuario, que puede modificar cómo se inicializa el servidor. Los datos de usuario pueden ser cualquier archivo cloud-config
o scripts que el servidor pueda interpretar, como scripts Bash.
En el resto de este paso, creará un script Bash y lo especificará como datos de usuario del Droplet. El script instalará NGINX como parte del proceso de inicialización. Además, el script también reemplazará el contenido del archivo /var/www/html/index.html
(el archivo predeterminado servido por NGINX) con el nombre de host y la dirección IP del Droplet, lo que hará que los dos servidores NGINX sirvan archivos diferentes. En el siguiente paso, colocará ambos servidores NGINX detrás de un balanceador de carga; al servir archivos diferentes, será evidente si el balanceador de carga está distribuyendo correctamente las solicitudes o no.
Todavía en main.ts
, agregue una nueva propiedad userData
al objeto de configuración del Droplet:
Advertencia: Asegúrese de que no haya nuevas líneas antes del shebang (#!
); de lo contrario, es posible que el script no se ejecute.
Cuando se provisiona el Droplet por primera vez, el script se ejecutará como usuario root
. Utilizará el gestor de paquetes de Ubuntu, APT, para instalar el paquete nginx
. Luego, utilizará el Servicio de Metadatos de DigitalOcean para recuperar información sobre sí mismo y escribirá el nombre de host y la dirección IP en index.html
, el cual es servido por NGINX.
En este paso, se definieron dos Droplets que ejecutan Ubuntu, configurando cada uno con acceso SSH e instalando NGINX mediante la función de datos de usuario. En el siguiente paso, se definirá un balanceador de carga que se situará frente a estos servidores NGINX y se configurará para equilibrar la carga de manera circular.
Paso 6 — Definir un Balanceador de Carga
En este paso, se definirá un Balanceador de Carga de DigitalOcean mediante la definición de una instancia del recurso digitalocean_loadbalancer
.
Todavía en main.ts
, añade la siguiente definición para un balanceador de carga al final del constructor de MyStack
:
El argumento forwardingRule
indica al balanceador de carga que escuche las solicitudes HTTP en el puerto 80
y las reenvíe a cada uno de los Droplets en el puerto 80
.
Los dropletIds
especifican los Droplets a los que el balanceador de carga pasará las solicitudes. Toma un número, pero el valor de droplet.id
es una cadena. Por lo tanto, has utilizado la función de Terraform Fn.tonumber
para convertir el valor de la identificación de Droplet de cadena a número.
Nota: Has utilizado la función de Terraform Fn.tonumber
aquí en lugar de parseInt
nativo de JavaScript porque el valor de droplet.id
es desconocido hasta que se provisiona el Droplet. Las funciones de Terraform están diseñadas para operar en valores de tiempo de ejecución desconocidos antes de que Terraform aplique una configuración.
Guarda y cierra el archivo.
Ahora has definido dos Droplets y un balanceador de carga que está delante de ellos. Tu archivo main.ts
debería lucir similar a esto:
En el siguiente paso, utilizarás la herramienta CLI cdktf
para actualizar todo tu proyecto CDKTF.
Paso 7 — Provisionamiento de tu Infraestructura
En este paso, utilizarás la herramienta cdktf
CLI para aprovisionar los Droplets y balanceadores de carga que definiste en los pasos anteriores.
Asegúrate de estar en el directorio infra/
y haber establecido la variable de entorno DIGITALOCEAN_ACCESS_TOKEN
para tu sesión de terminal, luego ejecuta el comando cdktf deploy
:
Deberías ver una salida similar a la siguiente:
Outputinfra Initializing the backend...
infra Initializing provider plugins...
infra - Reusing previous version of digitalocean/digitalocean from the dependency lock file
infra - Using previously-installed digitalocean/digitalocean v2.19.0
infra Terraform has been successfully initialized!
infra Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
infra # digitalocean_droplet.bar (bar) will be created
+ resource "digitalocean_droplet" "bar" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ graceful_shutdown = false
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "bar"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "lon1"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ ssh_keys = [
+ "34377800",
]
+ status = (known after apply)
+ urn = (known after apply)
+ user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1"
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
# digitalocean_droplet.foo (foo) será creado
+ resource "digitalocean_droplet" "foo" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ graceful_shutdown = false
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "foo"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "lon1"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ ssh_keys = [
+ "34377800",
]
+ status = (known after apply)
+ urn = (known after apply)
+ user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1"
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
# digitalocean_loadbalancer.lb (lb) será creado
+ resource "digitalocean_loadbalancer" "lb" {
+ algorithm = "round_robin"
+ disable_lets_encrypt_dns_records = false
+ droplet_ids = (known after apply)
+ enable_backend_keepalive = false
+ enable_proxy_protocol = false
+ id = (known after apply)
+ ip = (known after apply)
+ name = "default"
+ redirect_http_to_https = false
+ region = "lon1"
+ size_unit = (known after apply)
+ status = (known after apply)
+ urn = (known after apply)
+ vpc_uuid = (known after apply)
+ forwarding_rule {
+ certificate_id = (known after apply)
+ certificate_name = (known after apply)
+ entry_port = 80
+ entry_protocol = "http"
+ target_port = 80
+ target_protocol = "http"
+ tls_passthrough = false
}
+ healthcheck {
+ check_interval_seconds = (known after apply)
+ healthy_threshold = (known after apply)
+ path = (known after apply)
+ port = (known after apply)
+ protocol = (known after apply)
+ response_timeout_seconds = (known after apply)
+ unhealthy_threshold = (known after apply)
}
+ sticky_sessions {
+ cookie_name = (known after apply)
+ cookie_ttl_seconds = (known after apply)
+ type = (known after apply)
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: plan
To perform exactly these actions, run the following command to apply:
terraform apply "plan"
Please review the diff output above for infra
❯ Approve Applies the changes outlined in the plan.
Dismiss
Stop
Nota: CDKTF aún está en desarrollo y la salida puede diferir de la que se muestra arriba.
Esta pantalla lista todos los recursos y propiedades que cdktf
planea crear, actualizar y destruir. Algunos valores, como el ID de un Droplet, solo se conocen después de que el recurso se aprovisiona. Para esos, verás (conocido después de aplicar)
como el valor de propiedad en la salida.
Revisa la lista de recursos para asegurarte de que sea lo que esperas. Luego, usa las teclas de flecha para seleccionar la opción Aprobar y presiona ENTER
.
Verás una salida similar a la siguiente:
Outputinfra digitalocean_droplet.foo (foo): Creating...
digitalocean_droplet.bar (bar): Creating...
infra digitalocean_droplet.bar (bar): Still creating... [10s elapsed]
infra digitalocean_droplet.foo (foo): Still creating... [10s elapsed]
1 Stack deploying 0 Stacks done 0 Stacks waiting
Esta salida te indica que cdktf
está comunicándose con la API de DigitalOcean para crear el Droplet. cdktf
está creando los Droplets primero porque el balanceador de carga depende del ID del Droplet, que es desconocido hasta que los Droplets se aprovisionan.
La creación del Droplet generalmente demora menos de un minuto. Una vez que los Droplets se han aprovisionado, cdktf
pasa a crear el balanceador de carga.
Outputinfra digitalocean_droplet.bar (bar): Creation complete after 54s [id=298041598]
infra digitalocean_droplet.foo (foo): Creation complete after 55s [id=298041600]
infra digitalocean_loadbalancer.lb (lb): Creating...
infra digitalocean_loadbalancer.lb (lb): Still creating... [10s elapsed]
El balanceador de carga puede tardar más. Después de que se haya creado el balanceador de carga, verás un resumen que muestra que la pila se ha implementado correctamente.
Outputinfra digitalocean_loadbalancer.lb (lb): Still creating... [1m30s elapsed]
infra digitalocean_loadbalancer.lb (lb): Creation complete after 1m32s [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
No outputs found.
Ahora puedes visitar la consola de DigitalOcean, donde verás un balanceador de carga llamado default
y dos Droplets saludables llamados foo
y bar
, cada uno sirviendo como objetivo para el balanceador de carga.
Puedes comprobar que NGINX está en funcionamiento y sirviendo contenido correctamente visitando la dirección IP de cada Droplet. Deberías ver un texto similar al siguiente:
Droplet: bar, IP Address: droplet_ip
Si no ves esa cadena de texto o el servidor no responde, verifica que los datos de usuario que especificaste sean correctos y que no haya caracteres (incluyendo saltos de línea) antes del shebang (#!
). También puedes hacer SSH en el Droplet usando tu clave privada SSH y revisar los registros de salida generados por CloudInit en /var/log/cloud-init-output.log
:
Una vez que hayas confirmado que los Droplets están activos y sirviendo contenido, puedes comenzar a probar el balanceador de carga. Lo haces enviando algunas solicitudes.
Ejecuta el siguiente comando desde tu terminal para enviar diez solicitudes al balanceador de carga:
Deberías ver una salida similar a la siguiente, aunque las direcciones IP mostradas serán diferentes:
OutputDroplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Muestra que las solicitudes al balanceador de carga fueron reenviadas a cada Droplet cinco veces, lo que indica que el balanceador de carga está funcionando.
Nota: El balanceador de carga no siempre distribuirá equitativamente entre los dos Droplets; es posible que encuentres que cuatro solicitudes fueron enviadas a un Droplet y seis a otro. Este comportamiento es normal.
En este paso, utilizaste cdktf
para aprovisionar tus recursos, y luego utilizaste la consola de DigitalOcean para descubrir las direcciones IP de tus Droplets y balanceador de carga. Luego enviaste solicitudes a cada Droplet y balanceador de carga para confirmar que funcionan.
En el próximo paso, obtendrás las direcciones IP de los Droplets y el balanceador de carga sin iniciar sesión en la consola de DigitalOcean.
Paso 8 — Información de salida
En el paso anterior, tuviste que iniciar sesión en la Consola de DigitalOcean para obtener las direcciones IP de tu Droplet y balanceador de carga. En este paso, modificarás tu código ligeramente para que esta información se imprima en la salida del comando cdktf deploy
, ahorrándote un viaje a la consola.
Terraform registra la configuración y el estado de sus recursos administrados en archivos de estado. Para tu pila infra
, el archivo de estado se puede encontrar en infra/terraform.infra.tfstate
. Podrás encontrar las direcciones IP de los Droplets y el balanceador de carga dentro de este archivo de estado.
Sin embargo, ordenar un archivo grande puede ser inconveniente. CDKTF proporciona el constructor TerraformOutput
, que puedes usar para emitir variables y hacerlas disponibles fuera de la pila. Cualquier salida se imprime en stdout
después de que se ejecute cdktf deploy
. Ejecutar cdktf output
también puede imprimir salidas en cualquier momento.
Nota: Aunque solo utilice salidas para imprimir información en la consola en este tutorial, su verdadero poder proviene de las pilas que utilizan salidas de otras pilas como entrada, una característica conocida como referencias entre pilas.
Actualice el archivo main.ts
para incluir las salidas de las direcciones IP del balanceador de carga y los Droplets:
Guarde y cierre el archivo.
Ejecute cdktf deploy
para actualizar el cambio:
Dentro de la salida, debería ver algo similar a lo siguiente:
Output─────────────────────────────────────────────────────────────────────────────
Changes to Outputs:
+ droplet0IP = "droplet_foo_ip"
+ droplet1IP = "droplet_bar_ip"
+ loadBalancerIP = "load_balancer_ip"
You can apply this plan to save these new output values to the Terraform
state, without changing any real infrastructure.
─────────────────────────────────────────────────────────────────────────────
Esta salida le indica que no se realizarán cambios en la infraestructura, solo lo que se produce como salida de la pila.
Use las teclas de flecha para seleccionar Aprobar, y luego presione ENTER
. Al final de la salida del terminal, debería ver algo similar a:
Outputinfra
droplet0IP = droplet_foo_ip
droplet1IP = droplet_bar_ip
loadBalancerIP = load_balancer_ip
Ahora, cada vez que ejecute cdktf deploy
o cdktf output
, la dirección IP de los Droplets y los balanceadores de carga se imprimirán en la salida del terminal, eliminando la necesidad de acceder a esa información desde la consola de DigitalOcean.
Ahora ha provisionado dos Droplets y un balanceador de carga y ha confirmado que están funcionando. Puede utilizar el proyecto CDKTF que ha desarrollado como base para definir infraestructuras más sofisticadas (puede encontrar una implementación de referencia en do-community / digitalocean-cdktf-typescript
).
Los recursos provisionados en este tutorial incurrirán en un cargo. Si no tienes la intención de utilizar la infraestructura creada, debes destruirla. En el siguiente y último paso, limpiarás el proyecto destruyendo los recursos creados en este tutorial.
Paso 9 — Destruyendo tu Infraestructura
En este paso, eliminarás todos los recursos creados en este tutorial.
Todavía dentro del directorio infra/
, ejecuta cdktf destroy
:
Deberías ver una salida similar a la siguiente:
Outputinfra Initializing the backend...
infra Initializing provider plugins...
infra - Reusing previous version of digitalocean/digitalocean from the dependency lock file
infra - Using previously-installed digitalocean/digitalocean v2.19.0
infra Terraform has been successfully initialized!
infra digitalocean_droplet.bar (bar): Refreshing state... [id=298041598]
digitalocean_droplet.foo (foo): Refreshing state... [id=298041600]
infra digitalocean_loadbalancer.lb (lb): Refreshing state... [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
infra # digitalocean_droplet.bar (bar) will be destroyed
- resource "digitalocean_droplet" "bar" {
- backups = false -> null
- created_at = "2022-05-02T10:04:16Z" -> null
- disk = 25 -> null
- graceful_shutdown = false -> null
- id = "298041598" -> null
- image = "ubuntu-20-04-x64" -> null
- ipv4_address = "droplet_bar_public_ip" -> null
- ipv4_address_private = "droplet_bar_private_ip" -> null
- ipv6 = false -> null
- locked = false -> null
- memory = 1024 -> null
- monitoring = false -> null
- name = "bar" -> null
- price_hourly = 0.00744 -> null
- price_monthly = 5 -> null
- private_networking = true -> null
- region = "lon1" -> null
- resize_disk = true -> null
- size = "s-1vcpu-1gb" -> null
- ssh_keys = [
- "34377800",
] -> null
- status = "active" -> null
- tags = [] -> null
- urn = "do:droplet:298041598" -> null
- user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" -> null
- vcpus = 1 -> null
- volume_ids = [] -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
}
# digitalocean_droplet.foo (foo) será destruido
- resource "digitalocean_droplet" "foo" {
- backups = false -> null
- created_at = "2022-05-02T10:04:16Z" -> null
- disk = 25 -> null
- graceful_shutdown = false -> null
- id = "298041600" -> null
- image = "ubuntu-20-04-x64" -> null
- ipv4_address = "droplet_foo_public_ip" -> null
- ipv4_address_private = "droplet_foo_private_ip" -> null
- ipv6 = false -> null
- locked = false -> null
- memory = 1024 -> null
- monitoring = false -> null
- name = "foo" -> null
- price_hourly = 0.00744 -> null
- price_monthly = 5 -> null
- private_networking = true -> null
- region = "lon1" -> null
- resize_disk = true -> null
- size = "s-1vcpu-1gb" -> null
- ssh_keys = [
- "34377800",
] -> null
- status = "active" -> null
- tags = [] -> null
- urn = "do:droplet:298041600" -> null
- user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" -> null
- vcpus = 1 -> null
- volume_ids = [] -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
}
# digitalocean_loadbalancer.lb (lb) será destruido
- resource "digitalocean_loadbalancer" "lb" {
- algorithm = "round_robin" -> null
- disable_lets_encrypt_dns_records = false -> null
- droplet_ids = [
- 298041598,
- 298041600,
] -> null
- enable_backend_keepalive = false -> null
- enable_proxy_protocol = false -> null
- id = "4f9ae2b7-b649-4fb4-beed-96b95bb72dd1" -> null
- ip = "load_balancer_ip" -> null
- name = "default" -> null
- redirect_http_to_https = false -> null
- region = "lon1" -> null
- size_unit = 1 -> null
- status = "active" -> null
- urn = "do:loadbalancer:4f9ae2b7-b649-4fb4-beed-96b95bb72dd1" -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
- forwarding_rule {
- entry_port = 80 -> null
- entry_protocol = "http" -> nul
infra l
- target_port = 80 -> null
- target_protocol = "http" -> null
- tls_passthrough = false -> null
}
- healthcheck {
- check_interval_seconds = 10 -> null
- healthy_threshold = 5 -> null
- path = "/" -> null
- port = 80 -> null
- protocol = "http" -> null
- response_timeout_seconds = 5 -> null
- unhealthy_threshold = 3 -> null
}
- sticky_sessions {
- cookie_ttl_seconds = 0 -> null
- type = "none" -> null
}
}
Plan: 0 to add, 0 to change, 3 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: plan
To perform exactly these actions, run the following command to apply:
terraform apply "plan"
Please review the diff output above for infra
❯ Approve Applies the changes outlined in the plan.
Dismiss
Stop
Esta vez, en lugar de mostrar +
junto a cada recurso, muestra -
, lo que indica que CDKTF planea destruir el recurso. Revisa los cambios propuestos, luego usa las teclas de flecha para seleccionar Aprobar y presiona ENTER
. El proveedor de DigitalOcean ahora se comunicará con la API de DigitalOcean para destruir los recursos.
Outputinfra digitalocean_loadbalancer.lb (lb): Destroying... [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra digitalocean_loadbalancer.lb (lb): Destruction complete after 1s
infra digitalocean_droplet.bar (bar): Destroying... [id=298041598]
digitalocean_droplet.foo (foo): Destroying... [id=298041600]
El balanceador de carga fue eliminado primero porque no tiene dependencias (ningún otro recurso hace referencia al balanceador de carga en sus entradas). Debido a que los Droplets hacen referencia al balanceador de carga, solo pueden ser destruidos después de que el balanceador de carga sea destruido.
Después de que los recursos hayan sido destruidos, verás la siguiente línea impresa en la salida:
OutputDestroy complete! Resources: 3 destroyed.
Conclusión
En este tutorial, utilizaste CDKTF para aprovisionar y destruir una página web balanceada de carga, que consta de dos Droplets de DigitalOcean ejecutando servidores NGINX, servidos detrás de un balanceador de carga. También generaste información sobre los recursos en la terminal.
CDKTF es una capa de abstracción sobre Terraform. Comprender Terraform es útil para entender CDKTF. Si deseas aprender más sobre Terraform, puedes leer la serie Cómo Administrar Infraestructura con Terraform, que cubre Terraform en profundidad.
También puedes consultar la documentación oficial de CDK para Terraform y los tutoriales para aprender más sobre CDKTF.