

# Controles proactivos para Lambda con AWS CloudFormation Guard
<a name="governance-cloudformation-guard"></a>

[AWS CloudFormation Guard](https://docs.aws.amazon.com/cfn-guard/latest/ug/what-is-guard.html) es una herramienta de evaluación de políticas como código, de uso general y de código abierto. Se puede utilizar para la gobernanza y el cumplimiento preventivos mediante la validación del cumplimiento con las políticas de las plantillas de infraestructura como código (IaC) y las composiciones de los servicios. Estas reglas se pueden personalizar en función de los requisitos de su equipo o de la organización. En el caso de las funciones Lambda, las reglas de Guard se pueden utilizar para controlar la creación de recursos y las actualizaciones de configuración mediante la definición de los ajustes de propiedades necesarios al crear o actualizar una función de Lambda.

Los administradores de conformidad definen la lista de controles y políticas de gobernanza que se requieren para implementar y actualizar las funciones de Lambda. Los administradores de la plataforma implementan los controles en los canales de CI/CD, como webhooks de validación previa a la confirmación con repositorios de código, y proporcionan a los desarrolladores herramientas de línea de comandos para validar las plantillas y el código en las estaciones de trabajo locales. Los desarrolladores crean el código, validan las plantillas con herramientas de línea de comandos y, a continuación, envían el código a los repositorios, que luego se validan automáticamente mediante los canales de CI/CD antes de la implementación en un entorno de AWS.

Guard le permite [escribir sus reglas](https://docs.aws.amazon.com/cfn-guard/latest/ug/writing-rules.html) e implementar sus controles con un lenguaje específico del dominio, como se muestra a continuación.

 ![\[Guard rules include resource type, property name, operator, expression value, and optional comment\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/governance-cloudformation-guard.png) 

Por ejemplo, imagine que quiere asegurarse de que los desarrolladores elijan solo los tiempos de ejecución más recientes. Puede especificar dos políticas diferentes, una para identificar los [tiempos de ejecución](lambda-runtimes.md) que ya están en desuso y otra para identificar los tiempos de ejecución que caducarán pronto. Para ello, puede escribir el siguiente archivo de `etc/rules.guard`:

```
let lambda_functions = Resources.*[
    Type == "AWS::Lambda::Function"
]

rule lambda_already_deprecated_runtime when %lambda_functions !empty {
    %lambda_functions {
        Properties {
            when Runtime exists {
                Runtime !in ["dotnetcore3.1", "nodejs12.x", "python3.6", "python2.7", "dotnet5.0", "dotnetcore2.1", "ruby2.5", "nodejs10.x", "nodejs8.10", "nodejs4.3", "nodejs6.10", "dotnetcore1.0", "dotnetcore2.0", "nodejs4.3-edge", "nodejs"] <<Lambda function is using a deprecated runtime.>>
            }
        }
    }
}

rule lambda_soon_to_be_deprecated_runtime when %lambda_functions !empty {
    %lambda_functions {
        Properties {
            when Runtime exists {
                Runtime !in ["nodejs16.x", "nodejs14.x", "python3.7", "java8", "dotnet7", "go1.x", "ruby2.7", "provided"] <<Lambda function is using a runtime that is targeted for deprecation.>>
            }
        }
    }
}
```

Ahora imagine que escribe la siguiente plantilla de CloudFormation de `iac/lambda.yaml` que define una función de Lambda:

```
  Fn:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.7
      CodeUri: src
      Handler: fn.handler
      Role: !GetAtt FnRole.Arn
      Layers:
        - arn:aws:lambda:us-east-1:111122223333:layer:LambdaInsightsExtension:35
```

Tras [instalar](https://docs.aws.amazon.com/cfn-guard/latest/ug/setting-up.html) la utilidad Guard, valide la plantilla:

```
cfn-guard validate --rules etc/rules.guard --data iac/lambda.yaml
```

El resultado tendrá este aspecto:

```
lambda.yaml Status = FAIL
FAILED rules
rules.guard/lambda_soon_to_be_deprecated_runtime
---
Evaluating data lambda.yaml against rules rules.guard
Number of non-compliant resources 1
Resource = Fn {
  Type      = AWS::Lambda::Function
  Rule = lambda_soon_to_be_deprecated_runtime {
    ALL {
      Check =  Runtime not IN  ["nodejs16.x","nodejs14.x","python3.7","java8","dotnet7","go1.x","ruby2.7","provided"] {
        ComparisonError {
          Message          = Lambda function is using a runtime that is targeted for deprecation.
          Error            = Check was not compliant as property [/Resources/Fn/Properties/Runtime[L:88,C:15]] was not present in [(resolved, Path=[L:0,C:0] Value=["nodejs16.x","nodejs14.x","python3.7","java8","dotnet7","go1.x","ruby2.7","provided"])]
        }
          PropertyPath    = /Resources/Fn/Properties/Runtime[L:88,C:15]
          Operator        = NOT IN
          Value           = "python3.7"
          ComparedWith    = [["nodejs16.x","nodejs14.x","python3.7","java8","dotnet7","go1.x","ruby2.7","provided"]]
          Code:
               86.  Fn:
               87.    Type: AWS::Lambda::Function
               88.    Properties:
               89.      Runtime: python3.7
               90.      CodeUri: src
               91.      Handler: fn.handler

      }
    }
  }
}
```

 Guard les permite a los desarrolladores comprobar desde sus estaciones de trabajo locales que necesitan actualizar la plantilla para utilizar un tiempo de ejecución permitido por la organización. Esto ocurre antes de iniciar sesión en un repositorio de código y no pasar las comprobaciones realizadas en los canales de CI/CD. Como resultado, los desarrolladores reciben esta información sobre cómo desarrollar plantillas compatibles y dedicar su tiempo a escribir código que aporte valor empresarial. Este control se puede aplicar en la estación de trabajo del desarrollador local, en un webhook de validación previo a la confirmación, o en el canal de CI/CD antes de la implementación. 

## Advertencias
<a name="governance-cloudformation-guard-considerations"></a>

Si utiliza plantillas de AWS Serverless Application Model (AWS SAM) para definir funciones de Lambda, tenga en cuenta que debe actualizar la regla de Guard para buscar el tipo de recurso `AWS::Serverless::Function` de la siguiente manera.

```
let lambda_functions = Resources.*[
    Type == "AWS::Serverless::Function"
]
```

Guard también espera que las propiedades se incluyan en la definición del recurso. Mientras tanto, las plantillas de AWS SAM permiten especificar las propiedades en una sección [Global](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy-globals.html) independiente. Las propiedades que se definen en la sección Global no se validan con sus reglas de Guard.

Como se indica en la [documentación](https://docs.aws.amazon.com/cfn-guard/latest/ug/troubleshooting.html) de solución de problemas de Guard, tenga en cuenta que Guard no admite tipos intrínsecos abreviados, como `!GetAtt` o `!Sub`. Por el contrario, requiere el uso de formas expandidas, como `Fn::GetAtt` y `Fn::Sub`. (El [ejemplo anterior](#guard-iac-yaml) no evalúa la propiedad Role, por lo que se utilizó el tipo intrínseco abreviado por simplicidad).