

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

# ガードルールでの変数の割り当てと参照
<a name="variables"></a>

 AWS CloudFormation Guard ルールファイルに変数を割り当てて、Guard ルールで参照する情報を保存できます。Guard はワンショット変数割り当てをサポートしています。変数は遅延的に評価されます。つまり、Guard はルールの実行時にのみ変数を評価します。

**Topics**
+ [変数の割り当て](#assigning-variables)
+ [変数の参照](#referencing-variables)
+ [変数のスコープ](#variable-scope)
+ [ガードルールファイルの変数の例](#variables-examples)

## 変数の割り当て
<a name="assigning-variables"></a>

`let` キーワードを使用して変数を初期化して割り当てます。ベストプラクティスとして、変数名にはスネークケースを使用します。変数は、クエリの結果として生じる静的リテラルまたは動的プロパティを保存できます。次の例では、 変数は静的文字列値 `ecs_task_definition_task_role_arn`を保存します`arn:aws:iam:123456789012:role/my-role-name`。

```
let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-role-name'
```

次の例では、 変数は、 テンプレート内のすべての`AWS::ECS::TaskDefinition` CloudFormation リソースを検索するクエリの結果`ecs_tasks`を保存します。ルールを記述するときに、 `ecs_tasks`を参照してこれらのリソースに関する情報にアクセスできます。

```
let ecs_tasks = Resources.*[
    Type == 'AWS::ECS::TaskDefinition'
]
```

## 変数の参照
<a name="referencing-variables"></a>

`%` プレフィックスを使用して変数を参照します。

の`ecs_task_definition_task_role_arn`変数の例に基づいて[変数の割り当て](#assigning-variables)、Guard ルール句の `query|value literal`セクション`ecs_task_definition_task_role_arn`で を参照できます。このリファレンスを使用すると、CloudFormation テンプレート内の`AWS::ECS::TaskDefinition`リソースの `TaskDefinitionArn`プロパティに指定された値が静的文字列値 になります`arn:aws:iam:123456789012:role/my-role-name`。

```
Resources.*.Properties.TaskDefinitionArn == %ecs_task_definition_role_arn
```

の`ecs_tasks`変数の例に基づいて[変数の割り当て](#assigning-variables)、クエリ`ecs_tasks`で を参照できます (%ecs\$1tasks.Properties など）。まず、Guard は変数を評価し`ecs_tasks`、返された値を使用して階層を横断します。変数が文字列以外の値に`ecs_tasks`解決された場合、Guard はエラーをスローします。

**注記**  
現在、Guard はカスタムエラーメッセージ内の変数の参照をサポートしていません。

## 変数のスコープ
<a name="variable-scope"></a>

スコープとは、ルールファイルで定義された変数の可視性を指します。変数名は、スコープ内で 1 回のみ使用できます。変数を宣言できるレベルは 3 つ、または可能な変数スコープは 3 つあります。
+ **ファイルレベル** – 通常、ルールファイルの上部で宣言され、ルールファイル内のすべてのルールでファイルレベルの変数を使用できます。ファイル全体に表示されます。

  次のルールファイルの例では、変数 `ecs_task_definition_task_role_arn`と `ecs_task_definition_execution_role_arn`はファイルレベルで初期化されます。

  ```
  let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-task-role-name'
  let ecs_task_definition_execution_role_arn = 'arn:aws:iam::123456789012:role/my-execution-role-name'
  
  rule check_ecs_task_definition_task_role_arn
  {
      Resources.*.Properties.TaskRoleArn == %ecs_task_definition_task_role_arn
  }
  
  rule check_ecs_task_definition_execution_role_arn
  {
      Resources.*.Properties.ExecutionRoleArn == %ecs_task_definition_execution_role_arn
  }
  ```
+ **ルールレベル** – ルール内で宣言されたルールレベルの変数は、その特定のルールにのみ表示されます。ルール外の参照はエラーになります。

  次のルールファイルの例では、変数 `ecs_task_definition_task_role_arn`と `ecs_task_definition_execution_role_arn`はルールレベルで初期化されます。は、`check_ecs_task_definition_task_role_arn`名前付きルール内でのみ参照`ecs_task_definition_task_role_arn`できます。`ecs_task_definition_execution_role_arn` 変数は、`check_ecs_task_definition_execution_role_arn`名前付きルール内でのみ参照できます。

  ```
  rule check_ecs_task_definition_task_role_arn
  {
      let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-task-role-name'
      Resources.*.Properties.TaskRoleArn == %ecs_task_definition_task_role_arn
  }
  
  rule check_ecs_task_definition_execution_role_arn
  {
      let ecs_task_definition_execution_role_arn = 'arn:aws:iam::123456789012:role/my-execution-role-name'
      Resources.*.Properties.ExecutionRoleArn == %ecs_task_definition_execution_role_arn
  }
  ```
+ **ブロックレベル** – `when`句などのブロック内で宣言されたブロックレベルの変数は、その特定のブロックにのみ表示されます。ブロック外の参照はエラーになります。

  次のルールファイルの例では、変数 `ecs_task_definition_task_role_arn`と `ecs_task_definition_execution_role_arn`は`AWS::ECS::TaskDefinition`タイプブロック内のブロックレベルで初期化されます。`ecs_task_definition_task_role_arn` および `ecs_task_definition_execution_role_arn`変数は、それぞれのルールの`AWS::ECS::TaskDefinition`型ブロック内でのみ参照できます。

  ```
  rule check_ecs_task_definition_task_role_arn
  {
      AWS::ECS::TaskDefinition
      {
          let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-task-role-name'
          Properties.TaskRoleArn == %ecs_task_definition_task_role_arn
      }
  }
  
  rule check_ecs_task_definition_execution_role_arn
  {
      AWS::ECS::TaskDefinition
      {
          let ecs_task_definition_execution_role_arn = 'arn:aws:iam::123456789012:role/my-execution-role-name'
          Properties.ExecutionRoleArn == %ecs_task_definition_execution_role_arn
      }
  }
  ```

## ガードルールファイルの変数の例
<a name="variables-examples"></a>

以下のセクションでは、変数の静的割り当てと動的割り当ての両方の例を示します。

### 静的割り当て
<a name="assigning-static-variables"></a>

CloudFormation テンプレートの例を次に示します。

```
Resources:
  EcsTask:
    Type: 'AWS::ECS::TaskDefinition'
    Properties:
      TaskRoleArn: 'arn:aws:iam::123456789012:role/my-role-name'
```

このテンプレートに基づいて、すべてのテンプレート`AWS::ECS::TaskDefinition`リソースの `TaskRoleArn`プロパティ`check_ecs_task_definition_task_role_arn`が であることを保証する というルールを記述できます`arn:aws:iam::123456789012:role/my-role-name`。

```
rule check_ecs_task_definition_task_role_arn
{
    let ecs_task_definition_task_role_arn = 'arn:aws:iam::123456789012:role/my-role-name'
    Resources.*.Properties.TaskRoleArn == %ecs_task_definition_task_role_arn
}
```

ルールの範囲内で、 という変数を初期化`ecs_task_definition_task_role_arn`し、静的文字列値 を割り当てることができます`'arn:aws:iam::123456789012:role/my-role-name'`。ルール句は、 `query|value literal`セクションの `ecs_task_definition_task_role_arn`変数を参照`arn:aws:iam::123456789012:role/my-role-name`することで、`EcsTask`リソースの `TaskRoleArn`プロパティに指定された値が であるかどうかをチェックします。

### 動的割り当て
<a name="example-dynamic-assignment"></a>

CloudFormation テンプレートの例を次に示します。

```
Resources:
  EcsTask:
    Type: 'AWS::ECS::TaskDefinition'
    Properties:
      TaskRoleArn: 'arn:aws:iam::123456789012:role/my-role-name'
```

このテンプレートに基づいて、 ファイル`ecs_tasks`の範囲内で という変数を初期化し、クエリ を割り当てることができます`Resources.*[ Type == 'AWS::ECS::TaskDefinition'`。Guard は入力テンプレート内のすべてのリソースをクエリし、それらの情報を に保存します`ecs_tasks`。すべての`AWS::ECS::TaskDefinition`テンプレートリソースの `TaskRoleArn`プロパティ`check_ecs_task_definition_task_role_arn`が `arn:aws:iam::123456789012:role/my-role-name`

```
let ecs_tasks = Resources.*[
    Type == 'AWS::ECS::TaskDefinition'
]

rule check_ecs_task_definition_task_role_arn
{
    %ecs_tasks.Properties.TaskRoleArn == 'arn:aws:iam::123456789012:role/my-role-name'
}
```

ルール句は、 `query`セクションの `ecs_task_definition_task_role_arn`変数を参照`arn:aws:iam::123456789012:role/my-role-name`することで、`EcsTask`リソースの `TaskRoleArn`プロパティに指定された値が であるかどうかをチェックします。

### CloudFormation テンプレート設定の適用
<a name="example-3"></a>

本番稼働用ユースケースのより複雑な例を見てみましょう。この例では、Amazon ECS タスクの定義方法をより厳密に制御するための Guard ルールを記述します。

CloudFormation テンプレートの例を次に示します。

```
Resources:
  EcsTask:
    Type: 'AWS::ECS::TaskDefinition'
    Properties:
      TaskRoleArn: 
        'Fn::GetAtt': [TaskIamRole, Arn]
      ExecutionRoleArn:
        'Fn::GetAtt': [ExecutionIamRole, Arn]

  TaskIamRole:
    Type: 'AWS::IAM::Role'
    Properties:
      PermissionsBoundary: 'arn:aws:iam::123456789012:policy/MyExamplePolicy'

  ExecutionIamRole:
    Type: 'AWS::IAM::Role'
    Properties:
      PermissionsBoundary: 'arn:aws:iam::123456789012:policy/MyExamplePolicy'
```

このテンプレートに基づいて、これらの要件が満たされるように次のルールを記述します。
+ テンプレート内の各`AWS::ECS::TaskDefinition`リソースには、タスクロールと実行ロールの両方がアタッチされています。
+ タスクロールと実行ロールは AWS Identity and Access Management (IAM) ロールです。
+ ロールは テンプレートで定義されます。
+ `PermissionsBoundary` プロパティはロールごとに指定されます。

```
# Select all Amazon ECS task definition resources from the template
let ecs_tasks = Resources.*[
    Type == 'AWS::ECS::TaskDefinition'
]

# Select a subset of task definitions whose specified value for the TaskRoleArn property is an Fn::Gett-retrievable attribute
let task_role_refs = some %ecs_tasks.Properties.TaskRoleArn.'Fn::GetAtt'[0]

# Select a subset of TaskDefinitions whose specified value for the ExecutionRoleArn property is an Fn::Gett-retrievable attribute
let execution_role_refs = some %ecs_tasks.Properties.ExecutionRoleArn.'Fn::GetAtt'[0]

# Verify requirement #1
rule all_ecs_tasks_must_have_task_end_execution_roles 
    when %ecs_tasks !empty 
{
    %ecs_tasks.Properties {
        TaskRoleArn exists
        ExecutionRoleArn exists
    }
}

# Verify requirements #2 and #3
rule all_roles_are_local_and_type_IAM
    when all_ecs_tasks_must_have_task_end_execution_roles
{
    let task_iam_references = Resources.%task_role_refs
    let execution_iam_reference = Resources.%execution_role_refs

    when %task_iam_references !empty {
        %task_iam_references.Type == 'AWS::IAM::Role'
    }

    when %execution_iam_reference !empty {
        %execution_iam_reference.Type == 'AWS::IAM::Role'
    }
}

# Verify requirement #4
rule check_role_have_permissions_boundary
    when all_ecs_tasks_must_have_task_end_execution_roles
{
    let task_iam_references = Resources.%task_role_refs
    let execution_iam_reference = Resources.%execution_role_refs

    when %task_iam_references !empty {
        %task_iam_references.Properties.PermissionsBoundary exists
    }

    when %execution_iam_reference !empty {
        %execution_iam_reference.Properties.PermissionsBoundary exists
    }
}
```