本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
撰寫 AWS CloudFormation Guard 規則
在 中 AWS CloudFormation Guard,規則是policy-as-code規則。您可以使用 Guard 網域特定語言 (DSL) 撰寫規則,以驗證 JSON 或 YAML 格式的資料。規則由 子句組成。
您可以將使用 Guard DSL 寫入的規則儲存到使用任何副檔名的純文字檔案中。
您可以建立多個規則檔案,並將其分類為規則集。規則集可讓您同時針對多個規則檔案驗證 JSON 或 YAML 格式的資料。
主題
子句
子句是評估為 true (PASS) 或 false () 的布林表達式FAIL。子句使用二進位運算子來比較在單一值上操作的兩個值或單一運算子。
Unary 子句的範例
下列 unary 子句會評估集合是否為TcpBlockedPorts空。
InputParameters.TcpBlockedPorts not empty
下列 unary 子句會評估 ExecutionRoleArn 屬性是否為字串。
Properties.ExecutionRoleArn is_string
二進位子句的範例
下列二進位子句會評估 BucketName 屬性是否包含字串 encrypted,無論大小寫為何。
Properties.BucketName != /(?i)encrypted/
下列二進位子句會評估 ReadCapacityUnits 屬性是否小於或等於 5,000。
Properties.ProvisionedThroughput.ReadCapacityUnits <= 5000
撰寫 Guard 規則子句的語法
<query> <operator> [query|value literal] [custom message]
Guard 規則子句的屬性
query- 
       
以點 (
.) 分隔的表達式,寫入以周遊階層資料。查詢表達式可以包含篩選條件表達式,以值的子集為目標。查詢可以指派給變數,以便您可以寫入一次,並在規則集中的其他位置參考它們,這可讓您存取查詢結果。如需撰寫查詢和篩選的詳細資訊,請參閱 定義查詢和篩選。
必要:是
 operator- 
      
單一或二進位運算子,可協助檢查查詢的狀態。二進位運算子的左側 (LHS) 必須是查詢,而右側 (RHS) 必須是查詢或值常值。
支援的二進位運算子:
==(等於) |!=(不等於) |>(大於) |>=(大於或等於) |<(小於) |<=(小於或等於) |IN(在形式 【x、y、z】 的清單中支援的統一運算子:
exists|empty|is_string|is_list|is_struct|not(!)必要:是
 query|value literal- 
      
查詢或支援的值常值,例如
string或integer(64)。支援的值常值:
- 
        
所有基本類型:
string、integer(64)、float(64)、bool、char、regex - 
        
表達
integer(64)、float(64)或 範圍的所有專用char範圍類型,表示為:- 
          
r[<lower_limit>, <upper_limit>],其會轉譯為滿足下列表達k式的任何值:lower_limit <= k <= upper_limit - 
          
r[<lower_limit>, <upper_limit>)k,其會轉譯為滿足下列表達式的任何值:lower_limit <= k < upper_limit - 
          
r(<lower_limit>, <upper_limit>],其會轉譯為滿足下列表達k式的任何值:lower_limit < k <= upper_limit - 
          
r(<lower_limit>, <upper_limit>),可轉換為滿足下列表達k式的任何值:lower_limit < k < upper_limit 
 - 
          
 - 
        
巢狀索引鍵/值結構資料的關聯陣列 (對應)。例如:
{ "my-map": { "nested-maps": [ { "key": 10, "value": 20 } ] } } - 
        
基本類型或關聯陣列類型的陣列
 
必要:有條件;使用二進位運算子時為必要。
 - 
        
 custom message- 
      
提供 子句相關資訊的字串。訊息會顯示在
validate和test命令的詳細輸出中,有助於了解或偵錯階層資料上的規則評估。必要:否
 
在 子句中使用查詢
如需撰寫查詢的資訊,請參閱 定義查詢和篩選和 在 Guard 規則中指派和參考變數。
在 子句中使用運算子
以下是 CloudFormation 範本Template-1和 的範例Template-2。為了示範如何使用支援的運算子,本節中的範例查詢和子句會參考這些範例範本。
Template-1
Resources: S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: MyServiceS3Bucket BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: 'aws:kms' KMSMasterKeyID: 'arn:aws:kms:us-east-1:123456789:key/056ea50b-1013-3907-8617-c93e474e400' Tags: - Key: stage Value: prod - Key: service Value: myService
Template-2
Resources: NewVolume: Type: AWS::EC2::Volume Properties: Size: 100 VolumeType: io1 Iops: 100 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: us-east-1 Tags: - Key: environment Value: test DeletionPolicy: Snapshot
使用 unary 運算子的子句範例
- 
     
empty– 檢查集合是否為空。您也可以使用它來檢查查詢在階層資料中是否有值,因為查詢會導致集合。您無法使用它來檢查字串值查詢是否已定義空字串 ("")。如需詳細資訊,請參閱定義查詢和篩選。下列子句會檢查範本是否已定義一或多個資源。它會評估 為 ,
PASS因為具有邏輯 ID 的資源S3Bucket是在 中定義Template-1。Resources !empty下列子句會檢查是否為
S3Bucket資源定義一或多個標籤。它會評估 為 ,PASS因為 中S3Bucket有兩個為Tags屬性定義的標籤Template-1。Resources.S3Bucket.Properties.Tags !empty - 
     
exists– 檢查每個查詢的出現是否具有值,並可用於取代!= null。下列子句會檢查是否已為 定義
BucketEncryption屬性S3Bucket。它評估為 ,PASS因為BucketEncryption是在S3Bucket中為 定義的Template-1。Resources.S3Bucket.Properties.BucketEncryption exists 
注意
empty 和 not exists檢查會在周遊輸入資料時評估 true 是否有遺失的屬性索引鍵。例如,如果未在 的範本中定義 Properties區段S3Bucket,則 子句會Resources.S3Bucket.Properties.Tag empty評估為 true。exists 和 empty檢查不會在錯誤訊息中顯示文件內的 JSON 指標路徑。這兩個子句通常都有無法維護此周遊資訊的擷取錯誤。
- 
     
is_string– 檢查查詢的每個出現是否為string類型。下列子句會檢查是否為
S3Bucket資源的BucketName屬性指定字串值。它會評估 為 ,PASS因為字串值"MyServiceS3Bucket"是在BucketName中為 指定的Template-1。Resources.S3Bucket.Properties.BucketName is_string - 
     
is_list– 檢查查詢的每個出現是否為list類型。下列子句會檢查是否為
S3Bucket資源的Tags屬性指定清單。它評估為 ,PASS因為在Tags中為 指定了兩個鍵值對Template-1。Resources.S3Bucket.Properties.Tags is_list - 
     
is_struct– 檢查查詢的每個出現是否為結構化資料。下列子句會檢查是否為
S3Bucket資源的BucketEncryption屬性指定結構化資料。它評估為 ,PASS因為BucketEncryption是使用 中的ServerSideEncryptionConfiguration屬性類型(物件)指定Template-1。Resources.S3Bucket.Properties.BucketEncryption is_struct 
注意
若要檢查反轉狀態,您可以使用 ( not !) 運算子搭配 is_string、 is_list和 is_struct運算子 。
使用二進位運算子的子句範例
下列子句會檢查 中S3Bucket資源BucketName屬性指定的值是否Template-1包含字串 encrypt,無論大小寫為何。這會評估 為 ,PASS因為指定的儲存貯體名稱"MyServiceS3Bucket"不包含字串 encrypt。
Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
下列子句會檢查 中NewVolume資源Size屬性指定的值是否Template-2在特定範圍內:50 <= Size <= 200。它會評估 為 ,PASS因為 100 是針對 所指定Size。
Resources.NewVolume.Properties.Size IN r[50,200]
下列子句會檢查 中NewVolume資源VolumeType屬性指定的值是否為 Template-2 io1、 io2或 gp3。它會評估 為 ,PASS因為 io1 是針對 所指定NewVolume。
Resources.NewVolume.Properties.NewVolume.VolumeType IN [ 'io1','io2','gp3' ]
注意
在 子句中使用自訂訊息
在下列範例中, 的 子句Template-2包含自訂訊息。
Resources.NewVolume.Properties.Size IN r(50,200) << EC2Volume size must be between 50 and 200, not including 50 and 200 >> Resources.NewVolume.Properties.VolumeType IN [ 'io1','io2','gp3' ] <<Allowed Volume Types are io1, io2, and gp3>>
合併子句
在 Guard 中,在新行上寫入的每個子句會使用 結合 (布林and邏輯) 隱含地與下一個子句結合。請參閱以下範例。
# clause_A ^ clause_B ^ clause_C clause_A clause_B clause_C
您也可以透過or|OR在第一個子句結尾指定 ,使用 解散來結合子句與下一個子句。
<query> <operator> [query|value literal] [custom message] [or|OR]
在 Guard 子句中,會先評估接合點,接著評估接合點。Guard 規則可以定義為將評估為 (PASS) 或 true() 的 子句 false( or|ORand|AND的 ) 解譯的組合FAIL。這類似於 Conjunctive 正常形式
下列範例示範 子句的評估順序。
# (clause_E v clause_F) ^ clause_G clause_E OR clause_F clause_G # (clause_H v clause_I) ^ (clause_J v clause_K) clause_H OR clause_I clause_J OR clause_K # (clause_L v clause_M v clause_N) ^ clause_O clause_L OR clause_M OR clause_N clause_O
所有以範例為基礎的子句Template-1都可以使用 結合來組合。請參閱以下範例。
Resources.S3Bucket.Properties.BucketName is_string Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/ Resources.S3Bucket.Properties.BucketEncryption exists Resources.S3Bucket.Properties.BucketEncryption is_struct Resources.S3Bucket.Properties.Tags is_list Resources.S3Bucket.Properties.Tags !empty
搭配 Guard 規則使用區塊
區塊是從一組相關子句、條件或規則中移除詳細程度和重複性的組合。區塊有三種類型:
- 
    
查詢區塊
 - 
    
when區塊 - 
    
具名規則區塊
 
查詢區塊
以下是以範例 為基礎的 子句Template-1。結合用於合併 子句。
Resources.S3Bucket.Properties.BucketName is_string Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/ Resources.S3Bucket.Properties.BucketEncryption exists Resources.S3Bucket.Properties.BucketEncryption is_struct Resources.S3Bucket.Properties.Tags is_list Resources.S3Bucket.Properties.Tags !empty
每個子句中的查詢表達式部分都會重複。您可以使用查詢區塊,改善可編譯性,並從具有相同初始查詢路徑的一組相關子句中移除詳細程度和重複性。您可以撰寫一組相同的子句,如下列範例所示。
Resources.S3Bucket.Properties { BucketName is_string BucketName != /(?i)encrypt/ BucketEncryption exists BucketEncryption is_struct Tags is_list Tags !empty }
在查詢區塊中,區塊前面的查詢會設定區塊內子句的內容。
如需使用區塊的詳細資訊,請參閱 編寫具名規則區塊。
when 區塊
   您可以使用採用下列格式的區塊來有條件地評估when區塊。
when <condition> { Guard_rule_1 Guard_rule_2 ... }
when 關鍵字會指定when區塊的開始。 condition 是 Guard 規則。只有在條件的評估結果為 true() 時,才會評估 區塊PASS。
以下是以 為基礎的範例when區塊Template-1。
when Resources.S3Bucket.Properties.BucketName is_string { Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/ }
只有在為 指定的值BucketName是字串時,才會評估when區塊中的 子句。如果在範本的 Parameters區段中參考為 BucketName 指定的值,如下列範例所示,則不會評估when區塊中的 子句。
Parameters: S3BucketName: Type: String Resources: S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: Ref: S3BucketName ...
具名規則區塊
您可以將名稱指派給一組規則 (規則集),然後在其他規則中參考這些模組化驗證區塊,稱為命名規則區塊。Named-rule 區塊採用下列形式。
rule <rule name> [when <condition>] { Guard_rule_1 Guard_rule_2 ... }
rule 關鍵字會指定 name-rule 區塊的開頭。
rule name 是人類可讀取的字串,可唯一識別具名規則區塊。這是其封裝的 Guard 規則集的標籤。在此使用中,Guard 規則一詞包含子句、查詢區塊、when區塊和命名規則區塊。規則名稱可用來參考其封裝的規則集評估結果,這使得命名規則區塊可重複使用。規則名稱也提供 validate和 test命令輸出中規則失敗的相關內容。規則名稱與區塊的評估狀態 (PASS、 FAIL或 SKIP) 一起顯示在規則檔案的評估輸出中。請參閱以下範例。
# Sample output of an evaluation where check1, check2, and check3 are rule names. template.json Status = **FAIL** **SKIP rules** check1 **SKIP** **PASS rules** check2 **PASS** **FAILED rules** check3 **FAIL**
您也可以在規則名稱後面指定when關鍵字後面接著條件,以有條件的方式評估具名規則區塊。
以下是本主題先前討論的範例when區塊。
rule checkBucketNameStringValue when Resources.S3Bucket.Properties.BucketName is_string { Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/ }
使用具名規則區塊,上述也可以編寫如下。
rule checkBucketNameIsString { Resources.S3Bucket.Properties.BucketName is_string } rule checkBucketNameStringValue when checkBucketNameIsString { Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/ }
您可以使用其他 Guard 規則重複使用並分組具名規則區塊。以下是幾個範例。
rule rule_name_A { Guard_rule_1 OR Guard_rule_2 ... } rule rule_name_B { Guard_rule_3 Guard_rule_4 ... } rule rule_name_C { rule_name_A OR rule_name_B } rule rule_name_D { rule_name_A rule_name_B } rule rule_name_E when rule_name_D { Guard_rule_5 Guard_rule_6 ... }
使用內建函數
AWS CloudFormation Guard 提供內建函數,您可以在規則中用來執行字串操作、JSON 剖析和資料類型轉換等操作。函式僅透過指派至變數來支援。
關鍵函數
json_parse(json_string)- 
       
從範本剖析內嵌 JSON 字串。剖析之後,您可以評估結果物件的屬性。
 count(collection)- 
       
傳回查詢解析的項目數量。
 regex_replace(base_string, regex_to_extract, regex_replacement)- 
       
使用規則表達式取代字串的一部分。
 
如需可用函數的完整清單,包括字串操作、集合操作和資料類型轉換函數,請參閱 Guard GitHub 儲存庫中的函數文件