

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS CloudFormation Guard ルールの記述
<a name="writing-rules"></a>

では AWS CloudFormation Guard、*ルール*は policy-as-code ルールです。JSON 形式または YAML 形式のデータを検証できる Guard ドメイン固有の言語 (DSL) でルールを記述します。ルールは **句で構成されます。

Guard DSL を使用して記述されたルールは、任意のファイル拡張子を使用するプレーンテキストファイルに保存できます。

複数のルールファイルを作成し、*ルールセット*として分類できます。ルールセットを使用すると、JSON 形式または YAML 形式のデータを複数のルールファイルに対して同時に検証できます。

**Topics**
+ [句](#clauses)
+ [句でのクエリの使用](#clauses-queries)
+ [句での演算子の使用](#clauses-operators)
+ [句でのカスタムメッセージの使用](#clauses-custom-messages)
+ [句の組み合わせ](#combining-clauses)
+ [ガードルールでのブロックの使用](#blocks)
+ [組み込み関数の使用](#built-in-functions)
+ [ガードクエリの定義とフィルタリング](query-and-filtering.md)
+ [ガードルールでの変数の割り当てと参照](variables.md)
+ [で名前付きルールブロックを作成する AWS CloudFormation Guard](named-rule-block-composition.md)
+ [コンテキスト対応評価を実行するための句の記述](context-aware-evaluations.md)

## 句
<a name="clauses"></a>

句は、true (`PASS`) または false () のいずれかに評価されるブール式です`FAIL`。句は、バイナリ演算子を使用して 2 つの値を比較するか、単一の値で動作する単一演算子を使用します。

**単項句の例**

次の unary 句は、コレクション`TcpBlockedPorts`が空かどうかを評価します。

```
InputParameters.TcpBlockedPorts not empty
```

次の unary 句は、 `ExecutionRoleArn`プロパティが文字列であるかどうかを評価します。

```
Properties.ExecutionRoleArn is_string
```

**バイナリ句の例**

次のバイナリ句は、大文字と小文字に関係なく`encrypted`、 `BucketName`プロパティに文字列 が含まれているかどうかを評価します。

```
Properties.BucketName != /(?i)encrypted/
```

次のバイナリ句は、`ReadCapacityUnits`プロパティが 5,000 以下であるかどうかを評価します。

```
Properties.ProvisionedThroughput.ReadCapacityUnits <= 5000
```

### ガードルール句を記述するための構文
<a name="clauses-syntax"></a>

```
<query> <operator> [query|value literal] [custom message]
```

### ガードルール句のプロパティ
<a name="clauses-properties"></a>

`query`  <a name="clauses-properties-query"></a>
階層データをトラバースするために書き込まれたドット (`.`) 区切り式。クエリ式には、値のサブセットをターゲットとするフィルター式を含めることができます。クエリを変数に割り当てると、変数を 1 回書き込み、ルールセットの他の場所で参照できるため、クエリ結果にアクセスできます。  
クエリの記述とフィルタリングの詳細については、「」を参照してください[クエリとフィルタリングの定義](query-and-filtering.md)。  
 *必須:* はい

`operator`  <a name="clauses-properties-operator"></a>
クエリの状態を確認するのに役立つ単項演算子またはバイナリ演算子。バイナリ演算子の左側 (LHS) はクエリで、右側 (RHS) はクエリまたは値リテラルである必要があります。  
 *サポートされているバイナリ演算子*: `==` (Equal) \| `!=` (Not equal) \| `>` (Greater than) \| `>=` (Greater than or equal to) \| `<` (Less than) \| `<=` (Less than than) \| `IN` (In a list of form [x, y, z]  
 *サポートされている単項演算子*: `exists` \| `empty` \| `is_string` \| `is_list` \| `is_struct` \| `not(!)`  
 *必須:* はい

`query|value literal`  <a name="clauses-properties-value-literal"></a>
クエリ、または `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`  <a name="clauses-properties-custom-message"></a>
句に関する情報を提供する文字列。メッセージは `validate`および `test` コマンドの詳細出力に表示され、階層データのルール評価の理解やデバッグに役立ちます。  
 *必須:* いいえ

## 句でのクエリの使用
<a name="clauses-queries"></a>

クエリの記述の詳細については、[クエリとフィルタリングの定義](query-and-filtering.md)「」および「」を参照してください[ガードルールでの変数の割り当てと参照](variables.md)。

## 句での演算子の使用
<a name="clauses-operators"></a>

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
```

### 単項演算子を使用する句の例
<a name="clauses-unary-operators"></a>
+ `empty` – コレクションが空かどうかを確認します。これを使用して、クエリがコレクションになるため、クエリに階層データの値があるかどうかを確認することもできます。文字列値クエリに空の文字列 (`""`) が定義されているかどうかを確認するために使用することはできません。詳細については、「[クエリとフィルタリングの定義](query-and-filtering.md)」を参照してください。

  次の句は、テンプレートに 1 つ以上のリソースが定義されているかどうかを確認します。論理 ID を持つリソース`S3Bucket`が で定義されている`PASS`ため、 に評価されます`Template-1`。

  ```
  Resources !empty
  ```

  次の句は、`S3Bucket`リソースに 1 つ以上のタグが定義されているかどうかを確認します。`S3Bucket` には の `Tags`プロパティに 2 つのタグが定義されている`PASS`ため、 に評価されます`Template-1`。

  ```
  Resources.S3Bucket.Properties.Tags !empty
  ```
+ `exists` – クエリの各出現に値があり、 の代わりに使用できるかどうかを確認します`!= null`。

  次の句は、 `BucketEncryption`プロパティが に対して定義されているかどうかを確認します`S3Bucket`。は `S3Bucket`で に`BucketEncryption`定義されている`PASS`ため、 に評価されます`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`プロパティに文字列値が指定されているかどうかをチェックします。文字列値が `BucketName`の に`"MyServiceS3Bucket"`指定されている`PASS`ため、 に評価されます`Template-1`。

  ```
  Resources.S3Bucket.Properties.BucketName is_string
  ```
+ `is_list` – クエリの各出現が `list`タイプであるかどうかを確認します。

  次の句は、`S3Bucket`リソースの `Tags`プロパティにリストが指定されているかどうかを確認します。2 つのキーと値のペアが `Tags`で に指定されている`PASS`ため、 に評価されます`Template-1`。

  ```
  Resources.S3Bucket.Properties.Tags is_list
  ```
+ `is_struct` – クエリの各出現が構造化データであるかどうかをチェックします。

  次の句は、`S3Bucket`リソースの `BucketEncryption`プロパティに構造化データが指定されているかどうかを確認します。`BucketEncryption` で `ServerSideEncryptionConfiguration`プロパティタイプ {{(オブジェクト)}} を使用して が指定され`PASS`るため、 に評価されます`Template-1`。

  ```
  Resources.S3Bucket.Properties.BucketEncryption is_struct
  ```

**注記**  
逆状態を確認するには、 (` not !`) 演算子を `is_string`、`is_list`、および `is_struct`演算子で使用できます。

### バイナリ演算子を使用する句の例
<a name="clauses-binary-operators"></a>

次の句は、 の`S3Bucket`リソースの `BucketName`プロパティに指定された値に、大文字と小文字に関係なく`encrypt`文字列 `Template-1`が含まれているかどうかを確認します。指定されたバケット名に文字列 が含まれ`"MyServiceS3Bucket"`ていない`PASS`ため、これは に評価されます`encrypt`。

```
Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
```

次の`Template-2`句は、 の`NewVolume`リソースの `Size`プロパティに指定された値が、50 <= `Size` <= 200 の範囲内にあるかどうかを確認します。が に`100`指定されている`PASS`ため、 に評価されます`Size`。

```
Resources.NewVolume.Properties.Size IN r[50,200]
```

次の`Template-2`句は、 の`NewVolume`リソースの `VolumeType`プロパティに指定された値が `io1`、`io2`、または であるかどうかをチェックします`gp3`。が に`io1`指定されている`PASS`ため、 に評価されます`NewVolume`。

```
Resources.NewVolume.Properties.NewVolume.VolumeType IN [ 'io1','io2','gp3' ]
```

**注記**  
このセクションのクエリ例は、論理 IDs `S3Bucket`と を持つリソースを使用した演算子の使用を示しています`NewVolume`。多くの場合、リソース名はユーザー定義であり、Infrastructure as Code (IaC) テンプレートで任意の名前を付けることができます。汎用的で、テンプレートで定義されているすべての`AWS::S3::Bucket`リソースに適用されるルールを記述する場合、使用されるクエリの最も一般的な形式は です`Resources.*[ Type == ‘AWS::S3::Bucket’ ]`。詳細については、使用状況の詳細については[クエリとフィルタリングの定義](query-and-filtering.md)「」を参照し、`cloudformation-guard`GitHub リポジトリの [examples](https://github.com/aws-cloudformation/cloudformation-guard/tree/main/guard-examples) ディレクトリを参照してください。

## 句でのカスタムメッセージの使用
<a name="clauses-custom-messages"></a>

次の例では、 の 句にカスタムメッセージ`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>>
```

## 句の組み合わせ
<a name="combining-clauses"></a>

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 句では、差分が最初に評価され、次に結合が評価されます。ガードルールは、 (`or|OR`) または `true` () のいずれかに評価される句 ( `and|AND` の `PASS`) の分散の組み合わせとして定義できます`false``FAIL`。これは[、補助的な通常の形式](https://en.wikipedia.org/wiki/Conjunctive_normal_form)に似ています。

次の例は、 句の評価の順序を示しています。

```
# (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
```

## ガードルールでのブロックの使用
<a name="blocks"></a>

ブロックは、関連する句、条件、またはルールのセットから冗長性と繰り返しを削除する構成です。ブロックには 3 つのタイプがあります。
+ クエリブロック
+ `when` ブロック
+ 名前付きルールブロック

### クエリブロック
<a name="query-blocks"></a>

以下は、例 に基づく句です`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
}
```

クエリブロックでは、ブロックの前のクエリがブロック内の句のコンテキストを設定します。

ブロックの使用の詳細については、「」を参照してください[名前付きルールブロックの作成](named-rule-block-composition.md)。

### `when` ブロック
<a name="when-blocks"></a>

ブロックは、次の形式の`when`ブロックを使用して条件付きで評価できます。

```
  when <condition> {
       Guard_rule_1
       Guard_rule_2
       ...
   }
```

`when` キーワードは`when`ブロックの開始を指定します。 `condition`はガードルールです。ブロックは、条件の評価が `true` () になった場合にのみ評価されます`PASS`。

以下は、 に基づく`when`ブロックの例です`Template-1`。

```
when Resources.S3Bucket.Properties.BucketName is_string {
     Resources.S3Bucket.Properties.BucketName != /(?i)encrypt/
 }
```

`when` ブロック内の 句は、 に指定された値が文字列である場合にのみ評価`BucketName`されます。次の例に示すように、 に指定された値がテンプレートの `Parameters`セクションで参照`BucketName`されている場合、 `when`ブロック内の 句は評価されません。

```
Parameters:
   S3BucketName:
     Type: String
 Resources:
   S3Bucket:
     Type: AWS::S3::Bucket
     Properties:
       BucketName: 
         Ref: S3BucketName
     ...
```

### 名前付きルールブロック
<a name="named-rule-blocks"></a>

ルールのセット (*ルールセット*) に名前を割り当て、他のルールで*名前付きルールブロックと呼ばれるモジュラー検証ブロック*を参照できます。名前付きルールブロックの形式は次のとおりです。

```
  rule <rule name> [when <condition>] {
    Guard_rule_1
    Guard_rule_2
    ...
    }
```

`rule` キーワードは、named-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
    ...
}
```

## 組み込み関数の使用
<a name="built-in-functions"></a>

AWS CloudFormation Guard には、文字列操作、JSON 解析、データ型変換などのオペレーションを実行するためにルールで使用できる組み込み関数が用意されています。関数は、変数への割り当てによってのみサポートされます。

### キー関数
<a name="key-functions"></a>

`json_parse(json_string)`  
テンプレートからインライン JSON 文字列を解析します。解析後、結果のオブジェクトのプロパティを評価できます。

`count(collection)`  
クエリが解決される項目の数を返します。

`regex_replace(base_string, regex_to_extract, regex_replacement)`  
正規表現を使用して文字列の一部を置き換えます。

文字列操作、コレクションオペレーション、データ型変換関数など、使用可能な関数の完全なリストについては、Guard GitHub リポジトリの [Functions ドキュメント](https://github.com/aws-cloudformation/cloudformation-guard/blob/main/docs/FUNCTIONS.md)を参照してください。