View a markdown version of this page

CloudFormation 語言延伸支援 - AWS Serverless Application Model

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

CloudFormation 語言延伸支援

AWS SAM CLI 支援使用AWS::LanguageExtensions轉換的範本,包括 Fn::ForEachFn::ToJsonStringFn::LengthFn::FindInMapDefaultValue。如需這些建構模組的完整參考資訊,請參閱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 buildsam packagesam deploysam syncsam validatesam local start-api、 和 sam local invokesam local start-lambda使用使用這些建構的範本。

本機處理預設為關閉。關閉時, AWS SAM CLI會傳遞範本,並在部署時間 CloudFormation 處理AWS::LanguageExtensions轉換伺服器端。如需啟用方法,請參閱 啟用語言延伸模組

啟用時,擴展會分兩個階段進行:

  1. 階段 1 (語言延伸)Fn::ForEach迴圈會展開,內部函數會盡可能解析,且範本會轉換為標準 CloudFormation。

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

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

啟用語言延伸模組

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

  1. CLI flag--language-extensions傳遞單一調用:

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

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

  2. 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 項目會載入為 命令的預設值,因此會像通過旗標一樣生效,因此會勝過環境變數。

  3. 環境變數SAM_CLI_ENABLE_LANGUAGE_EXTENSIONS=1設定為針對目前的 Shell 啟用 :

    export SAM_CLI_ENABLE_LANGUAGE_EXTENSIONS=1 sam build sam local invoke MyFunction

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

重要

每個命令都需要自己的啟用。傳遞--language-extensionssam 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擴展至 OrdersFunctionUsersFunctionProductsFunction,每個項目都是從其個別來源目錄建置。

動態成品屬性

當可封裝屬性使用迴圈變數 (例如 ./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.ImageUriAWS::Lambda::Function),值會在資源上的巢狀位置讀取和寫入。產生的映射名稱只會使用屬性路徑的分葉區段。

當屬性經過循環調整時,映射名稱為 SAM<LeafProperty><LoopName>(例如, SAMCodeUriServicesSAMScriptLocationJobs)。

重要

客戶編寫的映射不應以這些字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內文中的兩個資源宣告相同的動態成品屬性 (例如, ApiStateMachine使用 DefinitionUri) 時, AWS SAM CLI會附加從資源邏輯 ID 範本的靜態部分取得的尾碼,以保持映射名稱是唯一的:

具有碰撞尾碼的映射名稱範例
資源範本 屬性 映射名稱

${Svc}Api

DefinitionUri

SAMDefinitionUriServicesApi

${Svc}StateMachine

DefinitionUri

SAMDefinitionUriServicesStateMachine

沒有碰撞時,會使用基本名稱 (例如 SAMDefinitionUriServices)。

參數型集合

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

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

  2. 範本中的 參數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可以攜帶ConditionDependsOn就像任何其他資源一樣。條件或相依性會複寫到每個產生的資源:

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

支援的內部函數

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

在語言擴展期間,內部函數會在本機解析
函式 說明

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::GetAttFn::ImportValueFn::GetAZs) 的函數會在部署時保留 CloudFormation 供 解析。

驗證錯誤

在 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 會解析伺服器端。

限制

  • 集合必須在建置/封裝時間解析。使用 Fn::GetAttFn::ImportValue或 SSM/Secrets Manager 動態參考的Fn::ForEach集合無法在本機擴展。請--parameter-overrides改用 參數搭配 。

  • 動態成品映射會在封裝時間修正。Fn::ForEach集合是參數參考且迴圈內文使用動態成品屬性 (例如 CodeUri: ./services/${Name}) 時,產生的SAM*映射只會包含套件時間解析的參數值項目。如果您在部署時間--parameter-overrides變更該參數而不重新封裝,則新值不會有映射項目,且部署將會失敗。這不適用於不用於驅動動態成品 的參數Fn::ForEach

  • DeletionPolicyUpdateReplacePolicy 在擴展期間經過驗證和解決。它們支援Ref參數,但不支援其他內部函數。

  • 巢狀限制。最多Fn::ForEach可以巢狀 5 個層級,符合 CloudFormation 伺服器端限制。

  • 預留映射名稱。以下列任何項目開頭的映射名稱會保留給 AWS SAM CLI,請勿使用這些字首編寫您自己的映射:

    • SAMCodeUriSAMImageUriSAMContentUriSAMDefinitionUriSAMSchemaUriSAMBodyS3LocationSAMDefinitionS3LocationSAMCode、、 SAMContentSAMTemplateURLsam package由 針對動態成品屬性發出。請參閱 動態成品屬性資料表。

    • SAMLayers — 當 Fn::ForEach產生的函數挑選自動產生的相依性層參考 (Lambda 會將 AWS SAM CLI建置分層為巢狀堆疊) sam build時由 發出。此字首沒有對應的使用者撰寫屬性;它會自動新增。

遙測

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