Skip to main content

Herramientas para detectar la desviación de infraestructura

Escrito por
Headshot of William Beuil

William Beuil

feature iac drift blue

15 de marzo de 2022

0 minutos de lectura

Aviso de obsolescencia: detección de desviaciones en recursos administrados

La detección de desviaciones en recursos administrados, incluidos snyk iac describe --only-managed and snyk iac describe --drift, dejó de estar disponible. La fecha de fin de vida útil de la detección de desviaciones en recursos administrados es el 30 de septiembre de 2023.

Predecir las desviaciones de infraestructura es como predecir las nevadas en invierno… sabes que ocurrirán en algún momento, pero no puedes saber exactamente cuándo. Y, al igual que con las nevadas, contar con una forma de detectarlas lo antes posible te permitirá estar mejor preparado y proteger más tu infraestructura.

En este artículo, exploraremos los principios de la detección de desviaciones, sus distintos tipos y causas, y las herramientas que ayudan a detectarlas con un ejemplo sencillo.

¿Qué es la detección de desviaciones?

Para entender por qué necesitas herramientas de detección de desviaciones, primero debes comprender qué es la desviación de infraestructura. En pocas palabras, puedes pensar en ella como una diferencia entre toda tu infraestructura y tu archivo de configuración.

Para esta publicación, nos centraremos en HashiCorp Terraform como herramienta de software de infraestructura como código (IaC) para implementar recursos en la nube. En el mundo de Terraform, hay una desviación cuando el archivo de estado no coincide con lo que implementaste en tu proveedor de nube.

Aquí es donde las herramientas adecuadas para detectar esas desviaciones pueden mejorar significativamente tu postura de seguridad. Imagina un mundo perfecto en el que recibes alertas si alguien cambia manualmente tu grupo de seguridad en lugar de usar Terraform. Y, además, ¿no sería fantástico recibir alertas sobre recursos nuevos creados fuera de Terraform?

Recursos administrados y no administrados

Para ilustrar ese mundo perfecto, distinguiremos dos tipos de desviaciones:

Desviaciones en recursos administrados por IaC

Como contamos con los archivos de configuración y de estado de todos los recursos implementados en tu proveedor de nube, tu herramienta de IaC suele ser muy útil para detectar cambios realizados fuera de ella o que aún no se han aplicado.

Desviaciones en recursos no administrados por IaC

Por otro lado, este tipo de desviación es difícil de detectar, ya que esos recursos no están definidos en tu archivo de configuración ni en el de estado.

¿Por qué ocurren las desviaciones?

Las desviaciones ocurren por muchas razones obvias, pero HashiCorp lo explica mejor que nadie:

«En el contexto de tu configuración, ocurre cuando agregas o eliminas recursos o cambias sus definiciones. Fuera de tu configuración, el desvío se produce cuando los recursos se dan de baja o fallan, y cuando se hacen cambios manualmente o mediante otras herramientas de automatización».

HashiCorpHashiCorp

Christie Koehler

Developer Advocate, HashiCorp

Veamos ejemplos reales de los dos tipos de desviación y su impacto. Una desviación en un recurso administrado podría ocurrir si alguien cambia manualmente el control de versiones de tu bucket de Amazon S3 configurado con Terraform. En cambio, una desviación en un recurso no administrado podría ocurrir si alguien agrega manualmente un bucket de S3 fuera de Terraform (por ejemplo, desde la consola de AWS). (Consulta nuestro artículo anterior para obtener consejos para administrar las desviaciones causadas por cambios manuales.)

¿Qué herramientas pueden ayudarnos a detectar esas desviaciones?

Ahora, centrémonos en las herramientas que te ayudan a detectar desviaciones en recursos administrados y no administrados. Para el resto de esta publicación, usaremos el mismo ejemplo sencillo de Terraform que explicamos antes:

resource "aws_s3_bucket" "example" {
        bucket = "drift-example-managed-resource"
        versioning {
                enabled = true
        }
}

Solo cambiaremos en la consola el atributo de control de versiones a false para generar una desviación. Además, crearemos manualmente el mismo bucket de S3 desde la consola de AWS.

Consola de buckets de AWS S3 que muestra buckets administrados y no administrados de ejemplo en la región Oeste de EE. UU. (Oregón), ambos marcados como privados.

Ahora veamos tres herramientas para administrar las desviaciones:

  1. terraform plan

  2. CloudQuery

  3. driftctl

1. terraform plan

El comando terraform plan describe de forma sencilla qué se debe aplicar para obtener la implementación deseada. Veamos el resultado de este comando en nuestra infraestructura actual:

$ terraform plan

aws_s3_bucket.example: Refreshing state... [id=drift-example-managed-resource]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # aws_s3_bucket.example has changed
  ~ resource "aws_s3_bucket" "example" {
        id                          = "drift-example-managed-resource"
        # (10 unchanged attributes hidden)

      ~ versioning {
          ~ enabled    = true -> false
            # (1 unchanged attribute hidden)
        }
    }

Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include actions to undo or respond to these changes.

────────────────────────────────────────────────────────────
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_s3_bucket.example will be updated in-place
  ~ resource "aws_s3_bucket" "example" {
        id                          = "drift-example-managed-resource"
        # (10 unchanged attributes hidden)

      ~ versioning {
          ~ enabled    = false -> true
            # (1 unchanged attribute hidden)
        }
    }

Plan: 0 to add, 1 to change, 0 to destroy.

────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

Terraform indica que encontró una desviación en el recurso administrado y explica en qué consistió el cambio (por ejemplo, el control de versiones pasó de true a false). Después, muestra qué hará si decidimos aplicar el plan (por ejemplo, volverá a establecer el control de versiones en true).

Ventajas:

  • Forma consistente de detectar desviaciones en recursos administrados

  • Admite todos los recursos de Terraform

Desventajas:

  • No permite detectar desviaciones en recursos no administrados

  • No admite ejecutar planes en varios archivos de estado

2. CloudQuery

CloudQuery es un inventario de activos en la nube de código abierto basado en SQL. De forma predeterminada, extrae todos tus recursos de los proveedores de nube que elijas, les da formato y los carga en PostgreSQL. Luego, incorpora un comando de detección de desviaciones para «convertir este problema de desviación en un problema de datos», como dicen ellos.

Una vez instalado el CLI de CloudQuery, volvamos a detectar las desviaciones de nuestro bucket de S3.

$ cloudquery fetch

Initializing CloudQuery Providers...

✓ cq-provider-aws@v0.10.10 verified    0s  100 %

Finished provider initialization...

Upgrading CloudQuery providers aws

✓ Upgraded provider aws to latest successfully.

Finished upgrading providers...

Starting provider fetch...

✓ cq-provider-aws@latest fetch complete   15s   Finished Resources: 129/129

Provider fetch complete.

Provider aws fetch summary: ✓ Total Resources fetched: 523 ⚠️ Warnings: 0 ❌ Errors: 0

El primer comando, como explicamos antes, obtiene todos mis recursos de los proveedores de nube y los almacena en una tabla de PostgreSQL.

Tabla de base de datos oscura que muestra recursos administrados y no administrados, con el estado del control de versiones indicado como Suspendido y Habilitado.
$ cloudquery drift scan --deep --debug terraform.tfstate

Initializing CloudQuery Providers...

⌛cq-provider-aws@v0.10.11 downloading...                           4s  100 %

Finished provider initialization...

Using profile drift-example
Starting module...
DIFF RESOURCE: s3.buckets:drift-example-managed-resource
+------------------------------------------+-----------+---------------+-------------------------+
|                 AWS EXPR                 |  AWS VAL  | TERRAFORM VAL |     TERRAFORM EXPR      |
+------------------------------------------+-----------+---------------+-------------------------+
| COALESCE("c"."versioning_status",'')     | Suspended | <nil>         | versioning_status       |
| COALESCE("c"."versioning_mfa_delete",'') | Disabled  | <nil>         | versioning_mfa_delete   |
| "c"."block_public_acls"                  | true      | <nil>         | block_public_acls       |
| "c"."block_public_policy"                | true      | <nil>         | block_public_policy     |
| "c"."ignore_public_acls"                 | true      | <nil>         | ignore_public_acls      |
| "c"."restrict_public_buckets"            | true      | <nil>         | restrict_public_buckets |
+------------------------------------------+-----------+---------------+-------------------------+
Matching attributes "region", "logging_target_prefix", "logging_target_bucket", "policy", "tags", "replication_role", "arn", "ownership_controls"
+-----------------------+---------------------------------------------------------+
|       ATTRIBUTE       |                     MATCHING VALUE                      |
+-----------------------+---------------------------------------------------------+
| region                | us-west-2                                               |
| logging_target_prefix |                                                         |
| logging_target_bucket |                                                         |
| policy                | <nil>                                                   |
| replication_role      |                                                         |
| arn                   | arn:aws:s3:::drift-example-managed-resource             |
| ownership_controls    | <nil>                                                   |
+-----------------------+---------------------------------------------------------+
Module output:
=== DRIFT RESULTS  ===
1 Resources not managed by Terraform
  aws:s3.buckets:
    - drift-example-un-managed-resource
1 Resources managed by Terraform but drifted
  aws:s3.buckets:
    - drift-example-managed-resource
=== SUMMARY ===
Total number of resources: 2
 - 1 not managed by Terraform
 - 1 managed by Terraform but drifted
 - 50% covered by Terraform
Finished module

Este resultado es bastante interesante, ya que podemos ver que encontró mis dos buckets de S3: uno administrado y otro no administrado. Además, detectó una desviación en mi bucket administrado, pero el análisis resulta bastante extraño: indica que el bucket de S3 no tiene control de versiones en AWS, pero que ese dato es desconocido en mi archivo de estado. Probablemente sea un error en la forma en que interpreta los atributos de Terraform. Los otros atributos desviados me hacen preguntarme qué pasaría si tuviera un bucket administrado sin desviaciones.

Volví a aplicar la configuración inicial de mi bucket con terraform apply y ejecuté otra vez cloudquery fetch y cloudquery drift scan --deep --debug terraform.tfstate:

$ terraform plan

aws_s3_bucket.example: Refreshing state... [id=drift-example-managed-resource]

No changes. Your infrastructure matches the configuration.

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

$ cloudquery drift scan --deep --debug terraform.tfstate

...

DIFF RESOURCE: s3.buckets:drift-example-managed-resource
+------------------------------------------+----------+---------------+-------------------------+
|                 AWS EXPR                 | AWS VAL  | TERRAFORM VAL |     TERRAFORM EXPR      |
+------------------------------------------+----------+---------------+-------------------------+
| COALESCE("c"."versioning_status",'')     | Enabled  | <nil>         | versioning_status       |
| COALESCE("c"."versioning_mfa_delete",'') | Disabled | <nil>         | versioning_mfa_delete   |
| "c"."block_public_acls"                  | true     | <nil>         | block_public_acls       |
| "c"."block_public_policy"                | true     | <nil>         | block_public_policy     |
| "c"."ignore_public_acls"                 | true     | <nil>         | ignore_public_acls      |
| "c"."restrict_public_buckets"            | true     | <nil>         | restrict_public_buckets |
+------------------------------------------+----------+---------------+-------------------------+
…

CloudQuery siguió detectando una desviación en mi bucket, aunque en su tabla de datos el estado del control de versiones había cambiado. Se trata claramente de un falso positivo que no debería tenerse en cuenta, ya que el control de versiones está habilitado en mi bucket desde la consola de AWS.

Ventajas:

  • Enumeración muy rápida de mis recursos en la nube con el comando fetch

  • Detecta recursos no administrados con el sencillo comando drift scan

  • Admite analizar varios archivos de estado

Desventajas:

  • Resultados poco confiables para los atributos con desviaciones de buckets de S3 con el comando drift scan --deep --debug

  • Solo admite algunos backends para almacenar los archivos de estado (por ejemplo, S3 y almacenamiento local)

  • No admite todos los recursos de Terraform

  • Requiere una base de datos SQL

3. driftctl

driftctl es una herramienta CLI de código abierto y gratuita que alerta sobre desviaciones de infraestructura. Ayuda a detectar, rastrear y generar alertas sobre desviaciones en recursos administrados y no administrados. Probémosla con nuestro ejemplo. Nota: driftctl es el motor de detección de desviaciones de código abierto de Snyk.

$ driftctl scan --deep

Scanned states (1)
Found resources not covered by IaC:
  aws_s3_bucket:
    - drift-example-un-managed-resource
Found changed resources:
  From tfstate://terraform.tfstate
    - drift-example-managed-resource (aws_s3_bucket.example):
        ~ versioning.0.enabled: true => false
Found 2 resource(s)
 - 50% coverage
 - 1 resource(s) managed by Terraform
     - 1/1 resource(s) out of sync with Terraform state
 - 1 resource(s) not managed by Terraform
 - 0 resource(s) found in a Terraform state but missing on the cloud provider
Scan duration: 17s
Provider version used to scan: 3.74.3. Use --tf-provider-version to use another version.

Este resultado nos indica que driftctl encontró nuestros dos recursos. En el administrado encontró un atributo con una desviación: el estado del control de versiones. El otro recurso es nuestro bucket de S3 no administrado.

Ventajas:

  • Detecta atributos desviados en recursos administrados con el driftctl scan --deep command

  • Detecta desviaciones en recursos no administrados con el driftctl scan command

  • Admite analizar varios archivos de estado

Desventajas:

  • El análisis en modo --deep puede tardar mucho, ya que enumera todos los recursos de una cuenta y obtiene los detalles de cada uno

  • Pueden ocurrir errores de limitación de solicitudes de la API durante el análisis, porque depende mucho de la API del proveedor de nube para recopilar toda la información

  • No admite todos los recursos de Terraform

Consideraciones sobre las herramientas para detectar desviaciones

Estas tres herramientas hacen muy bien su trabajo. Veamos qué las hace destacar en situaciones específicas.

El terraform plan comando es una herramienta muy eficaz que puedes usar en una canalización programada para todos tus archivos de estado. Además de permitirte cubrir todos los recursos con la herramienta, ofrece una forma universal y bastante fácil de leer de mostrar los atributos desviados. Su única desventaja es que no puedes agrupar todos tus archivos de estado y ejecutar el comando en un solo lugar para comprobar si hay recursos desviados. Aunque informar sobre recursos no administrados no sea el objetivo de la herramienta, es una función esencial.

Los resultados de la herramienta de línea de comandos de CloudQuery son variados. Por un lado, su comando de enumeración (fetch) es una maravilla tecnológica. Te ofrece gratis una alternativa de código abierto para obtener visibilidad detallada de tu infraestructura en la nube, con SQL como motor de consultas y políticas. Por otro lado, su comando de detección de desviaciones es bastante limitado. Según mis pruebas, no puedes confiar en que encuentre desviaciones en recursos administrados. Además, solo puedes usar esta herramienta para encontrar recursos no administrados si tienes una situación sencilla: puedes acceder al archivo de estado de forma local (la mayoría de las veces, para probar la herramienta) o mediante un bucket de S3 (la práctica recomendada si quieres probarla en una CI). Por suerte, su comando de detección de desviaciones todavía está en fase alfa, así que tengo muchas ganas de ver cómo evoluciona esta herramienta de línea de comandos.

Si integras driftctl en tu CI y lo ejecutas a diario, tendrás una forma continua de recibir alertas sobre desviaciones en recursos administrados y no administrados. La variedad de backends compatibles para almacenar archivos de estado la convierte en una buena opción para la mayoría de las infraestructuras. Además, al igual que con CloudQuery, puedes filtrar u omitir los recursos que no te interesan para obtener un informe a tu medida. Una debilidad importante, relacionada con el diseño de driftctl, es que puede ser difícil ejecutarlo sin problemas en infraestructuras grandes debido a la limitación de solicitudes de la API. Por último, el tiempo de ejecución en modo --deep puede ser molesto al hacer pruebas locales en infraestructuras grandes; en una canalización de CI es menos problemático.

Por último, pero no menos importante: los permisos. Ni driftctl ni CloudQuery necesitan tu código de Terraform para funcionar; solo necesitan el archivo de estado, lo que simplifica las cosas. Ambas respetan la práctica recomendada de usar el mínimo de permisos necesarios para analizar todo tu proveedor de nube, así que para ejecutar cualquiera de los dos comandos solo necesitas una política de solo lectura. Obviamente, esto no aplica al comando de Terraform, ya que requiere permisos de lectura y escritura para crear, actualizar y eliminar tu infraestructura, y debe leer tu código para saber qué implementar o quitar.

Lo que sigue para Snyk IaC

Si te interesa incorporar los recursos no administrados al control de IaC y, al mismo tiempo, detectar desviaciones en los recursos administrados, Snyk te ayuda a hacerlo. La administración de desviaciones en Snyk IaC te permite proteger la infraestructura más rápido al informar sobre problemas y soluciones directamente a los desarrolladores, con términos fáciles de entender. Al crear un ciclo de retroalimentación más rápido entre los equipos de seguridad en la nube y desarrollo, los desarrolladores podrán hacerse cargo de su Terraform, desde el código hasta la nube, y proteger las configuraciones de infraestructura después de su implementación. Además, muestra los recursos no administrados en distintos entornos de nube, para que puedas incorporarlos al control de IaC y reducir el riesgo de desviaciones desde el inicio.

Recursos adicionales sobre la administración de desviaciones

Para seguir aprendiendo sobre la administración de desviaciones en Terraform, publicamos algunos artículos más en nuestro blog:

Protege la infraestructura desde el origen

Snyk automatiza la seguridad y el cumplimiento de IaC en los flujos de trabajo, y detecta recursos con desviaciones de configuración y recursos faltantes.

Leer más

feature insights context
Blog

Los ataques autónomos ya están aquí. La defensa debe estar a su altura.

Los atacantes autónomos están reduciendo el tiempo disponible para defenderse. Descubre cómo el descubrimiento, la corrección, la validación y la prevención continuos pueden ayudar a los equipos de seguridad a seguirles el ritmo.

Blog

Evo ADS Govern Agent Behavior ya está disponible: controla el uso de MCP

Evo ADS Govern Agent Behavior ya está disponible, comenzando con MCP Governance. Descubre, aprueba, monitorea, registra y bloquea el uso de servidores MCP en los principales agentes de programación con IA.

illustration hero ai
Blog

¿Qué es Agentic AppSec?

Descubre cómo Agentic AppSec usa agentes de IA con contexto, límites definidos y verificación independiente para ejecutar el ciclo de seguridad de aplicaciones.