AWS CloudFormation Guard를 사용하는 Lambda의 사전 예방적 제어
AWS CloudFormation Guard는 오픈 소스, 범용, 코드형 정책 평가 도구입니다. 정책 규칙을 기준으로 코드형 인프라(IaC) 템플릿 및 서비스 구성을 검증함으로써 예방적 거버넌스 및 규정 준수를 위해 사용할 수 있습니다. 이러한 규칙은 팀 또는 조직의 요구 사항에 따라 사용자 지정할 수 있습니다. Lambda 함수의 경우 Guard 규칙을 사용하여 Lambda 함수를 생성 또는 업데이트하는 동안 필요한 필수 속성 설정을 정의함으로써 리소스 생성 및 구성 업데이트를 제어할 수 있습니다.
규정 준수 관리자는 Lambda 함수를 배포하고 업데이트하는 데 필요한 제어 및 거버넌스 정책 목록을 정의합니다. 플랫폼 관리자는 코드 리포지토리가 포함된 사전 커밋 검증 웹후크로 CI/CD 파이프라인에서 제어를 구현하고, 개발자에게 로컬 워크스테이션에서 템플릿 및 코드를 검증하기 위한 명령줄 도구를 제공합니다. 개발자는 코드를 작성하고 명령줄 도구를 사용해 템플릿을 검증한 후 리포지토리에 코드를 커밋합니다. 그러면 리포지토리를 AWS 환경에 배포하기 전에 CI/CD 파이프라인을 통해 코드가 자동으로 검증됩니다.
Guard를 사용하면 다음과 같이 도메인별 언어로 규칙을 작성하고 제어를 구현할 수 있습니다.
예를 들어 개발자가 최신 런타임만 선택하려고 한다고 가정합니다. 두 가지 정책을 지정할 수 있습니다. 하나는 이미 지원이 중단된 런타임을 식별하는 정책이고 다른 하나는 곧 지원 중단 예정인 런타임을 식별하는 정책입니다. 이를 위해 다음 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.>> } } } }
이제 Lambda 함수를 정의하는 다음과 같은 iac/lambda.yaml
CloudFormation 템플릿을 작성한다고 가정합니다.
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
Guard 유틸리티를 설치한 후 템플릿을 검증합니다.
cfn-guard validate --rules etc/rules.guard --data iac/lambda.yaml
출력은 다음과 같습니다.
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를 사용하면 개발자가 로컬 개발자 워크스테이션에서 조직이 허용하는 런타임을 사용하도록 템플릿을 업데이트해야 한다는 사실을 확인할 수 있습니다. 코드 리포지토리를 커밋하고 이후 CI/CD 파이프라인 내에서 검사에 실패하기 전에 확인할 수 있습니다. 따라서 개발자는 규정을 준수하는 템플릿을 개발하고 비즈니스 가치를 전달하는 코드를 작성하는 데 시간을 더 할애하는 방법에 대한 피드백을 받을 수 있습니다. 이 제어는 배포 전에 로컬 개발자 워크스테이션, 사전 커밋 검증 웹후크 및/또는 CI/CD 파이프라인에 적용할 수 있습니다.
경고
AWS Serverless Application Model(AWS SAM) 템플릿을 사용하여 Lambda 함수를 정의하는 경우 다음과 같이 AWS::Serverless::Function
리소스 유형을 검색하도록 Guard 규칙을 업데이트해야 합니다.
let lambda_functions = Resources.*[ Type == "AWS::Serverless::Function" ]
또한 Guard에서는 리소스 정의에 속성을 포함한다고 예상합니다. 한편, AWS SAM 템플릿을 사용하면 별도의 글로벌 섹션에서 속성을 지정할 수 있습니다. 글로벌 섹션에 정의된 속성은 Guard 규칙으로 검증되지 않습니다.
Guard 문제 해결 설명서에 설명된 대로, Guard에서는 짧은 양식의 내장 함수(예: !GetAtt
또는 !Sub
)를 지원하지 않으며, 대신 확장된 양식(Fn::GetAtt
및 Fn::Sub
)을 사용해야 합니다. (이전 예제에서는 역할 속성을 평가하지 않으므로 단순한 설명을 위해 짧은 양식의 내장 함수를 사용했습니다.)