Contrôles proactifs pour Lambda avec AWS CloudFormation Guard - AWS Lambda

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Contrôles proactifs pour Lambda avec AWS CloudFormation Guard

AWS CloudFormation Guardest un outil d'évaluation open source à usage général. policy-as-code Cela peut être utilisé à des fins de gouvernance préventive et de conformité en validant les modèles d'infrastructure en tant que code (IaC) et les compositions de services par rapport aux règles de politique. Ces règles peuvent être personnalisées en fonction des exigences de votre équipe ou de votre organisation. Pour les fonctions Lambda, les règles Guard peuvent être utilisées pour contrôler la création de ressources et les mises à jour de configuration en définissant les paramètres de propriété requis lors de la création ou de la mise à jour d'une fonction Lambda.

Les administrateurs de conformité définissent la liste des contrôles et des politiques de gouvernance nécessaires au déploiement et à la mise à jour des fonctions Lambda. Les administrateurs de plate-forme mettent en œuvre les contrôles dans les CI/CD pipelines, as pre-commit validation webhooks with code repositories, and provide developers with command line tools for validating templates and code on local workstations. Developers author code, validate templates with command line tools, and then commit code to repositories, which are then automatically validated via the CI/CD pipelines avant le déploiement dans un AWS environnement.

Guard vous permet d'écrire vos règles et d'implémenter vos contrôles dans un langage spécifique au domaine comme suit.

Guard rules include resource type, property name, operator, expression value, and optional comment

Supposons, par exemple, que vous souhaitiez vous assurer que les développeurs choisissent uniquement les derniers environnements d'exécution. Vous pouvez spécifier deux politiques différentes, l'une pour identifier les environnements d'exécution déjà obsolètes et l'autre pour identifier les environnements d'exécution qui le seront bientôt. Pour cela, vous pouvez écrire le fichier etc/rules.guard suivant :

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.>> } } } }

Supposons maintenant que vous écriviez le iac/lambda.yaml CloudFormation modèle suivant qui définit une fonction 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

Après avoir installé l'utilitaire Guard, validez votre modèle :

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

Le résultat se présente comme suit :

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 permet à vos développeurs de savoir depuis leur poste de travail local qu'ils doivent mettre à jour le modèle afin d'utiliser un environnement d'exécution autorisé par l'organisation. Cela se produit avant la validation dans un référentiel de code et avant l'échec des vérifications dans un CI/CD pipeline. As a result, your developers get this feedback on how to develop compliant templates and shift their time to writing code that delivers business value. This control can be applied on the local developer workstation, in a pre-commit validation webhook, and/or in the CI/CD pipeline avant le déploiement.

Mises en garde

Si vous utilisez des modèles AWS Serverless Application Model (AWS SAM) pour définir des fonctions Lambda, sachez que vous devez mettre à jour la règle Guard pour rechercher le type de AWS::Serverless::Function ressource comme suit.

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

Guard s'attend également à ce que les propriétés soient incluses dans la définition de la ressource. Dans le même temps, les AWS SAM modèles permettent de spécifier les propriétés dans une section Globals distincte. Les propriétés définies dans la section Globals ne sont pas validées par vos règles Guard.

Comme indiqué dans la documentation de dépannage de Guard, sachez que Guard ne prend pas en charge les formulaires intrinsèques abrégés tels que !GetAtt ou !Sub et nécessite plutôt l'utilisation des formulaires étendus : Fn::GetAtt et. Fn::Sub (L'exemple précédent n'évaluant pas la propriété Role, la forme abrégée intrinsèque a été utilisée pour des raisons de simplicité.)