[{"content":" Conditional Expressions # En Terraform, las expresiones condicionales se utilizan para evaluar una condición y tomar decisiones basadas en el resultado de esa evaluación. Esto puede ser útil para controlar el comportamiento de recursos y la configuración en función de ciertas condiciones.\nLas expresiones condicionales en Terraform se pueden utilizar en varios contextos, como en el valor de un atributo de un recurso, en un bloque de recurso condicional, en la creación de variables condicionales, entre otros.\nAquí tenemos un ejemplo de cómo usar una expresión condicional en Terraform:\nvariable \u0026#34;enable_s3_bucket\u0026#34; { default = true } resource \u0026#34;aws_s3_bucket\u0026#34; \u0026#34;example\u0026#34; { bucket = var.enable_s3_bucket ? \u0026#34;example-bucket\u0026#34; : null } En este ejemplo, se define una variable enable_s3_bucket que indica si se debe crear un bucket de Amazon S3 o no. Luego, en el recurso aws_s3_bucket, se utiliza una expresión condicional para determinar el valor del atributo bucket. Si enable_s3_bucket es true, se asigna el valor \u0026quot;example-bucket\u0026quot; al atributo bucket, de lo contrario se asigna null.\nLas expresiones condicionales en Terraform siguen la sintaxis condición ? valor_si_verdadero : valor_si_falso. En este caso, condición es una expresión booleana que evalúa si enable_s3_bucket es true. Si la condición es verdadera, se utiliza el valor después del ?, de lo contrario se utiliza el valor después del :.\nLas expresiones condicionales pueden volverse más complejas al combinarlas con otras funciones y operadores lógicos, lo que te permite crear lógica condicional más avanzada en tu código de Terraform.\nHay que recordar que la expresión condicional sigue la siguiente sintaxis: condición ? valor_si_verdadero : valor_si_falso.\nAquí proponemos tener una variable denominada is_test que permitirá crear o bien un recurso para el ambiente de dev en caso de que se encuentre en true, o de lo contrario, crear un recurso para el ambiente de prod.\nPor ejemplo, si nosotros tenemos el siguiente código:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;prod\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.xlarge\u0026#34; tags = { Name = \u0026#34;Prod instance\u0026#34; } } resource \u0026#34;aws_instance\u0026#34; \u0026#34;dev\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;Dev Instance\u0026#34; } } Si nosotros generamos un archivo de configuración con estos dos recursos y corremos terraform plan, esto lo que hará es generar los dos recursos. Lo que nosotros buscamos es que o bien se cree uno o bien se cree el otro, dependiendo del valor de una variable is_test.\nPara esto, en el mismo archivo de configuración creamos una variable denominada is_test. Y luego a cada bloque de instancias le agregamos count = var.is_test? 1 : 0. Hay que recordar que el atributo count permite generar la cantidad de copias del mismo recurso.\nPráctica # Ejemplo nº 1 # Archivos utilizados:\n51_main.tf 52_variables.tf terraform.ftvars Implementación:\n51_main.tf variable \u0026#34;is_test\u0026#34; { type = bool default = true } resource \u0026#34;aws_instance\u0026#34; \u0026#34;prod\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.xlarge\u0026#34; count = var.is_test ? 0 : 1 tags = { Name = \u0026#34;Prod Instance\u0026#34; } } resource \u0026#34;aws_instance\u0026#34; \u0026#34;dev\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; count = var.is_test ? 1 : 0 tags = { Name = \u0026#34;Dev Instance\u0026#34; } } Por lo tanto, la salida del comando terraform plan cuando el valor de la variable is_test es true, será:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;dev\u0026#34; { + ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; + arn = (known after apply) ... + ebs_optimized = (known after apply) + get_password_data = false + host_id = (known after apply) ... + instance_type = \u0026#34;t2.micro\u0026#34; + ipv6_address_count = (known after apply) + ipv6_addresses = (known after apply) ... ... ... } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Dev Instance\u0026#34; } + tenancy = (known after apply) + user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. En cambio, la salida del comando terraform plan cuando el valor de la variable is_test es false, será:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;prod\u0026#34; { + ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; + arn = (known after apply) ... + ebs_optimized = (known after apply) + get_password_data = false ... + instance_state = (known after apply) + instance_type = \u0026#34;t2.xlarge\u0026#34; + ipv6_address_count = (known after apply) ... ... + secondary_private_ips = (known after apply) + security_groups = (known after apply) + source_dest_check = true + spot_instance_request_id = (known after apply) + subnet_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Prod Instance\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Prod Instance\u0026#34; } + tenancy = (known after apply) ... Plan: 1 to add, 0 to change, 0 to destroy. Ejercicio nº 2 # Otra de las cosas que se pueden hacer es ingresar la cantidad de la configuración en 3 para que sea más evidente el cambio:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;dev\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; count = var.is_test ? 3 : 0 tags = { Name = \u0026#34;Dev Instance\u0026#34; } } Y por otro lado, distribuimos la definición y la asignación de la variable is_true a través de las otros archivos. Por lo tanto la salida del comando terraform plan es la siguiente:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;dev\u0026#34; { + ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; .. + disable_api_termination = (known after apply) + ebs_optimized = (known after apply) + get_password_data = false + host_id = (known after apply) .. + instance_type = \u0026#34;t2.micro\u0026#34; .. .. + public_ip = (known after apply) + secondary_private_ips = (known after apply) + security_groups = (known after apply) + source_dest_check = true + spot_instance_request_id = (known after apply) + subnet_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Dev Instance\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Dev Instance\u0026#34; } .. Plan: 3 to add, 0 to change, 0 to destroy. Local Values # En Terraform, un \u0026ldquo;local value\u0026rdquo; es una forma de definir una variable local dentro de un archivo de configuración de Terraform. Estas variables locales se utilizan para calcular valores que pueden ser reutilizados dentro del mismo archivo de configuración, lo que permite simplificar la configuración y mejorar la legibilidad del código.\nLos valores locales se definen utilizando el bloque locals en un archivo de configuración de Terraform. Aquí tienes un ejemplo básico de cómo se define un valor local:\nlocals { instance_count = 3 } En este ejemplo, se define un valor local llamado instance_count con un valor de 3. Una vez definido, este valor local puede ser referenciado en otras partes del archivo de configuración de Terraform utilizando la sintaxis local.nombre_del_valor, donde nombre_del_valor es el nombre del valor local definido.\nPor ejemplo, podrías usar el valor local instance_count en la configuración de un recurso de esta manera:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;example\u0026#34; { count = local.instance_count # Otras configuraciones... } En este caso, el valor de count para el recurso aws_instance se establecerá en el valor de instance_count definido como variable local.\nLos valores locales pueden contener expresiones más complejas, incluidas referencias a otras variables y funciones de Terraform. Esto permite calcular valores basados en lógica más avanzada dentro de tu configuración de Terraform.\nLos valores locales en Terraform son una forma conveniente de definir y reutilizar valores calculados dentro de un archivo de configuración, lo que puede ayudar a hacer que tu código sea más modular y fácil de mantener.\nEn este caso por ejemplo, lo que utilizamos es el atributo tags que siempre es común a muchos recursos de AWS. Por lo tanto, para no tener que repetir código, se puede definir una variable local y poder de esta manera hacer más legible el código.\nPráctica # Ejemplo nº 1 # Archivos:\n52_main.tf 52_variables.tf terraform.ftvars Implementación:\n52_main.tf resource \u0026#34;aws_instance\u0026#34; \u0026#34;dev\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = local.common_tags count = var.is_test ? 3 : 0 } resource \u0026#34;aws_instance\u0026#34; \u0026#34;prod\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.xlarge\u0026#34; tags = local.common_tags count = var.is_test ? 0 : 1 } 52_variables.tf variable \u0026#34;is_test\u0026#34; { type = bool default = true } locals { common_tags = { Owner = \u0026#34;Devops Teams\u0026#34; service = \u0026#34;Backend\u0026#34; } } terraform.ftvars is_test = true Por lo tanto, la salida del comando terraform plan será:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;dev\u0026#34; { + ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; ... + ebs_optimized = (known after apply) + get_password_data = false ... + instance_type = \u0026#34;t2.micro\u0026#34; ... + placement_partition_number = (known after apply) ... + source_dest_check = true + spot_instance_request_id = (known after apply) + subnet_id = (known after apply) + tags = { + \u0026#34;Owner\u0026#34; = \u0026#34;Devops Teams\u0026#34; + \u0026#34;service\u0026#34; = \u0026#34;Backend\u0026#34; } + tags_all = { + \u0026#34;Owner\u0026#34; = \u0026#34;Devops Teams\u0026#34; + \u0026#34;service\u0026#34; = \u0026#34;Backend\u0026#34; } + tenancy = (known after apply) + user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = (known after apply) } Plan: 3 to add, 0 to change, 0 to destroy. Por lo tanto, vemos que genera 3 instancias porque la variable is_test se encuentra en true y además podemos observar que los tags se generan de forma correcta con los dos valores ingresados de forma local.\nAlgunos puntos importantes # También esta nomenclatura permite un abanico de oportunidades como se puede ver en la filmina, donde se permite establecer un nombre según si viene definido o no en la variable var.name y esto se puede agregar en cada una de las instancias y por lo tanto se tiene repetido el mismo comportamiento en todas los recursos que iremos a construir.\nlocals { environment = \u0026#34;production\u0026#34; instance_type = local.environment == \u0026#34;production\u0026#34; ? \u0026#34;t2.large\u0026#34; : \u0026#34;t2.micro\u0026#34; } En este ejemplo, se define un valor local llamado instance_type que se utiliza para especificar el tipo de instancia de AWS EC2 que se utilizará. La expresión condicional local.environment == \u0026quot;production\u0026quot; ? \u0026quot;t2.large\u0026quot; : \u0026quot;t2.micro\u0026quot; evalúa si la variable local environment es igual a \u0026quot;production\u0026quot;. Si es verdadero, asignará \u0026quot;t2.large\u0026quot; a instance_type; de lo contrario, asignará \u0026quot;t2.micro\u0026quot;.\nEste ejemplo ilustra cómo podemos usar una expresión condicional dentro de un valor local para asignar diferentes valores basados en una condición dada. Esto puede ser útil cuando necesitas configuraciones diferentes según el entorno, como producción o desarrollo.\nHay varias situaciones comunes en las que se pueden utilizar los valores locales en Terraform:\nReutilización de valores calculados: Cuando necesitas calcular un valor basado en una expresión compleja o una combinación de otras variables y quieres reutilizar este valor en múltiples lugares dentro de tu configuración.\nParametrización de configuraciones repetitivas: Cuando tienes configuraciones repetitivas que podrían necesitar cambios en el futuro y prefieres definir estos valores una sola vez como valores locales para facilitar su mantenimiento y actualización.\nDefinición de constantes: Cuando tienes valores que son constantes dentro de tu configuración y prefieres definirlos una vez como valores locales en lugar de repetirlos en varios lugares.\nAumentar la legibilidad del código: Cuando quieres hacer que tu código sea más legible y comprensible al asignar nombres significativos a valores calculados o constantes.\nSimplificación de lógica condicional: Cuando necesitas simplificar la lógica condicional dentro de tu configuración al calcular valores intermedios que se utilizan en múltiples lugares.\nFacilitar la modularidad: Cuando estás construyendo módulos reutilizables y quieres permitir que los usuarios de esos módulos personalicen ciertos valores sin tener que modificar directamente la lógica del módulo.\nCálculos de valores predeterminados: Cuando deseas establecer valores predeterminados para configuraciones que pueden ser sobrescritos por el usuario, pero también necesitas calcular valores predeterminados basados en otras variables.\nLos valores locales son una herramienta versátil en Terraform que pueden ser utilizados en una variedad de situaciones para simplificar y mejorar la configuración de la infraestructura. Su uso puede ayudar a hacer que el código sea más modular, fácil de mantener y comprensible.\nOtro ejemplo (de ChatGPT) # En Terraform, puedes usar valores locales para definir expresiones y lógica que se reutilizan en tu configuración. Un valor local puede incluir expresiones condicionales (condition ? true_value : false_value) para decidir qué valor asignar en función de una condición.\nSupongamos que quieres definir el tipo de instancia de AWS en función del entorno (producción o desarrollo).\n# Definición de la variable environment variable \u0026#34;environment\u0026#34; { type = string default = \u0026#34;development\u0026#34; } # Definición de variables de AMI para cada entorno variable \u0026#34;ami_production\u0026#34; { type = string default = \u0026#34;ami-prod-12345678\u0026#34; } variable \u0026#34;ami_development\u0026#34; { type = string default = \u0026#34;ami-dev-87654321\u0026#34; } # Definición de valores locales locals { instance_type = var.environment == \u0026#34;production\u0026#34; ? \u0026#34;t2.large\u0026#34; : \u0026#34;t2.micro\u0026#34; ami_id = var.environment == \u0026#34;production\u0026#34; ? var.ami_production : var.ami_development } # Recurso de instancia AWS resource \u0026#34;aws_instance\u0026#34; \u0026#34;example\u0026#34; { ami = local.ami_id instance_type = local.instance_type tags = { Name = \u0026#34;example-instance\u0026#34; Environment = var.environment } } Explicación:\nDefinición de la variable environment: Define la variable environment de tipo string, con el valor por defecto development. Definición de las variables ami_production y ami_development: Estas variables contienen las IDs de las AMIs para producción y desarrollo, respectivamente. Definición de valores locales: instance_type: Utiliza una expresión condicional para establecer el tipo de instancia en función del entorno. Si el entorno es production, el tipo de instancia será t2.large, de lo contrario será t2.micro. ami_id: Similarmente, selecciona la AMI adecuada en función del entorno. Uso de valores locales en el recurso aws_instance: El recurso aws_instance utiliza los valores locales local.ami_id y local.instance_type para configurar la instancia de AWS. Este ejemplo muestra cómo usar valores locales y expresiones condicionales para ajustar configuraciones dinámicamente en Terraform según el entorno u otras condiciones.\nTerraform Functions # Lista de funciones # Para ver todo el listado de funciones built-in que contiene Terraform, podemos remontarnos a la siguiente página\nTerraform categoriza cada una de las funciones según su finalidad. Eso lo podemos observar en el menú izquierdo de la pantalla. Debemos recordar que Terraform NO SOPORTA funciones generadas por el usuario.\nDefinición de Funciones en Terraform # En Terraform, las funciones son herramientas que permiten realizar manipulaciones y operaciones en los datos dentro de tus archivos de configuración. Estas funciones proporcionan una forma poderosa de realizar transformaciones, cálculos y manipulaciones en los valores de tus recursos, variables y otros elementos dentro de tu configuración.\nLas funciones en Terraform se utilizan principalmente para:\nManipulación de cadenas: Terraform proporciona varias funciones para trabajar con cadenas, como concatenación, conversión de mayúsculas/minúsculas, división y reemplazo de cadenas. Operaciones numéricas: Puedes realizar operaciones matemáticas simples como suma, resta, multiplicación y división utilizando funciones. Trabajo con listas y mapas: Terraform ofrece funciones para trabajar con listas y mapas, como agregar elementos, eliminar elementos, filtrar elementos, etc. Generación de valores dinámicos: Puedes utilizar funciones para generar valores dinámicos basados en condiciones o en otros datos dentro de tu configuración. Validación y manipulación de datos: Las funciones pueden ayudarte a validar y limpiar datos antes de utilizarlos en tus recursos. Manipulación de fechas y horas: Terraform proporciona funciones para trabajar con fechas y horas, como obtener la fecha actual, convertir formatos de fecha, agregar o restar tiempo, etc. Por ejemplo, aquí hay un uso básico de una función en Terraform que concatena dos cadenas:\nresource \u0026#34;aws_s3_bucket\u0026#34; \u0026#34;example\u0026#34; { bucket = \u0026#34;example-${lower(var.environment)}\u0026#34; } En este caso, la función lower() se utiliza para convertir el valor de la variable environment a minúsculas antes de concatenarlo con la cadena \u0026quot;example-\u0026quot;.\nLas funciones en Terraform te permiten realizar una amplia variedad de manipulaciones y cálculos en tus datos, lo que te ayuda a crear configuraciones más dinámicas y flexibles. Puedes encontrar una lista completa de funciones disponibles en la documentación oficial de Terraform.\nEs importante notar que Terraform no soporta funciones generadas por el usuario. Sin embargo, existen funciones generadas dentro de Terraform para dar soporte a múltiples escenarios y están divididos (como se puede ver en la filmina) en varios tipos.\nEn la documentación de Terraform podremos ver cada una de las funciones (en el menú de la izquierda) dependiendo de su utilidad.\nComando: terraform console # Para poder consultar el funcionamiento de las funciones built-in de Terraform, tenemos la posibilidad de invocar al comando terraform console.\nEl comando terraform console es una herramienta interactiva que te permite evaluar expresiones y funciones de Terraform en tiempo real dentro de una consola interactiva. Esto te permite probar y experimentar con código Terraform sin necesidad de aplicar los cambios a tu infraestructura.\nCuando ejecutas el comando terraform console, Terraform inicia una sesión interactiva donde puedes ingresar y evaluar expresiones de Terraform. Por ejemplo, puedes realizar cálculos simples, manipulaciones de cadenas, operaciones matemáticas, y mucho más.\nPor ejemplo, podrías ejecutar el siguiente comando:\nterraform console Una vez que ingreses a la consola interactiva, podrías ingresar expresiones como estas:\n\u0026gt; \u0026#34;Hello, \u0026#34; + \u0026#34;World!\u0026#34; El cual te daría como resultado:\n\u0026#34;Hello, World!\u0026#34; Otras operaciones más complejas también son posibles, por ejemplo:\n\u0026gt; upper(\u0026#34;hello\u0026#34;) Dará como resultado:\n\u0026#34;HELLO\u0026#34; Esta herramienta es útil para probar rápidamente cómo se comportan las expresiones y las funciones de Terraform antes de integrarlas en tus archivos de configuración. Además, puede ser útil para depurar y comprender mejor cómo funcionan ciertas funciones o expresiones en Terraform. Sin embargo, hay que tener en cuenta que terraform console no tiene acceso a ningún estado de Terraform o recursos reales, por lo que algunas operaciones que dependen del estado de la infraestructura real no serán posibles de evaluar.\nPráctica nº 1 # La idea es ver cómo funcionan cada una de las funciones. En el código escrito, se podrán ver algunas de las funciones utilizadas, tales como: lookup().\nArchivos:\n53_main.tf\n53_variables.tf\nterraform.ftvars\n53_main.tf\n# A simple instance in EC2 resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { ami = lookup(var.zones, var.region, \u0026#34;us-east-2b\u0026#34;) instance_type = var.instance_type count = 1 tags = local.common_tags } 53_variables.tf variable \u0026#34;region\u0026#34; { type = string default = \u0026#34;us-east-3c\u0026#34; } variable \u0026#34;zones\u0026#34; { type = map default = { us-east-1a = \u0026#34;ami-051f8a213df8bc090\u0026#34; us-east-2b = \u0026#34;ami-052f8a213df8bc091\u0026#34; us-east-3c = \u0026#34;ami-051f8a213df8bc092\u0026#34; us-east-4d = \u0026#34;ami-051f8a213df8bc093\u0026#34; } } variable \u0026#34;instance_type\u0026#34; { type = string default = \u0026#34;t2.micro\u0026#34; } locals { common_tags = { Name = \u0026#34;Terraform\u0026#34; Owner = \u0026#34;DevOps Team\u0026#34; } } Como podemos ver, la función empleada en este caso es: lookup(var.zones, var.region, \u0026ldquo;us-east-2b\u0026rdquo;), la cual permite evaluar en una variable de tipo denominada var.zones el valor de otra variable denominada var.region. En caso de no encontrarse este valor, por defecto buscará el valor us-east-2b, por lo tanto tenemos que estar asegurados de que este valor exista en la variable de tipo map.\nPráctica nº 2 # 53_main.tf resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { ami = lookup(var.zones, var.region, \u0026#34;us-east-2b\u0026#34;) instance_type = var.instance_type count = 2 tags = { Name = element(var.tags_list, count.index) } } 53_variables.tf # ... variable \u0026#34;tags_list\u0026#34; { type = list default = [\u0026#34;Terraform-Dev\u0026#34;, \u0026#34;Terraform-Prod\u0026#34;] } En este ejemplo lo que podemos ver es que podemos utilizar la función element() para poder recorrer una lista según un índice de count.index . Esto nos permite utilizar varios nombres según lo que se encuentre dentro de la lista tags_list.\nRecordar que para probar todas estas funciones tenemos dos recursos disponibles:\nLa documentación oficial de Terraform. La consola propia de Terraform que se invoca desde terraform console. # aws_instance.terraformEC2[0] will be created + resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { + ami = \u0026#34;ami-051f8a213df8bc092\u0026#34; ... + ebs_optimized = (known after apply) + get_password_data = false ... + instance_type = \u0026#34;t2.micro\u0026#34; ... + placement_partition_number = (known after apply) ... + source_dest_check = true + spot_instance_request_id = (known after apply) + subnet_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-Dev\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-Dev\u0026#34; } + tenancy = (known after apply) + user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = (known after apply) } # aws_instance.terraformEC2[1] will be created + resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { + ami = \u0026#34;ami-051f8a213df8bc092\u0026#34; ... + ebs_optimized = (known after apply) + get_password_data = false ... + instance_type = \u0026#34;t2.micro\u0026#34; + ipv6_address_count = (known after apply) ... ... + source_dest_check = true + spot_instance_request_id = (known after apply) + subnet_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-Prod\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-Prod\u0026#34; } + tenancy = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = (known after apply) } Podemos ver que ambos tags han sido tomados con éxito.\nPráctica nº 3 # Lo que podemos hacer a continuación es generar una variable para que se imprima en la salida de tipo output. El problema aquí es que para que la variable se imprima deberemos de haber ejecutado el comando terraform apply. El problema de esto es que la clave id_rsa.pub es un número generado al azar y por lo tanto se va a terminar de impactar en el proveedor de manera incorrecta.\n1 53_main.tf\noutput \u0026#34;time_exec\u0026#34; { value = local.timestamp } 53_variables.tf # ... locals { common_tags = { Name = \u0026#34;Terraform\u0026#34; Owner = \u0026#34;DevOps Team\u0026#34; } timestamp = { time = formatdate(\u0026#34;DD MM YYY hh:mm\u0026#34;, timestamp()) } } Continuará # ¡Hola! ¿cómo están? Espero que muy bien. En las próximas clases empezaremos a ver los denominados Data Sources, cómo utilizarlos, algunos ejemplos y sus casos de uso.\nEspero que tengan un feliz comienzo de año 2026.\n","date":"4 enero 2026","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part9/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003eConditional Expressions\n    \u003cdiv id=\"conditional-expressions\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#conditional-expressions\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\u003cp\u003eEn Terraform, las expresiones condicionales se utilizan para evaluar una condición y tomar decisiones basadas en el resultado de esa evaluación. Esto\npuede ser útil para controlar el comportamiento de recursos y la configuración en función de ciertas condiciones.\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 9","type":"publicaciones"},{"content":"","date":"4 enero 2026","externalUrl":null,"permalink":"/publicaciones/terraform/","section":"Publicaciones","summary":"","title":"Artículos de Terraform","type":"publicaciones"},{"content":"","date":"4 enero 2026","externalUrl":null,"permalink":"/series/curso-terraform/","section":"Series","summary":"","title":"Curso Terraform","type":"series"},{"content":"","date":"4 enero 2026","externalUrl":null,"permalink":"/publicaciones/","section":"Publicaciones","summary":"","title":"Publicaciones","type":"publicaciones"},{"content":"","date":"4 enero 2026","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","date":"4 enero 2026","externalUrl":null,"permalink":"/","section":"Universo 25","summary":"","title":"Universo 25","type":"page"},{"content":" Obteniendo datos de Maps y List en variables # Lo que se abordará en esta lección es cómo relacionar las variables con los valores de un tipo list o de un tipo map. Por ejemplo, un tipo list es la siguiente variable:\nelb_az = [\u0026#34;us-west-2a\u0026#34;, \u0026#34;us-west-2b\u0026#34;, \u0026#34;us-west-2c\u0026#34;] Ejemplos # Ejemplo: Map type # Por ejemplo, si nosotros tenemos la siguiente definición de variables:\nvariable \u0026#34;list\u0026#34; { type = list default = [\u0026#34;m5.large\u0026#34;, \u0026#34;m5.xlarge\u0026#34;, \u0026#34;t2.medium\u0026#34;] } variable \u0026#34;types\u0026#34; { type = map default = { us-east-1 = \u0026#34;t2.micro\u0026#34; us-west-2 = \u0026#34;t2.nano\u0026#34; us-south-3 = \u0026#34;t2.small\u0026#34; } } Y luego la siguiente configuración:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;myEC2\u0026#34; { ami = \u0026#34;ami-120384135345sf\u0026#34; instance_type = var.types[\u0026#34;us-west-2\u0026#34;] } Esto dará como resultado t2.nano, pero porque es un tipo map. Invocamos terraform plan:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;myEC2\u0026#34; { + ami = \u0026#34;ami-120384135345sf\u0026#34; + arn = (known after apply) ... + ebs_optimized = (known after apply) + get_password_data = false + host_id = (known after apply) ... + instance_state = (known after apply) + instance_type = \u0026#34;t2.nano\u0026#34; + ipv6_address_count = (known after apply) Ejemplo: List type # Ahora, por ejemplo, si nosotros tenemos lo mismo:\nvariable \u0026#34;list\u0026#34; { type = list default = [\u0026#34;m5.large\u0026#34;, \u0026#34;m5.xlarge\u0026#34;, \u0026#34;t2.medium\u0026#34;] } variable \u0026#34;types\u0026#34; { type = map default = { us-east-1 = \u0026#34;t2.micro\u0026#34; us-west-2 = \u0026#34;t2.nano\u0026#34; us-south-3 = \u0026#34;t2.small\u0026#34; } } Pero ingresamos lo siguiente:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;myEC2\u0026#34; { ami = \u0026#34;ami-120384135345sf\u0026#34; instance_type = var.list[2] } Esto dará como resultado t2.medium, pero porque es un tipo list. Invocamos terraform plan:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;myEC2\u0026#34; { + ami = \u0026#34;ami-120384135345sf\u0026#34; + arn = (known after apply) ... + instance_lifecycle = (known after apply) + instance_state = (known after apply) + instance_type = \u0026#34;t2.medium\u0026#34; + ipv6_address_count = (known after apply) + ipv6_addresses = (known after apply) + key_name = (known after apply) + monitoring = (known after ap Ejemplo: List type # Ahora, por ejemplo, si nosotros tenemos lo mismo:\nvariable \u0026#34;list\u0026#34; { type = list default = [\u0026#34;m5.large\u0026#34;, \u0026#34;m5.xlarge\u0026#34;, \u0026#34;t2.medium\u0026#34;] } variable \u0026#34;types\u0026#34; { type = map default = { us-east-1 = \u0026#34;t2.micro\u0026#34; us-west-2 = \u0026#34;t2.nano\u0026#34; us-south-3 = \u0026#34;t2.small\u0026#34; } } Pero ingresamos lo siguiente:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;myEC2\u0026#34; { ami = \u0026#34;ami-120384135345sf\u0026#34; instance_type = var.list[1] } Esto dará como resultado m5.xlarge, pero porque es un tipo list. Invocamos terraform plan:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;myEC2\u0026#34; { + ami = \u0026#34;ami-120384135345sf\u0026#34; + arn = (known after apply) ... + instance_state = (known after apply) + instance_type = \u0026#34;m5.xlarge\u0026#34; + ipv6_address_count = (known after apply) + ipv6_addresses = (known after apply) + key_name = (known after apply) Count and Count Index # En Terraform, un count parameter es un atributo que se utiliza para crear múltiples instancias de un recurso de manera dinámica basándose en un valor numérico especificado. Este parámetro se utiliza principalmente en recursos que pueden repetirse varias veces con configuraciones similares, como instancias de máquinas virtuales, subredes, grupos de seguridad, etc.\nCuando se utiliza el parámetro count se especifica un número entero que indica cuántas veces se debe crear el recurso. Terraform generará automáticamente tantas instancias del recurso como se especifique en el parámetro \u0026ldquo;count\u0026rdquo;, y cada instancia se numerará de manera incremental. Esto permite definir múltiples instancias del mismo recurso con una sola declaración en el código.\nPor ejemplo, supongamos que deseas crear tres instancias de máquinas virtuales en un proveedor de nube. Puedes usar el parámetro \u0026ldquo;count\u0026rdquo; para lograr esto de la siguiente manera:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;example\u0026#34; { count = 3 ami = \u0026#34;ami-12345678\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; } En este caso, Terraform creará tres instancias de máquinas virtuales utilizando la misma AMI y tipo de instancia, pero cada una tendrá un nombre único generado automáticamente (por ejemplo, aws_instance.example[0], aws_instance.example[1], aws_instance.example[2]).\nEl uso del parámetro \u0026ldquo;count\u0026rdquo; puede simplificar la gestión de recursos repetitivos y evitar la necesidad de repetir bloques de código idénticos, lo que hace que la infraestructura sea más fácil de mantener y escalar.\nEste tipo de parámetro se utiliza para no repetir dos veces el mismo código ya que de lo contrario, entorpece la lectura.\nEjemplos # Archivos:\n50_main.tf\n50_variables.tf\nterraform.ftvars -\u0026gt; este archivo estará vacío\n50_main.tf\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { ami = var.instance_ami instance_type = var.instance_type count = 3 tags = { Name = \u0026#34;Terraform EC2\u0026#34; } } Con esta configuración, terraform debería de crearnos 3 tipos de instancias. Si invocamos terraform plan veremos que nos lista 3 instancias y luego la cantidad de recursos a crear:\n# aws_instance.terraformEC2[0] will be created # ... # aws_instance.terraformEC2[1] will be created # ... # aws_instance.terraformEC2[2] will be created # ... Plan: 3 to add, 0 to change, 0 to destroy. Save name resources # El problema con el que nos enfrentamos es el nombre de los recursos que creamos al emplear el parámetro count. Estos nombres, como se puede visualizar en la salida del comando terraform plan anterior, se puede observar que se crean y se guardan en una lista que será el nombre local con el que generamos el recurso en nuestro archivo de configuración.\nEn nuestro caso sería algo así como aws_instance.terraformEC2[i] siendo i un iterador menor al número de instancias creadas (en nuestro caso 3).\nEjemplo 2 # Lo que haremos ahora es generar dos entradas nuevas a los archivos creados:\nresource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { name = var.iam_user_name path = var.iam_user_path count = 2 tags = { Name = \u0026#34;Terraform IAM User\u0026#34; } } variable \u0026#34;iam_user_name\u0026#34; { type = string default = \u0026#34;Emiliano\u0026#34; } variable \u0026#34;iam_user_path\u0026#34; { type = string default = \u0026#34;~/.config/system\u0026#34; } Luego invocamos el comando terraform plan:\n# aws_iam_user.iamUser[0] will be created + resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { + arn = (known after apply) + force_destroy = false + id = (known after apply) + name = \u0026#34;Emiliano\u0026#34; + path = \u0026#34;~/.config/system\u0026#34; + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + unique_id = (known after apply) } # aws_iam_user.iamUser[1] will be created + resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { + arn = (known after apply) + force_destroy = false + id = (known after apply) + name = \u0026#34;Emiliano\u0026#34; + path = \u0026#34;~/.config/system\u0026#34; + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + unique_id = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. Problema con Ejemplo 2 # Como podemos observar, se crean dos recursos y los nombres se encontrarían dentro de la lista aws_iam_user.iamUser[]. Pero el problema es que el nombre será el mismo para los 2 recursos creados. Cada recurso se puede distinguir internamente mediante su ARN, por lo tanto no hace falta que se distinga del nombre proporcionado por var.iam_user_name.\nEjemplo 3 # Pero si nosotros queremos identificarlo de manera que a nuestros ojos podamos distinguirlos, lo que podemos hacer es lo siguiente:\n# Diferent names in all the IAM users created resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { name = \u0026#34;User_n${count.index}\u0026#34; path = var.iam_user_path count = 2 tags = { Name = \u0026#34;Terraform IAM User\u0026#34; } } variable \u0026#34;iam_user_name\u0026#34; { type = string default = \u0026#34;Emiliano\u0026#34; } variable \u0026#34;iam_user_path\u0026#34; { type = string default = \u0026#34;~/.config/system\u0026#34; } De esta manera mediante ${count.index} es posible que por cada iteración que se haga en los usuarios generados, se creen nuevos nombres. Por lo tanto, la salida del comando terraform plan es la siguiente:\n# aws_iam_user.iamUser[0] will be created + resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { + arn = (known after apply) + force_destroy = false + id = (known after apply) + name = \u0026#34;User_n0\u0026#34; + path = \u0026#34;~/.config/system\u0026#34; + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + unique_id = (known after apply) } # aws_iam_user.iamUser[1] will be created + resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { + arn = (known after apply) + force_destroy = false + id = (known after apply) + name = \u0026#34;User_n1\u0026#34; + path = \u0026#34;~/.config/system\u0026#34; + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + unique_id = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. Podemos ver que el nombre de cada uno de los usuarios de IAM serán los siguientes:\n+ name = \u0026#34;User_n0\u0026#34; + name = \u0026#34;User_n1\u0026#34; Lo que se tiene que tener en cuenta que ${count.index} se podrá utilizar en un mismo bloque donde se tiene definido el count .\nProblema con Ejemplo 3 # El problema que se tiene utilizando nombres como User_n0 o User_n1 es que no hacen referencia a nada. Es muy difícil saber en ambientes u organizaciones grandes, a qué hace referencia cada uno de estos usuarios. Por lo tanto, hay una manera mucho más aceptable de identificar los nombres de los recursos gestionados y es mediante la utilización del tipo list\nEjemplo 4 # Sería mucho mejor utilizar una lista de nombres para que de esta forma podamos identificar mucho mejor los recursos que generaremos, por lo tanto podríamos gestionar una variable con los siguientes nombres:\nresource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { name = var.iam_user_name[count.index] path = var.iam_user_path count = 4 tags = { Name = \u0026#34;Terraform IAM User\u0026#34; } } variable \u0026#34;iam_user_name\u0026#34; { type = list default = [\u0026#34;dev.iam.user\u0026#34;, \u0026#34;qa.iam.user\u0026#34;, \u0026#34;stage.iam.user\u0026#34;, \u0026#34;prod.iam.user\u0026#34;] } Luego de utilizar terraform plan, obtenemos:\n# aws_iam_user.iamUser[0] will be created + resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { + arn = (known after apply) + force_destroy = false + id = (known after apply) + name = \u0026#34;dev.iam.user\u0026#34; + path = \u0026#34;~/.config/system\u0026#34; + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + unique_id = (known after apply) } # aws_iam_user.iamUser[1] will be created + resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { + arn = (known after apply) + force_destroy = false + id = (known after apply) + name = \u0026#34;qa.iam.user\u0026#34; + path = \u0026#34;~/.config/system\u0026#34; + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + unique_id = (known after apply) } # aws_iam_user.iamUser[2] will be created + resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { + arn = (known after apply) + force_destroy = false + id = (known after apply) + name = \u0026#34;stage.iam.user\u0026#34; + path = \u0026#34;~/.config/system\u0026#34; + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + unique_id = (known after apply) } # aws_iam_user.iamUser[3] will be created + resource \u0026#34;aws_iam_user\u0026#34; \u0026#34;iamUser\u0026#34; { + arn = (known after apply) + force_destroy = false + id = (known after apply) + name = \u0026#34;prod.iam.user\u0026#34; + path = \u0026#34;~/.config/system\u0026#34; + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform IAM User\u0026#34; } + unique_id = (known after apply) } Plan: 4 to add, 0 to change, 0 to destroy. Continuará\u0026hellip; # En las siguientes secciones aprenderemos a utilizar Expresiones condicionales para poder hacer que nuestro código sea mucho más dinámico según determinadas condiciones.\nComo dije anteriormente, no estoy subiendo muy seguido este tipo de cursos porque mi gata se me está muriendo. Tengo cursos de Docker, Kubernetes, AWS, Python y varias herramientas más pero realmente la pérdida de mi gata, no me dan ganas de hacer absolutamente nada.\n¡Saludos!\n","date":"26 diciembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part8/","section":"Publicaciones","summary":"\u003ch2 class=\"relative group\"\u003eObteniendo datos de Maps y List en variables\n    \u003cdiv id=\"obteniendo-datos-de-maps-y-list-en-variables\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#obteniendo-datos-de-maps-y-list-en-variables\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003eLo que se abordará en esta lección es cómo relacionar las variables con los valores de un tipo \u003ccode\u003elist\u003c/code\u003e o de un tipo \u003ccode\u003emap\u003c/code\u003e. Por ejemplo, un tipo \u003ccode\u003elist\u003c/code\u003e es la siguiente variable:\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 8","type":"publicaciones"},{"content":" Data Type - List # ¿Qué es el tipo de dato List? # En Terraform, el tipo de dato list es una colección ordenada de valores. Los elementos en una lista pueden ser de cualquier tipo de dato, como números, cadenas, mapas u otros. Las listas se definen utilizando corchetes ([]), y los elementos se separan con comas.\nvariable \u0026#34;example_list\u0026#34; { type = list(string) default = [\u0026#34;value1\u0026#34;, \u0026#34;value2\u0026#34;, \u0026#34;value3\u0026#34;] } resource \u0026#34;aws_instance\u0026#34; \u0026#34;example\u0026#34; { count = length(var.example_list) ami = \u0026#34;ami-12345678\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = var.example_list[count.index] } } En este ejemplo, se define una variable example_list que es una lista de cadenas. Luego, se utiliza esta lista para crear múltiples instancias de AWS EC2. La propiedad count en el recurso aws_instance se establece en el número de elementos de la lista, y cada instancia se etiqueta con uno de los valores de la lista.\nEjemplo nº 1 # NOTA: Los archivos son meramente ejemplos, es simplemente para ejemplificar lo que se viene hablando de tipos de datos.\n48_main.tf resource \u0026#34;aws_instance\u0026#34; \u0026#34;AWSInstance\u0026#34; { ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; vpc_security_group_ids = var.instance.vpc tags = { Name = var.instance_name } } 48_variables.tf variable \u0026#34;instance_name\u0026#34; { type = number } variable \u0026#34;instance_vpc\u0026#34; { type = list } terraform.tfvars instance_name = \u0026#34;AWSDevInstance\u0026#34; instance.vpc = \u0026#34;value1\u0026#34; Esto causará un error, porque el tipo que pide la variable vpc_security_group_ids es del tipo list, y como se puede observar, el valor que le damos en el archivo terraform.tfvars es de tipo string. Por lo tanto, para convertirla en lista, deberíamos de utilizar la siguiente nomenclatura:\ninstance.vpc = [\u0026quot;value1\u0026quot;] Ejemplo nº 2 # NOTA: Los archivos son meramente ejemplos, es simplemente para ejemplificar lo que se viene hablando de tipos de datos.\n48_main.tf resource \u0026#34;aws_instance\u0026#34; \u0026#34;AWSInstance\u0026#34; { ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; vpc_security_group_ids = var.instance.vpc tags = { Name = var.instance_name } } 48_variables.tf variable \u0026#34;instance_name\u0026#34; { type = number } variable \u0026#34;instance_vpc\u0026#34; { type = list } terraform.tfvars instance_name = [\u0026#34;emiliano\u0026#34;] En este caso, si nosotros ingresamos terraform plan podremos ver que efectivamente terraform nos permite actuar o realizar este plan porque la nomenclatura utilizada en el archivo terraform.tfvarses la de una lista con un sólo elemento.\nEjemplo nº 3 # 48_main.tf resource \u0026#34;aws_instance\u0026#34; \u0026#34;AWSInstance\u0026#34; { ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; vpc_security_group_ids = var.instance.vpc tags = { Name = var.instance_name } } 48_variables.tf variable \u0026#34;instance_name\u0026#34; { type = number } variable \u0026#34;instance_vpc\u0026#34; { type = list } terraform.tfvars instance_name = [\u0026#34;emiliano\u0026#34;, \u0026#34;ejemplo 1\u0026#34;, \u0026#34;ejemplo 2\u0026#34;] En este caso, si utilizamos el comando terraform.tfvars también vamos a poder ver que el comando terraform plan es aceptado ya que se le ingresa una lista.\nEjemplo nº 4 # 48_main.tf resource \u0026#34;aws_instance\u0026#34; \u0026#34;AWSInstance\u0026#34; { ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; vpc_security_group_ids = var.instance.vpc tags = { Name = var.instance_name } } 48_variables.tf variable \u0026#34;instance_name\u0026#34; { type = number } variable \u0026#34;instance_vpc\u0026#34; { type = list(number) } terraform.tfvars instance_name = [5,8] Podemos ver que también se puede configurar que una lista sólo acepte ciertos tipos de valores, como por ejemplo una lista de números; para esto, debemos de configurar esto en la definición del tipo de la variable, de la siguiente manera: type=list(number).\nSi ingresamos terraform plan podemos ver que efectivamente toma de forma correcta nuestra configuración:\n+ user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = [ + \u0026#34;5\u0026#34;, + \u0026#34;8\u0026#34;, ] } Pero si en cambio lo que hacemos es modificar la lista y le pasamos una cadena de caracteres (en vez de números como se encuentra definido en variables.tf) de la siguiente forma en el archivo terraform.tfvars:\nvpc = [\u0026#34;emiliano\u0026#34;, \u0026#34;florencia\u0026#34;] Entonces veremos el siguiente error:\nPlanning failed. Terraform encountered an error while generating this plan. ╷ │ Error: Invalid value for input variable │ │ on terraform.tfvars line 3: │ 3: vpc = [\u0026#34;emiliano\u0026#34;, \u0026#34;florencia\u0026#34;] │ │ The given value is not suitable for var.vpc declared at 48_variables_2.tf:15,1-15: a number is required. Data Type - Map # ¿Qué es el tipo de dato Map? # En Terraform, el tipo de dato map es una colección no ordenada de pares clave-valor, donde cada clave es única y está asociada con un valor. Las claves son generalmente cadenas, pero los valores pueden ser de cualquier tipo de dato. Los mapas son útiles para almacenar y acceder a configuraciones y datos estructurados.\nvariable \u0026#34;example_map\u0026#34; { type = map(string) default = { \u0026#34;us-east-1\u0026#34; = \u0026#34;ami-12345678\u0026#34; \u0026#34;us-west-2\u0026#34; = \u0026#34;ami-87654321\u0026#34; \u0026#34;eu-west-1\u0026#34; = \u0026#34;ami-11223344\u0026#34; } } resource \u0026#34;aws_instance\u0026#34; \u0026#34;example\u0026#34; { ami = var.example_map[var.region] instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;example-instance\u0026#34; } } variable \u0026#34;region\u0026#34; { type = string default = \u0026#34;us-west-2\u0026#34; } En este ejemplo:\nDefinición de la variable example_map: Se declara una variable llamada example_map de tipo map(string), lo que indica que es un mapa donde las claves son cadenas y los valores también son cadenas. Se establece un valor por defecto que es un mapa con pares clave-valor que representan regiones de AWS y sus respectivas AMIs. Definición de la variable var.region: Como se puede observar, la variable example_map relaciona un string con otro string, permite el mapeo entre una clave y un valor. Es por eso que es necesario definirla como un tipo string el cual se le asigna un valor por defecto, para que en caso de que se corra el comando terraform plan el valor de var.region se asocie con el valor correspondiente dentro de example_map. Uso en un recurso: En el recurso aws_instance, el valor de ami se selecciona del mapa example_map utilizando otra variable var.region que contiene la clave correspondiente a la región de AWS deseada. Uso de tags como maps # En terraform, cuando se trata de generar un recurso de tipo aws_instance el atributo tags espera un tipo map. Este tipo de datos representa una colección de elementos tipo clave-valor. Podemos observar la definición en la página oficial:\ntags = { Name = \u0026#34;HelloWorld\u0026#34; } Esto se puede ver como que al valor Name le hace corresponder el valor HelloWorld. Si queremos ingresar múltiples valores, deberíamos de definir una variable de tipo map de la siguiente manera:\nvariable \u0026#34;mapa\u0026#34; { type = map default = { Name = \u0026#34;app-name\u0026#34; Environment = \u0026#34;dev\u0026#34; Team = \u0026#34;payments\u0026#34; } } En esta nueva definición, podemos observar que para cada valor Name Environment Team, le hace coincidir el valor de tipo string como \u0026quot;app-name\u0026quot;, \u0026quot;dev\u0026quot;, \u0026quot;payments\u0026quot;. .\nEjemplo nº 1 # Archivos:\n48.main_3.tf 48.variables_3.tf terraform.tfvars Si tenemos en cuenta la modificación realizada en estos archivos:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;myEC2\u0026#34; { ami = \u0026#34;ami-120384135345sf\u0026#34; instance_type = var.lista[1] vpc_security_group_ids = var.vpc tags = var.tags_map } variable \u0026#34;tags_map\u0026#34; { type = map default = { Name = \u0026#34;app-name\u0026#34; Environment = \u0026#34;dev\u0026#34; Team = \u0026#34;payments\u0026#34; } } Podemos llamar a terraform plan y observar que se toma de forma correcta los tags:\n+ spot_instance_request_id = (known after apply) + subnet_id = (known after apply) + tags = { + \u0026#34;Environment\u0026#34; = \u0026#34;dev\u0026#34; + \u0026#34;Name\u0026#34; = \u0026#34;app-name\u0026#34; + \u0026#34;Team\u0026#34; = \u0026#34;payments\u0026#34; } + tags_all = { + \u0026#34;Environment\u0026#34; = \u0026#34;dev\u0026#34; + \u0026#34;Name\u0026#34; = \u0026#34;app-name\u0026#34; + \u0026#34;Team\u0026#34; = \u0026#34;payments\u0026#34; } + tenancy = (known after apply) + user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = [ + \u0026#34;30\u0026#34;, + \u0026#34;50\u0026#34;, + \u0026#34;60\u0026#34;, ] } La forma en que tenemos para identificar el ingreso de este tipo de valores (así como una lista podemos identificarla mediante los corchetes []), a un tipo map es mediante los los caracteres denominados llaves {}.\nContinuará \u0026hellip; # En las próximas lecciones veremos cómo utilizar correctamente los tipos de datos maps y cómo seleccionar valores a través de ellos para automatizar aún más nuestros scripts.\nTambién quería hacer notar que estoy retrasado con las publicaciones de este tipo de contenido ya que mi gata Emma está muriendo de cáncer. Sé que no es relevante para nadie, pero para mi es alguien que me acompaño por durante casi 12 años y que se esté muriendo tan rápidamente hace que todo lo demás en mi vida se torne vacío.\nHasta toda esta información se puede obtener ahora desde cualquier servicio de IA; así como yo la he utilizado para poder obtener una definición clara sobre algunos conceptos, pero algunas veces noto que todo este trabajo es como echarle agua al océano.\n","date":"19 diciembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part7/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003eData Type - List\n    \u003cdiv id=\"data-type---list\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#data-type---list\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\n\u003ch2 class=\"relative group\"\u003e¿Qué es el tipo de dato \u003ccode\u003eList\u003c/code\u003e?\n    \u003cdiv id=\"qué-es-el-tipo-de-dato-list\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#qu%c3%a9-es-el-tipo-de-dato-list\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003eEn Terraform, el tipo de dato \u003ccode\u003elist\u003c/code\u003e es una colección ordenada de valores. Los elementos en una lista pueden ser de cualquier tipo de dato, como números, cadenas,\nmapas u otros. Las listas se definen utilizando corchetes (\u003ccode\u003e[]\u003c/code\u003e), y los elementos se separan con comas.\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 7","type":"publicaciones"},{"content":" Precedencia en la definición de variables # Según lo que venimos viendo en secciones anteriores, la pregunta que surje con respecto a las asignaciones de variables es ¿Cuál es el orden de precedencia que tiene la asignación de variables en Terraform?\nOrden de precedencia # El orden de precendencia es la siguiente:\nVariables de Entorno Si está presente, el archivo terraform.tfvars . Si está presente, el archivo terraform.tfvars.json. Cualquier archivo .auto.tfvars o .auto.tfvars.json, los cuales son procesados en forma lexicográfica según su nombre. Cualquier opción en la línea de comando de tipo -var y -var-file en el orden que sean provistas. En caso de que ninguna de las anteriores exista, entonces evalúa el valor by default. Esto se ve en la siguiente sección denominada como Valores por defecto. Esto significa que en caso de estar configurado los archivos tales como se muestran en los puntos 2 y en 5, quien tiene mayor precedencia es el 5, por lo tanto será con el valor del caso 5 con el que quedará asignada la variable.\nEjemplo nº 1 # Tenemos definido:\nTF_VAR_instance_type = \u0026quot;t2.micro\u0026quot; Y en un archivo, lo siguiente terraform.tfvars: instance_type = \u0026#34;t2.large\u0026#34; Resultado final será: t2.large Ejemplo nº 2 # Tenemos definido:\nTF_VAR_instance_type = \u0026quot;t2.micro\u0026quot; En un archivo lo siguiente: terraform.tfvars: instance_type = \u0026#34;t2.large\u0026#34; Se ingresa el comando terraform plan -var=\u0026quot;instance_type=m5.large\u0026quot; Resultado final: m5.large Default values # Si se asignan valores por defecto en las definiciones de variables, este valor será el que tendrá menor precedencia por sobre todos los demás. Estamos hablando de una definición de estas características:\nvariable \u0026#34;instance_type\u0026#34; { default = \u0026#34;t2.micro\u0026#34; } Por lo tanto, este valor será asignado a la variable instance_type en caso de que NO ESTÉ CONFIGURADO NINGÚN VALOR en ninguna otra parte de la siguiente lista:\nVariables de Entorno Si está presente, el archivo terraform.tfvars . Si está presente, el archivo terraform.tfvars.json. Cualquier archivo .auto.tfvars o .auto.tfvars.json, los cuales son procesados en forma lexicográfica según su nombre. Cualquier opción en la línea de comando de tipo -var y -var-file en el orden que sean provistas. En caso de que ninguna de las anteriores exista, entonces evalúa el valor by default. Esto se ve en la siguiente sección denominada como Valores por defecto. Tipos de variables para las variables # En Terraform, los tipos de variables que podemos utilizar en nuestros archivos de configuración son:\nString: Este tipo representa una cadena de texto. Number: Representa un número entero o decimal. Bool: Un booleano, es decir, un valor verdadero o falso. List: Una lista ordenada de valores del mismo tipo. Map: Un conjunto de pares clave-valor, donde todas las claves son del mismo tipo y todos los valores son del mismo tipo. Estos tipos de variables nos permiten definir parámetros flexibles en nuestras configuraciones de Terraform, lo que hace que nuestras infraestructuras sean más dinámicas y adaptables.\nTipos de restricciones # Lo que permite establecer esta configuración es el valor que se aceptará cuando se les asigne un valor a estas variables. Por ejemplo, si nosotros definimos una variable como string y luego queremos ingresarle un número, al validar nuestro código mediante terraform validate nos generará un error.\nPara aquellos fanáticos de vim, es posible instalar el siguiente plugin (no oficial): hashivim/vim-terraform, mediante el cual es posible tener tanto un coloreado de código como también una validación en tiempo real.\nvariable \u0026#34;instance_name\u0026#34; { type = number } Examinemos un ejemplo: Imaginemos que a partir de un requerimiento se nos pide que la variable instance_name debe contener el número de identificación de cada empleado. Para que ningún empleado pueda ingresar un valor como \u0026ldquo;john-123\u0026rdquo; lo que se hace es configurar esa variable con el tipo number a instance_name para que de esta forma si el empleado quiere ingresar una cadena de caracteres, terraform lo impida.\nPráctica # Archivos a utilizar:\n48_main.tf 48_variables.tf terraform.tfvars Ejemplo nº 1 # Archivo 48_main.tf: resource \u0026#34;aws_instance\u0026#34; \u0026#34;AWSInstance\u0026#34; { ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = var.instance_name } } Archivo 48_variables.tf: variable \u0026#34;instance_name\u0026#34; { type = number } Archivo terraform.tfvars: variable \u0026#34;instance_name\u0026#34; { type = number } En este caso, terraform nos dará un ERROR cuando ingresemos terraform plan porque el tipo de variable está definido como number y nosotros le estamos ingresando un string.\nEjemplo nº 2 # Archivo 48_main.tf: resource \u0026#34;aws_instance\u0026#34; \u0026#34;AWSInstance\u0026#34; { ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = var.instance_name } } Archivo 48_variables.tf: variable \u0026#34;instance_name\u0026#34; { type = string } Archivo terraform.tfvars: instance_name = 30397781 El problema acá es que si bien en la definición nosotros le indicamos que debería de ser un tipo string, cuando ingresamos el número en el archivo terraform.tfvars lo que sucede es que convierte estos números en cadena de caracteres y nos arroja lo siguiente luego de haber invocado al comando terraform plan:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;AWSInstance\u0026#34; { + ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; + arn = (known after apply) ... + disable_api_termination = (known after apply) + ebs_optimized = (known after apply) ... + instance_state = (known after apply) + instance_type = \u0026#34;t2.micro\u0026#34; ... + subnet_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;30397781\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;30397781\u0026#34; } + tenancy = (known after apply) + user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = (known after apply) } Como podemos ver, el lenguaje utilizado por Terraform de manera interna, no es fuertemente tipado por lo que estos errores pueden llegar a ocurrir de manera muy común.\nEjemplo nº 3 # Lo que utilizaremos ahora en vez de una instancia de AWS, será un ELB, que es un balanceador de carga. Esto es así ya que las zonas de disponibilidad se encuentra definido como un tipo list dentro de la documentación\n48_main.tf resource \u0026#34;aws_elb\u0026#34; \u0026#34;bar\u0026#34; { name = var.elb_name availability_zones = var.elb_az listener { instance_port = 8000 instance_protocol = \u0026#34;http\u0026#34; lb_port = 80 lb_protocol = \u0026#34;http\u0026#34; } health_check { healthy_threshold = 2 unhealthy_threshold = 2 timeout = 3 target = \u0026#34;HTTP:8000/\u0026#34; interval = 30 } cross_zone_load_balancing = true idle_timeout = var.elb_timeout connection_draining = true connection_draining_timeout = var.elb_timeout tags = { Name = \u0026#34;foobar-terraform-elb\u0026#34; } } 48_variables.tf variable \u0026#34;elb_name\u0026#34; { type = string } variable \u0026#34;elb_az\u0026#34; { type = list } variable \u0026#34;elb_timeout\u0026#34; { type = number } terraform.tfvars elb_name = \u0026#34;aws-elb-name\u0026#34; elb_az = [\u0026#34;us-west-2a\u0026#34;, \u0026#34;us-west-2b\u0026#34;, \u0026#34;us-west-2c\u0026#34;] elb_timeout = 400 En este caso podemos ver que si en el archivo 48_variables.tf nosotros no declaramos que el tipo elb_az sea un tipo list, terraform por más que nosotros le ingresemos una cadena de caracteres, no nos permitirá ingresarla porque no puede hacer la correspondencia de valores entre un string y un list. Por lo tanto, deberemos de ingresar el tipo list para poder solventar éste problema.\nNota sobre módulo en GitHub # Algo importante a tener en cuenta es que debemos de mirar cómo se encuentran definidas las variables según el módulo o servicio que estemos utilizando, en los repositorios de GitHub. Por ejemplo, en este caso estuvimos utilizando el módulo elb, por lo tanto si buscamos en Google, el repositorio será algo como \u0026ldquo;github terraform aws elb\u0026rdquo;:\nMódulo: link Variables: link Veremos que en la definición de variables (variables.tf) para cada una de las Input Variables que se manejan dentro del módulo de ELB. La cual sería una gran ayuda para saber qué tipo deberíamos de gestionar a nuestras variables para poder ingresarlas en los scripts.\nContinuará\u0026hellip; # En las próximas secciones veremos los tipos de datos List y Maps acompañado de algunos ejemplos prácticos.\n¡Hasta luego!\n","date":"11 diciembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part6/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003ePrecedencia en la definición de variables\n    \u003cdiv id=\"precedencia-en-la-definición-de-variables\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#precedencia-en-la-definici%c3%b3n-de-variables\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\u003cp\u003eSegún lo que venimos viendo en secciones anteriores, la pregunta que surje con respecto a las asignaciones de variables es \u003cem\u003e¿Cuál es el orden de precedencia que\ntiene la asignación de variables en Terraform?\u003c/em\u003e\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 6","type":"publicaciones"},{"content":" Archivo para definición de variables (TFVARS) # Esquema # Tenemos dos tipos de archivos que Hashicorp recomienda tener en proyectos grandes:\nvariables.tf terraform.tfvars Definición # variables.tf: Este archivo es utilizado para definir las variables que serán utilizadas en nuestra configuración de Terraform. Las variables en Terraform son útiles para parametrizar nuestra infraestructura y permitir una configuración más dinámica y reutilizable. En el archivo variables.tf, defines las variables junto con su tipo (como string, número, lista, etc.) y puedes asignarles un valor por defecto si lo deseas. Ejemplo de un archivo variables.tf:\nvariable \u0026#34;region\u0026#34; { type = string default = \u0026#34;us-east-1\u0026#34; } variable \u0026#34;instance_type\u0026#34; { type = string default = \u0026#34;t2.micro\u0026#34; } terraform.tfvars: Este archivo es utilizado para asignar valores concretos a las variables definidas en variables.tf. Es un archivo de configuración que contiene los valores específicos que serán utilizados cuando ejecutemos nuestra configuración de Terraform. Estos valores pueden ser diferentes según el entorno (desarrollo, pruebas, producción, etc.) o según los requisitos de la infraestructura. Ejemplo de un archivo terraform.tfvars:\nregion = \u0026#34;us-west-2\u0026#34; instance_type = \u0026#34;t3.micro\u0026#34; La relación entre estos dos archivos es que las variables definidas en variables.tf son referenciados en nuestra configuración de Terraform, mientras que los valores concretos para esas variables se proporcionan en el archivo terraform.tfvars.\nCuando ejecutamos estos scripts, Terraform buscará automáticamente el archivo terraform.tfvars en el directorio de trabajo y utilizará los valores allí definidos para reemplazar las variables correspondientes en nuestra configuración. Esto nos permite tener una separación clara entre la lógica de nuestra infraestructura y los valores específicos que pueden variar entre entornos o dependiendo de los requisitos de nuestra aplicación.\nComo se dijo anteriormente, se recomienda separar en 3 tipos de archivos la utilización de nuestras variables en Terraform:\nPor un lado tenemos el propio script de Terraform, donde se codifican cada uno de los recursos a construir. En el archivo variables.tf ingresamos la definición de las variables a utilizar como puede ser el valor por defecto, la descripción, el tipo de dato que aceptará, etc; y luego, En el archivo terraform.tfvars asignamos el valor a esas variables. Hashicorp recomienda que el nombre sea terraform, ya que si se le asigna otro nombre, se deberá de indicar en el comando apply el tipo de variable que deberá tomar para las variables definidas de la siguiente manera: terraform apply -var-file=prod.tfvars Separación entre ambientes # Lo interesante es que el archivo .tfvars puede estar dividido por ejemplo entre la cantidad de ambientes que tengamos, por ejemplo entre los ambientes dev y prod. Estos dos ambientes compartirán la definición de las variables pero no así su valor.\nEsto lo que permite es invocar el comando terraform apply -var-file=prod.tfvars lo que terminará construyendo un ambiente con los valores productivos.\nEn cambio, si utilizamos el comando terraform apply -var-file=dev.tfvars utilizaremos los valores para el ambiente de desarrollo.\nComando: terraform apply -var-file=\u0026lt;FILE.TFVARS\u0026gt; # El comando terraform apply -var-file=\u0026lt;file.tfvars\u0026gt; se utiliza en Terraform para aplicar los cambios en la infraestructura definida en nuestra configuración, tomando los valores de variables especificados en un archivo de variables externo (usualmente con extensión .tfvars).\nAquí una explicación detallada de cada parte del comando:\nterraform apply: Este es el comando principal de Terraform que se utiliza para aplicar los cambios definidos en nuestra configuración de Terraform. Cuando ejecutas terraform apply, Terraform analiza los archivos de configuración en nuestro directorio de trabajo y determina qué acciones deben tomarse para alcanzar el estado deseado de la infraestructura.\n-var-file=\u0026lt;file.tfvars\u0026gt;: Esta parte del comando especifica el archivo de variables externo que contiene los valores para las variables definidas en nuestra configuración de Terraform. Con esta opción, puedes proporcionar valores para las variables definidas en tus archivos variables.tf de una manera más organizada y separada de la configuración principal.\n\u0026lt;file.tfvars\u0026gt;: Esto debe ser reemplazado por el nombre del archivo de variables externo que deseas utilizar. Por lo general, estos archivos tienen una extensión .tfvars (por ejemplo, terraform.tfvars, dev.tfvars, production.tfvars, etc.).\nAl ejecutar este comando, Terraform aplicará los cambios en nuestra infraestructura según la configuración definida en tus archivos principales de Terraform (main.tf, variables.tf, etc.), tomando los valores de las variables del archivo especificado con -var-file. Esto permite una mayor flexibilidad y reutilización de la configuración de Terraform al separar la lógica de la infraestructura de los valores específicos de cada entorno o configuración.\nPráctica # Comportamiento normal # Para esta práctica se crearán 3 archivos:\n44_main.tf: donde se tendrá la definición de los recursos. 44_variables.tf: donde se tendrá la definición de las variables. terraform.tfvars: el cual contendrá los valores para cada una de las variables. Es muy importante que el nombre sea terraform.tfvars, ya que es el nombre que por default terraform buscará para poder llevar a cabo la interpolación de valores al ejecutar terraform plan es en base a este nombre. En el archivo 44_main.tf vamos a poder ver algo como esto:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { ami = var.ami instance_type = var.instance_type tags = { Name = \u0026#34;Terraform EC2\u0026#34; } } Se puede ver que tanto en la variable ami como en instance_type hacen referencia a valores de entrada (input values) que se encuentran definidos en el archivo 44_variables.tf:\nvariable \u0026#34;ami\u0026#34; {} variable \u0026#34;instance_type\u0026#34; {} Y luego, estas variables pueden tomar el valor del archivo terraform.tfvars:\nami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; En el archivo nº 2, podremos definir de forma más granular el tipo de variable, ya que si vamos a la documentación, podemos encontrar distintos argumentos:\nUna vez que ejecutamos terraform plan podremos ver si la salida es lo que esperábamos:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { + ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; + arn = (known after apply) + associate_public_ip_address = (known after apply) ... + instance_lifecycle = (known after apply) + instance_state = (known after apply) + instance_type = \u0026#34;t2.micro\u0026#34; + ipv6_address_count = (known after apply) ... + security_groups = (known after apply) + source_dest_check = true + spot_instance_request_id = (known after apply) + subnet_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform EC2\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform EC2\u0026#34; } + tenancy = (known after apply) ... + vpc_security_group_ids = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. Como podemos ver, los valores para ami y para instance_type fueron generados con éxito.\nValores por defecto nº 1 # En este caso si seguimos teniendo la misma disposición de archivos:\n44_main.tf: donde se tendrá la definición de los recursos. 44_variables.tf: donde se tendrá la definición de las variables y sus valores por default terraform.tfvars: el cual contendrá los valores para cada una de las variables, pero en este caso no tendrá ningún valor En este caso el archivo 44_main.tf quedará igual, pero el segundo archivo 44_variables.tf tendrá los valores de las variables por defecto y el archivo terraform.tfvars no contendrá ningún valor.\nPor lo tanto, el archivo 44_variables.tf contiene los siguientes valores:\nvariable \u0026#34;ami\u0026#34; { default = \u0026#34;ami-11222333444555\u0026#34; description = \u0026#34;This is an AMI from us-east-1\u0026#34; } variable \u0026#34;instance_type\u0026#34; { default = \u0026#34;t2.super.micro\u0026#34; description = \u0026#34;This is for develop use\u0026#34; } Como podemos observar, los valores por defecto para ambas variables son ficticios. Como el archivo terraform.tfvars se encuentra vacío, entonces Terraform al no encontrar valores para ser asociadas a las variables definidas, les asignará el valor por defecto.\nPor lo tanto, al invocar el comando terraform plan obtenemos lo siguiente:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { + ami = \u0026#34;ami-11222333444555\u0026#34; + arn = (known after apply) ... + ebs_optimized = (known after apply) + get_password_data = false + host_id = (known after apply) ... + instance_type = \u0026#34;t2.super.micro\u0026#34; + ipv6_address_count = (known after apply) ... Valores por defecto nº 2 # Volvemos a tener el mismo esquema anterior, pero:\n44_main.tf: donde se tendrá la definición de los recursos. 44_variables.tf: donde se tendrá la definición de las variables y sus valores por default terraform.tfvars: el cual contendrá los valores para cada una de las variables, pero en este caso tendrá un valor asociado de forma correcta. El archivo 44_variables.tf seguirá teniendo los valores por defecto, pero el archivo terraform.tfvars tendrá también valores los cuales tendrán mayor precedencia que los definidos como defaults. Por lo tanto el contenido de estos dos archivos será:\n44_variables.tf variable \u0026#34;ami\u0026#34; { default = \u0026#34;ami-11222333444555\u0026#34; description = \u0026#34;This is an AMI from us-east-1\u0026#34; } variable \u0026#34;instance_type\u0026#34; { default = \u0026#34;t2.super.micro\u0026#34; description = \u0026#34;This is for develop use\u0026#34; } terraform.tfvars ami = \u0026#34;ami-0c101f26f147fa7fd\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; Por lo tanto, al invocar el comando terraform plan obtenemos los valores definidos en terraform.tfvars y no en el archivo 44_variables.tf:\n+ resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformEC2\u0026#34; { + ami = \u0026#34;ami-11222333444555\u0026#34; + arn = (known after apply) ... + instance_state = (known after apply) + instance_type = \u0026#34;t2.super.micro\u0026#34; + ipv6_address_count = (known after apply) ... + subnet_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform EC2\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform EC2\u0026#34; } + tenancy = (known after apply) + user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = (known after apply) } Nota sobre el nombre del archivo tfvars # Como se dijo anteriormente: ¡Es muy importante que el nombre donde se encuentran los valores de las variables sea terraform.tfvars ya que es el nombre que por default terraform buscará para poder llevar a cabo la interpolación de valores al ejecutar terraform plan.\nSi el nombre ES DISTINTO, entonces deberemos de utilizar la siguiente secuencia de comandos\nterraform plan -var-file=\u0026lt;FILE.tfvars\u0026gt;\ny luego\nterraform apply -var-file=\u0026lt;FILE.tfvars\u0026gt;.\nEsto último es útil cuando se tienen distintos ambientes y por lo tanto se quiere desplegar infraestructura distintas, por lo tanto en este caso por ejemplo tendremos:\nUn archivo denominado dev.tfvars el cual tiene los valores para las variables del ambiente de desarrollo Una vez que queramos generar el plan invocamos terraform plan -var-file=\u0026quot;dev.tfvars\u0026quot; Si estamos satisfechos con el plan, ingresamos terraform apply -var-file=\u0026quot;dev.tfvars\u0026quot; Enfoques para la asignación de variables # Si nosotros definimos una variable, es necesario que se defina la variable en algún archivo, como puede ser variables.tf, pero además de ello debe tener un valor asociado a ella. En caso de que esto último no se defina, es decir que no tenga valor asignado, entonces al ejecutar por ejemplo el comando terraform plan lo que sucederá es que Terraform nos pedirá que ingresemos de manera manual el valor de la variable.\nPero luego de haber ingresado el valor cuando se realizó el comando terraform plan también se deberá de ingresar el valor nuevamente cuando se invoque el comando terraform apply ya que el valor no queda cacheado y por lo tanto se pierde.\nNota sobre el ingreso manual # Por lo tanto, en caso de que hayamos definido todas las partes de una variable y al ejecutar la planificación, nos solicita el ingreso del valor de la variable, entonces es un síntoma acerca de que Terraform no encuentra el archivo donde se alojan los valores de las variables. Por lo tanto, habrá que ver si el nombre corresponde a terraform.tfvars o si es distinto a este, entonces utilizar terraform plan -var-file=\u0026lt;FILE.tfvars\u0026gt;\nDefinición de variables # Los 4 lugares por los que Terraform buscará para cargar los valores de las variables serán:\nLa definición por default de los valores de las variables Archivo de definición de variables (tfvars) Variables de entorno Configuración de variables mediante la línea de comando. Variable Default # El primer lugar donde va a tomar los valores será de la propia definición de la variable, por ejemplo:\nvariable \u0026#34;app_port\u0026#34; { default = \u0026#34;8080\u0026#34; } En este será el primer lugar donde tomará los valores de las variables. En caso de que no esté definido en este lugar, pasa al próximo lugar para evaluar el valor.\nTfvars files # El próximo lugar donde mirará Terraform para asignar el valor a la variable será en los archivos definidos con la extensión .tfvars, como se comentó en las secciones anteriores. Por ejemplo, siguiendo con la variable definida anteriormente, podríamos tener un archivo denominado terraform.tfvars donde se explicite lo siguiente:\napp_port = \u0026#34;8080\u0026#34; En caso de que tampoco tengamos definida el valor de las variables dentro de un archivo de tipo .tfvars entonces se sigue al próximo escaño.\nAsignación de valores mediante CLI # También podemos definir un valor de las variables mediante el uso de la línea de comandos utilizando el parámetro -var=\u0026quot;app_port=8080\u0026quot;, donde el parámetro -var permite asignar el valor de una variable determinada mediante la línea de comando. En la filmina podemos ver que se puede ajustar tanto al comando terraform plan como al comando terraform apply por lo tanto, quedaría de la siguiente manera:\nterraform plan -var=\u0026quot;app_port=8080\u0026quot; terraform apply -var=\u0026quot;app_port=8080\u0026quot; Recordar que de esta manera, los valores utilizados en el punto nº 1 NO quedarán guardados en el caché, por lo tanto si utilizamos seguidamente el comando apply deberemos de ingresar nuevamente el parámetro -var para significar el valor de la variable nuevamente.\nComo se puede observar, el nombre de la variable ingresada mediante la CLI no deberá de contener al comienzo el prefijo var. En caso de que la variable en nuestro código sea var.app_port, cuando la ingresamos por la CLI, deberemos de ingresarla de la siguiente manera:\nterraform plan -var=\u0026quot;app_port=8080\u0026quot;\nVariables de entorno # Por último, tenemos la posibilidad de configurar las variables mediante variables de entorno. Para declarar una variable de entorno, debemos de seguir una convención para generar el nombre, la cual se encuentra documentada aquí\nPodemos ver que debemos de nombrar la variable de entorno anteponiéndole el nombre TF_VAR_ por lo tanto, en el ejemplo anterior deberíamos de exportar nuestra variable de la siguiente manera:\n$ export TF_VAR_app_port=\u0026#34;8080\u0026#34; Por lo tanto si en nuestro script de Terraform se encuentra configurado de la siguiente forma:\nvariable \u0026#34;app_port\u0026#34; {} Y luego invocamos terraform plan, automáticamente Terraform buscará como última instancia el nombre TF_VAR_APP_PORT y de encontrarlo en las variables de entorno, entonces lo asigna a la variable correspondiente.\nVariables de entorno en Linux/Mac # Para configurar las variables de ambiente en Linux, se puede buscar en internet cómo realizarlo. Por ejemplo aquí hay un link para poder entender los comandos printenv o export.\nContinuará\u0026hellip; # En las próximas lecciones veremos la precedencia a la hora de definir los valores para nuestras variables y cómo podemos configurar un tipo de datos a nuestras variables.\n¡Hasta pronto!\n","date":"8 diciembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part5/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003eArchivo para definición de variables (TFVARS)\n    \u003cdiv id=\"archivo-para-definición-de-variables-tfvars\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#archivo-para-definici%c3%b3n-de-variables-tfvars\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\n\u003ch2 class=\"relative group\"\u003eEsquema\n    \u003cdiv id=\"esquema\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#esquema\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003eTenemos dos tipos de archivos que Hashicorp recomienda tener en proyectos grandes:\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 5","type":"publicaciones"},{"content":" Revisión general de las variables de Terraform # Problema # Como bien se sabe, el generar variables ESTÁTICAS (o bien denominadas \u0026ldquo;variables hardcodeadas\u0026rdquo;) tiene el problema que no son una solución optima a la hora de funcionar en entornos dinámicos. Por ejemplo, podemos pensar en un requerimiento donde se pide generar una VPN con reglas de tipo inbound rule (denominadas whitelist o lista blanca). Como se puede pensar, ya es un problema tener que lidiar con una sola inbound rule, imagine el problema que sería ingresando todas estas direcciones a mano, por lo tanto, en organizaciones muy grandes esto puede escalar mucho más allá de cientos de reglas.\nPor lo tanto no es óptimo tener que manejar todo esto mediante valores expresados en el código, sino más bien que es mucho más óptimo y fácil generar una variable.\nSolución # Un mejor acercamiento para dar solución a esto es tener definida una variable global que permita ser alcanzada por todos los recursos cuyo atributo esté definida con ella y de esta manera en caso de tener que modificarse, se modifica en un sólo lugar y replicado en todos los demás lugares.\nOtra posibilidad es tener definas varias variables en un sólo lugar (como puede ser un archivo) y que a partir de ahí sea visible para todos los recursos que se quieran gestionar con Terraform.\nPráctica # Archivos a emplear:\n42_variables.tf central_variables.tf En el archivo central_variables.tf podemos observar el siguiente código:\nvariable \u0026#34;vpn_ip\u0026#34; { default = \u0026#34;101.0.62.210/32\u0026#34; } variable \u0026#34;vpn_port\u0026#34; { default = \u0026#34;80\u0026#34; } Para luego ser utilizado de la siguiente forma en el archivo 42_variables.tf:\nresource \u0026#34;aws_security_group\u0026#34; \u0026#34;terraform-firewall\u0026#34; { name = \u0026#34;terraform-firewall\u0026#34; description = \u0026#34;Managed from Terraform\u0026#34; tags = { Name = \u0026#34;Terraform-SG\u0026#34; } } resource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { # Notar que el id se compone del recurso del SG + \u0026#34;id\u0026#34; security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = \u0026#34;${var.vpn_ip}\u0026#34; from_port = var.vpn_port ip_protocol = \u0026#34;tcp\u0026#34; to_port = var.vpn_port tags = { Name = \u0026#34;Terraform-InboundRule\u0026#34; } } Es importante notar que para indicarle a Terraform que debe de ir a leer una variable global, se debe comenzar con el prefijo var seguido del nombre local, en nuestro caso tenemos var.vpn_ip y luego var.vpn_port. De esta manera Terraform sabrá que deberá de buscar la definición de estas variables en algún archivo por fuera de los scripts.\nPor lo tanto si invocamos al comando terraform plan vamos a poder observar que efectivamente toma los valores correctos:\n# aws_vpc_security_group_ingress_rule.allow_80_ipv4 will be created + resource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { + arn = (known after apply) + cidr_ipv4 = \u0026#34;101.0.62.210/32\u0026#34; + from_port = 80 + id = (known after apply) + ip_protocol = \u0026#34;tcp\u0026#34; + security_group_id = (known after apply) + security_group_rule_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-InboundRule\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-InboundRule\u0026#34; } + to_port = 80 } Plan: 2 to add, 0 to change, 0 to destroy. Podemos ver que en el atributo cidr_ipv4 como en from_port y to_port se encuentran gestionados con los valores provenientes del archivo central-variables.tf\nImportante # Cabe notar que NO importa el nombre del archivo en el que coloquemos las variables generales (en nuestro caso es central-variables.tf). Lo importante es la extensión .tf y la nomenclatura que se utiliza para hacer referencia a ellas dentro del código. Comos se dijo anteriormente, se debe utilizar var.\u0026lt;VARIABLE.NAME\u0026gt;\nModificación de variable # Lo que podemos hacer ahora, es modificar el archivo central-variables.tf y visualizar nuevamente si el cambio ha surgido efecto cuando invocamos terraform plan.\nPor lo tanto ahora el archivo central-variables.tf queda de la siguiente manera:\nvariable \u0026#34;vpn_ip\u0026#34; { default = \u0026#34;255.255.62.210/32\u0026#34; } variable \u0026#34;vpn_port\u0026#34; { default = \u0026#34;22\u0026#34; } Invocamos el comando terraform plan y vemos la salida:\naws_vpc_security_group_ingress_rule.allow_80_ipv4 will be created + resource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { + arn = (known after apply) + cidr_ipv4 = \u0026#34;255.255.62.210/32\u0026#34; + from_port = 22 + id = (known after apply) + ip_protocol = \u0026#34;tcp\u0026#34; + security_group_id = (known after apply) + security_group_rule_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-InboundRule\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-InboundRule\u0026#34; } + to_port = 22 } Plan: 2 to add, 0 to change, 0 to destroy. Podemos ver nuevamente que en el atributo cidr_ipv4 como en from_port y to_port se encuentran modificados a los nuevos valores provenientes del archivo central-variables.tf.\nLos beneficios de utilizar variables globales o definidas en un archivo central son:\nTenemos un único lugar donde modificar los valores asociados a la variable y por lo tanto podemos salvar tiempo de errores potenciales. Acorta el error humano por tener que modificar un solo lugar en vez de andar realizando las modificaciones a lo largo de los archivos de configuración de los recursos gestionados a través de los archivos .tf Terraform Variables - Practica 1 # Archivos a utilizar:\n43_GlobalVariables.tf 43_central_variables.tf Análisis de variables # Es la misma práctica que se hizo en la lección anterior. Simplemente se agregan más variables para poder tener más ejemplos para mostrar al final del comando terraform plan.\nEn este ejemplo lo que podemos ver es lo siguiente:\nresource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = \u0026#34;${var.vpn_ip}/16\u0026#34; from_port = var.vpn_from_port ip_protocol = \u0026#34;tcp\u0026#34; to_port = var.vpn_to_port tags = { Name = \u0026#34;Terraform-InboundRule\u0026#34; } } resource \u0026#34;aws_vpc_security_group_egress_rule\u0026#34; \u0026#34;allow_all_traffic_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = var.vpn_ip ip_protocol = \u0026#34;-1\u0026#34; tags = { Name = \u0026#34;Terraform-OutboundRule\u0026#34; } } Podemos ver que el atributo cidr_ipv4 se encuentra asociado tanto a una variable directa como a un string y que ambos valores son aceptados de forma correcta. Lo interesante para notar es que terraform plan también permite realizar una evaluación sobre los valores reemplazados por las variables globales. Por ejemplo, si tenemos el siguiente valor en el archivo central-variables.tf:\nvariable \u0026#34;vpn_ip\u0026#34; { default = \u0026#34;100.32.62.210/32\u0026#34; } Y luego tengo el siguiente código en el archivo 43_GlobalVariables.tf:\nresource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = \u0026#34;${var.vpn_ip}/16\u0026#34; # -\u0026gt; notar que el reemplazo daría 100.32.62.210/32/16\u0026#34; from_port = var.vpn_from_port ip_protocol = \u0026#34;tcp\u0026#34; to_port = var.vpn_to_port tags = { Name = \u0026#34;Terraform-InboundRule\u0026#34; } } La salida de terraform plan es la siguiente:\n│ Error: Invalid Attribute Value │ │ with aws_vpc_security_group_ingress_rule.allow_80_ipv4, │ on 43_GlobalVariables.tf line 18, in resource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34;: │ 18: cidr_ipv4 = \u0026#34;${var.vpn_ip}/16\u0026#34; │ │ Attribute cidr_ipv4 value must be a valid IPv4 CIDR that represents a network address, got: | 255.255.62.210/32/16 Y esto es porque realiza primero una interpolación de variables y luego un breve análisis sintáctico para evaluar si los valores reemplazados tienen la estructura gramatical para ser asignados.\nPara corregir los rangos CIDR podemos utilizar la siguiente aplicación: https://www.ipaddressguide.com/cidr\nInterpolación de variables # Luego de corregir los errores del apartado anterior, invocamos el comando terraform plan, obtenemos lo siguiente:\n+ resource \u0026#34;aws_vpc_security_group_egress_rule\u0026#34; \u0026#34;allow_all_traffic_ipv4\u0026#34; { + arn = (known after apply) + cidr_ipv4 = \u0026#34;54.164.75.253/32\u0026#34; + id = (known after apply) + ip_protocol = \u0026#34;-1\u0026#34; + security_group_id = (known after apply) + security_group_rule_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-OutboundRule\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-OutboundRule\u0026#34; } } + resource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { + arn = (known after apply) + cidr_ipv4 = \u0026#34;54.164.75.253/32\u0026#34; + from_port = 22 + id = (known after apply) + ip_protocol = \u0026#34;tcp\u0026#34; + security_group_id = (known after apply) + security_group_rule_id = (known after apply) + tags = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-InboundRule\u0026#34; } + tags_all = { + \u0026#34;Name\u0026#34; = \u0026#34;Terraform-InboundRule\u0026#34; } + to_port = 80 } Plan: 3 to add, 0 to change, 0 to destroy. Por lo tanto vemos que la interpolación de variables ha sido exitosa.\nImportante # Algo a tener en cuenta es que cuando tengamos que afrontar código de producción en Terraform, el código será muy largo, siendo muchos los recursos administrados. Es por eso que lo que conviene en estos casos es tratar de evitar las modificaciones de estos archivos lo más que se pueda.\nSiempre es importante generalizar todo a variables y con ello evitamos de tener que andar navegando y modificando valores a lo largo de archivos enormes donde podemos generar errores con facilidad.\nImportante 2 # Lo que recomiendan las buenas prácticas de Terraform declaradas en el siguiente link, es utilizar una convención de nombres para los archivos de configuración, permitiendo de esta manera encontrar con mayor certeza y claridad los recursos que estamos buscando. Esto es aplicable tanto para los archivos de configuración como para el de las variables globales.\nComo también es buena práctica en estas input variables utilizar el argumento description el cual, sólo funciona como una descripción de la variable para poder entender mejor a lo que hace referencia. Es para orientar de forma más eficiente al desarrollador. Por ejemplo de la siguiente manera:\nvariable \u0026#34;vpn_ip\u0026#34; { default = \u0026#34;54.164.75.253\u0026#34; description = \u0026#34;This is an VNP example implement through Terraform\u0026#34; } Importante 3 # Podemos ver que en la definición de una input variable no sólo existe el argumento default, sino un montón de otros argumentos. Esto se puede encontrar en la documentación de Hashicorp para tener una idea de todos los argumentos que soporta.\nContinuará\u0026hellip; # En las siguientes secciones veremos cómo se definen los archivos de variables (tfvars), la importancia de ello en el buen manejo de nuestra infraestructura y también pondré a disposición en mi repositorio personal los archivos .tf utilizados a lo largo de todas las secciones previas y posteriores.\n¡Abrazo de gol para todos!\n","date":"5 diciembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part4/","section":"Publicaciones","summary":"\u003ch2 class=\"relative group\"\u003eRevisión general de las variables de Terraform\n    \u003cdiv id=\"revisión-general-de-las-variables-de-terraform\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#revisi%c3%b3n-general-de-las-variables-de-terraform\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\n\u003ch3 class=\"relative group\"\u003eProblema\n    \u003cdiv id=\"problema\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#problema\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h3\u003e\n\u003cp\u003eComo bien se sabe, el generar variables \u003cstrong\u003eESTÁTICAS\u003c/strong\u003e (o bien denominadas \u0026ldquo;variables hardcodeadas\u0026rdquo;) tiene el problema que no son una solución optima a la hora de\nfuncionar en entornos dinámicos. Por ejemplo, podemos pensar en un requerimiento donde se pide generar una VPN con reglas de tipo \u003cem\u003einbound rule\u003c/em\u003e (denominadas\n\u003cem\u003ewhitelist\u003c/em\u003e o lista blanca). Como se puede pensar, ya es un problema tener que lidiar con una sola \u003cem\u003einbound rule\u003c/em\u003e, imagine el problema que sería ingresando todas\nestas direcciones a mano, por lo tanto, en organizaciones muy grandes esto puede escalar mucho más allá de cientos de reglas.\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 4","type":"publicaciones"},{"content":" Output Values # ¿Qué son los valores de salida? # En Terraform, los output values (valores de salida) son una forma de exponer información útil o resultados específicos después de que se ha aplicado la configuración de infraestructura. Estos valores pueden ser variables, atributos o cualquier otra información generada como resultado de la ejecución de la configuración de Terraform.\nCuando definimos outputs en la configuración de Terraform, estás especificando qué información deseas que Terraform muestre una vez que se ha aplicado la configuración. Esto puede ser útil para mostrar direcciones IP, identificadores de recursos, URLs o cualquier otra información relevante para el usuario o para otros sistemas que dependen de la infraestructura.\nAquí un ejemplo simple de cómo se definen los output values en Terraform:\noutput \u0026#34;instance_ip\u0026#34; { value = aws_instance.example.public_ip } En este ejemplo, instance_ip es el nombre del output. El valor de este output es la dirección IP pública de la instancia de AWS definida con el nombre example. Cuando aplicamos esta configuración y luego ejecutas terraform output, Terraform mostrará la dirección IP pública de la instancia.\nPodemos utilizar los \u0026ldquo;output values\u0026rdquo; de varias maneras, como integrarlos con otros sistemas, pasarlos como entrada a otras herramientas o scripts, o simplemente para proporcionar información a los usuarios sobre la infraestructura creada. Son una forma útil de comunicar información relevante generada por Terraform después de aplicar la configuración.\nHay que tener en cuenta que esta información se nos informará por pantalla luego de que el comando terraform apply haya finalizado.\nSi nosotros generamos una instancia de EC2, luego de haber ingresado el comando terraform apply lo que vamos a ver es una lista de atributos relacionados a nuestra instancia pero no se informa, por ejemplo nuestra dirección IP. Para que esto suceda, podremos ingresar a nuestra cuenta de AWS y ver la IP desde la consola.\nPero la realidad es que es muy trabajoso hacer esto y por lo tanto lo que podemos hacer es que al finalizar el comando terraform apply, automáticamente Terraform nos muestre la dirección en pantalla.\n41. Práctica # Hay que tener en cuenta que para este ejemplo se agregaron 2 componentes más que no modifican en nada lo anteriormente mencionado, como ser un Security Group y una Inbound Rule asociada.\nPara poder poner esto en práctica, lo que vamos a generar es simplemente una instancia de EC2 con el siguiente código y la variable de salida:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;TerraformEC2Instance\u0026#34; } } output \u0026#34;EC2_public_ip\u0026#34; { value = aws_instance.terraformec2.public_ip } Esto generará a la hora de finalizar con el comando, la siguiente salida (siendo N un número natural que conforma la dirección IP pública):\nEC2_public_ip: NNN.NNN.NNN.NNN Luego de aplicar el comando terraform apply podemos ver la salida del comando donde se nos indica el orden de creación de cada recurso, como también la variable de salida deseada:\nChanges to Outputs: + EC2_public_ip = (known after apply) aws_security_group.terraform-firewall: Creating... aws_instance.terraformec2: Creating... aws_security_group.terraform-firewall: Creation complete after 4s [id=sg-0d31d2401a575ae5a] aws_vpc_security_group_ingress_rule.allow_80_ipv4: Creating... aws_vpc_security_group_ingress_rule.allow_80_ipv4: Creation complete after 1s [id=sgr-0ac63f4b227856ae6] aws_instance.terraformec2: Still creating... [10s elapsed] aws_instance.terraformec2: Still creating... [20s elapsed] aws_instance.terraformec2: Creation complete after 25s [id=i-0b06b34e6d78c33e3] Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs: EC2_public_ip = \u0026#34;54.164.75.253\u0026#34; Concatenación de salidas # También podemos utilizar la interpolación de variables para poder agregar más información a la salida deseada, como por ejemplo:\noutput \u0026#34;URL Server\u0026#34; { value = \u0026#34;https://${aws_instance.terraformec2.public_ip}/80\u0026#34; } Esto se puede aplicar directamente haciendo terraform plan y luego terraform apply. Es decir, que no hace falta eliminar la infraestructura y volver a implementar para que se muestren las variables de salida.\nPor lo tanto, la salida es la siguiente:\nChanges to Outputs: ~ EC2_public_ip = \u0026#34;54.164.75.253\u0026#34; -\u0026gt; \u0026#34;https//54.164.75.253/8080\u0026#34; You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure. Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: EC2_public_ip = \u0026#34;https://54.164.75.253/8080\u0026#34; Visualizar todos los atributos # También existe la posibilidad de que queramos visualizar todos los atributos creados por el recurso y en ese caso lo único que hacemos es llamar al recurso en el que estamos interesados, sin solicitar el atributo:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;TerraformEC2Instance\u0026#34; } } # Listamos todos los atributos asociados al recurso. output \u0026#34;EC2_public_ip\u0026#34; { value = aws_instance.terraformec2 } De esta forma, cuando se implementen los cambios mediante terraform apply se nos listaran todos los atributos de la instancia creada o modificada. La salida del comando será:\nEC2_public_ip = { \u0026#34;ami\u0026#34; = \u0026#34;ami-0d7a109bf30624c99\u0026#34; \u0026#34;arn\u0026#34; = \u0026#34;arn:aws:ec2:us-east-1:657164278704:instance/i-0b06b34e6d78c33e3\u0026#34; \u0026#34;associate_public_ip_address\u0026#34; = true \u0026#34;availability_zone\u0026#34; = \u0026#34;us-east-1a\u0026#34; \u0026#34;capacity_reservation_specification\u0026#34; = tolist([ { \u0026#34;capacity_reservation_preference\u0026#34; = \u0026#34;open\u0026#34; \u0026#34;capacity_reservation_target\u0026#34; = tolist([]) }, ]) \u0026#34;cpu_core_count\u0026#34; = 1 \u0026#34;cpu_options\u0026#34; = tolist([ { \u0026#34;amd_sev_snp\u0026#34; = \u0026#34;\u0026#34; \u0026#34;core_count\u0026#34; = 1 \u0026#34;threads_per_core\u0026#34; = 1 }, ]) \u0026#34;cpu_threads_per_core\u0026#34; = 1 \u0026#34;credit_specification\u0026#34; = tolist([ { \u0026#34;cpu_credits\u0026#34; = \u0026#34;standard\u0026#34; }, ]) \u0026#34;disable_api_stop\u0026#34; = false \u0026#34;disable_api_termination\u0026#34; = false \u0026#34;ebs_block_device\u0026#34; = toset([]) \u0026#34;ebs_optimized\u0026#34; = false \u0026#34;enclave_options\u0026#34; = tolist([ { \u0026#34;enabled\u0026#34; = false }, ]) \u0026#34;ephemeral_block_device\u0026#34; = toset([]) \u0026#34;get_password_data\u0026#34; = false \u0026#34;hibernation\u0026#34; = false \u0026#34;host_id\u0026#34; = \u0026#34;\u0026#34; \u0026#34;host_resource_group_arn\u0026#34; = tostring(null) \u0026#34;iam_instance_profile\u0026#34; = \u0026#34;\u0026#34; \u0026#34;id\u0026#34; = \u0026#34;i-0b06b34e6d78c33e3\u0026#34; \u0026#34;instance_initiated_shutdown_behavior\u0026#34; = \u0026#34;stop\u0026#34; \u0026#34;instance_lifecycle\u0026#34; = \u0026#34;\u0026#34; \u0026#34;instance_market_options\u0026#34; = tolist([]) \u0026#34;instance_state\u0026#34; = \u0026#34;running\u0026#34; \u0026#34;instance_type\u0026#34; = \u0026#34;t2.micro\u0026#34; \u0026#34;ipv6_address_count\u0026#34; = 0 \u0026#34;ipv6_addresses\u0026#34; = tolist([]) \u0026#34;key_name\u0026#34; = \u0026#34;\u0026#34; \u0026#34;launch_template\u0026#34; = tolist([]) \u0026#34;maintenance_options\u0026#34; = tolist([ { \u0026#34;auto_recovery\u0026#34; = \u0026#34;default\u0026#34; }, ]) \u0026#34;metadata_options\u0026#34; = tolist([ { \u0026#34;http_endpoint\u0026#34; = \u0026#34;enabled\u0026#34; \u0026#34;http_protocol_ipv6\u0026#34; = \u0026#34;disabled\u0026#34; \u0026#34;http_put_response_hop_limit\u0026#34; = 2 \u0026#34;http_tokens\u0026#34; = \u0026#34;required\u0026#34; \u0026#34;instance_metadata_tags\u0026#34; = \u0026#34;disabled\u0026#34; }, ]) \u0026#34;monitoring\u0026#34; = false \u0026#34;network_interface\u0026#34; = toset([]) \u0026#34;outpost_arn\u0026#34; = \u0026#34;\u0026#34; \u0026#34;password_data\u0026#34; = \u0026#34;\u0026#34; \u0026#34;placement_group\u0026#34; = \u0026#34;\u0026#34; \u0026#34;placement_partition_number\u0026#34; = 0 \u0026#34;primary_network_interface_id\u0026#34; = \u0026#34;eni-068b4fadf95051f06\u0026#34; \u0026#34;private_dns\u0026#34; = \u0026#34;ip-172-31-86-101.ec2.internal\u0026#34; \u0026#34;private_dns_name_options\u0026#34; = tolist([ { \u0026#34;enable_resource_name_dns_a_record\u0026#34; = false \u0026#34;enable_resource_name_dns_aaaa_record\u0026#34; = false \u0026#34;hostname_type\u0026#34; = \u0026#34;ip-name\u0026#34; }, ]) \u0026#34;private_ip\u0026#34; = \u0026#34;172.31.86.101\u0026#34; \u0026#34;public_dns\u0026#34; = \u0026#34;ec2-54-164-75-253.compute-1.amazonaws.com\u0026#34; \u0026#34;public_ip\u0026#34; = \u0026#34;54.164.75.253\u0026#34; \u0026#34;root_block_device\u0026#34; = tolist([ { \u0026#34;delete_on_termination\u0026#34; = true \u0026#34;device_name\u0026#34; = \u0026#34;/dev/xvda\u0026#34; \u0026#34;encrypted\u0026#34; = false \u0026#34;iops\u0026#34; = 3000 \u0026#34;kms_key_id\u0026#34; = \u0026#34;\u0026#34; \u0026#34;tags\u0026#34; = tomap({}) \u0026#34;tags_all\u0026#34; = tomap({}) \u0026#34;throughput\u0026#34; = 125 \u0026#34;volume_id\u0026#34; = \u0026#34;vol-0f459e140ba7ca838\u0026#34; \u0026#34;volume_size\u0026#34; = 8 \u0026#34;volume_type\u0026#34; = \u0026#34;gp3\u0026#34; }, ]) \u0026#34;secondary_private_ips\u0026#34; = toset([]) \u0026#34;security_groups\u0026#34; = toset([ \u0026#34;default\u0026#34;, ]) \u0026#34;source_dest_check\u0026#34; = true \u0026#34;spot_instance_request_id\u0026#34; = \u0026#34;\u0026#34; \u0026#34;subnet_id\u0026#34; = \u0026#34;subnet-09096255cb789eefc\u0026#34; \u0026#34;tags\u0026#34; = tomap({ \u0026#34;Name\u0026#34; = \u0026#34;TerraformEC2Instance\u0026#34; }) \u0026#34;tags_all\u0026#34; = tomap({ \u0026#34;Name\u0026#34; = \u0026#34;TerraformEC2Instance\u0026#34; }) \u0026#34;tenancy\u0026#34; = \u0026#34;default\u0026#34; \u0026#34;timeouts\u0026#34; = null /* object */ \u0026#34;user_data\u0026#34; = tostring(null) \u0026#34;user_data_base64\u0026#34; = tostring(null) \u0026#34;user_data_replace_on_change\u0026#34; = false \u0026#34;volume_tags\u0026#34; = tomap(null) /* of string */ \u0026#34;vpc_security_group_ids\u0026#34; = toset([ \u0026#34;sg-08548269db38a916f\u0026#34;, ]) }* Valores referenciados a través de otros proyectos # Estas variables de salida, pueden ser compartidas mediante otros scripts de Terraform que no necesariamente deban estar o situarse dentro del mismo proyecto. Esto es así ya que como se mencionó anteriormente, Terraform luego de aplicar el comando terraform plan o el comando terraform apply crea o modifica el archivo terraform.tfstate donde se mantiene el estado actual de todos los recursos y atributos creados.\nEs posible que un Proyecto B acceda a la variable de salida de un Proyecto A para poder incorporarlo en la infraestructura a desplegar por éste último.\nSi bien esto se verá en lecciones posteriores, se hace mención para que se sepa que estas variables de salida son de un uso mucho más extenso que simplemente imprimirse por pantalla.\nContinuará \u0026hellip; # En la próxima parte, estaremos viendo las variables en Terraform.\n¡Abrazo de gol!\n","date":"3 diciembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part3/","section":"Publicaciones","summary":"\u003ch2 class=\"relative group\"\u003eOutput Values\n    \u003cdiv id=\"output-values\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#output-values\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\n\u003ch3 class=\"relative group\"\u003e¿Qué son los valores de salida?\n    \u003cdiv id=\"qué-son-los-valores-de-salida\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#qu%c3%a9-son-los-valores-de-salida\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h3\u003e\n\u003cp\u003eEn Terraform, los \u003cstrong\u003eoutput values\u003c/strong\u003e (valores de salida) son una forma de exponer información útil o resultados específicos después de que se ha aplicado la\nconfiguración de infraestructura. Estos valores pueden ser variables, atributos o cualquier otra información generada como resultado de la ejecución de la\nconfiguración de Terraform.\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 3","type":"publicaciones"},{"content":" Creando una IP Elástica con Terraform # Advertencia sobre el costo # Es importante tener en cuenta que si una IP elástica está asociada a una instancia en ejecución, no se incurre en cargos adicionales por la IP elástica mientras la instancia esté en ejecución. Sin embargo, si una instancia se detiene y la IP elástica sigue desplegada (es decir, que no se ha eliminado) pero no se encuentra asociada a ninguna instancia en ejecución, se pueden aplicar cargos por la IP elástica no utilizada.\nEs recomendable revisar la documentación oficial de AWS o consultar directamente la página de precios de AWS para obtener información actualizada sobre los costos de las IP elásticas en la región específica en la que estés utilizando los servicios de AWS.\n¿Qué es una IP Elástica en AWS? # Una IP elástica en Amazon Web Services (AWS) es una dirección IP estática que puedes asignar a instancias en ejecución en la nube de AWS. A diferencia de las direcciones IP estáticas tradicionales, las IP elásticas de AWS se pueden asociar y desasociar de instancias en ejecución de forma dinámica, lo que proporciona flexibilidad en la gestión de la infraestructura de red.\nLas IP elásticas son útiles en situaciones donde necesitas que una instancia tenga una dirección IP fija y predecible, por ejemplo, para alojar un sitio web o una aplicación con acceso público. Además, las IP elásticas pueden ser migradas entre diferentes instancias, lo que facilita la re asignación de direcciones IP en caso de fallas o actualizaciones de instancias.\nEs importante destacar que AWS cobra por el uso de IP elásticas que no estén asociadas a instancias en ejecución, pero no cobra por las IP elásticas asociadas a instancias en ejecución. Esto las convierte en una herramienta flexible para la gestión de la infraestructura en la nube de AWS.\nPráctica: nueva Elastic IP # Como siempre, nos basamos en la documentación para poder construir los recursos necesarios\nEl código de muestra es:\nresource \u0026#34;aws_eip\u0026#34; \u0026#34;lb\u0026#34; { instance = aws_instance.web.id domain = \u0026#34;vpc\u0026#34; } Como vemos, el código requiere de una instancia para ser adosada. Por lo tanto copiamos el código de la primera instancia creada de EC2, por lo que el código quedaría de la siguiente manera:\nprovider \u0026#34;aws\u0026#34;{ region = \u0026#34;us-east-1\u0026#34; access_key = \u0026#34;my-access-key\u0026#34; # Modificar con tu propia access-key secret_key = \u0026#34;my-secret-key\u0026#34; # Modificar con tu propia secret-key } resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;TerraformElasticIp\u0026#34; } } resource \u0026#34;aws_eip\u0026#34; \u0026#34;lb\u0026#34; { instance = aws_instance.terraformec2.id domain = \u0026#34;vpc\u0026#34; } Comando: terraform destroy # Luego de haber generado los recursos, debemos de eliminarlos por completo haciendo uso del comando terraform destroy -auto-approbe\nEsto lo realizamos para que no haya ninguna probabilidad de que nos quede desplegada una IP elástica sin asociar a ninguna instancia.\nAtributos básicos # ¿Qué son los atributos? # En Terraform, un atributo para un recurso se refiere a una propiedad específica o un valor dentro de un recurso definido en un archivo de configuración de Terraform. Los recursos en Terraform representan componentes de infraestructura, como instancias de máquinas virtuales, redes, bases de datos, entre otros.\nCuando defines un recurso en un archivo de configuración de Terraform, como por ejemplo un recurso de instancia de máquina virtual en un proveedor de nube, ese recurso tendrá una serie de atributos que puedes configurar. Estos atributos son propiedades específicas que controlan cómo se crea y se gestiona el recurso. Por ejemplo, para una instancia de máquina virtual, algunos atributos comunes podrían ser el tamaño de la instancia, la imagen de sistema operativo a utilizar, las direcciones IP, la configuración de red, etc.\nAquí hay un ejemplo simplificado de un recurso de instancia de máquina virtual en Terraform con algunos atributos configurados:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;example\u0026#34; { ami = \u0026#34;ami-0c55b159cbfafe1f0\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; subnet_id = \u0026#34;subnet-12345678\u0026#34; key_name = \u0026#34;my_key\u0026#34; } En este ejemplo:\nami, instance_type, subnet_id, y key_name son atributos del recurso aws_instance. ami define la Amazon Machine Image (AMI) que se utilizará para lanzar la instancia. instance_type especifica el tipo de instancia. subnet_id indica en qué subred se lanzará la instancia. key_name especifica el par de claves SSH que se utilizará para acceder a la instancia. Los atributos pueden variar según el proveedor de la nube y el tipo de recurso que estemos utilizando en nuestra configuración de Terraform. Cada recurso tiene su propio conjunto de atributos que se pueden configurar para ajustarse a nuestras necesidades específicas de infraestructura.\nDocumentación de los atributos # En todo recurso gestionado por Terraform, tendremos la sección correspondiente en la documentación, por ejemplo, para las instancias de AWS se tiene el siguiente link\nPráctica # Seguimos utilizando el archivo de la lección nº 38. Una vez que aplicamos el plan de terraform, vamos a ver que en el directorio se crea un archivo denominado terraform.tfstate.\nSi lo analizamos, este archivo lo que tiene es toda la información que recolecta Terraform de los recursos creados. Podremos observar que hay una sección destinada a ambos recursos (EIP y EC2) denominado como attributes:\n\u0026#34;instances\u0026#34;: [ { \u0026#34;schema_version\u0026#34;: 1, \u0026#34;attributes\u0026#34;: { \u0026#34;ami\u0026#34;: \u0026#34;ami-0d7a109bf30624c99\u0026#34;, \u0026#34;arn\u0026#34;: \u0026#34;arn:aws:ec2:us-east-1:657164278704:instance/i-05a77de4d83cc5438\u0026#34;, \u0026#34;associate_public_ip_address\u0026#34;: true, \u0026#34;availability_zone\u0026#34;: \u0026#34;us-east-1a\u0026#34;, \u0026#34;capacity_reservation_specification\u0026#34;: [ { \u0026#34;capacity_reservation_preference\u0026#34;: \u0026#34;open\u0026#34;, \u0026#34;capacity_reservation_target\u0026#34;: [] } ], ... # Muchas cosas más ], \u0026#34;ephemeral_block_device\u0026#34;: [], \u0026#34;get_password_data\u0026#34;: false, \u0026#34;hibernation\u0026#34;: false, \u0026#34;host_id\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;host_resource_group_arn\u0026#34;: null, \u0026#34;iam_instance_profile\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;i-05a77de4d83cc5438\u0026#34;, \u0026#34;instance_initiated_shutdown_behavior\u0026#34;: \u0026#34;stop\u0026#34;, \u0026#34;instance_lifecycle\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;instance_market_options\u0026#34;: [], \u0026#34;instance_state\u0026#34;: \u0026#34;running\u0026#34;, \u0026#34;instance_type\u0026#34;: \u0026#34;t2.micro\u0026#34;, \u0026#34;ipv6_address_count\u0026#34;: 0, \u0026#34;ipv6_addresses\u0026#34;: [], \u0026#34;key_name\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;launch_template\u0026#34;: [], \u0026#34;maintenance_options\u0026#34;: [ ... Como vemos, la información desplegada en este archivo se obtiene de lo generado por Terraform en el proveedor de AWS. La información obtenida es la que se va actualizando cada vez que se invoca el comando terraform plan o terraform apply.\nLo que podemos hacer con este archivo, es ir a la documentación de Terraform del recurso que hayamos aplicado los cambios, buscar el atributo deseado y luego buscarlo en el archivo terraform.tfstate. Por ejemplo, desde la documentación relacionada a la instancia, podemos buscar lo siguiente: host_resource_group y nos encontraremos con este link.\nPara entender cada uno de los atributos listados en el archivo terraform.tfstate es conveniente buscarlos en la documentación relacionada al recurso de esos atributos. Todos los atributos de algún recurso generados mediante Terraform se generarán en el archivo terraform.tfstate, por más nosotros no hayamos declarado el atributo de manera formal dentro del script, algunos valores se generarán de manera automática y se guardarán dentro de este archivo.\nReferencias cruzadas para los atributos de un Recurso # En los ambientes productivos, lo que se tienen son muchos recursos generados a partir de otros recursos, o quizás de atributos que dependan de una variable que se encuentra en otro recurso, por lo tanto es muy difícil poder relacionar cada atributo con cada recurso.\nPensemos que podemos tener:\nPor un lado la creación de una Elastic IP (EIP) en AWS Por el otro, un Security Group el cual tenga una inbound rule que permita el ingreso de todo el tráfico proveniente de la EIP. Como vemos, el segundo recurso, es decir, el Security Group, depende de un valor del primer recurso (EIP).\nRequerimiento # El siguiente será el flujo de trabajo que se debe realizar para que cada recurso se genere de forma, en orden correcto y sin generar error alguno:\nPrimero deberá de crearse el recurso de la Elastic IP y de esta forma obtener su dirección IP. Luego deberá de crearse el recurso de SG el cual tendrá una inbound rule asociada para que todo el tráfico proveniente de la dirección IP del recurso EIP no se vea eliminado por el firewall. Entonces la pregunta es ¿cómo lograr esto? ¿cómo lograr asegurarnos que un recurso se creará primero que otro para que las dependencias se satisfasgan de manera efectiva?.\nPráctica # Como parte de la solución, lo que debemos hacer como primera medida es investigar los atributos relacionados a la EIP y para ello vamos a la documentación de Terraform\nAquí podremos ver un montón de atributos de los que nos podemos servir para lograr nuestro cometido. Como por ejemplo, podemos ver que un atributo que Terraform obtendrá será el de la public_ip que es la dirección IP que nosotros buscamos para poder generar la inbound rule de nuestro recurso SG.\nHasta ahora podemos notar que ya hemos completado parte de la solución, ya que sabemos que un atributo de nuestro recurso EIP será el que debamos utilizar en la definición de nuestra inbound rule.\nTerraform tiene una característica que nos permite referenciar un atributo de un recurso y utilizarlo como atributo en otro recurso.\nY la forma de referenciar ese atributo es mediante la siguiente nomenclatura: \u0026lt;RESOURCE-TYPE\u0026gt;.\u0026lt;LOCAL-NAME\u0026gt;.\u0026lt;ATTRIBUTE\u0026gt;\nPor lo tanto, si obtenemos el código del archivo SecurityGroup.tf e implementamos lo que se sugiere en esta lección, podemos obtener lo siguiente:\nresource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = aws_eip.lb.public_ip # -\u0026gt; Acá vemos cómo es que se referencia al EIP from_port = 80 ip_protocol = \u0026#34;tcp\u0026#34; to_port = 80 tags = { Name = \u0026#34;Terraform-InboundRule\u0026#34; } } resource \u0026#34;aws_eip\u0026#34; \u0026#34;lb\u0026#34; { instance = aws_instance.terraformec2.id domain = \u0026#34;vpc\u0026#34; tags = { Name = \u0026#34;ElasticIP from Terraform\u0026#34; } } Una de las características importantes que implementa Terraform es que va a entender cómo proceder en el orden de creación de los recursos para poder generarlos sin que haya problemas de obtener los atributos correctos entre dependencias.\nPero así como está el código, NO va a funcionar, porque debemos ver que al atributo que le asignamos la dirección pública del EIP, es decir cidr_ipv4 espera una cadena, además de un rango de direcciones IP, algo como \u0026ldquo;132.35.55.142/16\u0026rdquo; y para ello utilizamos una suplantación de variables como se utiliza en bash scripting (con ${}) denominada como interpolación de variables, quedando de la siguiente manera:\nresource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = \u0026#34;${aws_eip.lb.public_ip}/16\u0026#34; from_port = 80 ip_protocol = \u0026#34;tcp\u0026#34; to_port = 80 tags = { Name = \u0026#34;Terraform-InboundRule\u0026#34; } } resource \u0026#34;aws_eip\u0026#34; \u0026#34;lb\u0026#34; { instance = aws_instance.terraformec2.id domain = \u0026#34;vpc\u0026#34; tags = { Name = \u0026#34;ElasticIP from Terraform\u0026#34; } } De esta forma, la variable aws_eip.lb.public_ip será reemplazada por un string y convertida a un rango de direcciones junto con el /16 final.\nSalida del comando terraform apply # Una vez que invoquemos el comando terraform apply, en la salida podremos visualizar el orden en el que es construido cada uno de los recursos que estamos generando. Como dijimos anteriormente Terraform es lo bastante inteligente como para saber crear el orden de dependencias sin que nosotros se lo especifiquemos.\nCross Resource Attribute References # Advertencia # Para esta práctica construiremos los siguientes recursos:\nInstancia EC2. Security Group. Elastic IP asociada a la instancia. Inbound Rule asociada a SG y cuyo rango se obtiene de Elastic IP. Como se comentó anteriormente, el problema que existe, es que si el recurso Elastic IP no se encuentra relacionada a una instancia de AWS, se nos cobrará mucho más que el tenerla asociada. Por lo tanto, habrá que estar atentos de invocar el comando terraform destroy luego de haber finalizado esta práctica.\nPráctica # Lo que haremos es como se dijo en la lección anterior, el utilizar el siguiente código para poder generar 4 recursos para poder demostrar cómo es que se gestionan los atributos cruzados. Por lo tanto parte del código es el siguiente:\n## Instancia resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;TerraformEC2Instance\u0026#34; } } ## Security Group resource \u0026#34;aws_security_group\u0026#34; \u0026#34;terraform-firewall\u0026#34; { name = \u0026#34;terraform-firewall\u0026#34; description = \u0026#34;Managed from Terraform\u0026#34; tags = { Name = \u0026#34;Terraform-SG\u0026#34; } } ## Inbound Rule resource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = \u0026#34;${aws_eip.lb.public_ip}/32\u0026#34; from_port = 443 ip_protocol = \u0026#34;tcp\u0026#34; to_port = 443 tags = { Name = \u0026#34;Terraform-InboundRule\u0026#34; } } ## Elastic IP resource \u0026#34;aws_eip\u0026#34; \u0026#34;lb\u0026#34; { instance = aws_instance.terraformec2.id domain = \u0026#34;vpc\u0026#34; tags = { Name = \u0026#34;ElasticIP from Terraform\u0026#34; } } Luego de esto, invocamos el comando terraform plan y vamos a poder notar que el plan es crear 4 recursos:\nPlan: 4 to add, 0 to change, 0 to destroy. Aplicamos los cambios # Si luego ingresamos terraform apply entonces podremos obtener el orden de creación de cada uno de los recursos planificados:\naws_security_group.terraform-firewall: Creating... aws_instance.terraformec2: Creating... aws_security_group.terraform-firewall: Creation complete after 4s [id=sg-08b9710ca6334833c] aws_instance.terraformec2: Still creating... [10s elapsed] aws_instance.terraformec2: Still creating... [20s elapsed] aws_instance.terraformec2: Still creating... [30s elapsed] aws_instance.terraformec2: Creation complete after 35s [id=i-04efe94814c26bcdc] aws_eip.lb: Creating... aws_eip.lb: Creation complete after 3s [id=eipalloc-07b7caf93ff4e22f5] aws_vpc_security_group_ingress_rule.allow_80_ipv4: Creating... aws_vpc_security_group_ingress_rule.allow_80_ipv4: Creation complete after 1s [id=sgr-00fe1a384b40435a6] En esta salida podemos ver cómo fueron creados cada uno de los recursos y en el orden correcto para poder permitir que los valores que tienen referencia cruzada puedan ser invocados y creados sin ningún problema.\nLuego, lo que podemos hacer es verificar mediante el archivo terraform.tfstate los atributos creados para cada uno de los recursos, así como también podemos observarlo desde el lado de AWS.\nEn esta instancia, podemos ver que el valor asignado al atributo public_ip es el mismo para el recurso Elastic IP:\n\u0026#34;instances\u0026#34;: [ { \u0026#34;schema_version\u0026#34;: 0, \u0026#34;attributes\u0026#34;: { ... \u0026#34;private_ip\u0026#34;: \u0026#34;172.31.91.244\u0026#34;, \u0026#34;public_dns\u0026#34;: \u0026#34;ec2-54-157-225-150.compute-1.amazonaws.com\u0026#34;, \u0026#34;public_ip\u0026#34;: \u0026#34;54.157.225.150\u0026#34;, ... ## Elastic IP \u0026#34;type\u0026#34;: \u0026#34;aws_eip\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;lb\u0026#34;, \u0026#34;provider\u0026#34;: \u0026#34;provider[\\\u0026#34;registry.terraform.io/hashicorp/aws\\\u0026#34;]\u0026#34;, \u0026#34;instances\u0026#34;: [ { ... \u0026#34;private_ip\u0026#34;: \u0026#34;172.31.91.244\u0026#34;, \u0026#34;public_dns\u0026#34;: \u0026#34;ec2-54-157-225-150.compute-1.amazonaws.com\u0026#34;, \u0026#34;public_ip\u0026#34;: \u0026#34;54.157.225.150\u0026#34;, \u0026#34;public_ipv4_pool\u0026#34;: \u0026#34;amazon\u0026#34;, \u0026#34;tags\u0026#34;: { ... ## Inbound Rule \u0026#34;name\u0026#34;: \u0026#34;allow_80_ipv4\u0026#34;, \u0026#34;provider\u0026#34;: \u0026#34;provider[\\\u0026#34;registry.terraform.io/hashicorp/aws\\\u0026#34;]\u0026#34;, \u0026#34;instances\u0026#34;: [ { \u0026#34;schema_version\u0026#34;: 0, \u0026#34;attributes\u0026#34;: { \u0026#34;arn\u0026#34;: \u0026#34;arn:aws:ec2:us-east-1:657164278704:security-group-rule/sgr-00fe1a384b40435a6\u0026#34;, \u0026#34;cidr_ipv4\u0026#34;: \u0026#34;54.157.225.150/32\u0026#34;, ... Por lo tanto, podemos ver que se han creado con satisfacción y de forma correcta todos los valores cruzados de los recursos que teníamos planificados.\nComando Terraform destroy # Cuando aplicamos el comando terraform destroy podemos observar que Terraform automáticamente sabe cómo destruir los recursos de forma correcta para que no haya errores:\nPlan: 0 to add, 0 to change, 4 to destroy. aws_vpc_security_group_ingress_rule.allow_80_ipv4: Destroying... [id=sgr-00fe1a384b40435a6] aws_vpc_security_group_ingress_rule.allow_80_ipv4: Destruction complete after 1s aws_eip.lb: Destroying... [id=eipalloc-07b7caf93ff4e22f5] aws_security_group.terraform-firewall: Destroying... [id=sg-08b9710ca6334833c] aws_security_group.terraform-firewall: Destruction complete after 2s aws_eip.lb: Destruction complete after 2s aws_instance.terraformec2: Destroying... [id=i-04efe94814c26bcdc] aws_instance.terraformec2: Still destroying... [id=i-04efe94814c26bcdc, 10s elapsed] aws_instance.terraformec2: Still destroying... [id=i-04efe94814c26bcdc, 20s elapsed] aws_instance.terraformec2: Still destroying... [id=i-04efe94814c26bcdc, 30s elapsed] aws_instance.terraformec2: Still destroying... [id=i-04efe94814c26bcdc, 40s elapsed] aws_instance.terraformec2: Destruction complete after 42s Creación a la mitad # También podría suceder la siguiente secuencia de acciones:\nUna vez que finalizamos de generar nuestro código en Terraform, aplicamos el comando terraform validate para saber si nuestro código escrito es correcto. Luego aplicamos el comando terraform plan para que nos cree un plan de forma correcta Luego aplicamos el comando terraform apply. Pero en este punto puede suceder que parte de los recursos se crearon de forma correcta y luego por algún error, el comando terraform apply sale con un error inesperado. Solución a la creación parcial # ¿Qué sucede con esta situación? Podemos optar por dos opciones:\nResolver las cosas de manera manual (NO ES LO RECOMENDADO). En esta opción, lo que nos puede quedar por crear quizás es la regla inbound rule y quizás pueda generarse mediante la consola de AWS. En este caso quizás lo que pueda suceder es que si lo solucionamos a mano y luego modificamos el código agregando la solución y otros recursos, y luego el comando terraform plan y terraform apply, puede que quede sanjado el problema. La segunda solución (y la recomendada) es destruir todo y comenzar de nuevo. Por lo tanto, primero llamar a terraform destroy para que se elimine parte de los recursos creados, solucionar el error en el código y luego volver a invocar al comando terraform apply. De esta forma tenemos el estado desired state igual que el current state y todo sigue funcionando sin problema alguno mediante Terraform. Advertencia sobre plan y apply # Si bien el comando terraform plan nos puede servir para diagramar el plan a implementar, esto no significa que una vez que invoquemos el comando terraform apply este vaya a funcionar correctamente. Por lo tanto hay que tener en mente cómo proceder en caso de que el comando terraform apply no funcione como esperábamos.\nContinuará\u0026hellip; # En la próxima parte estaremos viendo lo que son los outputs values, su utilidad y porqué son tan importantes para nuestro día a día.\n¡Hasta pronto!\n","date":"2 diciembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part2/","section":"Publicaciones","summary":"\u003ch2 class=\"relative group\"\u003eCreando una IP Elástica con Terraform\n    \u003cdiv id=\"creando-una-ip-elástica-con-terraform\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#creando-una-ip-el%c3%a1stica-con-terraform\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\n\u003ch3 class=\"relative group\"\u003eAdvertencia sobre el costo\n    \u003cdiv id=\"advertencia-sobre-el-costo\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#advertencia-sobre-el-costo\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h3\u003e\n\u003cp\u003eEs importante tener en cuenta que si una IP elástica está asociada a una instancia en ejecución, \u003cstrong\u003eno se incurre en cargos adicionales\u003c/strong\u003e por la IP elástica mientras la instancia \u003cstrong\u003eesté en ejecución\u003c/strong\u003e. Sin embargo, si una instancia se detiene y la IP elástica sigue desplegada (es decir, que no se ha eliminado) pero no se encuentra asociada a ninguna instancia en ejecución, se pueden aplicar cargos por la \u003cstrong\u003eIP elástica no utilizada\u003c/strong\u003e.\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 2","type":"publicaciones"},{"content":" Sección nº 4 # Vista general sobre la sección actual # En esta sección iremos viendo distintas configuraciones permitidas en Terraform. Para ello es preferible mantener ordenadas las carpetas que nosotros vayamos a crear para mantener dentro de ellas todos los scripts relacionadas a las distintas secciones de aprendizaje de la herramienta, como pueden ser:\nCreación de las instancias de EC2 Recursos de tutoría Expresiones condicionales Uno de los repositorios donde se tienen varios ejemplos de lo que hablaremos en esta sección, es el siguiente:\nGitHub Repository: https://github.com/zealvora/terraform-beginner-to-advanced-resource Importante: utilizar terraform destroy # Siempre debemos destruir los recursos luego de haber finalizado la práctica mediante el comando terraform destroy. Esto nos permitirá evitar gastar dinero con recursos que quedarán generados en el proveedor de AWS de manera obsoleta.\nAlcance del tutorial # Debemos de comprender que este tutorial está pensado para poner de manifiesto las ventajas de utilizar Terraform para orquestar y gestionar nuestra infraestructura. Es importante notar que de ninguna manera se hará uso de casi los 200 servicios que tiene Amazon desplegados en su nube. Simplemente se utilizarán aquellos servicios básicos que generen menos gastos al usuario.\nPor lo tanto, se utilizarán pocos servicios de AWS que sean soporte para que podamos entender los conceptos fundamentales de Terraform como herramienta de IaC. Algunos de los los servicios a utilizar de AWS son:\nEC2 Security Groups (firewalls) IAM Users Elastic IP (Public IP address) Quizás algún otro servicio para demostrar alguna particularidad de Terraform. Cuando haga falta, se hará una introducción a cada uno de los servicios de AWS que iremos viendo para que se comprenda mejor el uso que le daremos.\nEn caso de que se tenga el conocimiento de lo que es un Firewall o un Security groups por ejemplo, entonces daremos una introducción sobre ellos.\nConceptos básicos de Firewall en AWS # Introducción a los puertos # En Internet, la comunicación entre dispositivos se realiza a través de protocolos de red, como el Protocolo de Control de Transmisión (TCP) o el Protocolo de Datagramas de Usuario (UDP). Los puertos son números de identificación asociados con direcciones IP que permiten que múltiples servicios o aplicaciones se comuniquen simultáneamente en un mismo dispositivo.\nAquí hay algunas funciones clave de los puertos en Internet:\nIdentificación de servicios: Los puertos permiten que múltiples servicios se ejecuten en una sola máquina. Cada servicio tiene asignado un número de puerto único. Por ejemplo, el servicio web generalmente utiliza el puerto 80 para HTTP y el puerto 443 para HTTPS.\nMultiplexación: Los puertos permiten que una única dirección IP pueda admitir múltiples conexiones simultáneas. Esto se logra asignando diferentes números de puerto a cada conexión. Cuando un paquete de datos llega a una máquina, el sistema operativo lo dirige al proceso correspondiente en función del puerto al que está dirigido.\nComunicación cliente-servidor: Los puertos facilitan la comunicación entre clientes y servidores. Cuando un cliente solicita un servicio a un servidor (por ejemplo, una página web), el cliente envía la solicitud al puerto específico asociado con ese servicio en el servidor. El servidor luego responde al cliente a través del mismo puerto.\nSeguridad: Los puertos también pueden utilizarse para controlar el acceso a servicios específicos. Por ejemplo, un firewall puede configurarse para permitir o bloquear el tráfico en ciertos puertos, lo que ayuda a proteger la red contra ataques maliciosos.\nPor lo tanto, los puertos en Internet son herramientas fundamentales que permiten la comunicación entre dispositivos, la identificación de servicios y la seguridad en la red. Son una parte esencial de cómo funcionan las redes informáticas y son utilizados por ingenieros de software y administradores de redes para garantizar un funcionamiento eficiente y seguro de los sistemas.\nHay que entender que cada aplicación que esté corriendo el servidor, escuchará en un puerto determinado. Estos puertos pueden ser conocidos o no, pero siempre una aplicación deberá de tener asociada un puerto determinado.\nAWS: Apertura de puertos # Si queremos saber los puertos que se encuentran abiertos en alguna instancia de AWS que estemos corriendo (siempre que sea de tipo Linux), deberemos de conectarnos a ella tanto por SSH o por CloudShell e ingresar:\nPara listar los puertos: netstat -ntlp Si tenemos una instancia levantada en AWS, podremos ver que los puertos que se encuentran posiblemente abiertos sean los los puertos 22 (SSH) y el puerto 80 (HTTP) Conceptos básicos de firewall # Un firewall es un componente de seguridad fundamental en redes informáticas que controla y regula el tráfico de red basado en un conjunto de reglas predefinidas. Su función principal es proteger una red privada o un dispositivo de accesos no autorizados, ataques maliciosos y otros riesgos de seguridad en Internet.\nAquí hay algunos conceptos clave relacionados con los firewalls:\nFiltrado de paquetes: Un firewall puede inspeccionar los paquetes de datos que entran y salen de una red. Puede permitir o bloquear paquetes basándose en criterios como la dirección IP de origen o destino, el número de puerto, el tipo de protocolo, entre otros.\nControl de acceso: Los firewalls pueden configurarse para permitir o bloquear el tráfico en función de reglas específicas. Por ejemplo, se pueden establecer reglas para permitir el acceso solo a ciertos servicios o para bloquear ciertos tipos de tráfico conocidos por ser maliciosos.\nNAT (Traducción de Dirección de Red): Algunos firewalls también pueden realizar funciones de NAT, que permiten que múltiples dispositivos en una red privada compartan una única dirección IP pública. Esto ayuda a proteger la identidad y la seguridad de los dispositivos internos.\nInspección de estado: Los firewalls de inspección de estado pueden monitorear el estado de las conexiones de red y permitir el tráfico de datos asociado con conexiones establecidas legítimamente. Esto ayuda a prevenir ataques como los de denegación de servicio (DDoS) y otros intentos de explotar conexiones no autorizadas.\nSeguridad perimetral: Los firewalls suelen ubicarse en la frontera entre una red privada y una red pública, como Internet. Esta posición estratégica les permite proteger la red interna de amenazas externas.\nPor lo tanto, un firewall es una barrera de seguridad muy importante que protege las redes informáticas al controlar el tráfico de red según reglas predefinidas. Ayuda a prevenir accesos no autorizados, ataques maliciosos y otras amenazas, y es una parte fundamental de la infraestructura de seguridad de cualquier red, ya sea a nivel de red doméstica, empresarial o de proveedores de servicios de Internet.\nAWS: Security Groups # En el contexto de AWS (Amazon Web Services), un Security Group es un mecanismo de seguridad que actúa como un firewall virtual para controlar el tráfico de red hacia y desde las instancias de EC2 (Elastic Compute Cloud), así como también para otras instancias de servicios de AWS que pueden estar asociadas.\nAquí hay algunos puntos clave sobre los Security Groups en AWS:\nControl de acceso: Al igual que un firewall tradicional, un Security Group permite definir reglas para permitir o bloquear el tráfico de red basado en direcciones IP de origen, direcciones IP de destino, números de puerto y protocolos.\nAsociación con instancias: Cada instancia de EC2 en AWS debe estar asociada con uno o más Security Groups. Estos grupos controlan el tráfico de red hacia y desde la instancia.\nReglas de seguridad: Las reglas de un Security Group pueden ser configuradas para permitir el acceso desde ciertas direcciones IP, rangos de direcciones IP, o desde otras instancias de AWS que estén en el mismo grupo o en grupos específicos.\nImplementación dinámica: Los cambios en la configuración de los Security Groups se aplican de manera casi inmediata, lo que permite una gestión ágil y flexible de la seguridad de la red en la nube.\nDefensa en profundidad: Los Security Groups se pueden utilizar en conjunto con otras medidas de seguridad de AWS, como listas de control de acceso (ACL) de red y reglas de enrutamiento, para proporcionar una defensa en profundidad y una seguridad robusta para las aplicaciones alojadas en la nube.\nPor lo tanto un Security Group en AWS es una forma de controlar y gestionar la seguridad del tráfico de red hacia y desde las instancias de EC2 y otros servicios de AWS. Funciona de manera similar a un firewall tradicional, pero está diseñado específicamente para entornos de nube y se integra estrechamente con otros servicios de AWS para proporcionar una seguridad integral en la nube.\nTambién debemos recordar que un Security Group permite establecer tanto reglas para la entrada de datos (inbound rules) hacia la instancia como también los datos que pueden salir desde la instancia hacia internet (outbound rules).\nPráctica de Security Groups # Si el usuario sabe cómo abordar la creación de una instancia de EC2 mediante la consola de AWS, lo animo a que juegue con los Security Groups para evidenciar cómo pueden ser configurados. En caso de que el estudiante no sepa cómo realizarlo, posteriormente publicaré un extenso tutorial sobre la certificación de AWS Developer donde se abordarán estos temas con sumo cuidado.\nCreando reglas de Firewall (Firewalls Rules) usando Terraform # A continuación lo que haremos será crear los siguientes recursos en AWS utilizando Terraform:\nUn Security Group (firewall de AWS) llamado localmente terraform-firewall Una regla de entrada (inbound rule): allow 80 from 0.0.0.0/0 Otra regla de salida (outbound rule): allow all Terraform siempre va a tener en su documentación los distintos servicios a los que dará soporte. En este caso como vamos a generar un Security Group, lo que podríamos buscar es la documentación de Terraform basado en el servicio de Security Groups (SG) para AWS. Por lo tanto podremos buscar en internet algo como \u0026ldquo;Terraform Security Group\u0026rdquo;.\nEl link es el siguiente A la hora de haber sido generado este tutorial, podemos observar en el link, que hubieron cambios en la definición del recurso con respecto a las reglas de entrada y de salida, por lo tanto a los nuevos recursos definidos, hay que llamarlos como aws_vpc_security_group_egress_rule y aws_vpc_security_group_ingress_rule.\nPráctica: create SG # Lo que haremos es copiar el ejemplo que nos provee la documentación de Terraform e ir realizando los cambios según nuestro requerimiento:\nresource \u0026#34;aws_security_group\u0026#34; \u0026#34;allow_tls\u0026#34; { name = \u0026#34;allow_tls\u0026#34; description = \u0026#34;Allow TLS inbound traffic and all outbound traffic\u0026#34; vpc_id = aws_vpc.main.id tags = { Name = \u0026#34;allow_tls\u0026#34; } } Para esta primera parte, lo que hay que tener en cuenta es que tiene las mismas características que si generaríamos el recurso mediante la consola web de AWS, ya que tendríamos que ingresar para ello un nombre, una descripción, y una VPC asociada. Por lo tanto, si sabemos cómo generar el recurso de forma manual, mediante Terraform nos será una tarea transparente.\nPor lo tanto, vamos completando nuestro script según el requerimiento expuesto al comienzo de la lección y lo llamamos terraform-securityGroup.tf:\nresource \u0026#34;aws_security_group\u0026#34; \u0026#34;terraform-firewall\u0026#34; { name = \u0026#34;terraform-firewall\u0026#34; description = \u0026#34;Managed from Terraform\u0026#34; #vpc_id = aws_vpc.main.id tags = { Name = \u0026#34;Terraform-SG\u0026#34; } } Podemos buscar a lo largo de la documentación y ver que el parámetro description como vpc_id son OPCIONALES, por lo tanto se pueden quitar o comentar (que es la opción que implementamos aquí).\nLuego de haber modificado el archivo, invocamos terraform init para descargar el provider y luego lo que hacemos es invocar el comando terraform plan. Si estamos de acuerdo con el plan, procedemos a invocar el comando terraform apply -auto-approve.\nSi vamos a la consola de AWS \u0026gt; EC2 \u0026gt; Security Group vamos a poder notar si el nuevo recurso se generó de forma satisfactoria. Pero veremos que no tiene ninguna regla de entrada ni de salida, por lo tanto deberemos de actualizar el script para poder generarlas.\nPráctica: creando reglas de SG # Acto seguido, a nuestro script le agregamos los siguientes bloques que conforman los inbound y outbound rules. Hay que notar lo siguiente:\nQue la nueva nomenclatura de Terraform sobre estas reglas son denominadas recursos, por lo tanto, en la documentación tienen entradas aparte, así como lo tiene el recurso de security group. Por lo tanto tenemos dos páginas distintas: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule El ejemplo que proporciona la documentación son para IPv4 e IPv6. Por lo tanto, lo que haremos es copiar la que se relaciona a IPv4. El código finalizado es el siguiente:\nresource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = \u0026#34;0.0.0.0/0\u0026#34; from_port = 80 ip_protocol = \u0026#34;tcp\u0026#34; to_port = 80 } resource \u0026#34;aws_vpc_security_group_egress_rule\u0026#34; \u0026#34;allow_all_traffic_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = \u0026#34;0.0.0.0/0\u0026#34; ip_protocol = \u0026#34;-1\u0026#34; # semantically equivalent to all ports } Para el recurso aws_vpc_security_group_ingress_rule hay que saber que:\nLo que debemos de notar es que el ID de cada variable para security group id se compone del recurso del SG (terraform-firewall) + .id (esta nomenclatura la veremos más adelante) Por otra parte, las opciones de from_port y to_port son para indicar un rango de puertos, por ejemplo 80-100. Esto se puede hacer configurando from_port = 80 y to_port = 100 Es importante también ver que la opción ip_protocol del recurso aws_vpc_security_group_egress_rule se puede configurar para que, o bien acepte todos los puertos y esto es lo que permite la opción -1 o especificarle qué puerto debe filtrar.\nPráctica: modificando la opción to_port # Ahora cambiemos la opción to_port del recurso aws_vpc_security_group_ingress_rule a 100 para que veamos lo dicho anteriormente con respecto a los rangos de los puertos. Por lo tanto, el código quedaría de la siguiente manera:\nresource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;allow_80_ipv4\u0026#34; { security_group_id = aws_security_group.terraform-firewall.id cidr_ipv4 = \u0026#34;0.0.0.0/0\u0026#34; from_port = 80 ip_protocol = \u0026#34;tcp\u0026#34; to_port = 100 } Generamos un plan con el comando terraform plan y luego aplicamos los cambios terraform apply para poder observar estos cambios en la consola de AWS.\nPráctica: agregar una inbound rule al Security Group por defecto # Otra característica interesante es que el recurso aws_vpc_security_group_ingress_rule por ejemplo, cuya opción es security_group_id no sólo soporta variables sino también el ID directamente obtenido del SG del Security Group ID. Por ejemplo, el ID de un SG por default que tiene mi cuenta personal de AWS es el siguiente: sg-08548269db38a916f. Por lo tanto, se lo asignaremos también a mi SG default.\nEl código queda de la siguiente manera:\nresource \u0026#34;aws_vpc_security_group_ingress_rule\u0026#34; \u0026#34;tempRule\u0026#34; { security_group_id = \u0026#34;sg-08548269db38a916f\u0026#34; cidr_ipv4 = \u0026#34;0.0.0.0/0\u0026#34; from_port = 80 ip_protocol = \u0026#34;tcp\u0026#34; to_port = 100 tags = { Name = \u0026#34;Terraform-tmpRule\u0026#34; } } Luego podemos ir a la consola de AWS y ver cómo ha impactado en el Security Group.\nActualizaciones de código en la documentación # Muchas veces Hashicorp actualiza la documentación referida a cada uno de los providers con los que trabaja ya que del lado del proveedor se agregan nuevas funcionalidades o se modifican otras para mejor funcionamiento.\nLo importante es entender que siempre vamos a necesitar la documentación a la hora de codificar en Terraform, ya que es imposible codificar de memoria cada uno de los recursos y cada una de las opciones.\nRetro-compatibilidad # Por lo anteriormente dicho, Terraform permite que cada una de los lanzamientos de las nuevas versiones de los providers sean retro compatibles con versiones anteriores, por lo que muchas nuevas viejas funcionalidades funcionarán con las nuevas versiones del plugin del provider.\nOtra cosa interesante es que en la documentación de Terraform, es posible visualizar que debajo de banner de Terraform, tengamos una referencia similar a Providers / hashicorp / aws / Version 5.42.0. Nótese que la versión es posible ingresar a ella con el mouse y listar las versiones viejas para poder tener a mano la documentación referida a esa versión en específica.\nTambién podemos basarnos en la versión que se encuentra explicitada en la URL, como por ejemplo:\nEsta es la versión actual: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group Esta es una versión vieja: https://registry.terraform.io/providers/hashicorp/aws/5.23.1/docs/resources/security_group Podemos ver que el tag latest se modifica por el número de versión vieja 5.23.1. Guiándonos de esta forma, también podemos abordar la documentación antigua.\nPuntos a tener en cuenta # Hashicorp recomienda siempre tener actualizados las nuevas funcionalidades de Terraform pero esto no significa que las viejas funcionalidades no funcionen con las nuevas versiones de los proveedores.\nPor lo dicho anteriormente, las organizaciones pueden estar tranquilas que su código no necesitará actualizarse constantemente y por lo tanto el código ya testeado no será necesario modificarlo en cada nueva versión.\nPara empresas muy grandes es mejor quedarse con una versión determinada del proveedor y por lo dicho anteriormente notamos que de ser así, no habrá inconvenientes acerca de que sigan funcionando los recursos codificados con el código antiguo.\nContinuará\u0026hellip; # En la próxima parte, estaremos viendo qué es una IP Elástica en AWS, y cómo crear este recurso de una manera sencilla. Además estaremos respasando los atributos de los recursos y cómo configurarlos.\n","date":"2 diciembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_04_configurations_part1/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003eSección nº 4\n    \u003cdiv id=\"sección-nº-4\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#secci%c3%b3n-n%c2%ba-4\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\n\u003ch2 class=\"relative group\"\u003eVista general sobre la sección actual\n    \u003cdiv id=\"vista-general-sobre-la-sección-actual\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#vista-general-sobre-la-secci%c3%b3n-actual\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003eEn esta sección iremos viendo distintas configuraciones permitidas en Terraform. Para ello es preferible mantener ordenadas las carpetas que nosotros vayamos a crear para mantener dentro de ellas todos los scripts relacionadas a las distintas secciones de aprendizaje de la herramienta, como pueden ser:\u003c/p\u003e","title":"04 - Configuraciones - Parte nº 1","type":"publicaciones"},{"content":" Sección nº 3 # Autenticación (Authentication) y Autorización (Authorization) # Para comenzar con Terraform, lo que primero debemos de generar son los accesos correctos para que Terraform pueda generar la infraestructura que nosotros le pedimos. Si nosotros no generamos estos accesos desde el lado de AWS, Terraform cada vez que quiera impactar los cambios solicitados, obtendrá un error como respuesta. AWS por defecto no permite que ningún servicio se conecte a su nube excepto que configuremos los accesos de forma correcta.\nPero primero hagamos la distinción entre Autenticación (Authentication y Authorization)\nAuthentication (Autenticación): La autenticación se refiere al proceso de verificar la identidad de un usuario o un sistema para asegurarse de que sean quienes dicen ser. En el contexto de AWS, la autenticación implica la verificación de las credenciales de acceso proporcionadas por un usuario o una aplicación para confirmar su identidad antes de permitirles acceder a los recursos y servicios de AWS. Las credenciales de acceso pueden incluir nombres de usuario y contraseñas, así como también tokens de acceso o certificados digitales.\nAuthorization (Autorización): La autorización se refiere al proceso de determinar qué acciones y recursos están permitidos para un usuario o una aplicación después de que su identidad haya sido autenticada con éxito. En el contexto de AWS, la autorización implica definir y aplicar políticas de acceso que determinen qué usuarios o roles tienen permiso para realizar acciones específicas en los recursos de AWS. Estas políticas de acceso se definen mediante el uso de AWS Identity and Access Management (IAM), y pueden basarse en una variedad de criterios, como identidades de usuario, grupos, roles, direcciones IP y más.\nLa autenticación en AWS verifica la identidad de un usuario o una aplicación, mientras que la autorización determina qué acciones y recursos están permitidos para ese usuario o aplicación después de la autenticación. Juntas, la autenticación y la autorización garantizan que solo los usuarios autorizados tengan acceso a los recursos y servicios de AWS según sus roles y permisos asignados.\nPor lo tanto, Terraform necesita el acceso a credenciales con determinados permisos dentro de la nube del proveedor para poder generar los deploys solicitados en el código. Por lo tanto, deberemos de tener un usuario y password que Terraform utilizará para poder ingresar a la nube de AWS y luego con los accesos gestionados para ese usuario, podrá desplegar la infraestructura requerida.\nDocumentación del Proveedor AWS: Autenticación # Algo importante a tener en cuenta es que para distintos proveedores existen distintas credenciales de acceso solicitados por Terraform. Por ejemplo, para AWS Terraform necesitará access_key y secret_key, por lo tanto, cada proveedor que utilicemos en Terraform, requerirá distintos medios de autenticación.\nPodemos revisar la documentación oficial de Terraform para el proveedor de AWS. Aquí podremos observar lo que necesitaremos gestionar desde el lado de AWS.\nEn esta documentación, se puede observar el proceso que genera Terraform para poder gestionar las solicitudes a la API de AWS. Se puede buscar en la sección \u0026lsquo;Provider Configuration\u0026rsquo; de la documentación, que explícitamente es necesario lo siguiente:\nprovider \u0026#34;aws\u0026#34; { region = \u0026#34;us-west-2\u0026#34; access_key = \u0026#34;my-access-key\u0026#34; secret_key = \u0026#34;my-secret-key\u0026#34; } Lo mismo sucede con otros providers como GitHub, Azure, etc. Por ejemplo, en Github, cuando un usuario externo le damos permisos al repositorio, podemos atomizar estos permisos y permitirle determiados accesos para determinadas acciones (lo que anteriormente denominamos como Autorización).\nCreación de usuario (AWS IAM) # Para esto, necesitaremos utilizar la cuenta Root de AWS e iremos al servicio de IAM para poder crear un nuevo usuario. Debemos tener especial cuidado cuando manipulamos la consola de AWS logueados con la cuenta de ROOT ya que tenemos el control total de la cuenta.\nNos logueamos a nuestra cuenta de AWS con el usuario Root Vamos al servicio de IAM \u0026gt; Users \u0026gt; Create User User Name: Terraform Permission \u0026gt; Attach policies directly Y seleccionamos el siguiente permiso: Administrator Access Create User Una vez que nuestro nuevo usuario se encuentra creado, lo que deberemos de hacer es:\nLo seleccionamos de la lista de IAM \u0026gt; Users En la pestaña Security Credentials \u0026gt; Create Access Key \u0026gt; CLI Agregamos alguna descripción que querramos Create Access Key ¡Cuidado! Hay que tener presente que estas credenciales se podrán ver por única vez en este paso, es por ello que por temas de seguridad, se recomienda bajar el csv donde se tienen las llaves en texto plano. Luego de esto, copiamos tanto el Access Key como el valor del Secret Access Key.\nLanzamiento de nuestra primera máquina virtual (EC2) # Al utilizar Terraform para la gestión de infraestructura, es fundamental comprender que los nombres de los servicios y recursos varían según el proveedor de nube. En el contexto de Amazon Web Services (AWS), su servicio de computación (servidores virtuales) se denomina EC2, acrónimo de Elastic Compute Cloud.\nConsideraciones Esenciales para el Despliegue # Regiones Geográficas: Cada proveedor de nube ofrece la posibilidad de desplegar recursos en diferentes regiones. La selección de la región debe basarse estrictamente en los requisitos de la organización, considerando factores como la latencia, la soberanía de los datos y la cercanía a los usuarios finales.\nEspecificaciones de Instancia (EC2): Al crear una instancia EC2 en AWS, es importante definir sus características técnicas. Estas especificaciones determinarán el rendimiento y la capacidad del servidor. Las propiedades clave a configurar incluyen:\nTipo de Instancia: Define la capacidad de procesamiento (CPU). Memoria (RAM): Establece la cantidad de memoria disponible. Almacenamiento: Determina el tamaño y el tipo de los discos asociados. Imagen de Máquina de Amazon (AMI): Especifica el sistema operativo base de la instancia. Estas características deben ser definidas de manera explícita en el código de configuración de Terraform. Al ejecutar el código, Terraform interpretará estas definiciones y emitirá la orden precisa al proveedor (AWS) para que las instancias se creen con las especificaciones requeridas.\nCreación de la instancia EC2 de manera manual # Antes de pasar a crear un servicio de forma automática en Terraform, recomiendo ver algún video en Youtube sobre la creación de una instancia de manera manual mediante la consola de AWS, para ver el tiempo que toma configurar y desplegar un servicio de estas características.\nVideo de ejemplo\nDespliegue de la Primera Instancia con Terraform # Para iniciar el despliegue de nuestra primera instancia en AWS utilizando Terraform, es imprescindible consultar la documentación oficial del proveedor. El punto de referencia es el registro de Terraform para el proveedor AWS\nUso de la Documentación del Recurso aws_instance # La documentación del proveedor AWS especifica cómo estructurar los scripts de Terraform para cada servicio. Dado que el objetivo es lanzar una instancia EC2, nos enfocaremos en la sección correspondiente al recurso aws_instance\nEsta documentación proporciona ejemplos prácticos que sirven como punto de partida para nuestra configuración. Tomaremos como base el siguiente bloque de código:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;web\u0026#34; { ami = data.aws_ami.ubuntu.id instance_type = \u0026#34;t3.micro\u0026#34; tags = { Name = \u0026#34;HelloWorld\u0026#34; } } Análisis de la Configuración del Recurso # En el bloque de código, es fundamental comprender los siguientes elementos:\nresource: Es la palabra clave que indica que estamos declarando un recurso de infraestructura. \u0026quot;aws_instance\u0026quot;: Este es el tipo de recurso. Hace referencia explícita al servicio de instancia EC2 en AWS. Este parámetro debe mantenerse. \u0026quot;web\u0026quot;: Es el nombre local o la etiqueta de referencia única que le daremos al recurso dentro de nuestro código de Terraform. Este nombre se cambiará a \u0026quot;terraformec2\u0026quot; para identificarlo en este proyecto. ami: Especifica el Amazon Machine Image (AMI), que es la imagen base del sistema operativo. instance_type: Define el tipo de instancia (por ejemplo, t2.micro o t3.micro), lo que determina la capacidad de cómputo (CPU y memoria). Obtención del AMI # El valor para el parámetro ami se obtiene directamente desde la consola de AWS. Para ello, se puede navegar a la sección EC2 \u0026gt; Launch Instances \u0026gt; Application and OS Images, y seleccionar la imagen deseada (por ejemplo, las que tienen la indicación uefi-preferred).\nScript Final de Configuración # Una vez definidos todos los parámetros, la configuración final de nuestro script (.tf) debe incluir la definición del proveedor y el recurso.\nNota sobre credenciales: Aunque en este ejemplo se incluyen las claves de acceso, no se recomienda gestionar las credenciales de esta forma en entornos de producción. Se sugiere utilizar métodos más seguros como Roles de IAM o variables de entorno. Las claves en toda este tutorial son meramente ilustrativas y deben ser reemplazadas por los valores que correspondan a cada key obtenida por el usuario:\nprovider \u0026#34;aws\u0026#34; { region = \u0026#34;us-east-1\u0026#34; access_key = \u0026#34;my-access-key\u0026#34; secret_key = \u0026#34;my-secret-key\u0026#34; } resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; # Sustituir por un AMI válido y reciente instance_type = \u0026#34;t2.micro\u0026#34; } Secuencia de Comandos para el Despliegue Inicial # Una vez completada la escritura del script de configuración en Terraform, el despliegue de la infraestructura requiere la ejecución de una serie de comandos en secuencia.\nterraform init: Este es el primer comando a ejecutar. Su función es inicializar el directorio de trabajo, descargar los plugins del proveedor necesarios (en este caso, AWS), y preparar el backend para la gestión de estados. Es una etapa fundamental para que Terraform pueda gestionar la infraestructura solicitada.\nterraform validate: Tras la inicialización, se invoca este comando para inspeccionar la sintaxis de los archivos de configuración (.tf). terraform validate verifica que el código esté escrito correctamente y que respete las reglas de HCL (HashiCorp Configuration Language).\nterraform plan: Una vez validada la sintaxis, este comando genera un plan de ejecución. El plan describe detalladamente las acciones que Terraform llevará a cabo para alcanzar el estado deseado definido en el código (por ejemplo, qué recursos se crearán, modificarán o eliminarán). Es crucial notar que terraform plan no aplica ninguna modificación a la infraestructura real, sino que únicamente traza y muestra el impacto de la configuración.\nterraform apply: Si el plan generado es satisfactorio y se aprueba la ejecución, se invoca terraform apply. Este comando es el responsable de ejecutar el plan propuesto, interactuando efectivamente con el proveedor (AWS) para crear o modificar los recursos de infraestructura.\nVerificación Post-Despliegue: Es importante acceder a la consola de AWS (sección EC2 \u0026gt; Instances) para confirmar visualmente que la infraestructura ha sido impactada y gestionada correctamente de acuerdo con la configuración codificada.\nActualización de la Configuración: Asignación de Etiquetas (Tags) # Una vez que la instancia ha sido desplegada con éxito, el siguiente paso práctico es actualizarla, por ejemplo, asignándole una etiqueta (o tag). Las etiquetas son pares clave-valor que resultan esenciales para la organización, la facturación y la diferenciación de recursos dentro del entorno de AWS.\nEl proveedor AWS sugiere la siguiente sintaxis para añadir una etiqueta de nombre al recurso aws_instance: Referencia\ntags = { Name = \u0026#34;EC2-Example\u0026#34; } En este caso, la clave es Name y el valor es EC2-Example.\nModificación del Código # Al integrar esta etiqueta, el bloque del recurso en nuestro código de Terraform debe ser modificado para incluir la nueva propiedad:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;EC2-Example\u0026#34; } } Secuencia de Aplicación de Cambios # Para aplicar esta modificación, se sigue un proceso simplificado de comandos:\nterraform plan: Se ejecuta nuevamente para que Terraform compare el estado actual de la infraestructura (ahora existente en AWS) con el nuevo estado deseado definido en el código. El resultado mostrará una diferencia (diff) indicando que se realizará una modificación (1 to add, 0 to destroy, 1 to change).\nterraform apply: Si el plan de modificación es aceptado, este comando se invoca para ejecutar la actualización. Terraform aplicará el cambio en caliente, asignando la etiqueta a la instancia EC2 existente.\nVerificación de la Actualización Al regresar a la consola de AWS y actualizar la lista de instancias EC2, se observará que el nombre (basado en la etiqueta Name) ha sido correctamente impactado en la primera instancia desplegada.\nProvider section # La sección que no cambiará a lo largo del tiempo en nuestro código, será la perteneciente a la sección provider. Y es así porque aquí se tiene la configuración necesaria para que Terraform pueda conectarse a la nube de AWS y crear nuestras instancias. Por lo tanto, la siguiente sección, SIEMPRE SERÁ LA MISMA para todos nuestros scripts:\nprovider \u0026#34;aws\u0026#34; { region = \u0026#34;us-east-1\u0026#34; access_key = \u0026#34;my-access-key\u0026#34; secret_key = \u0026#34;my-secret-key\u0026#34; } Punto de Seguridad Crítico # Las claves de acceso (Access Key) y claves secretas (Secret Key) de AWS cumplen la función de credenciales (equivalentes a nombre de usuario y contraseña) para gestionar su cuenta de AWS.\nAdvertencia de Seguridad:\nCuando comparta su código de Terraform en foros públicos, plataformas de aprendizaje (como la sección de Preguntas y Respuestas de Udemy) o cualquier otro medio, es fundamental asegurarse de NO incluir las claves de acceso y secretas.\nAntes de publicar cualquier fragmento de código, debe eliminar o sustituir estas claves por marcadores de posición. Nunca exponga las credenciales de su cuenta.\nRecursos y proveedores (proveedores) # Lo interesante de utilizar Terraform es que tiene soporte para mas de 3000 proveedores (entre ellos los más conocidos como AWS, GCP, Azure, Alibaba, etc). Esto se puede ver si nos dirigimos al siguiente link\nEn esta página lo que podemos ver es que si vamos a la sección Browser providers podremos listar todos los proveedores de servicios que da soporte Terraform; por lo tanto nos puede dar un indicio de lo grande que ha sido la adopción de Terraform en estos últimos años.\nProveedor # En Terraform, un proveedor (provider en inglés) es un componente fundamental que permite a Terraform interactuar con servicios en la nube, proveedores de infraestructura local u otros sistemas externos para gestionar recursos. Cada proveedor es responsable de traducir las configuraciones de Terraform en acciones específicas para el servicio que representa.\nAquí hay algunos puntos clave sobre los proveedores en Terraform:\nInterfaz de API: Los proveedores proporcionan una interfaz de programación de aplicaciones (API) que Terraform utiliza para comunicarse con los servicios o plataformas que desees gestionar. Esta API permite a Terraform realizar operaciones como crear, modificar y eliminar recursos.\nRecursos: Cada proveedor define un conjunto de recursos que pueden ser gestionados a través de Terraform. Estos recursos pueden ser máquinas virtuales, bases de datos, redes, balanceadores de carga, entre otros, dependiendo del servicio que el proveedor represente. Terraform proporciona un conjunto extenso de recursos integrados para varios proveedores, y también permite a los usuarios crear sus propios recursos personalizados si es necesario.\nConfiguración del proveedor: Para utilizar un proveedor en Terraform, necesitas configurarlo en tu archivo de configuración. Esto generalmente incluye detalles como el nombre del proveedor, la región, las credenciales de autenticación y cualquier otra configuración específica del proveedor.\nVersiones y actualizaciones: Los proveedores de Terraform son software independiente y se actualizan regularmente para agregar nuevas funcionalidades, corregir errores y mantenerse al día con los cambios en los servicios que representan. Es importante especificar la versión del proveedor en tu archivo de configuración de Terraform para asegurarte de que tus configuraciones funcionen de manera consistente, incluso si hay actualizaciones disponibles.\nEn resumen, los proveedores en Terraform son extensiones que permiten a Terraform interactuar con servicios en la nube y otros sistemas externos para gestionar la infraestructura como código. Proporcionan una abstracción uniforme sobre una amplia variedad de servicios y permiten a los usuarios gestionar sus recursos de manera consistente y automatizada.\nterraform init # Como se dijo anteriormente, un proveedor para Terraform es una extensión que permite adoptar un método a la hora de interactuar con las APIs de los distintos proveedores de la nube.\nCuando invocamos el comando terraform init lo que sucede es que Terraform descargará la estensión (plugin) necesaria que se especifica en nuestro código tf. Como en nuestro ejemplo anterior, el proveedor del que nos íbamos a servir sería AWS, terraform adopta esta configuración y descarga automáticamente la extensión para saber cómo interactua con la API de los servicios de AWS.\nCuando esta extensión se descarga, se hace dentro de una nueva carpeta que se crea denominada .terraform, la cual se encuentra oculta en el directorio raíz en el que iniciamos nuestro proyecto de Terraform (algo similar sucede cuando en nuestro repositorio queremos iniciar un versionado con git haciendo git init, el cual inicializa todos sus archivos de configuración en la carpeta oculta .git).\nSi listamos todos los directorios que se encuentran en .terraform y buscamos la extensión descargada para nuestro proveedor, veremos que habrá descargado un archivo de casi 430 Mb:\n.terraform/providers/registry.terraform.io/hashicorp/aws/5.41.0/linux_amd64: total 429M Trabajar con distintos proveedores # Si nosotros queremos trabajar por ejemplo con otro proveedor, como Azure, simplemente nos será suficiente ingresar la siguiente línea a nuestro código de ejemplo first_ec2.tf:\nprovider \u0026#34;azurerm\u0026#34; { } Y luego invocar el comando terraform init. Esto será suficiente como para que Terraform entienda que debe descargar la extensión para poder manejar la API de todos los servicios de Azure.\nEl inconveniente que tiene esto es que por cada repositorio, tendremos unos 500Mb apropiados sólo para el ejecutable que provee la lógica para que nuestro código se pueda comunicar con las APIs.\nRecursos # En Terraform, un \u0026ldquo;recurso\u0026rdquo; (resource en inglés) es una entidad representada dentro de la configuración que describe un objeto específico que existe dentro de tu infraestructura. Estos recursos pueden ser máquinas virtuales, bases de datos, redes, grupos de seguridad, balanceadores de carga, entre otros.\nCada recurso en Terraform está asociado a un proveedor particular. Por ejemplo, si estás trabajando con Amazon Web Services (AWS) y quieres crear una instancia EC2, utilizarías el recurso aws_instance y especificarías los detalles necesarios, como el tipo de instancia, la imagen de la máquina virtual, el tipo de almacenamiento, etc.\nAquí hay un ejemplo básico de cómo se vería un recurso en un archivo de configuración de Terraform:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;example\u0026#34; { ami = \u0026#34;ami-0c55b159cbfafe1f0\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; } En este ejemplo:\naws_instance es el tipo de recurso que estamos creando, que representa una instancia EC2 en AWS. \u0026quot;example\u0026quot; es el nombre dado a este recurso en el contexto de este archivo de configuración. Este nombre se utiliza para hacer referencia a este recurso en otros lugares de tu configuración. Dentro de las llaves {}, se especifican los atributos del recurso, como la AMI (Amazon Machine Image) a utilizar y el tipo de instancia. Los recursos son la base de la configuración de Terraform y representan las entidades que deseas gestionar en tu infraestructura. Terraform utiliza esta información para generar un plan de ejecución que describe cómo se modificará tu infraestructura para alcanzar el estado deseado.\nResource block # Debemos comprender que cada bloque tiene un tipo de recurso asociado (en el caso anterior es aws_instance) junto con un nombre local para denominar a ese recurso (que en nuestro ejemplo lo denominamos terraformec2)\nAlgo importante a tener en cuenta es que el nombre del recurso junto con el nombre local asignado a ese recurso, hacen un identificador único en todo el código:\nPor lo tanto, si tenemos este ejemplo:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; } resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-33333222255555151\u0026#34; instance_type = \u0026#34;t3.micro\u0026#34; } Veremos que ambas instancias son distintas, pero que para Terraform no lo es, ya que junto con el nombre del recurso aws_isntance junto con el nombre local para ese recurso asignado terraformec2, Terraform considera que es el mismo recurso, ya que el recurso y su nombre NO pueden ser el mismo.\nCada proveedor con su recurso # Otra de las condiciones que establece Terraform es que para cada tipo de recurso, debe ir acompañado con su tipo de proveedor declarado. Es decir, NO SE PUEDE hacer lo siguiente:\nprovider \u0026#34;azurerm\u0026#34; { source = \u0026#34;hashicorp/azurerm\u0026#34; version = \u0026#34;\u0026gt;= 2.0.0, \u0026lt; 3.0.0\u0026#34; } resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; } Vemos que el recurso aws_instance es un recurso que NO pertenece a Azure, sino al proveedor de AWS.\nAún así, es posible en el mismo archivo, tener dos declaraciones de proveedores y por lo tanto esto permite manejar tanto los recursos de uno como del otro en un mismo código tf.\n¿Necesito aprenderme las particularidades de cada proveedor? # La respuesta rotunda es no. Si uno comprende el core de Terraform, no será difícil el trabajar con distintos proveedores. Ya que la sintáxis del lenguaje es igual a lo largo de todos los proveedores.\nProblemas con los proveedores # Puede ser que a lo largo de nuestro uso de Terraform, nos encontremos con errores o problemas relacionados específicamente a cada proveedor que soporta de manera oficial la herramienta. Cuando nos suceda esto, deberemos de encontrar la respuesta en cada una de las distintas páginas que mantiene abiertas Hashicorp para cada uno de los proveedores. Si no encontramos la respuesta a nuestro problema, podremos subir un ticket reportando el inconveniente con las pruebas para que sea analizada desde la parte técnica.\nSi bien, es muy difícil encontrar un bug, ya que millones de personas utilizan Terraform a lo largo del mundo, más que seguro que ya exista una solución a nuestro problema. En caso de que no sea así, podremos como se mencionó anteriormente levantar un ticket en la página correspondiente al proveedor que estemos utilizando.\nProvider Tiers (niveles de proovedores) # Para entender lo que son los Provider Tiers (niveles de provedores), antes hay que entender primero:\nLo que es un Provider Registry. Lo que es un Provider Mainteiner. Y por último lo que significa Provider Tiers. Provider Registry (Proveedor de registro) # El proveedor de registros (provider registry en inglés) en Terraform es un servicio proporcionado por HashiCorp que actúa como un repositorio centralizado de proveedores de Terraform y módulos. Este registro permite a los usuarios buscar, descubrir y acceder fácilmente a los proveedores de Terraform y módulos creados y mantenidos por la comunidad y por HashiCorp.\nAquí hay algunas características clave del proveedor de registros en Terraform:\nExploración y búsqueda: El proveedor de registros proporciona una interfaz de búsqueda que permite a los usuarios encontrar proveedores de Terraform y módulos según sus necesidades. Los usuarios pueden buscar por nombre, categoría, etiquetas y otros criterios para encontrar los recursos que mejor se adapten a sus requisitos.\nPublicación y distribución: Los maintainers de proveedores y módulos pueden publicar sus creaciones en el proveedor de registros para que otros usuarios de Terraform puedan utilizarlos. Esto facilita la distribución de código y fomenta la colaboración en la comunidad de Terraform.\nVersionado y control de calidad: El proveedor de registros incluye características de versionamiento que permiten a los maintainers de proveedores y módulos publicar diferentes versiones de sus creaciones. Los usuarios pueden especificar qué versión de un proveedor o módulo desean utilizar en sus configuraciones de Terraform, lo que ayuda a garantizar la estabilidad y compatibilidad de las configuraciones.\nIntegración con Terraform CLI: Los usuarios pueden acceder al proveedor de registros directamente desde la línea de comandos de Terraform utilizando el comando terraform init con la opción -upgrade. Esto permite a Terraform descargar automáticamente los proveedores y módulos necesarios desde el registro durante la inicialización del directorio de trabajo.\nEn resumen, el proveedor de registros en Terraform es una herramienta poderosa que facilita la gestión y distribución de proveedores de Terraform y módulos, simplificando el proceso de descubrimiento y utilización de recursos de infraestructura como código en la comunidad de Terraform.\nProviders Maintainers # Los \u0026ldquo;provider maintainers\u0026rdquo; en Terraform son individuos o equipos responsables del desarrollo y mantenimiento de los proveedores de Terraform. Un proveedor en Terraform es un complemento que permite a Terraform interactuar con servicios en la nube, proveedores de infraestructura local u otros sistemas externos para gestionar recursos.\nLos proveedores mantienen la integración de Terraform con servicios específicos y se encargan de asegurar que los proveedores sean compatibles, estables y estén actualizados con las últimas características y cambios de los servicios que representan. Esto implica tareas como:\nDesarrollo de nuevas características: Los maintainers de los proveedores trabajan en la implementación de nuevas características y funcionalidades que sean compatibles con los servicios que el proveedor representa. Esto puede incluir la adición de nuevos recursos, la mejora de la compatibilidad con versiones específicas de API de servicio, entre otros.\nCorrección de errores: Los maintainers son responsables de solucionar problemas y errores que surjan en el proveedor. Esto puede incluir errores de comportamiento, problemas de rendimiento o cualquier otro problema que afecte el funcionamiento del proveedor.\nActualización de versiones: Los maintainers aseguran que los proveedores se mantengan actualizados con las últimas versiones de los servicios que representan. Esto implica seguir de cerca los cambios y actualizaciones de los servicios en la nube y adaptar el proveedor en consecuencia.\nSoporte y comunidad: Los maintainers pueden proporcionar soporte a los usuarios que utilizan el proveedor, responder preguntas en foros, resolver problemas reportados por la comunidad y colaborar con otros usuarios para mejorar la documentación y la experiencia general del proveedor.\nEn resumen, los maintainers de los proveedores juegan un papel importante en el ecosistema de Terraform al garantizar que los proveedores sean confiables, estables y estén al día con los servicios en la nube y otras plataformas que representan. Su trabajo ayuda a los usuarios de Terraform a aprovechar al máximo la herramienta al proporcionar una integración sólida con una amplia gama de servicios y plataformas.\nProvider Tiers # Existen 3 niveles de soporte para los proveedores y módulos de Terraform:\nOfficial: son aquellos proveedores que pertenecen y son mantenidos por la compañía Hashicorp Partner: son aquellos proveedores que pertenecen y son mantenidos por compañías de tecnología que mantienen una asociación con Hashicorp. En este caso puede ser que Google mantenga algunos módulos para Terraform. Community: En este caso los módulos o proveedores pertenecen y son mantenidos por contribuyentes individuales, externos a Hashicorp y que no mantienen ninguna alianza estratégica. Ejemplo práctico # Para ver esto último, podemos ir al siguiente link\nEn la esquina superior izquierda, podremos ver los tres diferentes niveles de los que hablamos. Esta sección permite filtrar los proveedores por sus distintos niveles. Por ejemplo, podemos tildar sólo el filtro de \u0026lsquo;Official\u0026rsquo; y podemos ver que proveedores como AWS, Azure o GCP son mantenidos exclusivamente por la compañía Hashicorp. Ahora si filtramos por el partner tier podremos ver que algunos de estos proveedores son Alibaba u Oracle, lo que significa que estos proveedores son matenidos por empresas externas pero relacionadas a Hashicorp.\nLo que hay que comprender es que para el nivel de community tiers los bugs que puedan resultar de estos módulos o proveedores, pueden tardar mucho tiempo en ser resueltos, por lo tanto no son recomendados para producción.\nProvider registry: namespaces # En el contexto del registro de proveedores de Terraform, el término namespaces se refiere a una forma de organizar y categorizar los proveedores de Terraform y los módulos asociados dentro del registro. Los \u0026ldquo;namespaces\u0026rdquo; actúan como contenedores lógicos que agrupan los recursos relacionados según el autor o el mantenimiento del proveedor.\nCada namespace en el registro de proveedores de Terraform está asociado con un nombre único, que generalmente corresponde al nombre del autor o del mantenedor del proveedor o módulo. Estos nombres pueden ser nombres de organizaciones, nombres de usuarios o cualquier otro identificador único.\nLos namespaces permiten a los usuarios del registro de proveedores de Terraform identificar fácilmente los proveedores y módulos mantenidos por una determinada entidad. Esto facilita la búsqueda y el descubrimiento de recursos relevantes para sus necesidades específicas.\nPor ejemplo, si estás buscando un proveedor de Terraform para interactuar con un servicio en la nube específico, puedes buscar proveedores dentro del \u0026ldquo;namespace\u0026rdquo; de esa empresa o servicio en el registro de proveedores. Esto te ayudará a encontrar rápidamente los recursos relevantes y confiables asociados con ese proveedor en particular.\nRetomando, los namespaces en el registro de proveedores de Terraform son una forma de organizar y categorizar los proveedores y módulos, lo que facilita a los usuarios encontrar y utilizar recursos específicos mantenidos por una entidad o autor particular.\nTenemos nuevamente 3 niveles con los que se categorizan estos namespaces:\nOfficial: Este tendrá el nombre de la compañía Hashicorp que es la encargada del desarrollo de Terraform. Partner: Tendrán el nombre de una organización de terceros, como por ejemplo mongodb/mongodbatlas. Community: tendrán nombres especiales de individuos o cuentas de organizaciones. Ejemplo de namespaces # Official namespaces # Por ejemplo, si navegamos en https://registry.terraform.io/browse/providers y abrimos por ejemplo, el provider de AWS y el de Azure, veremos las siguientes URL:\nhttps://registry.terraform.io/providers/hashicorp/azurerm/latest https://registry.terraform.io/providers/hashicorp/aws/latest Podemos ver que ambas páginas comparten el mismo namespace providers/hashicorp/ y esto es porque todos los módulos que se albergan detrás de estos proveedores, han sido desarrollados por Hashicorp.\nPartner namespaces # En cambio, si filtramos por el nivel \u0026lsquo;Partner\u0026rsquo;, y abrimos el enlace del proveedor de Alibaba Cloud, veremos el siguiente URL:\nhttps://registry.terraform.io/providers/aliyun/alicloud/latest https://registry.terraform.io/providers/oracle/oci/latest Podremos ver el siguiente namespaces: providers/aliyun/alicloud lo que nos da una idea acerca de los módulos que se encuentran dentro de este espacio son desarrollados por empresas de terceros asociadas a Hashicorp. Lo mismo sucede con la nube de Oracle.\nCommunity namespaces # Ahora filtremos por los proveedores \u0026lsquo;community\u0026rsquo; y veremos por ejemplo lo siguiente:\nhttps://registry.terraform.io/providers/milosbackonja/1password/latest Podremos ver que el namespace ya pertenece a un individuo y luego a una aplicación: \u0026ldquo;providers/milosbackonja/1password\u0026rdquo;\nPunto importante sobre los namespace # Algo importante a destacar sobre la sección de bloque providers, es que Hashicorp solicita explícitamente a aquellos proveedores que no están soportados por la propia Hashicorp, utilicen el bloque denominado como required_providers en vez del provider \u0026quot;aws\u0026quot; por ejemplo. Este último se encuentra soportado por Hashicorp, en cambio el primero, se encuentra por fuera del mantenimiento de Hashicorp, y es por eso que tiene que utilizar otro bloque distinto.\nPráctica # Por ejemplo, si en nuestro código del archivo first_ec2.tf ingresamos el siguiente bloque de código solicitando el proveedor digitalocean de la siguiente manera:\nprovider \u0026#34;digitalocean\u0026#34; { } Y luego sobre el directorio donde se encuentra nuestro archivo ejecutamos terraform init, producirá un error, ya que el proveedor digitalocean al no ser sorportado oficialmente por Hashicorp, no puede descargar los paquetes del proveedor, buscarlos dentro del namespace hashicorp/digitalocean, el cual efectivamente no existe por no ser soportado oficialmente.\n¿Cómo sabremos qué namespace le corresponde? Bueno, podemos hacer lo siguiente:\nNos dirigimos a https://registry.terraform.io/browse/providers Luego realizamos una búsqueda con la palabra clave digitalocean. Esto dará lugar a una lista de proveedores que estárán ordenados según determinada valoración de los usuarios. En este primer ordenamiento, veremos que el namespaces es digitalocean/digitalocean, pero si ingresamos a ese proveedor Obtenemos la URL siguiente: https://registry.terraform.io/providers/digitalocean/digitalocean/latest que efectivamente tiene el namespaces: providers/digitalocean/digitalocean ¡PERO! También hay que utilizar el bloque required_providers, ya que digitalocean NO está oficialmente soportado. En el ejemplo de uso dentro de la documentación del proveedor, debemos observar el siguiente código de ejemplo: terraform { required_providers { digitalocean = { source = \u0026#34;digitalocean/digitalocean\u0026#34; version = \u0026#34;~\u0026gt; 2.0\u0026#34; } } } Como vemos, al no ser un proveedor soportado oficialmente por Hashicorp, debemos de utilizar tanto el bloque required_providers como también el correcto namespaces digitalocean/digitalocean . Una vez modificado esto en el código, podremos inicializar el proyecto mediante terraform init de forma correcta.\nOfficial required providers # También hay que tener encuenta que la cláusula required_providers puede ser utilizada por proveedores que son oficiales, pero NO al revés. Por ejemplo, si nos dirigimos al proveedor oficial de AWS, podremos ver en su documentación el siguiente ejemplo:\nterraform { required_providers { aws = { source = \u0026#34;hashicorp/aws\u0026#34; version = \u0026#34;~\u0026gt; 5.0\u0026#34; } } } Esta cláusula la desarrollaremos más en detalle en secciones siguientes. Pero hay que recordar que la cláusula required_providers puede utilizarse o no con proveedores oficiales, pero debe usarse obligadamente con aquellos que no son soportados por Hashicorp.\nCon los proveedores oficiales podemos utilizar para que sea más sencillo de leer, la cláusula provider \u0026quot;aws\u0026quot; por ejemplo para utilizar las extensiones de AWS.\nCrear un Repositorio de GitHub mediante Terraform # Como se dijo en una lección pasada, una de las potencialidades que tiene utilizar IaC y más específicamente Terraform, es que podemos darle seguimiento a todas las modificaciones de nuestra infraestructura en el tiempo mediante un versionado de código como puede ser git.\nEn este caso lo que se hará es crear un repositorio de GitHub pero mediante Terraform, demostrando que la potencia de Terraform es hablar con las APIs de los servicios de la nube y por eso es que es una herramienta tan abarcativa.\nPráctica: Github # Lo que primero debemos de buscar es el proveedor Github en la página de Terraform, obteniendo el siguiente enlace\nComo veremos, el namespace es providers/integrations/github. Deberemos de tener en cuenta 3 cosas:\nDeberemos de crear un nuevo archivo con el nombre github.tf y se encontrará en el mismo directorio que el anterior archivo first_ec2.tf. La sección que corresponde a la selección del proveedor. La parte que corresponde a la authentication. Por lo tanto, luego de generar un archivo con nombre github.tf copiamos la primera parte que será la siguiente:\nterraform { required_providers { github = { source = \u0026#34;integrations/github\u0026#34; version = \u0026#34;~\u0026gt; 6.0\u0026#34; } } } Y luego para la otra sección, iremos a la parte de la documentación que se encuentra señalizado como authentication, veremos la siguiente sección:\nprovider \u0026#34;github\u0026#34; { token = var.token # or `GITHUB_TOKEN` } Por lo tanto, el código nos quedará de la siguiente manera:\nterraform { required_providers { github = { source = \u0026#34;integrations/github\u0026#34; version = \u0026#34;~\u0026gt; 6.0\u0026#34; } } } Para poder generar un token de Github, deberemos de realizar los siguiente pasos:\nIngresamos a nuestra cuenta de Github Settings Developer settings Personal Access Token Fine-grained token -\u0026gt; Generate New Token Lo generamos y el nombre de nuestro token será Terraform En la sección de Repository Acces marcamos \u0026ldquo;All repositories\u0026rdquo; En Permissions, nos posicionamos en la sección \u0026ldquo;Administration\u0026rdquo; y le otorgamos el acceso de Read/Write. Generate Token Copiamos el token y lo pegamos en la sección provider \u0026quot;github\u0026quot; indicada anteriormente, quedando de la siguiente manera: # Configure the GitHub Provider provider \u0026#34;github\u0026#34; { token = \u0026#34;github_pat_aBcD123456EeFfGgHhIiJ1111111111111111111111199999999999999\u0026#34; } Hasta ahora no hemos generado ningún servicio en el código, por lo tanto iremos nuevamente a la página del proveedor Github de Terraform y filtraremos por el servicio github_repository: https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository\nresource \u0026#34;github_repository\u0026#34; \u0026#34;example\u0026#34; { name = \u0026#34;example\u0026#34; description = \u0026#34;My awesome codebase\u0026#34; visibility = \u0026#34;public\u0026#34; } Código completo # Por lo tanto, el archivo github.tf quedará de la siguiente manera:\nterraform { required_providers { github = { source = \u0026#34;integrations/github\u0026#34; version = \u0026#34;~\u0026gt; 6.0\u0026#34; } } } # Configure the GitHub Provider provider \u0026#34;github\u0026#34; { token = \u0026#34;github_pat_aBcD123456EeFf11111111111111111111111999999999999999999999\u0026#34; } resource \u0026#34;github_repository\u0026#34; \u0026#34;example\u0026#34; { name = \u0026#34;example\u0026#34; description = \u0026#34;My awesome codebase\u0026#34; visibility = \u0026#34;public\u0026#34; } Por lo tanto, luego de crear el archivo, lo que debemos de hacer es:\nAplicar el comando terraform init y una vez que haya descargado las extensiones para el proveedor de github pasaremos al segundo punto. El comando terraform plan. Deberemos de ver que el comando plan nos indicará que sólo impactará una sola modificación (que será la creación de nuestro repositorio \u0026ldquo;example\u0026rdquo;) Y si estamos de acuerdo con ello invocaremos el comando terraform apply Terraform Destroy # Así como existe el comando terraform apply para llevar a cabo el plan conseguido por terraform plan, también existe un comando que nos permite eliminar toda la infraestructura creada. Este comando es terraform destroy.\nPreliminar: terraform plan -destroy # Para saber qué plan de destrucción aplicará terraform destroy, debemos invocar al comando terraform plan -destroy\nComando: terraform destroy # El comando para destruir o eliminar toda la infraestructura que se ha creado con Terraform es terraform destroy. Este comando desmantela y elimina todos los recursos que fueron creados por Terraform según la configuración definida en tus archivos.\nEs importante tener en cuenta que terraform destroy eliminará todos los recursos definidos en tu configuración, por lo que debes tener cuidado al usarlo en entornos de producción para evitar la pérdida de datos o recursos importantes.\nAntes de ejecutar terraform destroy, es una buena práctica revisar el plan de destrucción generado por Terraform para asegurarte de que comprendes qué recursos se eliminarán. Puedes obtener este plan ejecutando terraform plan -destroy para ver una lista detallada de los recursos que serán eliminados.\nUna vez estés seguro de que deseas continuar con la eliminación de los recursos, simplemente ejecuta terraform destroy y confirma la acción cuando se te solicite. Terraform comenzará a eliminar los recursos de manera segura y controlada de acuerdo con la configuración definida en tus archivos.\nEl comando terraform destroy se utiliza para eliminar de forma segura y controlada todos los recursos que Terraform ha creado y administra según la configuración definida en tus archivos de Terraform. Aquí hay más información sobre este comando:\nEliminación de recursos: Cuando ejecutas terraform destroy, Terraform desmantela y elimina todos los recursos que ha creado según la configuración en tus archivos. Esto incluye la eliminación de instancias de máquinas virtuales, grupos de seguridad, redes, bases de datos, y cualquier otro recurso gestionado por Terraform.\nConfirmación de eliminación: Antes de llevar a cabo la eliminación de los recursos, Terraform solicitará confirmación para asegurarse de que estás seguro de que deseas proceder con la acción. Debes confirmar explícitamente la eliminación escribiendo \u0026ldquo;yes\u0026rdquo; en la línea de comandos para evitar la eliminación accidental de recursos importantes.\nActualización del estado: Después de eliminar los recursos, Terraform actualizará el archivo de estado para reflejar los cambios realizados. Esto asegura que Terraform tenga un registro actualizado del estado de tu infraestructura y evita conflictos futuros al aplicar cambios.\nControl de recursos: Es importante tener en cuenta que terraform destroy eliminará todos los recursos definidos en tu configuración, por lo que debes tener cuidado al usarlo en entornos de producción para evitar la pérdida de datos o recursos importantes. Se recomienda realizar una copia de seguridad o una revisión cuidadosa de los recursos antes de ejecutar este comando en un entorno de producción.\nEn resumen, terraform destroy es el comando que utilizas cuando deseas eliminar de forma segura y controlada todos los recursos gestionados por Terraform. Asegúrate de entender completamente el impacto de esta acción antes de ejecutarla, especialmente en entornos de producción.\nterraform destroy consideraciones # Como se dijo anteriormente, para saber el plan qué se aplicará a la hora de eliminar los recursos, se debe invocar a terraform plan -destroy. Debemos de recordar que este comando tomará en cuenta para eliminar a aquellos recursos que se encuentren dentro de la carpeta de proyecto. Es decir, tomará en cuenta los recursos creados por los siguientes archivos:\nfirst_ec2.tf github.tf Por lo tanto, Terraform sólo eliminará los recursos que se hayan creado dentro de estos dos archivos y no más. Por eso siempre es recomendable gestionar previamente un plan de destrucción, para poder evidenciar aquellos recursos que serán eliminados.\nComando: terraform destroy -target # Algunas veces, no vamos a necesitar eliminar todos los recursos que se encuentran dentro de nuestro repositorio. En el caso actual, si nosotros aplicaríamos terraform destroy, se eliminarían los recursos de:\nfirst_ec2.tf github.tf Pero supongamos que nosotros queremos mantener las instancias generadas en AWS pero queremos eliminar los recursos gestionados en GitHub ¿Cómo podemos hacer esto?.\nEsto se puede hacer mediante el comando terraform destroy -target \u0026lt;TARGET\u0026gt;.\nEl comando terraform destroy -target \u0026lt;TARGET\u0026gt; es una variación del comando terraform destroy que te permite especificar un recurso específico que deseas destruir en lugar de eliminar todos los recursos gestionados por Terraform. Esto puede ser útil cuando solo quieres eliminar un recurso particular en lugar de toda la infraestructura, lo que te permite controlar de manera más precisa qué recursos se eliminarán.\nAquí hay más detalles sobre cómo funciona este comando:\nEspecificación del objetivo: Con la opción -target, puedes especificar el recurso específico que deseas destruir. Esto se hace proporcionando la dirección del recurso como argumento. La dirección del recurso es la ruta completa al recurso en el árbol de recursos de Terraform, como en nuestro caso aws_instances.terraformec2 o github_respository.example.\nDestrucción del recurso objetivo: Cuando ejecutas terraform destroy -target \u0026lt;TARGET\u0026gt;, Terraform desmantela y elimina únicamente el recurso especificado y cualquier recurso que dependa directa o indirectamente de él. Terraform analiza la dependencia del recurso objetivo y elimina los recursos en el orden adecuado para evitar conflictos o errores.\nPrecaución: Es importante tener en cuenta que terraform destroy -target \u0026lt;TARGET\u0026gt; elimina solo el recurso especificado y sus dependencias, pero no elimina otros recursos no relacionados que puedan estar presentes en tu configuración de Terraform. Por lo tanto, debes tener cuidado al usar este comando para evitar la eliminación accidental de recursos importantes o infraestructura dependiente.\nPor lo tanto, terraform destroy -target \u0026lt;TARGET\u0026gt; te permite eliminar de manera selectiva un recurso específico y sus dependencias utilizando Terraform. Esto te brinda un mayor control sobre el proceso de destrucción de la infraestructura y te permite evitar la eliminación accidental de recursos no deseados. Sin embargo, debes utilizar este comando con precaución y asegurarte de comprender completamente su impacto en tu infraestructura.\nPara eliminar por ejemplo, nuestro recurso de AWS, sin eliminar el de GitHub, lo que debemos hacer es lo siguiente:\n$ terraform destroy -target aws_instances.terraformec2 De lo contrario (en el caso de que querramos eliminar el repositorio de Github) podremos hacer:\n$ terraform destroy -target github_repository.example Importante # Algo importante de tener en cuenta, es que la próxima vez que se corra el comando terraform plan, este leerá nuevamente los comandos desplegados dentro de nuestro repositorio, encontrará nuevamente el recurso aws_instance.terraformec2 y planificará crearlo.\nPor lo que es es recomendable que cada vez que destruimos un recurso, es importante quitarlo de nuestro código (en caso que ya no lo necesitemos). De lo contrario, cada vez que corramos el comando terraform apply, se volverá a generar una nueva instancia de AWS. Por lo tanto podremos comentar el bloque de código para que no vuelva a crearse el servicio de nuevo.\nImportante 2 # Otra forma en la que podemos eliminar recursos es simplemente comentando en el código el recurso que querramos eliminar, luego aplicamos el comando terraform plan para ver que efectivamente haya tomando los cambios de los comentarios y en caso de que sea así, eliminará los recursos que han sido comentados ya que entenderá que esos ya no son necesarios de tenerlos activos.\nEntendiendo el archivo state # En las siguientes lecciones se abordará la temática sobre el estado de los archivos.\nComo vimos anteriormente, si nosotros comentamos los recursos dentro de los scripts de tf y ejecutamos el comando terraform plan, podemos ver que Terraform sabe qué recurso deberá ser destruido como así también qué recurso fue eliminado. La pregunta que surje es \u0026ldquo;¿cómo hace Terraform para poder saber el estado de cada uno de los recursos?\u0026rdquo;\nTerraform internamente mantiene el estado de nuestro código para saber el estado por el cual pasó cada uno de los recursos detallados dentro. Esto le permite a Terraform poder mapear los recursos del mundo real a nuestra configuración.\nTerraform state files # En Terraform, los state files (archivos de estado) son archivos que contienen información sobre la infraestructura gestionada por Terraform. Estos archivos almacenan el estado actual de los recursos que Terraform administra, incluyendo los recursos creados, sus atributos y cualquier otra información relevante.\nAquí hay algunos puntos clave sobre los archivos de estado en Terraform:\nRegistro del estado de la infraestructura: Los archivos de estado registran el estado actual de la infraestructura gestionada por Terraform. Esto incluye información sobre los recursos que Terraform ha creado, modificado o eliminado, así como sus atributos y configuraciones actuales.\nSincronización con la infraestructura real: Los archivos de estado se utilizan para mantener un registro sincronizado de la infraestructura real y la definición de infraestructura en tus archivos de configuración de Terraform. Esto permite a Terraform determinar qué recursos están gestionados por Terraform y qué cambios han sido aplicados a esos recursos.\nPrevención de conflictos: Los archivos de estado evitan conflictos al permitir que Terraform realice cambios de manera controlada y predecible. Terraform utiliza el archivo de estado como fuente de verdad para determinar qué cambios son necesarios para alcanzar el estado deseado de la infraestructura.\nAlmacenamiento local o remoto: Los archivos de estado pueden almacenarse localmente en tu máquina de desarrollo o en un sistema de control de versiones como Git, pero también es común almacenarlos de forma remota en un servicio de almacenamiento específico, como Terraform Cloud, Amazon S3, Azure Blob Storage, o Google Cloud Storage. Almacenar los archivos de estado de forma remota proporciona una mayor seguridad y colaboración entre equipos.\nEn resumen, los archivos de estado en Terraform son fundamentales para el funcionamiento de la herramienta, ya que registran el estado actual de la infraestructura gestionada y permiten a Terraform realizar cambios de manera segura y predecible. Es importante manejar y proteger los archivos de estado adecuadamente para garantizar la integridad y la seguridad de tu infraestructura.\nEjemplo # Volvamos al ejemplo de creación de:\nUna instancia de AWS Un repositorio de Github Create # Cuando creamos una instancia de AWS y un repositorio de Github mediante Terraform, este además de generar la infraestructura solicitada, mantiene un registro de estos recursos y toda la información que crea necesaria para poder mantener un seguimiento efectivo. A través de estos archivos de estado, es que Terraform puede seguir o trackear el estado de nuestra nuestra infraestructura.\nDestroy # Cuando se destruye un recurso mediante el comando terraform destroy (por ejemplo la instancia de AWS), el recurso eliminado también genera la eliminación del archivo de estado (state file) asociado. Pero deja sin efecto al recurso de GitHub.\nEs por esto que cuando volvemos a invocar el comando terraform plan y luego terraform apply Terraform puede leer los archivos de estado y darse cuenta que la instancia de AWS no contiene ningún archivo y el de GitHub si, y por lo tanto deberá de aplicar la creación del recurso.\nState file name # Podemos observar que al inicializar un directorio de Terraform, se genera un directorio oculto denominado .terraform y dentro de él podemos ver que existe un archivo denominado terraform.fstate. Si nosotros abrimos este documento, podremos ver que toda la información se encuentra almacenada con una jerarquía JSON. Aquí es donde Terraform ordena toda la información relevante sobre los recursos que crea.\nSi dentro del archivo no se encuentra el recurso de AWS, para Terraform esto significa que el recurso no existe, ya que no le está haciendo seguimiento, y por lo tanto, cuando apliquemos terraform plan y luego terraform apply, terraform revisará este archivo y al no encontrar la entrada para el recurso de AWS, lo intentará crear.\nBuena práctica para el archivo .tfstate # Al trabajar con equipos grandes, una buena práctica es mantener el archivo terraform.tfstate en un almacenamiento remoto, como S3 con bloqueo de DynamoDB o Google Cloud Storage. Esto permite que los integrantes del equipo accedan al estado compartido antes de realizar cambios en la infraestructura, garantizando que todos mantengan una visión sincronizada del proyecto y evitando conflictos al aplicar modificaciones concurrentes.\nBackup .tfstate file # Terraform también generará un archivo de extensión .backup para este archivo de estado cuando se elimina el recurso asociado. Este será el estado del directorio una vez que se haya generado un recurso y eliminado:\n-rw-rw-r-- 1 user user 308 mar 23 20:44 first_ec2.tf -rw-rw-r-- 1 user user 395 mar 23 14:05 github.tf drwxr-xr-x 3 user user 4096 mar 20 23:59 .terraform/ -rw-r--r-- 1 user user 1377 mar 20 23:59 .terraform.lock.hcl -rw-rw-r-- 1 user user 180 mar 23 20:50 terraform.tfstate -rw-rw-r-- 1 user user 4858 mar 23 20:50 terraform.tfstate.backup Podemos ver que luego de haber invocado al comando terraform destroy, se genera un archivo de nombre terraform.tfstate.backup, que le permite a Terraform hacerle un seguimiento a los servicios generados.\nImportante # Terraform no sólo guardará los recursos creados a partir de nuestro script, sino también toda la información asociada a los recursos creados, como por ejemplo en caso de ser una instancia de AWS, guardará información sobre el tipo de instancia, los volúmenes asociados, los Security Groups, las interfaces de Red, las direcciones IP, los balanceadores de carga asociados, etc.\nPor lo tanto no hay que modificar este archivo bajo ninguna circunstancia ya que el estado en el que quedará la instancia será no-deseado y los resultados obtenidos podrían llegar a ser un caos del cual sería muy difícil volver a un estado anterior.\nEntendiendo el Desired \u0026amp; Current States # Desired State (Estado deseado) # En Terraform, el término desired state (estado deseado) se refiere al estado en el que deseas que se encuentre tu infraestructura según lo definido en tus archivos de configuración de Terraform. Este estado deseado se describe mediante la especificación de recursos y sus atributos en los archivos de configuración.\nAquí hay algunos puntos clave sobre el \u0026ldquo;desired state\u0026rdquo; en Terraform:\nDefinición de recursos: En tus archivos de configuración de Terraform, defines los recursos que deseas que Terraform administre. Estos recursos pueden ser instancias de máquinas virtuales, bases de datos, redes, balanceadores de carga, entre otros, dependiendo del proveedor y los servicios que estés utilizando.\nAtributos y configuraciones: Junto con la definición de recursos, también especificas los atributos y configuraciones de esos recursos que deseas que Terraform aplique. Esto incluye detalles como el tipo de instancia, la región, el tamaño del disco, las reglas de firewall, etc.\nGestión de cambios: Terraform se encarga de llevar la infraestructura al estado deseado, comparando el estado actual de los recursos con el estado deseado definido en los archivos de configuración. Si hay diferencias entre el estado actual y el estado deseado, Terraform realiza los cambios necesarios para converger hacia el estado deseado.\nPlanificación y ejecución: Antes de aplicar los cambios, Terraform genera un plan detallado que describe los pasos necesarios para alcanzar el estado deseado. Este plan muestra qué recursos serán creados, modificados o eliminados para alcanzar el estado deseado. Luego, Terraform ejecuta estos cambios de manera segura y controlada.\nEn resumen, el \u0026ldquo;desired state\u0026rdquo; en Terraform representa el estado en el que deseas que se encuentre tu infraestructura según lo definido en tus archivos de configuración. Terraform utiliza esta especificación para gestionar los recursos y aplicar los cambios necesarios para alcanzar ese estado deseado.\nLa función principal de Terraform es la de crear, modificar y destruir recursos de infraestructura que se encuentren presentes en el código valiéndose de los archivos de estados que se encuentran en su configuración.\nAquí podemos ver que estas 3 acciones (crear, modificar y destruir) se harán en pos de llegar a un estado deseado (desired state). Por ejemplo, cuando tenemos el siguiente código:\nresource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;First TerraformEC2\u0026#34; } } Lo que tratará de realizar Terraform será de generar una instancia de AWS en nuestra cuenta con las particularidades que se le asignan en el bloque de código interno, como por ejemplo que la AMI sea ami-0d7a109bf30624c99, o que el nombre de la instancia sea First TerraformEC2\nEn caso de que el bloque de código anterior, se encuentre comentado, el comando terraform apply le indicará a Terraform que el estado deseado será el de eliminar la instancia.\nCurrent state # Puede suceder que una vez que implementamos nuestra infraestructura mediante terraform apply, alguien desde el lado del proveedor AWS modifique la instancia y por ejemplo, modifique el tipo de la instancia (de t2.micro a t2 micro). Esto significa que el \u0026lsquo;desired state\u0026rsquo; y el \u0026lsquo;current state\u0026rsquo; (estado actual) no se corresponderán.\nImportante # Terraform siempre tratará de que la estructura que despliegue se base en el estado deseado. Por lo tanto, si sucede que hay una inconsistencia entre el estado deseado (que se encuentra configurado en terraform) con el estado actual (que se encuentra desplegado en AWS) como en el ejemplo anterior, entonces lo que tratará de hacer Terraform la próxima vez que se ejecute, es tratar de volver al estado deseado y cuando lancemos terraform plan nos mostrará un plan para para volver al estado deseable que se encuentra configurado en el código. Por lo tanto nos mostrará los pasos que aplicará para actualizar el estado actual y llevarlo al estado deseado.\nPor lo tanto, cuando Terraform encuentra una inconsistencia entre el desired state y el current state tratará de volver todo atrás y aplicar cambios para volver al desired state nuevamente.\nDesafíos con el current state en los valores calculados # Comando: terraform refresh # El comando terraform refresh es utilizado en Terraform para actualizar el estado conocido por Terraform con el estado actual de la infraestructura gestionada por los proveedores. Cuando ejecutas este comando, Terraform realiza una consulta a la infraestructura real para obtener información actualizada sobre los recursos existentes y sus atributos.\nAquí hay más detalles sobre cómo funciona terraform refresh:\nActualización del estado: Terraform compara el estado conocido (almacenado en los archivos de estado) con el estado actual de los recursos en la nube o en el proveedor de infraestructura local. Si hay diferencias entre el estado conocido y el estado actual, Terraform actualiza su estado interno para reflejar la información más reciente.\nNo aplica cambios: A diferencia de otros comandos de Terraform como terraform apply, terraform refresh no aplica cambios a la infraestructura. En su lugar, solo actualiza el estado interno de Terraform con la información actualizada de la infraestructura existente.\nÚtil para sincronización: terraform refresh es útil cuando necesitas sincronizar el estado de Terraform con cambios realizados externamente a través de otros medios que no sean Terraform, como cambios manuales realizados directamente en la consola del proveedor de nube o mediante otras herramientas de administración de infraestructura.\nPrecaución: Aunque terraform refresh no realiza cambios en la infraestructura, puede tener implicaciones si hay diferencias significativas entre el estado conocido y el estado real. Siempre es importante revisar cuidadosamente el resultado de terraform refresh para comprender cualquier diferencia y asegurarse de que el estado de Terraform refleje con precisión el estado real de la infraestructura.\nPor lo tanto, terraform refresh se utiliza para actualizar el estado interno de Terraform con la información más reciente sobre los recursos gestionados por los proveedores, sin realizar cambios en la infraestructura. Es útil para mantener sincronizado el estado de Terraform con cambios externos en la infraestructura.\nCurrent state non matching # Hay que entender que Terraform sólo sigue los recursos que se encuentran especificados dentro del código que nosotros le suministramos. Tengamos por ejemplo que nosotros simplemente tenemos este código:\nprovider \u0026#34;aws\u0026#34; { region = \u0026#34;us-east-1\u0026#34; access_key = \u0026#34;my-access-key\u0026#34; secret_key = \u0026#34;my-secret-key\u0026#34; } resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;First TerraformEC2\u0026#34; } } Implementamos este tipo de instancias mediante terraform apply, obteniendo como ya sabemos el archivo de seguimiento terraform.tfstate y entre todas las configuraciones que obtiene, vemos lo referido al Security Group\n... \u0026#34;secondary_private_ips\u0026#34;: [], \u0026#34;security_groups\u0026#34;: [ \u0026#34;default\u0026#34; ], ... Luego de esto, supongamos que un usuario desde el lado de AWS modifica el Security Group de la instancia, pasándola desde default a una generada por nosotros con nombre custom. Actualizamos el archivo de estado mediante el comando terraform refresh y el archivo terraform.tfstate se actualiza al siguiente estado:\n... \u0026#34;secondary_private_ips\u0026#34;: [], \u0026#34;security_groups\u0026#34;: [ \u0026#34;custom\u0026#34; ], ... Si lanzamos el comando terraform plan vamos a ver que terraform nos indicará que no hay ninguna modificación que realizar y que nuestra infraestructura se encuentra actualizada. ¿Y esto por qué? Ya que el Security Group cambió de default a custom.\nEsto es porque Terraform sólo se ocupa de llevar al estado deseado (desired state) la infraestructura que le da seguimiento y se encuentra configurada en nuestro código, por lo tanto, como el Security Group NO es parte de la infraestructura codificada por nosotros, no actualizará nada.\nTerraform Provider Versioning # La versión de proveedor (provider versioning en inglés) en Terraform se refiere al proceso de gestionar y controlar las versiones de los proveedores de Terraform utilizados en tu configuración. Cada proveedor de Terraform es mantenido y actualizado por un equipo específico, y regularmente se lanzan nuevas versiones para incluir nuevas funcionalidades, correcciones de errores y mejoras de rendimiento.\nAquí hay algunas cosas importantes que debes saber sobre la versión de proveedor en Terraform:\nCompatibilidad de versión: Cada versión de Terraform es compatible con una serie de versiones de proveedor. Esto significa que si estás utilizando una versión específica de Terraform, debes asegurarte de utilizar una versión compatible del proveedor. Puedes consultar la documentación oficial de Terraform o del proveedor para encontrar información sobre la compatibilidad de versiones.\nEspecificación de versiones: En tus archivos de configuración de Terraform, puedes especificar la versión del proveedor que deseas utilizar. Esto te permite controlar qué versión del proveedor se utiliza en tu infraestructura y evitar actualizaciones no deseadas que podrían introducir cambios inesperados.\nActualización de versiones: Es importante mantener tus proveedores de Terraform actualizados para aprovechar las últimas funcionalidades y correcciones de errores. Puedes utilizar herramientas como terraform init -upgrade para actualizar automáticamente los proveedores a las últimas versiones compatibles.\nAdministración de versiones: Si necesitas utilizar una versión específica del proveedor por razones de compatibilidad o estabilidad, puedes administrar las versiones de los proveedores utilizando herramientas de administración de dependencias, como terraform init -backend-config.\nLa versión de proveedor en Terraform es un aspecto importante a tener en cuenta al trabajar con la herramienta. Te permite controlar qué versiones de proveedores se utilizan en tu infraestructura y garantizar la compatibilidad y estabilidad de tu entorno. Es recomendable mantener tus proveedores actualizados para aprovechar las últimas funcionalidades y correcciones de errores.\nBuenas prácticas en ambientes productivos # Cuando se inicializa un proyecto de Terraform mediante terraform init, si no se especifica la versión, entonces por defecto Terraform utilizará la versión más actual.\nEn las implementaciones para ambientes productivos, siempre se deben tener en la configuración de Terraform señalada la versión del proveedor con la que nosotros querramos contar, de lo contrario, podríamos estar trabajando con una versión 8 y luego de un tiempo al aplicar nuevos cambios a la misma infraestructura la versión del proveedor pasa a la 9 y esto puede traer problemas graves.\nEs por eso que siempre es buena práctica establecer la versión del proveedor con la que querremos implementar nuestra infraestructura:\nterraform { required_providers { github = { source = \u0026#34;integrations/github\u0026#34; version = \u0026#34;~\u0026gt; 3.0\u0026#34; } } } De esta manera aseguramos que siempre estemos trabajando con la misma extensión 3.0 de Terraform que maneja la API de Github.\nArgumentos para el provider # Como podemos ver, cuando especificamos en un bloque de código required_providers la versión, los símbolos utilizados pueden ser varios. A continuación damos una explicación sobre estos.\nEn Terraform, el bloque required_providers se utiliza para especificar qué proveedores y qué versiones de esos proveedores son requeridos por nuestra configuración. Cuando defines un proveedor en este bloque, puedes especificar la versión del proveedor utilizando símbolos semánticos para indicar rangos de versiones.\nAquí hay una explicación de los símbolos comunes utilizados para configurar la versión del proveedor en el bloque required_providers:\nVersión exacta: Puedes especificar una versión exacta del proveedor utilizando el formato = X.Y.Z, donde X.Y.Z es la versión específica del proveedor que deseas utilizar. Por ejemplo, = 2.0.0 especifica que se requiere exactamente la versión 2.0.0 del proveedor.\nRango de versiones: Puedes especificar un rango de versiones utilizando los operadores de comparación \u0026gt;, \u0026lt;, \u0026gt;=, \u0026lt;= o ~\u0026gt;. Por ejemplo:\n\u0026gt;= 2.0.0 significa que se requiere una versión igual o superior a 2.0.0. \u0026lt;= 3.0.0 significa que se requiere una versión igual o inferior a 3.0.0. \u0026gt; 1.2.0, \u0026lt; 2.0.0 significa que se requiere una versión mayor que 1.2.0 pero menor que 2.0.0. ~\u0026gt; 1.2.0 significa que se requiere una versión que sea compatible con 1.2.0, lo que incluye cualquier versión 1.x.y donde x es igual a 2 e y es mayor o igual a 0. Última versión: Si no especificas ninguna versión, Terraform utilizará la última versión disponible del proveedor. Sin embargo, esto puede no ser siempre recomendable en entornos de producción, ya que puede introducir cambios no previstos.\nAquí hay un ejemplo de cómo se vería el bloque required_providers especificando diferentes versiones del proveedor:\nterraform { required_providers { aws = { source = \u0026#34;hashicorp/aws\u0026#34; version = \u0026#34;\u0026gt;= 3.0.0\u0026#34; } azurerm = { source = \u0026#34;hashicorp/azurerm\u0026#34; version = \u0026#34;\u0026gt;= 2.0.0, \u0026lt; 3.0.0\u0026#34; } } } En este ejemplo, se requiere cualquier versión igual o superior a 3.0.0 del proveedor de AWS, y cualquier versión compatible con la gama 2.x.y pero inferior a 3.0.0 del proveedor de Azure. Estas versiones se utilizarán cuando inicialices tu configuración de Terraform utilizando terraform init.\nImportante # NO se recomienda utilizar el argumento ~\u0026gt; para ambientes productivos (ver apartado anterior para entender el significado), ya que puede suceder que nuestra infraestructura funcione adecuadamente con la versión 3.0, pero no lo haga de forma correcta con la versión 3.1, por lo tanto este argumento se desaconseja totalmente. En ambientes productivos, se aconseja el uso de =.\nEL archivo terraform.lock.hcl # El archivo terraform.lock.hcl es un archivo generado por Terraform que se utiliza para bloquear las versiones específicas de los módulos de Terraform y los proveedores de infraestructura utilizados en tu configuración. Este archivo ayuda a garantizar que las mismas versiones de los módulos y proveedores se utilicen de manera consistente en diferentes entornos y durante diferentes ejecuciones de Terraform.\nAquí hay algunas cosas importantes que debes saber sobre el archivo terraform.lock.hcl:\nVersiones específicas: El archivo terraform.lock.hcl contiene una lista de las versiones específicas de los módulos de Terraform y los proveedores de infraestructura que se han utilizado en la configuración. Estas versiones son determinadas por Terraform durante la ejecución de terraform init y se basan en las restricciones de versión especificadas en los archivos de configuración, como required_providers y required_version.\nReproducibilidad: Al incluir versiones específicas en el archivo terraform.lock.hcl, se garantiza que las mismas versiones de los módulos y proveedores se utilizarán cada vez que se ejecute Terraform en el mismo directorio de trabajo. Esto proporciona una mayor reproducibilidad y evita que las actualizaciones automáticas de los módulos y proveedores afecten la consistencia de la infraestructura.\nControl de versiones: El archivo terraform.lock.hcl puede y debe ser incluido en tu sistema de control de versiones (por ejemplo, Git) junto con tus otros archivos de configuración de Terraform. Esto asegura que todos los miembros del equipo utilicen las mismas versiones de los módulos y proveedores y facilita la colaboración en el desarrollo de infraestructura.\nActualización manual: Aunque Terraform gestiona automáticamente la generación y actualización del archivo terraform.lock.hcl, no se recomienda modificar manualmente este archivo. Terraform lo gestionará por ti durante terraform init y garantizará que refleje de manera precisa las versiones utilizadas en tu configuración.\nEl archivo terraform.lock.hcl es un componente importante de tus proyectos de Terraform que ayuda a garantizar la consistencia y la reproducibilidad de tu infraestructura al bloquear las versiones específicas de los módulos y proveedores utilizados. Debes incluir este archivo en tu control de versiones y dejar que Terraform lo gestione automáticamente durante las operaciones de inicialización.\nEste archivo es creado cuando utilizamos el comando terraform init. Este archivo lee la condición que nosotros le indicamos en la sección de versión y descarga el proveedor según esa condición. Luego lo que hace es bloquear la versión que nosotros configuramos para que no se produzcan errores al utilizar distintas versiones de proveedores.\nLo que sucede cuando se especifica una versión para el proveedor es que automáticamente se genera el archivo terraform.lock.hcl que impide que cualquier modificación descuidada genere problemas con los módulos desarrollados en los scripts de terraform.\nPara actualizar la versión, se puede realizar lo que se especifica en el siguiente apartado.\nComando terraform init -upgrade # El comando terraform init -upgrade se utiliza en Terraform para actualizar automáticamente los módulos de Terraform y los proveedores de infraestructura a las últimas versiones compatibles. Este comando es útil cuando queremos asegurarnos de que estamos utilizando las últimas funcionalidades y correcciones de errores proporcionadas por los proveedores de Terraform.\nCuando ejecutamos terraform init -upgrade, Terraform realiza las siguientes acciones:\nActualización de módulos y proveedores: Terraform verifica si hay nuevas versiones de los módulos de Terraform y los proveedores de infraestructura especificados en tus archivos de configuración. Si se encuentran nuevas versiones, Terraform las descarga automáticamente y las instala en tu entorno de trabajo.\nActualización del archivo terraform.lock.hcl: Después de actualizar los módulos y los proveedores, Terraform actualiza el archivo terraform.lock.hcl para reflejar las versiones específicas que se utilizarán en tu configuración. Esto garantiza que las mismas versiones sean utilizadas de manera consistente cada vez que se ejecute Terraform en el mismo directorio de trabajo.\nAdvertencias y confirmaciones: Durante el proceso de actualización, Terraform puede mostrar advertencias o solicitar confirmaciones si se detectan cambios significativos en las versiones de los módulos o proveedores. Esto te permite revisar y confirmar los cambios antes de que se apliquen.\nEn cuanto a la relación con las versiones de los proveedores, terraform init -upgrade asegura que estés utilizando las últimas versiones de los proveedores de infraestructura compatibles con tu configuración. Esto es importante porque las nuevas versiones pueden incluir nuevas funcionalidades, mejoras de rendimiento, correcciones de errores y parches de seguridad que pueden ser beneficiosos para tu infraestructura.\nEs importante tener en cuenta que aunque terraform init -upgrade actualiza los proveedores de infraestructura a las últimas versiones compatibles, no actualiza automáticamente la versión de Terraform en sí misma. Para actualizar la versión de Terraform, debes hacerlo manualmente instalando la nueva versión y ejecutando terraform init sin la opción -upgrade.\nPor ejemplo, en una primera instancia, teníamos:\nterraform { required_providers { aws = { source = \u0026#34;hashicorp/aws\u0026#34; version = \u0026#34;= 2.50\u0026#34; } } } Y luego actualizamos el código a:\nterraform { required_providers { aws = { source = \u0026#34;hashicorp/aws\u0026#34; version = \u0026#34;\u0026lt;= 3.0\u0026#34; } } } Ingresamos terraform init -upgrade y lo que hará Terraform es buscar la nueva versión compatible con lo que especificamos en nuestro código, por ejemplo, podrá descargar la versión 3.0. De lo contrario, de no ingresar -upgrade, el comando lanzará un error.\nImportante # En el examen nos pueden preguntar sobre el cambio de versión de la siguiente manera:\n\u0026ldquo;En caso de que hayamos desplegado nuestra infraestructura con una versión 1 del proveedor, y actualmente existe la versión 2 ¿es necesario bajar la nueva versión?\u0026rdquo;\nY la respuesta es depende. No es conveniente actualizarla por un acto deliverado. Esto algunas veces es necesario cuando por ejemplo nuestro proveedor saca un nuevo servicio que necesitamos tener y sólo la versión 2 la tiene implementada. En este caso deberemos de generar varias pruebas o testing antes de actualizar la infraestructura productiva, y una vez que esté todo testeado, proceder a la actualización.\nEl comando terraform refresh # Terraform cuando despliega la infraestructura deseada, no tiene la posibilidad de evitar que esta sea modificada del lado del proveedor de AWS. Es por esto que Terraform requiere tener alguna forma para validar si es que se han ocasionado modificacione de manera manual por fuera de su alcance y con ello saber si la infraestructura gestionada se encuentra de acuerdo con el estado deseado (desired state).\nAquí es donde es importante el comando terraform refresh, el cual escanea la infraestructura desplegada para saber el estado actual (current state) y compararlo con el estado desado (desired state) y revisar si no hubo alguna modificación.\nNosotros no nos veremos en la obligación de tener que invocar continuamente el comando terraform refresh ya que este comando se ejecuta por detrás, tanto cuando se invoca el comando terraform plan como el comando terraform apply.\nComando terraform apply -auto-approve # El comando terraform apply -auto-approve se utiliza en Terraform para aplicar los cambios en nuestra infraestructura sin necesidad de confirmación manual. Cuando ejecutamos este comando, Terraform realiza los siguientes pasos:\nGeneración del plan: Terraform analiza tus archivos de configuración y determina qué cambios deben aplicarse a tu infraestructura. Luego, genera un plan detallado que describe los recursos que serán creados, modificados o eliminados para alcanzar el estado deseado.\nVisualización del plan: Antes de aplicar los cambios, Terraform muestra el plan generado en la salida estándar para que puedas revisarlo y confirmar que los cambios propuestos son los esperados y deseables.\nAplicación automática: Después de mostrar el plan, si ejecutas terraform apply -auto-approve, Terraform aplicará automáticamente los cambios descritos en el plan sin solicitar confirmación adicional. Esto incluye la creación, modificación o eliminación de recursos según lo especificado en el plan.\nSeguimiento de la ejecución: Mientras Terraform aplica los cambios, muestra mensajes de progreso en la salida estándar para indicar qué recursos están siendo creados, modificados o eliminados, así como cualquier error o advertencia que pueda ocurrir durante el proceso.\nEs importante tener en cuenta que el uso de -auto-approve en terraform apply suprime la solicitud de confirmación, lo que significa que los cambios se aplicarán inmediatamente sin la oportunidad de revisarlos manualmente. Por lo tanto, debes usar esta opción con precaución, especialmente en entornos de producción, para evitar cambios no deseados o accidentales en tu infraestructura.\nEl comando completo sería:\n$ terraform apply -auto-approve Esto aplicará automáticamente los cambios en tu infraestructura sin necesidad de confirmación manual.\nPráctica # Propongo la siguiente práctica para revisar lo que ya hemos estado viendo:\nCrea una instancia en AWS mediante código como lo venimos haciendo en lecciones anteriores. Aplicar el comando terraform apply -auto-approve para que Terraform no pida la confirmación de la aplicación del plan que se genera. Luego volver a ejecutar el comando terraform plan para notar que uno de los mensajes de notificación es porque se genera una actualización por parte de Terraform sobre el estado actual de la infraestructura que se encuentra desplegada. Importante # Se desaconseja el utilizar el comando terraform refresh de manera manual ya que algunas veces puede conducir a situaciones indeseadas. Para retratar esto se pasan a explicar algunos casos.\nCaso nº 1 # Primero vayamos por el primer caso. La situación es similar a la anterior al comienzo:\nCrea una instancia en AWS mediante código como lo venimos haciendo en lecciones anteriores. Aplica el comando terraform apply -auto-approve para que Terraform no pida la confirmación de la aplicación del plan que se genera. Luego volver a ejecutar el comando terraform plan para notar que uno de los mensajes de notificación es porque se genera una actualización por parte de Terraform sobre el estado actual de la infraestructura que se encuentra desplegada. Luego de esto, modificamos la región de AWS, y ponemos por ejemplo, la región us-west-2 Invocamos el comando terraform plan y lo que nos termina mostrando el plan es que de aplicarse, se generará una segunda instancia. ¿Por qué? Porque cambiamos la región a otra distinta que la del comienzo y esto generará que en vez de ir a buscar el estado actual de la instancia a la región anterior, lo vaya a buscar a us-west-2 y por lo tanto, al no encontrar nada, lo que hará es crear una nueva instancia. Volvemos a modificar la región y la dejamos igual que antes y luego de ello volvemos a invocar terraform plan y veremos que el estado actual corresponde con el estado deseado, por lo tanto no hay nada que aplicar. Caso nº 2 # Luego vamos por el segundo caso y donde la situación algo similiar a la anterior:\nCrea una instancia en AWS mediante código como lo venimos haciendo en lecciones anteriores. Aplica el comando terraform apply -auto-approve para que Terraform no pida la confirmación de la aplicación del plan que se genera. Luego volver a ejecutar el comando terraform plan para notar que uno de los mensajes de notificación es porque se genera una actualización por parte de Terraform sobre el estado actual de la infraestructura que se encuentra desplegada. Luego de esto, modificamos la región de AWS, y ponemos por ejemplo, la región us-west-2 Pero esta vez invocamos el comando terraform refresh y lo que nos termina mostrando el plan es que de aplicarse el plan, se generará una segunda instancia. ¿Por qué? Por lo que digimos anteriormente, porque cambiamos la región a otra distinta que la del comienzo y esto generará que en vez de ir a buscar el estado actual de la instancia a la región anterior, lo vaya a buscar a us-west-2 y por lo tanto, al no encontrar nada, lo que hará es crear una nueva instancia. ¡Pero el problema principal! Es que este comando elimina todo el contenido del archivo terraform.tfstate y genera uno nuevo por lo que dijimos anteriormente, que del lado de Terraform, piensa que al ser una nueva instancia, deberá de configurar todo de nuevo y lanzar un nuevo plan en otra región. En este escenario, podemos hacer uso del archivo terraform.tfstate.backup y copiar toda la configuración anterior desde este archivo al archivo terraform.tfstate. Volvemos a modificar la región y la dejamos igual que antes y luego de ello volvemos a invocar terraform plan y veremos que el estado actual corresponde con el estado deseado, por lo tanto no hay nada que aplicar. Conclusiones # Por lo tanto, es preferible o deseable que el comando terraform refresh no se ejecute de manera manual, para evitar que el archivo terraform.tfstate sea elimando como en el caso anterior. Este comando siempre se ejecutará por detrás del comanado terraform plan y este último es más seguro ya que como vimos anteriormente, no eliminaría el contenido del archivo terraform.tfstate.\nImportante # El comando terraform refresh ha quedado en desuso en versiones actuales, por lo tanto el único modo de poder trabajar con él es mediante los comandos anteriormente mensionados: terraform plan y terraform apply.\nAWS Provider - Authentication Configuration # Hasta el momento las llaves de acceso (access_key) y las llaves secretas (secret_key) las hemos puesto en el bloque de provider. Si bien este abordaje permite tener la posibilidad de generar una conexión correcta, en verdad es que no es una buena práctica de seguridad el tener las llaves publicadas. Esto puede llevar a que las llaves se vean comprometidas en alguna plataforma como Github, y de esta forma, se compromete la seguridad.\nPor lo tanto se prohibe terminantemente que estos datos sensibles se encuentren dentro del bloque provider. Ahora bien, ¿cómo se puede solucionar este problema?\nAWS CLI # Cuando nosotros trabajamos con Terraform desde la perspectiva de AWS, lo que debemos de tener en cuenta es de instalar la CLI de AWS. Si bien no trabajaremos con ella mediante Terraform, si es útil para poder generar, configurar y almacenar las credenciales y los profiles que nos permitirán trabajar de manera más cómoda con Terraform.\nSobre esto se puede ver:\nInstalación de AWS CLI Configuración de AWS CLI y Terraform Solución nº 1 # Por defecto, no deberíamos tener problemas si no generamos las access_key ni las secret_key en el bloque provider. Esto sería correcto, pero siempre que no se tenga un perfil nuevo gestionado en ~/.aws/credentials.\nPor lo tanto nuestro código quedaría así de simple:\nprovider \u0026#34;aws\u0026#34; { region = \u0026#34;us-east-1\u0026#34; } resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;First TerraformEC2\u0026#34; } } Los directorios donde mirará Terraform en caso de no proveerle ninguna de las llaves de acceso para Linux o Max, serán:\n- `$HOME/.aws/config` - `$HOME/.aws/credentials` Solución nº 2 # La otra solución sería implementar en el bloque provider las opciones shared_config_files y shared_credentials_files de la siguiente manera:\nprovider \u0026#34;aws\u0026#34; { shared_config_files = [\u0026#34;~/.aws/config\u0026#34;] shared_credentials_files = [\u0026#34;~/.aws/credentials\u0026#34;] profile = \u0026#34;custom\u0026#34; } resource \u0026#34;aws_instance\u0026#34; \u0026#34;terraformec2\u0026#34; { ami = \u0026#34;ami-0d7a109bf30624c99\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; tags = { Name = \u0026#34;First TerraformEC2\u0026#34; } } ¿Cuál es el problema con esta configuración? Que todos los desarrolladores del equipo que compartan estos archivos deberan de situar los mismos archivos de configuración en el mismo lugar que especifica la configuración. Esto sabemos que es imposible, por lo tanto debemos de tener otra solución más elegante.\nSolución nº 3 # Como se dijo anteriormente, la otra solución es instalar la CLI de AWS para poder gestionar mejor las credenciales. Esto se puede ver en el siguiente enlace:\nhttps://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html La diferencia que parece haber entre GNU/Linux y Windows es que en este último no hace falta publicar o exportar la variable $AWS_PROFILE.\nEn la documentación de Terraform perteneciente al provider AWS, es posible ver estas soluciones que hemos estado revisando pero con más detenimiento\n","date":"12 noviembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_03/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003eSección nº 3\n    \u003cdiv id=\"sección-nº-3\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#secci%c3%b3n-n%c2%ba-3\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\n\u003ch2 class=\"relative group\"\u003eAutenticación (Authentication) y Autorización (Authorization)\n    \u003cdiv id=\"autenticación-authentication-y-autorización-authorization\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#autenticaci%c3%b3n-authentication-y-autorizaci%c3%b3n-authorization\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003ePara comenzar con Terraform, lo que primero debemos de generar son los accesos correctos para que Terraform pueda generar la infraestructura que nosotros le pedimos. Si nosotros no generamos estos accesos desde el lado de AWS, Terraform cada vez que quiera impactar los cambios solicitados, obtendrá un error como respuesta. AWS por defecto no permite que ningún servicio se conecte a su nube excepto que configuremos los accesos de forma correcta.\u003c/p\u003e","title":"03 - Desplegando la infraestructura","type":"publicaciones"},{"content":" Sección nº 2 # 8. Proceso de instalación de Terraform # La instalación es bastante sencilla. Hashicorp provee el binario para poder instalarlo en distintas plataformas. Para los sistemas basados en GNU/Linux se puede encontrar la forma de instalación en el siguiente enlace\nHay que recordar que Terraform soporta distintos Sistemas Operativos:\nWindows macOS Linux FreeBSD OpenBSD Solaris En esta lección se verá la forma de instalar el binario en Windows y en la siguiente se verá el proceso para instalar en Linux.\nInstalación en Windows # Para el SO Windows, habrá que ir al siguiente enlace y seguir los pasos. Recomiendo descargar el binario señalado como AMD64. Luego, descomprimimos el archivo zip y lo instalamos en la dirección que nosotros querramos. Una vez finalizado este punto, abrimos una terminal de windows e ingresamos el siguiente comando:\n$ terraform Si todo el proceso ha salido exitoso, entonces luego del ingreso de este comando, se mostrarán un montón de opciones sobre cómo utilizar el comando terraform.\nNota importante sobre Windows # Dependiendo del lugar donde se seleccionó para la instalación del binario, el comando terraform sólo podrá ejecutarse dentro del directorio donde se instaló. Esto es algo particular de la instalación de Windows.\nPor ejemplo, si se instaló terraform en el directorio C:\\User\\John\\Desktop entonces terraform podrá ser utilizado sólo dentro de la carpeta Desktop y para que esto no suceda, y podramos utilizarlo en otras jerarquías de directorios, habrá que configurar las variables globales. Esto se hace de la siguiente manera:\nGeneramos una nueva carpeta dentro de C:\\ denominada como Binaries y arrastramos el binario Terraform.exe que descomprimimos hacia ésta carpeta. Luego vamos a This PC \u0026gt; Click izquierdo \u0026gt; Properties \u0026gt; Advance system settings \u0026gt; Environment Variables Luego, seleccionamos la variable Path \u0026gt; Edit \u0026gt; Browse \u0026gt; y seleccionamos la carpeta Binaries Deberemos de abrir una nueva terminal y luego de ello podremos ir a cualquier carpeta y ejecutar terraform y efectivamente veremos que ahora nos toma el comando correctamente. 9. Documentación - Página oficial de descargas # https://www.terraform.io/downloads\n10. Instalación en MacOS y Linux # MacOS # Para MacOS se puede emplear tanto el packet manager como también el binario; ambos se encuentran en el siguiente enlace\nGNU/Linux # Según nuestro SO, podemos utilizar el gestor de paquetes o el binario según desde el siguiente link\n11. Seleccionando el mejor IDE # La idea es encontrar un IDE para poder codificar para Terraform. En este caso particular nosotros utilizaremos Vim y el plugin hashivim/vim-terraform (instalado mediante VimPlug), por lo tanto no hace falta conseguir ningún IDE.\nEl gestor de plugins para Vim se puede encontrar en el siguiente enlace\nAlgunos de los ides que más se suelen utilizar (y que considero totalmente útiles) son:\nVisual Studio Code Sublime Text Atom 12. Instalación y Configuración # Como se dijo anteriormente, como nosotros utilizaremos el editor Vim y plugins como hashivim/vim-terraform o NerdTree, no hará falta utilizar otro IDE,\n13. Visual Studio Code Extensions # Los plugins que se sugieren instalar (en caso de elegir el editor Visual Studio Code) son los siguientes:\nHashiCorp Terraform 14. Sample Code - Extension Test # resource \u0026#34;aws_instance\u0026#34; \u0026#34;myec2\u0026#34; { ami = \u0026#34;ami-00c39f71452c08778\u0026#34; instance_type = \u0026#34;t2.micro\u0026#34; } 15. Configurando nuestra cuenta de AWS. # Como se mencionó previamente, se recomienda enfáticamente utilizar una nueva cuenta de AWS que aún se encuentre dentro del periodo de la Capa Gratuita (denominada Free Tier). Esto tiene por objetivo minimizar los posibles gastos mensuales derivados de la ejecución de los ejemplos y prácticas a lo largo del curso.\nLa Capa Gratuita de AWS proporciona recursos limitados que pueden utilizarse sin costo durante los primeros doce (12) meses desde la creación de la cuenta. Tras este periodo inicial, o si se exceden las limitaciones impuestas, los recursos comenzarán a generar cargos.\nEs obligatorio que los usuarios lean detenidamente las especificaciones y límites de los servicios incluidos en el Free Tier. Esta información detallada está disponible en el siguiente enlace\nEjemplo de Limitación # Dentro del Free Tier, se ofrece la posibilidad de desplegar instancias basadas en la mayoría de los entornos Linux. Sin embargo, si se elige una Imagen de Máquina de Amazon (AMI) basada en Windows, esta acción sí generará un cobro. Por consiguiente, se deben considerar estos límites estrictos al momento de planificar y realizar el despliegue de recursos en AWS.\nPor otro lado, el proceder con la creación de la cuenta de AWS, siga el proceso indicado en el portal oficial:\nEnlace Directo para el Registro en AWS: Link\nNota Importante # Para completar el registro y la activación de la cuenta, se requerirá una tarjeta de crédito o débito válida. Este paso es obligatorio para fines de verificación de identidad y facturación futura, aunque los cargos no se aplicarán mientras los recursos se mantengan dentro de los límites del Free Tier.\n","date":"3 noviembre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_02/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003eSección nº 2\n    \u003cdiv id=\"sección-nº-2\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#secci%c3%b3n-n%c2%ba-2\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\n\u003ch2 class=\"relative group\"\u003e8. Proceso de instalación de Terraform\n    \u003cdiv id=\"8-proceso-de-instalación-de-terraform\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#8-proceso-de-instalaci%c3%b3n-de-terraform\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003eLa instalación es bastante sencilla. Hashicorp provee el binario para poder instalarlo en distintas plataformas. Para los sistemas basados en GNU/Linux se puede encontrar la forma de instalación en el \u003ca\n  href=\"https://developer.hashicorp.com/terraform/install?product_intent=terraform#linux\"\n    target=\"_blank\"\n  \u003esiguiente enlace\u003c/a\u003e\u003c/p\u003e","title":"02 - Configuración del Laboratorio","type":"publicaciones"},{"content":" Sección nº 1 # 1. Descripción general de Terraform y su certificación # Terraform es una herramienta que se utiliza para gestionar la infraestructura como código. En otras palabras, te permite definir tu infraestructura (como servidores, redes, bases de datos, etc.) utilizando un lenguaje de programación y luego desplegarla de manera automatizada.\nLa importancia de Terraform en el ámbito de DevOps radica en su capacidad para automatizar y estandarizar el proceso de aprovisionamiento de infraestructura. Esto significa que puedes definir tu infraestructura de forma coherente y repetible, lo que facilita la gestión y el despliegue de aplicaciones en diferentes entornos (desarrollo, pruebas, producción, etc.). Además, al utilizar Terraform, puedes mantener tu infraestructura bajo control de versiones, lo que facilita la colaboración y el seguimiento de cambios a lo largo del tiempo. En resumen, Terraform ayuda a acelerar el tiempo de entrega, mejorar la consistencia y reducir los errores en el ciclo de vida de desarrollo y despliegue de software.\nPodemos observar la importancia en el mundo laboral que ha tomado Terraform, con sólo buscar algunos avisos laborales en Linkedin.\nLo importante de aprender Terraform, es que una vez que aprendemos el corazón del lenguaje y a programar nuestra propia infraestructura, vamos a tener la posibilidad de implementarlo en cualquier proveedor de la nube, por lo tanto nos abstrae de andar aprendiendo las particularidades de cada una de las plataformas de los proveedores de la nube.\n2. Acerca del curso # Este curso sigue todas los puntos que aborda la certificación de HashiCorp\nEn caso de Hashicorp incorpore nuevos materiales de estudio, se irán agregando al curso.\nLa idea de este curso es ir de manera progresiva con respecto al material de estudio para que el conocimiento y la lectura sean de dificultad gradual.\nUn punto importante para un entendimiento completo, es que todo el código que se vea dentro del curso, estará subido dentro de algún repositorio en GitHub.\nProveedor utilizado: AWS # Si bien el curso es para obtener los conocimientos básicos de Terraform, el proveedor con el que se trabajará será AWS. La opción del proveedor es indistinto, ya que Terraform nos permite abstraernos de las particularidades de la API de cada uno de ellos y en contraposición, tener un lenguaje que los unifica; por lo que el estudiantado puede sentirse libre de elegir el proveedor con el que se sienta más cómodo. Cabe destacar que sólo se utilizarán los servicios básicos de AWS como es EC2, IAM y alguno más. Estos mismos servicios serán los que después terminarán impactando de igual manera en los demás proveedores (en caso de modificar el proveedor).\nHay que tener en cuenta que estos servicios son los más básicos y los que menos costo en la nube de AWS tienen, pero esto no significa que el costo de usarlos sea $0. Siempre se incurrirá en algún costo aunque sea mínimo.\nIMPORTANTE: Es por eso que aconsejo tomar este curso con una cuenta nueva de AWS, ya que de este modo tenemos un año completo dentro de la capa gratuita; capa que nos permite utilizar varios servicios básicos con un costo reducido.\n3. Documentación abierta # Existen varios lugares de donde podemos basarnos para realizar ciertos ejemplos. Uno de ellos es el siguiente: https://github.com/zealvora/terraform-beginner-to-advanced-resource\n4. Principios básicos de IaC # Aquí se comentan algunos de los beneficios que se tienen al aprender IaC (Infrastructure as Code). Es de suma importancia automatizar la generación de infraestructura, la cual ofrece una serie de beneficios bastante importantes, y aprender Infrastructure as Code (IaC) es fundamental para aprovechar al máximo estas ventajas, entra las cuales están:\nEficiencia y velocidad: Automatizar la generación de infraestructura permite desplegar recursos de manera rápida y consistente. Esto acelera el proceso de desarrollo y despliegue de aplicaciones, lo que resulta en un tiempo de entrega más corto y una respuesta más rápida a las necesidades del negocio.\nConsistencia: Al definir la infraestructura como código, se garantiza que todos los entornos, desde desarrollo hasta producción, estén configurados de la misma manera. Esto reduce la posibilidad de errores causados por configuraciones inconsistentes y simplifica la resolución de problemas al tener entornos uniformes.\nEscalabilidad: La automatización facilita la gestión de infraestructuras complejas y su escalabilidad. Puedes definir patrones de infraestructura que se repitan fácilmente y que se adapten a las necesidades cambiantes del negocio, sin necesidad de configurar manualmente cada recurso.\nControl de versiones y trazabilidad: Al mantener la infraestructura como código, puedes gestionarla mediante sistemas de control de versiones como Git. Esto proporciona un historial completo de los cambios realizados en la infraestructura, facilitando la colaboración entre equipos, la auditoría y la reversión de cambios si es necesario.\nReutilización y modularidad: Puedes crear módulos reutilizables que representen componentes de infraestructura comunes, lo que facilita la construcción y mantenimiento de aplicaciones. Esto promueve las prácticas de desarrollo ágil y la reutilización de buenas prácticas en toda la organización.\nEn resumen, aprender Infrastructure as Code (IaC), especialmente mediante herramientas como Terraform, es crucial para aprovechar los beneficios de la automatización de la infraestructura. Ayuda a los equipos de desarrollo y operaciones a trabajar de manera más eficiente, consistente y escalable, mejorando así la velocidad y la calidad de la entrega de software.\nAutomatización de tareas # Es sumamente importante resaltar la importancia de automatizar las tareas repetitivas y diarias para un profesional DevOps. Automatizar estas tareas repetitivas ofrece beneficios significativos:\nAhorro de tiempo y recursos: La automatización elimina la necesidad de que los equipos realicen tareas repetitivas manualmente, lo que ahorra tiempo y recursos valiosos. Esto permite que los equipos se enfoquen en actividades de mayor valor, como la innovación y la mejora continua.\nReducción de errores: Las tareas manuales están sujetas a errores humanos, mientras que la automatización proporciona consistencia y precisión en la ejecución de tareas. Esto ayuda a reducir los errores y minimiza los riesgos asociados con las operaciones manuales, lo que a su vez mejora la calidad y la fiabilidad del software.\nEscalabilidad: A medida que las organizaciones crecen y las demandas de infraestructura y desarrollo aumentan, la automatización permite escalar de manera eficiente. Las tareas automatizadas pueden ejecutarse en múltiples entornos y plataformas de manera consistente y rápida, lo que facilita la gestión de entornos complejos y en constante cambio.\nConsistencia: La automatización garantiza que las tareas se realicen de manera consistente en todos los entornos, lo que ayuda a mantener la coherencia en el desarrollo, las pruebas y la implementación de software. Esto reduce la posibilidad de discrepancias entre entornos y minimiza los problemas causados por configuraciones incorrectas.\nMejora de la colaboración: La automatización fomenta la colaboración entre equipos al proporcionar una forma estandarizada y reproducible de realizar tareas. Esto facilita la comunicación y la coordinación entre los equipos de desarrollo, operaciones y otros departamentos, lo que conduce a una mayor eficiencia y alineación en toda la organización.\n5. Eligiendo la herramienta correcta de IaC # El mercado está lleno de herramientas que permiten implementar IaC, y algunas de ellas son las siguientes:\nTerraform: Terraform es una herramienta de código abierto desarrollada por HashiCorp que permite definir y administrar la infraestructura como código. Utiliza un lenguaje declarativo para describir recursos de infraestructura y proporciona una amplia compatibilidad con proveedores de servicios en la nube y tecnologías de infraestructura.\nAWS CloudFormation: AWS CloudFormation es un servicio de AWS que facilita la creación y gestión de recursos en la nube de AWS mediante plantillas de texto JSON o YAML. Permite definir y aprovisionar de manera automatizada recursos como instancias EC2, grupos de Auto Scaling, bases de datos RDS y más.\nAzure Resource Manager (ARM) Templates: ARM Templates son archivos JSON utilizados para definir y desplegar recursos en Azure. Con ARM Templates, puedes describir todos los recursos necesarios para tu aplicación o solución en Azure, incluidos servicios como máquinas virtuales, redes, bases de datos y más.\nGoogle Cloud Deployment Manager: Google Cloud Deployment Manager es una herramienta que te permite definir y desplegar recursos en Google Cloud Platform (GCP) utilizando plantillas YAML o Jinja. Con Deployment Manager, puedes crear y gestionar recursos como máquinas virtuales, redes, bases de datos y más de forma programática.\nAnsible: Ansible es una herramienta de automatización de TI de código abierto que se utiliza para la provisión de infraestructura, la gestión de configuraciones y la orquestación de aplicaciones. Utiliza un lenguaje simple basado en YAML para describir tareas y configuraciones, lo que facilita la automatización de procesos en una variedad de entornos.\nChef: Chef es una plataforma de automatización de infraestructura que utiliza un enfoque basado en la \u0026ldquo;infraestructura como código\u0026rdquo; para gestionar y configurar servidores. Utiliza recetas (recipes) y roles para definir configuraciones y políticas, lo que permite la gestión centralizada y la aplicación consistente de configuraciones en múltiples nodos.\nPuppet: Puppet es una herramienta de gestión de configuración que automatiza el aprovisionamiento, la configuración y la gestión de infraestructura de manera consistente y escalable. Utiliza un lenguaje declarativo para describir el estado deseado de los sistemas, lo que facilita la automatización y la gestión de configuraciones en diferentes plataformas.\nOrquestación de la infraestructura y gestión de su configuración # Para poder entender mejor cuál podría ser la mejor herramienta para nuestra organización, lo mejor será tener en claro los siguientes aspectos.\nOrquestación de Infraestructura (Infrastructure Orchestration): La orquestación de infraestructura se refiere al proceso de coordinar y gestionar los recursos de infraestructura de manera automatizada y centralizada. Esto implica la gestión de la infraestructura a nivel macro, incluyendo la creación, configuración, escalado y eliminación de recursos en una infraestructura de TI. La orquestación de infraestructura a menudo se utiliza para gestionar entornos complejos y distribuidos, como clústeres de servidores, redes y almacenamiento en la nube. Un ejemplo de la tarea a la que se aboca esta categoría sería la de crear 3 servidores con 4Gb de RAM con 2 vCPUs, y cada uno de los servidores deberá de tener un firewall que permita la conexión SSH desde la IP de las oficinas centrales.\nGestión de Configuración (Configuration Management): La gestión de configuración se centra en garantizar que los sistemas y recursos de infraestructura estén configurados de manera consistente y conforme a un estado deseado. Esto implica definir, mantener y aplicar configuraciones de software y sistemas operativos en los servidores y otros dispositivos de la infraestructura. La gestión de configuración ayuda a automatizar la implementación y el mantenimiento de configuraciones, lo que garantiza que los sistemas funcionen de manera confiable y coherente. Un ejemplo de la tarea a la que se aboca esta categoría sería el tener instalado y configurado en todos los servidores un antivirus cuya versión sesa la 10.0.2\nPodemos catalogar las herramientas mencionadas en el apartado anterior en:\nOrquestación de Infraestructura (Infrastructure Orchestration): # Algunas de las herramientas que permiten la Orquestación de Infraestructura, son:\nTerraform AWS CloudFormation Azure Resource Manager (ARM) Templates Google Cloud Deployment Manager Gestión de Configuración (Configuration Management): # Por otro lado, algunas de las herramientas que permiten la Gestión de Configuraciones son:\nAnsible Chef Puppet Si bien algunas herramientas pueden tener capacidades que se superponen entre ambas categorías, generalmente se pueden catalogar según su enfoque principal. Las herramientas de orquestación de infraestructura se centran en la provisión y gestión de recursos de infraestructura en un nivel más alto, mientras que las herramientas de gestión de configuración se utilizan para definir y mantener configuraciones de software y sistemas en los recursos aprovisionados.\nIaC \u0026amp; Gestión de configuraciones # Luego de esta introducción, debemos entender que ambas categorías se solapan en aplicaciones tales como Ansible. Pero cuando nuestra Organización requiera exclusivamente IaC, entonces deberemos de pensar en Terraform.\nTerraform también se puede conectar con la herramienta Ansible para poder dar soporte en la Gestión de configuraciones de los servidores creados mediante Terraform. Es por eso que es tan importante Terraform, ya que nos permite conectarnos a otras aplicaciones tales como Ansible para poder tener un poder total sobre nuestra infraestructura.\n6. Pensando Casos de uso para IaC # Ahora pensemos casos de uso simples que nos permitan evaluar a grandes rasgos las distintas posibilidades de adoptar una herramienta de IaC. Hay que poner en evidencia, que en no todos los casos, la respuesta será Terraform.\nCaso de uso nº 1 # Pongamos un ejemplo de un caso de uso de una empresa:\nLa organización basará toda su infraestructura en AWS por los próximos 25 años. Se requerirá un soporte oficial en caso de que se enfrente con algún tipo de inconveniente con la herramienta de IaC o con su código. Se requiere algún tipo de interface (GUI) que soporte la generación de código automático. Vayamos evaluando punto por punto el requisito de la empresa:\nEste punto ya nos indica que no hará falta mudar nuestra infraestructura a otro proveedor distinto de AWS, por lo que nos ahorra el pensar en alguna herramienta que permita la abstracción del código del proveedor.\nEl servicio de CloudFormation (la herramienta de IaC propietaria de AWS) ofrece un soporte técnico pago que permite a la organización consultar en caso de que algo con respecto a la herramienta o con el código haya salido mal. También Terraform permite esto, dependiendo del nivel de suscripción que se haga a Terraform Cloud o Terraform Enterprise. Aún así, el soporte no está diseñado para escribir código; los ingenieros de HashiCorp a menudo brindan asistencia y orientación técnica profunda para diagnosticar fallas o problemas de state que se manifiestan debido a errores en la lógica del código HCL.\nPara este punto, debemos también hacer hincapié que per se Cloudformation no cuenta con una interface que permita la generación de código de manera automática, pero si existe un servicio denominado AWS Designer que permita visualizar la arquitectura existente, mostrando los recursos y sus conexiones mediante diagramas. También es posible con esta herramienta diseñar las plantillas en formato JSON o YAML, permitiendo así verificar la dependencia y la estructura del código. Este servicio se integra de manera nativa con el de Cloudformation. Por otro lado, Terraform no cuenta con ninguna herramienta de estas características soportada por Hashicorp.\nPosible Solución: la posible solución será utilizar el servicio de Cloudformation junto con algún nivel de suscripción para soporte técnico.\nCaso de uso nº 2 # En este ejemplo, los requisitos son:\nLa organización se basará en una solución híbrida: se utiliza VMWare para los servidores on-premises y los proveedores AWS, Azure y GCP para la nube. Se requerirá un soporte oficial en caso de que se enfrente con algún tipo de inconveniente con la herramienta de IaC. Estos casos suceden cuando los errores que está teniendo la herramienta corresponden con lo que se encuentra documentado en la página oficial de la herramienta. Analicemos los puntos de nuestro nuevo requerimiento nuevamente:\nCon este punto podremos saber que la herramienta requerida será Terraform, ya que soporta múltiples proveedores de infraestructura, a diferencia de CloudFormation que es propietaria de AWS y pensada para funcionar sólo dentro de su ámbito. Terraform soporta tanto los proveedores de la nube como también a VMWare. Esto último se pude buscar en la página oficial de proveedores de Terraform. Se puede observar que VMWare se encuentra soportado mediante VSphere\nLa compañía que gestiona Terraform, se llama Hashicorp y si vamos a su página oficial, podremos ver que existe la posibilidad de obtener soporte para la licencia Enterprise por lo tanto deberemos de pensar en este gasto para poder obtener este tipo de beneficio.\nPosible Solución: la posible solución en este caso será utilizar Terraform.\n","date":"31 octubre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/terraformassociate_01/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003eSección nº 1\n    \u003cdiv id=\"sección-nº-1\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#secci%c3%b3n-n%c2%ba-1\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\n\u003ch2 class=\"relative group\"\u003e1. Descripción general de Terraform y su certificación\n    \u003cdiv id=\"1-descripción-general-de-terraform-y-su-certificación\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#1-descripci%c3%b3n-general-de-terraform-y-su-certificaci%c3%b3n\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003eTerraform es una herramienta que se utiliza para gestionar la infraestructura como código. En otras palabras, te permite definir tu infraestructura (como servidores, redes, bases de datos, etc.) utilizando un lenguaje de programación y luego desplegarla de manera automatizada.\u003c/p\u003e","title":"01 - Introducción a Terraform","type":"publicaciones"},{"content":" Glosario # Perfiles de Terraform # Uno de los problemas principales que se tuvo administrando con Terraform los recursos de AWS, es que cuando se quiere ejecutar cualquier comando de terraform se debe utilizar un PERFIL. Para crear un perfil nuevo, se deben seguir los siguientes pasos:\nPara esto, necesitaremos la cuenta root de AWS e iremos al servicio de IAM para poder crear un nuevo usuario: Nos logueamos a nuestra cuenta de AWS con el usuario root Vamos al servicio de IAM \u0026gt; Users \u0026gt; Create User User Name: Terraform Permission \u0026gt; Attach policies directly Y seleccionamos el siguiente permiso: Administrator Access Create User Una vez que nuestro nuevo usuario se encuentra creado, lo que deberemos de hacer es: Lo seleccionamos de la lista de IAM \u0026gt; Users En la pestaña Security Credentials \u0026gt; Create Access Key \u0026gt; CLI Agregamos alguna descripción que querramos Create Access Key Por temas de seguridad, deberemos de bajar el csv donde se tienen las llaves en texto plano Luego de esto, copiamos tanto el Access Key como el valor del Secret Access Key. Luego lo que hacemos es seguir el paso nº 4 de la siguiente documentación: https://www.thegeekstuff.com/2019/03/aws-configure-examples/ Luego, deberemos de invocar el comando export AWS_PROFILE=terraform antes de invocar a comandos tales como terraform plan. Recordar que la invocación al comando export se debe realizar cada vez que se abra una nueva sesión en la consola. Luego de esta configuración, podemos revisarla invocando a aws configure list. Provider Maintainers # Los \u0026ldquo;provider maintainers\u0026rdquo; en Terraform son individuos o equipos responsables del desarrollo y mantenimiento de los proveedores de Terraform. Un proveedor en Terraform es un complemento que permite a Terraform interactuar con servicios en la nube, proveedores de infraestructura local u otros sistemas externos para gestionar recursos.\nLos proveedores mantienen la integración de Terraform con servicios específicos y se encargan de asegurar que los proveedores sean compatibles, estables y estén actualizados con las últimas características y cambios de los servicios que representan.\nProveedor de Registro (Provider Registry) # El proveedor de registros (Provider Registry en inglés) en Terraform es un servicio proporcionado por HashiCorp que actúa como un repositorio centralizado de proveedores de Terraform y módulos. Este registro permite a los usuarios buscar, descubrir y acceder fácilmente a los proveedores de Terraform y módulos creados y mantenidos por la comunidad y por HashiCorp.\nProvider Tiers # Los providers de Terraform, que son los plugins que permiten a Terraform interactuar con APIs externas (como AWS, Azure, Google Cloud, Kubernetes, etc.), se clasifican oficialmente en función de quién los mantiene y su nivel de confianza, lo cual podría verse como distintos \u0026ldquo;tiers\u0026rdquo;.\n1. Providers Oficiales (Official Providers) # Estos son los providers de mayor confianza y calidad, mantenidos directamente por HashiCorp (la empresa que desarrolla Terraform) o por el vendedor de la plataforma a la que se conectan (por ejemplo, AWS, Microsoft, Google, etc.), en estrecha colaboración con HashiCorp.\nCaracterísticas: Máximo soporte, actualizaciones más frecuentes, integración profunda con Terraform y con la plataforma subyacente. Ejemplos: aws, azurerm, google, kubernetes. 2. Providers Verificados (Verified Providers) # Son mantenidos por terceros que son partners tecnológicos o proveedores de software reconocidos y que han pasado por un proceso de verificación con HashiCorp.\nCaracterísticas: Son de alta calidad y están respaldados por una organización comercial establecida que colabora con HashiCorp. Ejemplos: Providers de empresas como Cloudflare, Datadog, Splunk, o VMWare. 3. Providers Comunitarios (Community Providers) # Son mantenidos por miembros individuales de la comunidad open-source.\nCaracterísticas: La calidad y el soporte varían. Dependen de la dedicación de sus mantenedores. Son esenciales para interactuar con herramientas más nicho o APIs menos populares. Ejemplos: Providers para algunas herramientas self-hosted o APIs específicas. Namespaces # En el contexto del registro de proveedores de Terraform, el término \u0026ldquo;namespaces\u0026rdquo; se refiere a una forma de organizar y categorizar los proveedores de Terraform y los módulos asociados dentro del registro. Los \u0026ldquo;namespaces\u0026rdquo; actúan como contenedores lógicos que agrupan los recursos relacionados según el autor o el mantenimiento del proveedor.\nCada \u0026ldquo;namespace\u0026rdquo; en el registro de proveedores de Terraform está asociado con un nombre único, que generalmente corresponde al nombre del autor o del mantenedor del proveedor o módulo. Estos nombres pueden ser nombres de organizaciones, nombres de usuarios o cualquier otro identificador único.\nLos \u0026ldquo;namespaces\u0026rdquo; permiten a los usuarios del registro de proveedores de Terraform identificar fácilmente los proveedores y módulos mantenidos por una determinada entidad. Esto facilita la búsqueda y el descubrimiento de recursos relevantes para sus necesidades específicas.\nFile State # En Terraform, los \u0026ldquo;state files\u0026rdquo; (archivos de estado) son archivos que contienen información sobre la infraestructura gestionada por Terraform. Estos archivos almacenan el estado actual de los recursos que Terraform administra, incluyendo los recursos creados, sus atributos y cualquier otra información relevante.\nAquí hay algunos puntos clave sobre los archivos de estado en Terraform:\nRegistro del estado de la infraestructura: Los archivos de estado registran el estado actual de la infraestructura gestionada por Terraform. Esto incluye información sobre los recursos que Terraform ha creado, modificado o eliminado, así como sus atributos y configuraciones actuales.\nSincronización con la infraestructura real: Los archivos de estado se utilizan para mantener un registro sincronizado de la infraestructura real y la definición de infraestructura en tus archivos de configuración de Terraform. Esto permite a Terraform determinar qué recursos están gestionados por Terraform y qué cambios han sido aplicados a esos recursos.\nPrevención de conflictos: Los archivos de estado evitan conflictos al permitir que Terraform realice cambios de manera controlada y predecible. Terraform utiliza el archivo de estado como fuente de verdad para determinar qué cambios son necesarios para alcanzar el estado deseado de la infraestructura.\nAlmacenamiento local o remoto: Los archivos de estado pueden almacenarse localmente en tu máquina de desarrollo o en un sistema de control de versiones como Git, pero también es común almacenarlos de forma remota en un servicio de almacenamiento específico, como Terraform Cloud, Amazon S3, Azure Blob Storage, o Google Cloud Storage. Almacenar los archivos de estado de forma remota proporciona una mayor seguridad y colaboración entre equipos.\nDesired \u0026amp; Current state # En Terraform, el término \u0026ldquo;desired state\u0026rdquo; (estado deseado) se refiere al estado en el que deseas que se encuentre tu infraestructura según lo definido en tus archivos de configuración de Terraform. Este estado deseado se describe mediante la especificación de recursos y sus atributos en los archivos de configuración.\nPuntos importantes:\nDefinición de recursos: En tus archivos de configuración de Terraform, defines los recursos que deseas que Terraform administre. Estos recursos pueden ser instancias de máquinas virtuales, bases de datos, redes, balanceadores de carga, entre otros, dependiendo del proveedor y los servicios que estés utilizando.\nAtributos y configuraciones: Junto con la definición de recursos, también especificas los atributos y configuraciones de esos recursos que deseas que Terraform aplique. Esto incluye detalles como el tipo de instancia, la región, el tamaño del disco, las reglas de firewall, etc.\nGestión de cambios: Terraform se encarga de llevar la infraestructura al estado deseado, comparando el estado actual de los recursos con el estado deseado definido en los archivos de configuración. Si hay diferencias entre el estado actual y el estado deseado, Terraform realiza los cambios necesarios para converger hacia el estado deseado.\nPlanificación y ejecución: Antes de aplicar los cambios, Terraform genera un plan detallado que describe los pasos necesarios para alcanzar el estado deseado. Este plan muestra qué recursos serán creados, modificados o eliminados para alcanzar el estado deseado. Luego, Terraform ejecuta estos cambios de manera segura y controlada.\nProvider Versioning # La versión de proveedor (provider versioning en inglés) en Terraform se refiere al proceso de gestionar y controlar las versiones de los proveedores de Terraform utilizados en tu configuración. Cada proveedor de Terraform es mantenido y actualizado por un equipo específico, y regularmente se lanzan nuevas versiones para incluir nuevas funcionalidades, correcciones de errores y mejoras de rendimiento.\nAquí hay algunas cosas importantes que debes saber sobre la versión de proveedor en Terraform:\nCompatibilidad de versión: Cada versión de Terraform es compatible con una serie de versiones de proveedor. Esto significa que si estás utilizando una versión específica de Terraform, debes asegurarte de utilizar una versión compatible del proveedor. Puedes consultar la documentación oficial de Terraform o del proveedor para encontrar información sobre la compatibilidad de versiones.\nEspecificación de versiones: En tus archivos de configuración de Terraform, puedes especificar la versión del proveedor que deseas utilizar. Esto te permite controlar qué versión del proveedor se utiliza en tu infraestructura y evitar actualizaciones no deseadas que podrían introducir cambios inesperados.\nActualización de versiones: Es importante mantener tus proveedores de Terraform actualizados para aprovechar las últimas funcionalidades y correcciones de errores. Puedes utilizar herramientas como terraform init -upgrade para actualizar automáticamente los proveedores a las últimas versiones compatibles.\nAdministración de versiones: Si necesitas utilizar una versión específica del proveedor por razones de compatibilidad o estabilidad, puedes administrar las versiones de los proveedores utilizando herramientas de administración de dependencias, como terraform init -backend-config.\n.terraform.lock.hcl # El archivo terraform.lock.hcl es un archivo generado por Terraform que se utiliza para bloquear las versiones específicas de los módulos de Terraform y los proveedores de infraestructura utilizados en tu configuración. Este archivo ayuda a garantizar que las mismas versiones de los módulos y proveedores se utilicen de manera consistente en diferentes entornos y durante diferentes ejecuciones de Terraform.\nAlgunos puntos importantes:\nVersiones específicas: El archivo terraform.lock.hcl contiene una lista de las versiones específicas de los módulos de Terraform y los proveedores de infraestructura que se han utilizado en la configuración. Estas versiones son determinadas por Terraform durante la ejecución de terraform init y se basan en las restricciones de versión especificadas en los archivos de configuración, como required_providers y required_version.\nReproducibilidad: Al incluir versiones específicas en el archivo terraform.lock.hcl, se garantiza que las mismas versiones de los módulos y proveedores se utilizarán cada vez que se ejecute Terraform en el mismo directorio de trabajo. Esto proporciona una mayor reproducibilidad y evita que las actualizaciones automáticas de los módulos y proveedores afecten la consistencia de la infraestructura.\nControl de versiones: El archivo terraform.lock.hcl puede y debe ser incluido en tu sistema de control de versiones (por ejemplo, Git) junto con tus otros archivos de configuración de Terraform. Esto asegura que todos los miembros del equipo utilicen las mismas versiones de los módulos y proveedores y facilita la colaboración en el desarrollo de infraestructura.\nActualización manual: Aunque Terraform gestiona automáticamente la generación y actualización del archivo terraform.lock.hcl, no se recomienda modificar manualmente este archivo. Terraform lo gestionará por ti durante terraform init y garantizará que refleje de manera precisa las versiones utilizadas en tu configuración.\nDebuging Terraform # TF_LOG es una variable de entorno que puedes configurar para controlar el nivel de detalle de los registros (logs) generados por Terraform durante la ejecución de los comandos. Esta variable de entorno es útil para depurar problemas, entender lo que está sucediendo bajo el capó de Terraform y obtener más información sobre cómo se están ejecutando tus comandos.\nPuedes establecer TF_LOG en uno de los siguientes niveles de detalle:\nTRACE: Este es el nivel de detalle más alto y proporciona información detallada sobre cada acción que Terraform está tomando, incluyendo todas las solicitudes a la API del proveedor de la nube, la planificación detallada y más. Este nivel es útil para depurar problemas específicos y entender el flujo de trabajo interno de Terraform, pero la cantidad de registros generados puede ser muy grande.\nDEBUG: Este nivel proporciona información detallada sobre lo que está haciendo Terraform, incluyendo la creación y actualización de recursos, la resolución de dependencias, la evaluación de expresiones y más. Es menos detallado que TRACE, pero aún así puede generar muchos registros.\nINFO: Este es el nivel predeterminado y proporciona información de nivel de información sobre el progreso de los comandos de Terraform, como los recursos que se están creando, actualizando o eliminando, y cualquier problema que ocurra durante la ejecución. Este nivel es útil para obtener una visión general de lo que está sucediendo sin inundar la salida con demasiada información.\nWARN: Este nivel solo muestra advertencias y errores. Es útil cuando solo estás interesado en problemas que puedan ocurrir durante la ejecución y no necesitas ver detalles sobre el progreso.\nERROR: Este nivel solo muestra mensajes de error. Es útil cuando solo necesitas ser notificado sobre errores críticos y no estás interesado en ningún otro tipo de mensaje.\nComandos # terraform console # Para poder consultar el funcionamiento de las funciones built-in de Terraform, tenemos la posibilidad de invocar al comando terraform console.\nEl comando terraform console es una herramienta interactiva que te permite evaluar expresiones y funciones de Terraform en tiempo real dentro de una consola interactiva. Esto te permite probar y experimentar con código Terraform sin necesidad de aplicar los cambios a tu infraestructura.\nCuando ejecutas el comando terraform console, Terraform inicia una sesión interactiva donde puedes ingresar y evaluar expresiones de Terraform. Por ejemplo, puedes realizar cálculos simples, manipulaciones de cadenas, operaciones matemáticas, y mucho más.\nPor ejemplo, podrías ejecutar el siguiente comando:\nterraform console Una vez que ingreses a la consola interactiva, podrías ingresar expresiones como estas:\n\u0026gt; \u0026#34;Hello, \u0026#34; + \u0026#34;World!\u0026#34; El cual te daría como resultado:\n\u0026#34;Hello, World!\u0026#34; Otras operaciones más complejas también son posibles, por ejemplo:\n\u0026gt; upper(\u0026#34;hello\u0026#34;) Dará como resultado:\n\u0026#34;HELLO\u0026#34; Esta herramienta es útil para probar rápidamente cómo se comportan las expresiones y las funciones de Terraform antes de integrarlas en tus archivos de configuración. Además, puede ser útil para depurar y comprender mejor cómo funcionan ciertas funciones o expresiones en Terraform. Sin embargo, ten en cuenta que terraform console no tiene acceso a ningún estado de Terraform o recursos reales, por lo que algunas operaciones que dependen del estado de la infraestructura real no serán posibles de evaluar.\nterraform init # El comando terraform init se utiliza para inicializar un directorio de trabajo de Terraform. Cuando trabajas con Terraform en un nuevo directorio o cuando clonas un repositorio que contiene archivos de configuración de Terraform, es necesario ejecutar terraform init antes de utilizar otros comandos de Terraform como terraform plan o terraform apply. Aquí hay más detalles sobre qué hace este comando:\nInstalación de proveedores y módulos: Una de las funciones principales de terraform init es descargar e instalar los proveedores de infraestructura y módulos de Terraform especificados en tus archivos de configuración. Los proveedores son los complementos que Terraform utiliza para interactuar con API de servicios en la nube, como AWS, Azure, Google Cloud, etc. Los módulos son paquetes reutilizables de configuración de Terraform. Inicialización del backend: Terraform utiliza un \u0026ldquo;backend\u0026rdquo; para almacenar el estado de la infraestructura. El backend puede ser local, en la nube o en un servicio de almacenamiento remoto. Durante la ejecución de terraform init, Terraform configura y establece el backend que se especifica en tu archivo de configuración. Esto es crucial para que Terraform mantenga y sincronice el estado de la infraestructura de manera adecuada. Inicialización de complementos: Además de los proveedores y módulos, Terraform puede requerir complementos adicionales para realizar ciertas operaciones, como la generación de gráficos de dependencia o la ejecución de validaciones de sintaxis. terraform init también se encarga de descargar e instalar estos complementos si es necesario. En resumen, terraform init es el primer comando que debes ejecutar al comenzar a trabajar en un nuevo directorio de Terraform. Prepara el entorno de trabajo descargando proveedores, módulos y complementos necesarios, y configura el backend para el almacenamiento del estado de la infraestructura. Es un paso fundamental para empezar a utilizar Terraform de manera efectiva en tu proyecto de infraestructura como código.\nterraform init -upgrade # El comando terraform init -upgrade se utiliza en Terraform para actualizar automáticamente los módulos de Terraform y los proveedores de infraestructura a las últimas versiones compatibles. Este comando es útil cuando quieres asegurarte de que estás utilizando las últimas funcionalidades y correcciones de errores proporcionadas por los proveedores de Terraform.\nCuando ejecutas terraform init -upgrade, Terraform realiza las siguientes acciones:\nActualización de módulos y proveedores: Terraform verifica si hay nuevas versiones de los módulos de Terraform y los proveedores de infraestructura especificados en tus archivos de configuración. Si se encuentran nuevas versiones, Terraform las descarga automáticamente y las instala en tu entorno de trabajo.\nActualización del archivo terraform.lock.hcl: Después de actualizar los módulos y los proveedores, Terraform actualiza el archivo terraform.lock.hcl para reflejar las versiones específicas que se utilizarán en tu configuración. Esto garantiza que las mismas versiones sean utilizadas de manera consistente cada vez que se ejecute Terraform en el mismo directorio de trabajo.\nAdvertencias y confirmaciones: Durante el proceso de actualización, Terraform puede mostrar advertencias o solicitar confirmaciones si se detectan cambios significativos en las versiones de los módulos o proveedores. Esto te permite revisar y confirmar los cambios antes de que se apliquen.\nEn cuanto a la relación con las versiones de los proveedores, terraform init -upgrade asegura que estés utilizando las últimas versiones de los proveedores de infraestructura compatibles con tu configuración. Esto es importante porque las nuevas versiones pueden incluir nuevas funcionalidades, mejoras de rendimiento, correcciones de errores y parches de seguridad que pueden ser beneficiosos para tu infraestructura.\nEs importante tener en cuenta que aunque terraform init -upgrade actualiza los proveedores de infraestructura a las últimas versiones compatibles, no actualiza automáticamente la versión de Terraform en sí misma. Para actualizar la versión de Terraform, debes hacerlo manualmente instalando la nueva versión y ejecutando terraform init sin la opción -upgrade.\nPor ejemplo, en una primera instancia, teníamos:\nterraform { required_providers { aws = { source = \u0026#34;hashicorp/aws\u0026#34; version = \u0026#34;= 2.50\u0026#34; } } } Y luego actualizamos el código a:\nterraform { required_providers { aws = { source = \u0026#34;hashicorp/aws\u0026#34; version = \u0026#34;\u0026lt;= 3.0\u0026#34; } } } Ingresamos terraform init -upgrade y lo que hará Terraform es buscar la nueva versión compatible con lo que especificamos en nuestro código, por ejemplo, podrá descargar la versión 3.0. De lo contrario, de no ingresar -upgrade, el comando lanzará un error.\nterraform fmt # El comando terraform fmt es ideal para dar formato a nuestros archivos de terraform. Esto posibilita la estandarización y la legibilidad de forma simple, a través de un simple comando.\nterraform validate # El comando terraform validate en Terraform se utiliza para verificar la validez de los archivos de configuración de Terraform. Básicamente, realiza dos tipos de validaciones:\nSintaxis del archivo: Verifica si la estructura y sintaxis de los archivos de configuración de Terraform son correctas. Esto incluye comprobar si hay errores de sintaxis, como errores de formato, errores de puntuación, errores de indentación, etc. Si hay algún error de sintaxis en tus archivos de configuración, el comando terraform validate te lo indicará para que puedas corregirlo antes de continuar. Referencias a recursos y proveedores: Terraform también verifica si las referencias a recursos y proveedores en tus archivos de configuración son válidas. Esto significa que comprueba si los recursos y proveedores a los que haces referencia realmente existen y están disponibles en las versiones especificadas de los proveedores de Terraform. Si intentas utilizar un recurso o proveedor que no existe o no está disponible en tu configuración, Terraform te lo hará saber durante la validación. En resumen, terraform validate es una herramienta útil para verificar la precisión y validez de tus archivos de configuración de Terraform antes de aplicar los cambios en tu infraestructura. Esto te ayuda a detectar y corregir errores de sintaxis y referencias inválidas antes de ejecutar comandos que puedan afectar a tu infraestructura en la nube. terraform plan # El comando terraform plan es uno de los comandos más importantes en Terraform. Se utiliza para generar un plan de ejecución que describe qué acciones Terraform llevará a cabo para alcanzar el estado deseado de la infraestructura según la configuración definida en los archivos de Terraform. Aquí hay algunos aspectos clave sobre el comando terraform plan:\nGeneración de un plan: Cuando ejecutas terraform plan, Terraform analiza tus archivos de configuración y consulta el estado actual de la infraestructura para determinar qué cambios son necesarios para alcanzar el estado deseado. Luego, genera un plan detallado que describe qué recursos se crearán, modificarán o eliminarán para lograr ese estado deseado. Visualización de cambios: El plan generado por terraform plan te muestra una lista de acciones que Terraform tomará, incluyendo la creación, modificación o eliminación de recursos. También te muestra cualquier cambio planeado en los atributos de los recursos existentes. Validación previa a la aplicación: Antes de aplicar cualquier cambio a tu infraestructura, es una buena práctica ejecutar terraform plan para revisar los cambios propuestos. Esto te permite entender completamente qué cambios se van a realizar y te da la oportunidad de detectar posibles problemas antes de que se apliquen los cambios. No aplica los cambios: Es importante tener en cuenta que terraform plan solo genera un plan de ejecución y no aplica ningún cambio a la infraestructura. Esto significa que puedes usar este comando de forma segura para revisar los cambios sin afectar a tu infraestructura en producción. En resumen, terraform plan es una herramienta fundamental para la gestión de la infraestructura con Terraform. Te permite visualizar y validar los cambios propuestos antes de aplicarlos, lo que ayuda a prevenir errores y asegura que tus modificaciones se realicen de manera controlada y predecible. terraform plan -target=\u0026lt;FILE.tf\u0026gt; # El comando terraform plan -target se utiliza para generar un plan de ejecución de Terraform limitado a un conjunto específico de recursos dentro de tu configuración. Aquí tienes una explicación breve sobre lo que hace:\nGenera un plan de ejecución limitado: El comando terraform plan por sí solo genera un plan de ejecución completo para todos los recursos definidos en tus archivos de configuración de Terraform. Sin embargo, al agregar -target, puedes restringir este plan solo a los recursos que especifiques, junto con sus dependencias. Especifica el objetivo: Con -target, puedes indicar a Terraform qué recursos deseas incluir en el plan. Esto es útil cuando solo quieres ver qué cambios se aplicarán en un subconjunto específico de recursos en lugar de en toda tu infraestructura. Evalúa dependencias: Terraform analiza los recursos especificados junto con sus dependencias para determinar qué cambios deben aplicarse. Esto puede incluir la creación, actualización o eliminación de recursos, así como las dependencias necesarias para mantener la integridad de la infraestructura. Proporciona una vista previa de los cambios: Una vez que ejecutas terraform plan -target, Terraform genera un plan detallado que muestra qué acciones tomará para los recursos especificados. Esto te permite revisar y validar los cambios propuestos antes de aplicarlos. terraform apply # El comando terraform apply es utilizado para aplicar los cambios definidos en tus archivos de configuración de Terraform a tu infraestructura. Este comando lleva a cabo las siguientes acciones:\nPlanificación y validación: Antes de aplicar los cambios, Terraform ejecuta implícitamente terraform plan para generar un plan detallado de los cambios propuestos. Esto te permite revisar los cambios que se van a realizar y validarlos antes de que tengan efecto en tu infraestructura. Interactividad opcional: Terraform solicitará confirmación antes de aplicar los cambios si estás ejecutando terraform apply de forma interactiva. Esto te da la oportunidad de revisar el plan y cancelar la operación si es necesario. Aplicación de los cambios: Una vez que confirmas la aplicación de los cambios, Terraform procede a ejecutar las acciones necesarias para alcanzar el estado deseado de la infraestructura. Esto puede incluir la creación, modificación o eliminación de recursos en tu entorno de nube. Actualización del estado: Después de aplicar los cambios con éxito, Terraform actualiza el archivo de estado para reflejar el estado actual de la infraestructura. Este archivo de estado se utiliza para realizar un seguimiento de los recursos gestionados por Terraform y garantizar que cualquier cambio futuro se aplique de manera coherente. Es importante tener en cuenta que terraform apply realiza cambios en tu infraestructura en la nube y debe utilizarse con precaución, especialmente en entornos de producción. Es recomendable revisar cuidadosamente el plan generado por terraform plan antes de aplicar los cambios y asegurarse de entender completamente el impacto de los mismos en tu infraestructura. Además, es una buena práctica hacer uso de entornos de desarrollo o pruebas para probar los cambios antes de aplicarlos en entornos de producción.\nterraform apply -target=\u0026lt;FILE.tf\u0026gt; # Aquí tienes una explicación breve sobre lo que hace el comando terraform apply -target=\u0026lt;FILE.tf\u0026gt;:\nAplica cambios limitados a recursos específicos: El comando terraform apply se utiliza para aplicar los cambios definidos en tu configuración de Terraform a tu infraestructura. Al agregar -target=\u0026lt;file.tf\u0026gt;, puedes limitar la aplicación de estos cambios solo a los recursos especificados en el archivo \u0026lt;file.tf\u0026gt; y sus dependencias. Identifica el objetivo de la aplicación: Mediante -target=\u0026lt;file.tf\u0026gt;, le indicas a Terraform qué recursos deseas que sean el objetivo de la aplicación de cambios. Esto te permite controlar exactamente qué recursos serán modificados, creados o eliminados durante la ejecución de terraform apply. Evalúa las dependencias necesarias: Terraform analiza los recursos especificados junto con sus dependencias para determinar qué cambios se deben aplicar y en qué orden. Esto garantiza que se respeten las dependencias entre los recursos y que la infraestructura se mantenga en un estado coherente. Aplica los cambios de manera selectiva: Una vez que ejecutas terraform apply -target=\u0026lt;file.tf\u0026gt;, Terraform aplica los cambios propuestos solo a los recursos especificados, lo que te permite realizar modificaciones de manera selectiva y controlada en tu infraestructura. terraform apply -auto-approve # El comando terraform apply -auto-approve se utiliza en Terraform para aplicar los cambios en tu infraestructura sin necesidad de confirmación manual. Cuando ejecutas este comando, Terraform realiza los siguientes pasos:\nGeneración del plan: Terraform analiza tus archivos de configuración y determina qué cambios deben aplicarse a tu infraestructura. Luego, genera un plan detallado que describe los recursos que serán creados, modificados o eliminados para alcanzar el estado deseado. Visualización del plan: Antes de aplicar los cambios, Terraform muestra el plan generado en la salida estándar para que puedas revisarlo y confirmar que los cambios propuestos son los esperados y deseables. Aplicación automática: Después de mostrar el plan, si ejecutas terraform apply -auto-approve, Terraform aplicará automáticamente los cambios descritos en el plan sin solicitar confirmación adicional. Esto incluye la creación, modificación o eliminación de recursos según lo especificado en el plan. Seguimiento de la ejecución: Mientras Terraform aplica los cambios, muestra mensajes de progreso en la salida estándar para indicar qué recursos están siendo creados, modificados o eliminados, así como cualquier error o advertencia que pueda ocurrir durante el proceso. Es importante tener en cuenta que el uso de -auto-approve en terraform apply suprime la solicitud de confirmación, lo que significa que los cambios se aplicarán inmediatamente sin la oportunidad de revisarlos manualmente. Por lo tanto, debes usar esta opción con precaución, especialmente en entornos de producción, para evitar cambios no deseados o accidentales en tu infraestructura.\nterraform apply -var-file=\u0026lt;file.tfvars\u0026gt; # El comando terraform apply -var-file=\u0026quot;[nombre_archivo]\u0026quot; se utiliza principalmente en situaciones donde necesitas separar los valores de las variables de la configuración de tu infraestructura y aplicarlos de una manera organizada, segura y repetible.\nLas situaciones clave donde se usa este comando son:\n1. Gestión de Múltiples Entornos (Dev, Staging, Prod) # Esta es la razón más común. Utilizar archivos de variables (.tfvars) permite aplicar el mismo código base de Terraform a diferentes entornos, simplemente cambiando el archivo de variables.\nSituación: Tienes la misma infraestructura (por ejemplo, una red, servidores web y una base de datos), pero necesitas diferentes tamaños, nombres o configuraciones según el entorno. Archivos: dev.tfvars: Contiene valores pequeños (ej: server_count = 1, db_size = \u0026quot;small\u0026quot;). prod.tfvars: Contiene valores grandes (ej: server_count = 10, db_size = \u0026quot;large\u0026quot;). Comando: Para desarrollo: terraform apply -var-file=\u0026quot;dev.tfvars\u0026quot; Para producción: terraform apply -var-file=\u0026quot;prod.tfvars\u0026quot; 2. Manejo de Datos Sensibles (Secretos) # Aunque la mejor práctica es usar herramientas como HashiCorp Vault, AWS Secrets Manager o Azure Key Vault, el uso de archivos de variables proporciona una capa de seguridad para datos menos críticos o durante el desarrollo local, especialmente si se añade el archivo a la lista de ignorados (.gitignore).\nSituación: Necesitas pasar claves de API o contraseñas a la configuración de Terraform sin codificarlas directamente en los archivos .tf. Práctica: Creas un archivo (ej: secrets.tfvars) que no se sube a tu repositorio de código (Git). Comando: terraform apply -var-file=\u0026quot;secrets.tfvars\u0026quot; 3. Sobrescribir Valores por Defecto (Defaults) # Si tienes variables con valores por defecto en tu archivo variables.tf, puedes usar un archivo de variables para sobrescribir solo aquellas que necesitas cambiar.\nSituación: Quieres cambiar rápidamente uno o dos parámetros de una configuración compleja sin tener que pasar cada variable individualmente en la línea de comandos (-var). Archivo: custom.tfvars solo incluye las variables que difieren del valor por defecto. Comando: terraform apply -var-file=\u0026quot;custom.tfvars\u0026quot; 4. Flujos de Trabajo CI/CD (Integración y Despliegue Continuo) # En sistemas de automatización, el uso de archivos de variables es crucial para mantener la configuración de un entorno separada del código de despliegue.\nSituación: Estás utilizando una herramienta de CI/CD (como Jenkins, GitLab CI o GitHub Actions) para desplegar tu infraestructura. Beneficio: El pipeline de CI/CD puede cargar el archivo de variables apropiado para el entorno de destino (por ejemplo, el archivo staging.tfvars cuando se ejecuta en la rama de staging). ¿Cuál es la diferencia con terraform.tfvars? # Si un archivo se llama terraform.tfvars, Terraform lo carga y lo aplica automáticamente sin necesidad de usar el flag -var-file.\nEl uso explícito de -var-file=\u0026quot;nombre_archivo.tfvars\u0026quot; es necesario cuando:\nEl nombre del archivo no es terraform.tfvars o *.auto.tfvars. Necesitas cargar múltiples archivos de variables en una sola ejecución. Ejemplo: terraform apply -var-file=\u0026quot;base.tfvars\u0026quot; -var-file=\u0026quot;prod.tfvars\u0026quot; terraform refresh # NOTA: Este comando se encuentra deshabilitado en versiones actuales de Terraform y la única posibilidad de utilizarlo es mediante los comandos terraform plan y terraform apply.\nterraform plan -destroy # El comando terraform plan -destroy es una variación del comando terraform plan que se utiliza específicamente para generar un plan detallado de destrucción de recursos. Este comando es útil cuando estás preparando la eliminación de la infraestructura gestionada por Terraform y quieres ver qué recursos serán eliminados antes de ejecutar terraform destroy.\nAquí hay más información sobre terraform plan -destroy:\nGeneración de un plan de destrucción: Al ejecutar terraform plan -destroy, Terraform analiza tus archivos de configuración y el estado actual de la infraestructura para determinar qué recursos serán eliminados si ejecutas terraform destroy. Terraform genera un plan detallado que describe los recursos que serán eliminados y cualquier cambio asociado, como la eliminación de dependencias. Visualización de cambios a ser eliminados: El plan de destrucción generado por terraform plan -destroy te mostrará una lista detallada de los recursos que serán eliminados. Esto incluye información sobre los recursos específicos, como sus nombres, tipos, y cualquier otra información relevante. Validación previa a la destrucción: Al revisar el plan de destrucción, puedes asegurarte de que comprendes completamente qué recursos serán eliminados y qué impacto tendrá en tu infraestructura. Esto te permite tomar decisiones informadas y verificar que estás eliminando los recursos deseados antes de ejecutar terraform destroy. terraform destroy # El comando para destruir o eliminar toda la infraestructura que se ha creado con Terraform es terraform destroy. Este comando desmantela y elimina todos los recursos que fueron creados por Terraform según la configuración definida en tus archivos.\nEs importante tener en cuenta que terraform destroy eliminará todos los recursos definidos en tu configuración, por lo que debes tener cuidado al usarlo en entornos de producción para evitar la pérdida de datos o recursos importantes.\nAntes de ejecutar terraform destroy, es una buena práctica revisar el plan de destrucción generado por Terraform para asegurarte de que comprendes qué recursos se eliminarán. Puedes obtener este plan ejecutando terraform plan -destroy para ver una lista detallada de los recursos que serán eliminados.\nUna vez estés seguro de que deseas continuar con la eliminación de los recursos, simplemente ejecuta terraform destroy y confirma la acción cuando se te solicite. Terraform comenzará a eliminar los recursos de manera segura y controlada de acuerdo con la configuración definida en tus archivos.\nEl comando terraform destroy se utiliza para eliminar de forma segura y controlada todos los recursos que Terraform ha creado y administra según la configuración definida en tus archivos de Terraform. Aquí hay más información sobre este comando:\nEliminación de recursos: Cuando ejecutas terraform destroy, Terraform desmantela y elimina todos los recursos que ha creado según la configuración en tus archivos. Esto incluye la eliminación de instancias de máquinas virtuales, grupos de seguridad, redes, bases de datos, y cualquier otro recurso gestionado por Terraform.\nConfirmación de eliminación: Antes de llevar a cabo la eliminación de los recursos, Terraform solicitará confirmación para asegurarse de que estás seguro de que deseas proceder con la acción. Debes confirmar explícitamente la eliminación escribiendo \u0026ldquo;yes\u0026rdquo; en la línea de comandos para evitar la eliminación accidental de recursos importantes.\nActualización del estado: Después de eliminar los recursos, Terraform actualizará el archivo de estado para reflejar los cambios realizados. Esto asegura que Terraform tenga un registro actualizado del estado de tu infraestructura y evita conflictos futuros al aplicar cambios.\nControl de recursos: Es importante tener en cuenta que terraform destroy eliminará todos los recursos definidos en tu configuración, por lo que debes tener cuidado al usarlo en entornos de producción para evitar la pérdida de datos o recursos importantes. Se recomienda realizar una copia de seguridad o una revisión cuidadosa de los recursos antes de ejecutar este comando en un entorno de producción.\nterraform destroy -target # Algunas veces, no vamos a necesitar eliminar todos los recursos que se encuentran dentro de nuestro repositorio. En el caso actual, si nosotros aplicaríamos terraform destroy, se eliminarían los recursos de:\nfirst_ec2.tf github.tf Pero supongamos que nosotros queremos mantener las instancias generadas en AWS pero queremos eliminar los recursos gestionados en GitHub ¿Cómo podemos hacer esto?.\nEsto se puede hacer mediante el comando terraform destroy -target \u0026lt;TARGET\u0026gt;.\nEl comando terraform destroy -target \u0026lt;TARGET\u0026gt; es una variación del comando terraform destroy que te permite especificar un recurso específico que deseas destruir en lugar de eliminar todos los recursos gestionados por Terraform. Esto puede ser útil cuando solo quieres eliminar un recurso particular en lugar de toda la infraestructura, lo que te permite controlar de manera más precisa qué recursos se eliminarán.\nDetalles:\nEspecificación del objetivo: Con la opción -target, puedes especificar el recurso específico que deseas destruir. Esto se hace proporcionando la dirección del recurso como argumento. La dirección del recurso es la ruta completa al recurso en el árbol de recursos de Terraform, como aws_instance.example o google_compute_instance.example.\nDestrucción del recurso objetivo: Cuando ejecutas terraform destroy -target \u0026lt;TARGET\u0026gt;, Terraform desmantela y elimina únicamente el recurso especificado y cualquier recurso que dependa directa o indirectamente de él. Terraform analiza la dependencia del recurso objetivo y elimina los recursos en el orden adecuado para evitar conflictos o errores.\nPrecaución: Es importante tener en cuenta que terraform destroy -target \u0026lt;TARGET\u0026gt; elimina solo el recurso especificado y sus dependencias, pero no elimina otros recursos no relacionados que puedan estar presentes en tu configuración de Terraform. Por lo tanto, debes tener cuidado al usar este comando para evitar la eliminación accidental de recursos importantes o infraestructura dependiente.\n","date":"25 octubre 2025","externalUrl":null,"permalink":"/publicaciones/terraform/glosario/","section":"Publicaciones","summary":"\u003ch1 class=\"relative group\"\u003eGlosario\n    \u003cdiv id=\"glosario\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#glosario\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h1\u003e\n\n\u003ch2 class=\"relative group\"\u003ePerfiles de Terraform\n    \u003cdiv id=\"perfiles-de-terraform\" class=\"anchor\"\u003e\u003c/div\u003e\n    \n    \u003cspan\n        class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none\"\u003e\n        \u003ca class=\"text-primary-300 dark:text-neutral-700 !no-underline\" href=\"#perfiles-de-terraform\" aria-label=\"Ancla\"\u003e#\u003c/a\u003e\n    \u003c/span\u003e\n    \n\u003c/h2\u003e\n\u003cp\u003eUno de los problemas principales que se tuvo administrando con Terraform los recursos de AWS, es que cuando se quiere ejecutar cualquier comando de \u003ccode\u003eterraform\u003c/code\u003e se debe utilizar un PERFIL. Para crear un perfil nuevo, se deben seguir los siguientes pasos:\u003c/p\u003e","title":"Glosario","type":"publicaciones"},{"content":"","externalUrl":null,"permalink":"/en/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/autores/","section":"Autores","summary":"","title":"Autores","type":"autores"},{"content":"","externalUrl":null,"permalink":"/categorias/","section":"Categorias","summary":"","title":"Categorias","type":"categorias"},{"content":"","externalUrl":null,"permalink":"/en/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/etiquetas/","section":"Etiquetas","summary":"","title":"Etiquetas","type":"etiquetas"},{"content":"","externalUrl":null,"permalink":"/en/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"}]