本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
CloudFormation 語言延伸支援
AWS SAM CLI 支援使用AWS::LanguageExtensions轉換的範本,包括 Fn::ForEach、Fn::ToJsonString、 Fn::Length和 Fn::FindInMap與 DefaultValue。如需這些建構模組的完整參考資訊,請參閱AWS CloudFormation 《 使用者指南》中的 AWS::LanguageExtensions 轉換。
若要在 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 invokesam local start-lambda使用使用這些建構的範本。
本機處理預設為關閉。關閉時, AWS SAM CLI會傳遞範本,並在部署時間 CloudFormation 處理AWS::LanguageExtensions轉換伺服器端。如需啟用方法,請參閱 啟用語言延伸模組。
啟用時,擴展會分兩個階段進行:
-
階段 1 (語言延伸) —
Fn::ForEach迴圈會展開,內部函數會盡可能解析,且範本會轉換為標準 CloudFormation。 -
階段 2 (AWS SAM 轉換) — 擴展的範本會照常由 AWS SAM Translator 處理。
原始範本 (Fn::ForEach完整) 會保留供 CloudFormation 部署使用,因為 會 CloudFormation 處理AWS::LanguageExtensions轉換伺服器端。
啟用語言延伸模組
的本機處理AWS::LanguageExtensions是依命令選擇加入。有三種同等的啟用方法,依優先順序列出:
-
CLI flag —
--language-extensions傳遞單一調用:sam build --language-extensions sam package --language-extensions ... sam deploy --language-extensions ...--no-language-extensions明確停用,覆寫以下所述的samconfig.toml和 環境變數。 -
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 = truesamconfig.toml項目會載入為 命令的預設值,因此會像通過旗標一樣生效,因此會勝過環境變數。 -
環境變數 —
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
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,每個項目都是從其個別來源目錄建置。
動態成品屬性
當可封裝屬性使用迴圈變數 (例如 ./services/${Name}) 時, AWS SAM CLI會產生區段 CloudFormation Mappings,將每個集合值映射至其 Amazon S3URI。內Fn::ForEach文會重寫為使用 Fn::FindInMap,以便在部署時 CloudFormation 解析正確的成品。
辨識的成品屬性與今天sam package重新寫入的成品屬性相同。這包括:
| Resource Type (資源類型) | 屬性 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
對於虛線屬性 (例如Command.ScriptLocation,在 上AWS::Glue::Job或在 Code.ImageUri上AWS::Lambda::Function),值會在資源上的巢狀位置讀取和寫入。產生的映射名稱只會使用屬性路徑的分葉區段。
當屬性經過循環調整時,映射名稱為 SAM<LeafProperty><LoopName>(例如, SAMCodeUriServices或 SAMScriptLocationJobs)。
重要
客戶編寫的映射不應以這些字SAM*首開頭,它們會保留給 AWS SAM CLI。請參閱 限制。
例如,在 之後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 內文的多個資源
單一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
映射名稱碰撞解析度
當同一Fn::ForEach內文中的兩個資源宣告相同的動態成品屬性 (例如, Api和StateMachine使用 DefinitionUri) 時, AWS SAM CLI會附加從資源邏輯 ID 範本的靜態部分取得的尾碼,以保持映射名稱是唯一的:
| 資源範本 | 屬性 | 映射名稱 |
|---|---|---|
|
|
|
|
|
|
沒有碰撞時,會使用基本名稱 (例如 SAMDefinitionUriServices)。
參數型集合
當Fn::ForEach集合是參數參考 (例如 !Ref ServiceNames) 且迴圈內文使用動態成品屬性 (例如 CodeUri: ./services/${Name}) 時, AWS SAM CLI需要集合值才能產生 中所述的SAM*映射動態成品屬性。它會在處理範本時解決這些問題,從:
-
--parameter-overrides傳遞至 AWS SAM CLI命令。 -
範本中的 參數
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"
巢狀堆疊
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
最多支援 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
Fn::ForEach 區塊也會在 Outputs區段中展開,因此您可以為每個集合值發出一個輸出:
Outputs: Fn::ForEach::FunctionArns: - Name - [alpha, beta] - ${Name}FunctionArn: Value: !GetAtt - !Sub "${Name}Function" - Arn
條件和 DependsOn
發出的資源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} 語法
&{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
支援的內部函數
下列內部函數會在擴充期間於本機解析:
| 函式 | 說明 |
|---|---|
|
迴圈擴展。 |
|
傳回清單元素的計數。 |
|
將值轉換為JSON字串。 |
|
地圖查詢,包括選用的 |
|
條件值選擇。 |
|
字串替換。 |
|
字串串連。 |
|
字串分割。 |
|
列出元素選擇。 |
|
Base64 編碼。 |
|
條件評估。 |
|
參數和虛擬參數參考。 |
需要部署資源 (Fn::GetAtt、Fn::ImportValue、Fn::GetAZs) 的函數會在部署時保留 CloudFormation 供 解析。
驗證錯誤
在 AWS SAM 轉換執行之前,會在本機發現下列範本問題:
| 原因 | 錯誤訊息 |
|---|---|
|
|
超過 5 個層級的 |
|
集合會解析為空白清單 (例如,具有 的 |
沒有錯誤 — 無提示地略過迴圈,也不會發出任何資源。 |
集合 |
沒有錯誤 – 未解析的參考會保留在範本中。在部署時間, CloudFormation 會解析伺服器端。 |
限制
-
集合必須在建置/封裝時間解析。使用
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—SAMTemplateURLsam package由 針對動態成品屬性發出。請參閱 動態成品屬性資料表。 -
SAMLayers— 當Fn::ForEach產生的函數挑選自動產生的相依性層參考 (Lambda 會將 AWS SAM CLI建置分層為巢狀堆疊)sam build時由 發出。此字首沒有對應的使用者撰寫屬性;它會自動新增。
-
遙測
當 AWS SAM CLI使用 --language-extensions(或其環境變數對等項目) 叫用命令,且範本宣告AWS::LanguageExtensions轉換時, 會發出CFNLanguageExtensions遙測事件。事件會在每次叫用時觸發一次,而且不會傳輸任何範本內容。當本機處理關閉 (預設值) 時,不會觸發事件。