

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# CloudFormation 語言延伸支援
<a name="sam-specification-language-extensions"></a>

 AWS SAM CLI 支援使用`AWS::LanguageExtensions`轉換的範本，包括 `Fn::ForEach`、`Fn::ToJsonString`、 `Fn::Length`和 `Fn::FindInMap`與 `DefaultValue`。如需這些建構模組的完整參考資訊，請參閱*AWS CloudFormation 《 使用者指南*》中的 [AWS：：LanguageExtensions 轉換](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-languageextensions.html)。

若要在 AWS SAM 範本中使用語言延伸，請在 *之前的* `Transform`區段`AWS::LanguageExtensions`中列出 `AWS::Serverless-2016-10-31`：

```
Transform:
  - AWS::LanguageExtensions
  - AWS::Serverless-2016-10-31
```

當 在 AWS SAM CLI範本的 `Transform`區段`AWS::LanguageExtensions`中偵測到 ，*且*您已選擇加入本機處理時，它會在執行 AWS SAM 轉換之前於本機擴展語言延伸建構。這可讓 `sam build`、`sam package`、`sam deploy`、`sam sync`、`sam validate`、`sam local start-api`、 和 `sam local invoke``sam local start-lambda`使用使用這些建構的範本。

本機處理預設為關閉。關閉時， AWS SAM CLI會傳遞範本，並在部署時間 CloudFormation 處理`AWS::LanguageExtensions`轉換伺服器端。如需啟用方法，請參閱 [啟用語言延伸模組](#sam-specification-language-extensions-enabling)。

啟用時，擴展會分兩個階段進行：

1. **階段 1 （語言延伸）** — `Fn::ForEach`迴圈會展開，內部函數會盡可能解析，且範本會轉換為標準 CloudFormation。

1. **階段 2 (AWS SAM 轉換）** — 擴展的範本會照常由 AWS SAM Translator 處理。

原始範本 (`Fn::ForEach`完整） 會保留供 CloudFormation 部署使用，因為 會 CloudFormation 處理`AWS::LanguageExtensions`轉換伺服器端。

## 啟用語言延伸模組
<a name="sam-specification-language-extensions-enabling"></a>

的本機處理`AWS::LanguageExtensions`是依命令選擇加入。有三種同等的啟用方法，依優先順序列出：

1. **CLI flag** — `--language-extensions`傳遞單一調用：

   ```
   sam build --language-extensions
   sam package --language-extensions ...
   sam deploy --language-extensions ...
   ```

   `--no-language-extensions` 明確停用，覆寫以下所述的 `samconfig.toml`和 環境變數。

1. **`samconfig.toml`** — 保留每個專案的選擇：

   ```
   [default.build.parameters]
   language_extensions = true
   
   [default.package.parameters]
   language_extensions = true
   
   [default.deploy.parameters]
   language_extensions = true
   
   [default.sync.parameters]
   language_extensions = true
   
   [default.local_invoke.parameters]
   language_extensions = true
   
   [default.local_start_api.parameters]
   language_extensions = true
   
   [default.local_start_lambda.parameters]
   language_extensions = true
   
   [default.validate.parameters]
   language_extensions = true
   ```

   `samconfig.toml` 項目會載入為 命令的預設值，因此會像通過旗標一樣生效，因此會勝過環境變數。

1. **環境變數** — `SAM_CLI_ENABLE_LANGUAGE_EXTENSIONS=1`設定為針對目前的 Shell 啟用 ：

   ```
   export SAM_CLI_ENABLE_LANGUAGE_EXTENSIONS=1
   sam build
   sam local invoke MyFunction
   ```

   真實值 （不區分大小寫） 為 `1`、 `true`和 `yes`。任何其他項目，包括空白字串，都會視為關閉。只有在 CLI 旗標或 都未`samconfig.toml`設定值時，才會參考環境變數。

**重要**  
每個命令都需要自己的啟用。傳遞`--language-extensions`至 `sam build` 不會傳播至稍後 `sam local invoke`- 本機處理會依命令叫用決定。使用環境變數或`samconfig.toml`項目跨命令啟用 ，而無需重複 旗標。

## Fn::ForEach
<a name="sam-specification-language-extensions-foreach"></a>

`Fn::ForEach` 從單一範本定義產生多個資源、條件或輸出：

```
Transform:
  - AWS::LanguageExtensions
  - AWS::Serverless-2016-10-31

Parameters:
  ServiceNames:
    Type: CommaDelimitedList
    Default: "Users,Orders,Products"

Resources:
  Fn::ForEach::Services:
    - Name
    - !Ref ServiceNames
    - ${Name}Function:
        Type: AWS::Serverless::Function
        Properties:
          Handler: index.handler
          Runtime: python3.12
          CodeUri: ./services/${Name}
```

執行 會將此項目`sam build`擴展至 `OrdersFunction`、 `UsersFunction`和 `ProductsFunction`，每個項目都是從其個別來源目錄建置。

### 動態成品屬性
<a name="sam-specification-language-extensions-dynamic-artifacts"></a>

當可封裝屬性使用迴圈變數 （例如 `./services/${Name}`) 時， AWS SAM CLI會產生區段 CloudFormation `Mappings`，將每個集合值映射至其 Amazon S3URI。內`Fn::ForEach`文會重寫為使用 `Fn::FindInMap`，以便在部署時 CloudFormation 解析正確的成品。

辨識的成品屬性與今天`sam package`重新寫入的成品屬性相同。這包括：


**辨識的動態成品屬性 AWS SAM CLI**  

| Resource Type (資源類型) | 屬性 | 
| --- | --- | 
| `AWS::Serverless::Function` | `CodeUri`, `ImageUri` | 
| `AWS::Serverless::LayerVersion` | `ContentUri` | 
| `AWS::Serverless::Api` | `DefinitionUri` | 
| `AWS::Serverless::HttpApi` | `DefinitionUri` | 
| `AWS::Serverless::StateMachine` | `DefinitionUri` | 
| `AWS::Serverless::GraphQLApi` | `SchemaUri`, `CodeUri` | 
| `AWS::Serverless::Application` | `Location` | 
| `AWS::Lambda::Function` | `Code`, `Code.ImageUri` | 
| `AWS::Lambda::LayerVersion` | `Content` | 
| `AWS::ApiGateway::RestApi` | `BodyS3Location` | 
| `AWS::ApiGatewayV2::Api` | `BodyS3Location` | 
| `AWS::AppSync::GraphQLSchema` | `DefinitionS3Location` | 
| `AWS::AppSync::Resolver` | `RequestMappingTemplateS3Location`, `ResponseMappingTemplateS3Location`, `CodeS3Location` | 
| `AWS::AppSync::FunctionConfiguration` | `RequestMappingTemplateS3Location`, `ResponseMappingTemplateS3Location`, `CodeS3Location` | 
| `AWS::StepFunctions::StateMachine` | `DefinitionS3Location` | 
| `AWS::ElasticBeanstalk::ApplicationVersion` | `SourceBundle` | 
| `AWS::Glue::Job` | `Command.ScriptLocation` | 
| `AWS::CloudFormation::Stack` | `TemplateURL` | 
| `AWS::CloudFormation::StackSet` | `TemplateURL` | 
| `AWS::CloudFormation::ModuleVersion` | `ModulePackage` | 
| `AWS::CloudFormation::ResourceVersion` | `SchemaHandlerPackage` | 

對於虛線屬性 （例如`Command.ScriptLocation`，在 上`AWS::Glue::Job`或在 `Code.ImageUri`上`AWS::Lambda::Function`)，值會在資源上的巢狀位置讀取和寫入。產生的映射名稱只會使用屬性路徑的分葉區段。

當屬性經過循環調整時，映射名稱為 `SAM<LeafProperty><LoopName>`（例如， `SAMCodeUriServices`或 `SAMScriptLocationJobs`)。

**重要**  
客戶編寫的映射不應以這些字`SAM*`首開頭，它們會保留給 AWS SAM CLI。請參閱 [限制](#sam-specification-language-extensions-limitations)。

例如，在 之後`sam package`：

```
Mappings:
  SAMCodeUriServices:
    Users:
      CodeUri: s3://my-bucket/abc123
    Orders:
      CodeUri: s3://my-bucket/def456
    Products:
      CodeUri: s3://my-bucket/ghi789

Resources:
  Fn::ForEach::Services:
    - Name
    - !Ref ServiceNames
    - ${Name}Function:
        Type: AWS::Serverless::Function
        Properties:
          Handler: index.handler
          Runtime: python3.12
          CodeUri: !FindInMap [SAMCodeUriServices, !Ref Name, CodeUri]
```

### 每個 ForEach 內文的多個資源
<a name="sam-specification-language-extensions-multiple-resources"></a>

單一`Fn::ForEach`內文每次反覆運算可以發出多個資源。每個資源都會針對每個集合值產生：

```
Resources:
  Fn::ForEach::Tables:
    - TableName
    - [Users, Orders, Products]
    - ${TableName}Table:
        Type: AWS::DynamoDB::Table
        Properties:
          TableName: !Sub "${AWS::StackName}-${TableName}"
          # ...

      ${TableName}StreamProcessor:
        Type: AWS::Serverless::Function
        Properties:
          CodeUri: stream-processors/${TableName}/
          Events:
            DDBStream:
              Type: DynamoDB
              Properties:
                Stream: !GetAtt
                  - !Sub "${TableName}Table"
                  - StreamArn
```

### 映射名稱碰撞解析度
<a name="sam-specification-language-extensions-mapping-collisions"></a>

當同一`Fn::ForEach`內文中的兩個資源宣告相同的動態成品屬性 （例如， `Api`和`StateMachine`使用 `DefinitionUri`) 時， AWS SAM CLI會附加從資源邏輯 ID 範本的靜態部分取得的尾碼，以保持映射名稱是唯一的：


**具有碰撞尾碼的映射名稱範例**  

| 資源範本 | 屬性 | 映射名稱 | 
| --- | --- | --- | 
| `${Svc}Api` | `DefinitionUri` | `SAMDefinitionUriServicesApi` | 
| `${Svc}StateMachine` | `DefinitionUri` | `SAMDefinitionUriServicesStateMachine` | 

沒有碰撞時，會使用基本名稱 （例如 `SAMDefinitionUriServices`)。

### 參數型集合
<a name="sam-specification-language-extensions-parameter-collections"></a>

當`Fn::ForEach`集合是參數參考 （例如 `!Ref ServiceNames`) 且迴圈內文使用動態成品屬性 （例如 `CodeUri: ./services/${Name}`) 時， AWS SAM CLI需要集合值才能產生 中所述的`SAM*`映射[動態成品屬性](#sam-specification-language-extensions-dynamic-artifacts)。它會在處理範本時解決這些問題，從：

1. `--parameter-overrides` 傳遞至 AWS SAM CLI命令。

1. 範本中的 參數`Default`值。

**重要**  
由於`SAM*`映射是在封裝時間於 中製作，因此每當您變更參數值 （例如，新增服務時） 時，都必須重新封裝，以便映射包含新值的項目。這僅適用於 參數驅動動態成品迴圈時；其他參數覆寫可以照常在部署時間變更。

```
# Package with the values you intend to deploy with
sam package --language-extensions --parameter-overrides ServiceNames="Users,Orders,Products"

# Deploy with the same values
sam deploy --language-extensions --parameter-overrides ServiceNames="Users,Orders,Products"
```

### 巢狀堆疊
<a name="sam-specification-language-extensions-nested-stacks"></a>

`Fn::ForEach` 支援巢狀堆疊範本 (`AWS::CloudFormation::Stack`)。會將父堆疊的 `Parameters` 屬性 AWS SAM CLI傳遞至子範本擴展，以便參考父系提供的參數的子`Fn::ForEach`集合正確解析。

```
# parent.yaml
Resources:
  ChildStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: ./child.yaml
      Parameters:
        ServiceNames: "Users,Orders,Products"
```

### 巢狀 Fn：：ForEach
<a name="sam-specification-language-extensions-nested-foreach"></a>

最多支援 5 個巢狀層級，符合 CloudFormation 限制：

```
Resources:
  Fn::ForEach::Envs:
    - Env
    - [Dev, Staging, Prod]
    - Fn::ForEach::Services:
        - Svc
        - [Users, Orders]
        - ${Env}${Svc}Function:
            Type: AWS::Serverless::Function
            Properties:
              CodeUri: ./services/${Svc}
              Environment:
                Variables:
                  STAGE: ${Env}
```

### 輸出中的 ForEach
<a name="sam-specification-language-extensions-foreach-outputs"></a>

`Fn::ForEach` 區塊也會在 `Outputs`區段中展開，因此您可以為每個集合值發出一個輸出：

```
Outputs:
  Fn::ForEach::FunctionArns:
    - Name
    - [alpha, beta]
    - ${Name}FunctionArn:
        Value: !GetAtt
          - !Sub "${Name}Function"
          - Arn
```

### 條件和 DependsOn
<a name="sam-specification-language-extensions-conditions-dependson"></a>

發出的資源`Fn::ForEach`可以攜帶`Condition`，`DependsOn`就像任何其他資源一樣。條件或相依性會複寫到每個產生的資源：

```
Conditions:
  IsProd: !Equals [!Ref Environment, prod]

Resources:
  SharedTable:
    Type: AWS::DynamoDB::Table
    # ...

  Fn::ForEach::Functions:
    - Name
    - [api, worker]
    - ${Name}Function:
        Type: AWS::Serverless::Function
        Condition: IsProd
        DependsOn: SharedTable
        Properties:
          Handler: main.handler
          CodeUri: functions/${Name}/
```

### &{identifier} 語法
<a name="sam-specification-language-extensions-identifier-syntax"></a>

`&{identifier}` 語法會從取代的值中去除非英數字元，這對於從 IP 地址等值產生有效的邏輯 IDs 非常有用：

```
Fn::ForEach::Hosts:
  - IP
  - ["10.0.0.1", "10.0.0.2"]
  - Host&{IP}:
      Type: AWS::EC2::Instance
      # Expands to Host10001, Host10002
```

## 支援的內部函數
<a name="sam-specification-language-extensions-supported-functions"></a>

下列內部函數會在擴充期間於本機解析：


**在語言擴展期間，內部函數會在本機解析**  

| 函式 | 說明 | 
| --- | --- | 
| `Fn::ForEach` | 迴圈擴展。 | 
| `Fn::Length` | 傳回清單元素的計數。 | 
| `Fn::ToJsonString` | 將值轉換為JSON字串。 | 
| `Fn::FindInMap` | 地圖查詢，包括選用的 `DefaultValue`。 | 
| `Fn::If` | 條件值選擇。 | 
| `Fn::Sub` | 字串替換。 | 
| `Fn::Join` | 字串串連。 | 
| `Fn::Split` | 字串分割。 | 
| `Fn::Select` | 列出元素選擇。 | 
| `Fn::Base64` | Base64 編碼。 | 
| `Fn::Equals`, `Fn::And`, `Fn::Or`, `Fn::Not` | 條件評估。 | 
| `Ref` | 參數和虛擬參數參考。 | 

需要部署資源 (`Fn::GetAtt`、`Fn::ImportValue`、`Fn::GetAZs`) 的函數會在部署時保留 CloudFormation 供 解析。

## 驗證錯誤
<a name="sam-specification-language-extensions-validation-errors"></a>

在 AWS SAM 轉換執行之前，會在本機發現下列範本問題：


**語言擴充功能擴展期間引發的驗證錯誤**  

| 原因 | 錯誤訊息 | 
| --- | --- | 
| `Fn::ForEach` 值格式錯誤：不是清單、沒有剛好 3 個元素，或具有非字串迴圈識別符。 | `Fn::ForEach::<key> layout is incorrect` （提高為 `InvalidTemplateException`)。 | 
| 超過 5 個層級的 `Fn::ForEach`會巢狀化。 | `Fn::ForEach nesting depth of <N> exceeds the maximum allowed depth of 5. CloudFormation supports up to 5 nested Fn::ForEach loops.` | 
| 集合會解析為空白清單 （例如，具有 的 `CommaDelimitedList` 參數`Default: ""`)。 | 沒有錯誤 — 無提示地略過迴圈，也不會發出任何資源。 | 
| 集合`!Ref`中的 會指向範本中未宣告的參數。 | 沒有錯誤 – 未解析的參考會保留在範本中。在部署時間， CloudFormation 會解析伺服器端。 | 

## 限制
<a name="sam-specification-language-extensions-limitations"></a>
+ **集合必須在建置/封裝時間解析。**使用 `Fn::GetAtt`、 `Fn::ImportValue`或 SSM/Secrets Manager 動態參考的`Fn::ForEach`集合無法在本機擴展。請`--parameter-overrides`改用 參數搭配 。
+ **動態成品映射會在封裝時間修正。**當`Fn::ForEach`集合是參數參考且迴圈內文使用動態成品屬性 （例如 `CodeUri: ./services/${Name}`) 時，產生的`SAM*`映射只會包含套件時間解析的參數值項目。如果您在部署時間`--parameter-overrides`變更該參數而不重新封裝，則新值不會有映射項目，且部署將會失敗。這不適用於不用於驅動動態成品 的參數`Fn::ForEach`。
+ **`DeletionPolicy` 和 `UpdateReplacePolicy`** 在擴展期間經過驗證和解決。它們支援`Ref`參數，但不支援其他內部函數。
+ **巢狀限制。**最多`Fn::ForEach`可以巢狀 5 個層級，符合 CloudFormation 伺服器端限制。
+ **預留映射名稱。**以下列任何項目開頭的映射名稱會保留給 AWS SAM CLI，請勿使用這些字首編寫您自己的映射：
  + `SAMCodeUri`、`SAMImageUri`、`SAMContentUri`、`SAMDefinitionUri`、`SAMSchemaUri`、`SAMBodyS3Location`、`SAMDefinitionS3Location`、`SAMCode`、、 `SAMContent` — `SAMTemplateURL``sam package`由 針對動態成品屬性發出。請參閱 [動態成品屬性](#sam-specification-language-extensions-dynamic-artifacts)資料表。
  + `SAMLayers` — 當 `Fn::ForEach`產生的函數挑選自動產生的相依性層參考 (Lambda 會將 AWS SAM CLI建置分層為巢狀堆疊） `sam build`時由 發出。此字首沒有對應的使用者撰寫屬性；它會自動新增。

## 遙測
<a name="sam-specification-language-extensions-telemetry"></a>

當 AWS SAM CLI使用 `--language-extensions`（或其環境變數對等項目） 叫用命令*，且*範本宣告`AWS::LanguageExtensions`轉換時， 會發出`CFNLanguageExtensions`遙測事件。事件會在每次叫用時觸發一次，而且不會傳輸任何範本內容。當本機處理關閉 （預設值） 時，不會觸發事件。