本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 Lambda 的主動式控制 AWS CloudFormation Guard
AWS CloudFormation Guard是開放原始碼、一般用途的 policy-as-code 評估工具。透過比照政策規則驗證基礎設施即程式碼 (IaC) 範本和服務組合,它可被用於實現預防性控管與合規。這些規則還可以依據您的團隊或組織要求進行自訂。對於 Lambda 函數,Guard 規則可透過在建立或更新 Lambda 函數時定義所需的必要屬性設定,控制資源建立和組態更新。
合規管理員會定義部署和更新 Lambda 函數所需的控制項和控管政策清單。平台管理員在 CI/CD 管道中實作控制項,做為程式碼儲存庫的預遞交驗證 Webhook,並為開發人員提供用於在本機工作站驗證範本和程式碼的命令列工具。開發人員撰寫程式碼、使用命令列工具驗證範本,然後將程式碼提交至儲存庫,然後在部署至環境之前,透過 CI/CD 管線自動驗證這些儲存庫。 AWS
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 管道中的檢查失敗。因此,您的開發人員將取得此回饋,以便了解如何開發合乎規範的範本,並且將他們的時間轉移到編寫可創造商業價值的程式碼。此控制可套用到本機的開發人員工作站,在預遞交驗證 Webhook 和/或在部署前的 CI/CD 管道中套用。
警告
如果您使用 AWS Serverless Application Model (AWS SAM) 範本來定義 Lambda 函數,請注意,您需要更新防護規則,以搜尋AWS::Serverless::Function
資源類型,如下所示。
let lambda_functions = Resources.*[ Type == "AWS::Serverless::Function" ]
Guard 還預期屬性會包含在資源定義當中。同時, AWS SAM 模板允許在單獨的 Globals 部分中指定屬性。「全域」區段裡定義的屬性不使用您的 Guard 規則進行驗證。
如 Guard 故障診斷文件中所述,應注意 Guard 不支援簡寫形式的內部函數 (例如 !GetAtt
或 !Sub
),而要求使用展開形式:Fn::GetAtt
和 Fn::Sub
。(先前的範例不會評估 Role 屬性,因此為了簡便起見而使用簡寫形式的內部函數。)