

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

# 使用 CloudFormation 範本
<a name="template-guide"></a>

 AWS CloudFormation 範本會定義您要在堆疊中建立、更新或刪除 AWS 的資源。它包含多個區段，但唯一必要的區段是 [Resources](resources-section-structure.md) 區段，且該區段必須宣告至少一項資源。

您可以使用下列方法建立範本：
+ **AWS Infrastructure Composer** – 用於設計範本的視覺化介面。
+ **文字編輯器** – 直接以 JSON 或 YAML 語法撰寫範本。
+ **IaC 產生器** – 從您帳戶中已佈建但目前未由 CloudFormation 管理的資源產生範本。IaC 產生器可搭配您所在區域中 Cloud Control API 支援的多種資源類型使用。

本節提供完整指南，說明如何使用 CloudFormation 範本的各個區段，以及如何開始建立堆疊範本。它涵蓋下列主題：

**Topics**
+ [範本的儲存位置](#where-they-get-stored)
+ [驗證範本](#template-validation)
+ [開始使用範本](#getting-started)
+ [範例範本](#sample-templates)
+ [範本格式](template-formats.md)
+ [範本區段](template-anatomy.md)
+ [Infrastructure Composer](infrastructure-composer-for-cloudformation.md)
+ [AWS CloudFormation 語言伺服器](ide-extension.md)
+ [IaC 產生器](generate-IaC.md)
+ [取得儲存在其他服務中的值](dynamic-references.md)
+ [取得 AWS 值](pseudo-parameter-reference.md)
+ [取得堆疊輸出](using-cfn-stack-exports.md)
+ [在執行時期指定現有資源](cloudformation-supplied-parameter-types.md)
+ [逐步解說](walkthroughs.md)
+ [範本程式碼片段](template-snippets.md)
+ [Windows 型堆疊](cfn-windows-stacks.md)
+ [使用 CloudFormation 提供的資源類型](cloudformation-supplied-resource-types.md)
+ [透過模組建立可重複使用的資源組態](modules.md)

## 範本的儲存位置
<a name="where-they-get-stored"></a>

**Amazon S3 儲存貯體**  
您可以將 CloudFormation 範本儲存在 Amazon S3 儲存貯體中。建立或更新堆疊時，您可以指定範本的 S3 URL，而非直接上傳。

如果您直接透過 AWS 管理主控台 或 上傳範本 AWS CLI，系統會自動為您建立 S3 儲存貯體。如需詳細資訊，請參閱[從 CloudFormation 主控台建立堆疊](cfn-console-create-stack.md)。

**Git 儲存庫**  
使用 [Git 同步](git-sync.md)，您可以在 Git 儲存庫中儲存範本。建立或更新堆疊時，您可以指定包含範本的 Git 儲存庫位置和分支，而非直接上傳或參考 S3 URL。CloudFormation 會自動監控指定儲存庫和分支的範本變更。如需詳細資訊，請參閱[使用 Git 同步從儲存庫原始程式碼建立堆疊](git-sync-create-stack-from-repository-source-code.md)。

## 驗證範本
<a name="template-validation"></a>

**語法驗證**  
您可以使用 [validate-template](service_code_examples.md#validate-template-sdk) CLI 命令，或在主控台上指定範本，驗證範本的 JSON 或 YAML 語法。主控台會自動執行驗證。如需詳細資訊，請參閱[從 CloudFormation 主控台建立堆疊](cfn-console-create-stack.md)。

但這些方法僅驗證您範本的語法，而不會驗證您為資源指定的屬性數值。

**其他驗證工具**  
如需更複雜的驗證和最佳實務檢查，您可以使用下列其他工具：
+ [CloudFormation Linter (cfn-lint)](https://github.com/aws-cloudformation/cfn-lint) – 依據 [CloudFormation 資源提供者結構描述](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/resource-type-schemas.html)驗證範本。包括檢查資源屬性的有效值，以及最佳實務。
+ [CloudFormation Rain (rain fmt)](https://github.com/aws-cloudformation/rain) – 將您的 CloudFormation 範本格式化為一致的標準，或重新格式化從 JSON 到 YAML (或 YAML 到 JSON) 的範本。使用 YAML 時會保留註解，並在可行的情況下將內建函數切換為簡短語法。

## 開始使用範本
<a name="getting-started"></a>

若要開始建立 CloudFormation 範本，請遵循下列步驟：

1. **選擇資源** – 識別您要包含在堆疊中的 AWS 資源，例如 EC2 執行個體、VPCs、安全群組等。

1. **撰寫範本** – 以 JSON 或 YAML 格式撰寫範本，定義資源及其屬性。

1. **儲存範本** – 在本機使用副檔名儲存範本，例如：`.json`、`.yaml` 或 `.txt`。

1. **驗證範本** – 使用 [驗證範本](#template-validation) 章節所述的方法驗證範本。

1. **建立堆疊** – 使用經驗證的範本建立堆疊。

### 規劃使用 CloudFormation 範本參考
<a name="additional-resources"></a>

撰寫範本時，您可以在《[AWS 資源與屬性類型參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)》中，找到不同資源類型的詳細語法文件。

您的堆疊範本通常需要使用內建函數，指派執行時期才會可用的屬性數值，並使用特殊屬性控制資源的行為。撰寫範本時，可參考下列資源取得指引：
+ [內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html) – 常用的內建函數包括：
  + `Ref` - 擷取資源的參數值或實體 ID。
  + `Sub` – 將字串中的預留位置替換為實際數值。
  + `GetAtt` – 傳回範本中某項資源的屬性數值。
  + `Join` – 將一組數值串聯為單一字串。
+ [資源屬性參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-product-attribute-reference.html) – 部分常用的特殊屬性包括：
  + `DependsOn` - 使用此屬性以指定必須在另一項資源後建立的資源。
  + `DeletionPolicy` - 使用此屬性指定 CloudFormation 應如何處理刪除資源。

## 範例範本
<a name="sample-templates"></a>

CloudFormation 提供開放原始碼堆疊範本，供您入門使用。如需詳細資訊，請參閱 GitHub 網站上的 [CloudFormation 範例範本](https://github.com/aws-cloudformation/aws-cloudformation-templates)。

請注意，這些範本並非可用於正式環境的版本。您應花時間了解其運作方式、根據自身需求調整，並確保其符合公司的合規標準。

此儲存庫中的每個範本都會通過 [CloudFormation Linter](https://github.com/aws-cloudformation/cfn-lint) (cfn-lint) 檢查，以及以Center for Internet Security (CIS)前 20 為基礎的一組基本 AWS CloudFormation Guard 規則，但某些規則的例外是，在合理的情況下，讓範例專注於單一使用案例。

# CloudFormation 範本格式
<a name="template-formats"></a>

您可用 JSON 或 YAML 格式編寫 CloudFormation 範本。這兩種格式用途相同，但在可讀性和複雜度方面各有獨特優勢。
+ **JSON** – JSON 是一種輕量級資料交換格式，易於機器解析和生成。但對於人類而言，撰寫和閱讀可能較為繁瑣，尤其是在處理複雜組態時。在 JSON 中，範本透過巢狀的大括號 `{}` 和方括號 `[]` 來建構，以定義資源、參數及其他元件。其語法要求每個元素都必須明確宣告，這可能使範本較為冗長，但能確保嚴格遵循結構化格式。
+ **YAML** – YAML 設計初衷是比 JSON 更易於人類閱讀，且更精簡。它使用縮排而非括號來表示巢狀關係，能更直觀地呈現資源和參數的階層結構。YAML 因其清晰性和易用性而備受青睞，尤其在處理較複雜的範本時。但 YAML 依賴縮排，若間距不一致可能導致錯誤，因此需仔細留意以確保正確性。

## 範本結構
<a name="template-structure"></a>

CloudFormation 範本分為多個區段，每個區段用於存放特定類型的資訊。部分區段必須按特定順序宣告，其他區段則無順序要求。不過，在您建置範本時，使用下列範例所示的邏輯順排可能有幫助，因為某個區段中的值可能會參照先前區段中的值。

建立範本時，請勿重複宣告主要區段 (例如 `Resources` 區段)。雖然 CloudFormation 可能會接受範本，但在處理範本時會有未定義的行為，並且可能不正確地佈建資源或傳回莫名錯誤。

### JSON
<a name="template-structure.json"></a>

下列範例顯示包含所有可用區段的 JSON 格式範本結構。

```
{
  "AWSTemplateFormatVersion" : "version date",

  "Description" : "JSON string",

  "Metadata" : {
    template metadata
  },

  "Parameters" : {
    set of parameters
  },
  
  "Rules" : {
    set of rules
  },

  "Mappings" : {
    set of mappings
  },

  "Conditions" : {
    set of conditions
  },

  "Transform" : {
    set of transforms
  },

  "Resources" : {
    set of resources
  },
  
  "Outputs" : {
    set of outputs
  }
}
```

### YAML
<a name="template-structure.yaml"></a>

下列範例顯示包含所有可用區段的 YAML 格式範本結構。

```
---
AWSTemplateFormatVersion: version date

Description:
  String

Metadata:
  template metadata

Parameters:
  set of parameters

Rules:
  set of rules

Mappings:
  set of mappings

Conditions:
  set of conditions

Transform:
  set of transforms

Resources:
  set of resources

Outputs:
  set of outputs
```

## 說明
<a name="template-comments"></a>

JSON 格式的範本不支援註解。JSON 本身並未設計註解語法，因此您無法在 JSON 結構中直接新增註解。但如果您需要加入說明性備註或文件，可考慮新增中繼資料。如需詳細資訊，請參閱 [Metadata 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html)。

在 YAML 格式的範本中，您可以使用 `#` 符號加入行內註解。

以下範例示範有內嵌評論的 YAML 範本。

```
AWSTemplateFormatVersion: 2010-09-09
Description: A sample CloudFormation template with YAML comments.
# Resources section
Resources:
  MyEC2Instance: 
    Type: AWS::EC2::Instance
    Properties: 
      # Linux AMI
      ImageId: ami-1234567890abcdef0 
      InstanceType: t2.micro
      KeyName: MyKey
      BlockDeviceMappings:
        - DeviceName: /dev/sdm
          Ebs:
            VolumeType: io1
            Iops: 200
            DeleteOnTermination: false
            VolumeSize: 20
```

## 規格
<a name="template-formats.supported-specifications"></a>

CloudFormation 支援以下 JSON 和 YAML 規格：

JSON  
CloudFormation 遵循 ECMA-404 JSON 標準。如需 JSON 格式的詳細資訊，請參閱 [http://www.json.org](http://www.json.org)。

YAML  
CloudFormation 支援 YAML 1.1 版規格，但有幾個例外狀況。CloudFormation 不支援以下功能：  
+ `binary`、`omap`、`pairs`、`set` 和 `timestamp` 標籤
+ 別名
+ 雜湊合併
如需 YAML 的詳細資訊，請參閱 [https://yaml.org/](https://yaml.org/)。

## 進一步了解
<a name="template-formats.learnmore"></a>

對於您在範本中指定的每個資源，都需使用 JSON 或 YAML 的特定語法規則定義其屬性和值。如需每種格式之範本語法的詳細資訊，請參閱[CloudFormation 範本區段](template-anatomy.md)。

# 在 CloudFormation 範本中使用常規表達式
<a name="cfn-regexes"></a>

可以在 CloudFormation 範本的多個位置中使用規則表達式 (通常稱為 regexe)，例如建立範本[參數](parameters-section-structure.md)時可用於 `AllowedPattern` 屬性。

CloudFormation 中的所有規則表達式皆符合 Java regex 語法。如需 Java regex 語法及其建構的全面描述，請參閱 [java.util.regex.Pattern](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html)。

如果使用 JSON 語法撰寫 CloudFormation 範本，則必須新增額外的反斜線，以轉義規則表達式中的任何反斜線字元 (\$1)。這是因為 JSON 將反斜線解譯為轉義字元，而且您需要將其轉義，以確保其在規則表達式中被視為常值反斜線。

舉例來說，若您要在 JSON 範本的常規表達式中加入 `\d` 以比對數字字元，則必須將該字元編寫為 `\\d`。

在下列範例中，`AllowedPattern` 屬性會指定符合四個連續數字字元 (`\d{4}`) 的規則表達式。不過，由於在 JSON 範本中定義規則表達式，因此需要使用額外的反斜線 (`\\d`) 來轉義反斜線字元。

```
{
  "Parameters": {
    "MyParameter": {
      "Type": "String",
      "AllowedPattern": "\\d{4}"
    }
  }
}
```

如果使用 YAML 語法撰寫 CloudFormation 範本，則必須使用單引號 ('') 括住規則表達式。不需要額外的轉義。

```
Parameters:
  MyParameter:
    Type: String
    AllowedPattern: '\d{4}'
```

**注意**  
CloudFormation 中的規則表達式只能在特定內容中用於驗證，例如 `AllowedPattern`。不支援其作為 CloudFormation 內建函數中的模式比對操作，例如 `Fn::Equals`，其僅執行確切的字串比較，而非模式比對。

# CloudFormation 範本區段
<a name="template-anatomy"></a>

每個 CloudFormation 範本都包含一個或多個區段，每個區段都有特定用途。

**資源**區段是每個 CloudFormation 範本的必要項目，也是範本的核心。本節指定堆疊資源和其屬性，例如 Amazon EC2 執行個體或 Amazon S3 儲存貯體。每個資源都會以唯一的邏輯 ID、類型和特定設定詳細資訊來定義。

**參數**區段雖然是選用的，但在提升範本彈性方面扮演重要角色。它可讓使用者在建立或更新堆疊時於執行時期傳遞值。這些參數可在 `Resources` 和 `Outputs` 區段中參考，無需修改範本本身即可實現自訂。例如，您可使用參數指定不同部署之間會變更的執行個體類型或環境設定。

**輸出**同樣為選用，用於定義檢視堆疊屬性時傳回的值。輸出會提供資源識別碼或 URL 等實用資訊，可用於操作用途或與其他堆疊整合。此區段協助使用者擷取並使用範本建立之資源的重要詳細資訊。

其他選用區段包括**映射**，其功能類似查閱表格，用於管理條件值。透過映射，您可以定義索引鍵/值對，並將其與 `Resources` 和 `Outputs` 區段中的 `Fn::FindInMap` 內建函數搭配使用。這適用於您需要根據 AWS 區域 或 環境等條件調整組態的情況。

**中繼資料**和**規則**區段雖較少使用，但提供額外功能。`Metadata` 可包含有關範本的額外資訊，而 `Rules` 會在建立或更新堆疊時驗證單一參數或參數組合，確保其符合特定標準。**條件**區段透過根據環境類型等條件控制是否建立特定資源或為屬性指派值，進一步提升彈性。

最後，**轉換**區段可用於在範本處理期間套用巨集。對於無伺服器應用程式 （也稱為 Lambda 應用程式），它會指定要使用的[AWS 無伺服器應用程式模型 (AWS SAM)](https://github.com/awslabs/serverless-application-specification) 版本。當您指定轉換時，您可以使用 AWS SAM 語法來宣告範本中的資源。此模型定義您可以使用的語法及其處理方式。您也可以使用 `AWS::Include` 轉換，以包含與主要 CloudFormation 範本分開存放的範本程式碼片段。

下列主題提供了關於使用每個區段的更多資訊和範例。

**Topics**
+ [Resources](resources-section-structure.md)
+ [Parameters](parameters-section-structure.md)
+ [Outputs](outputs-section-structure.md)
+ [Mappings](mappings-section-structure.md)
+ [Metadata](metadata-section-structure.md)
+ [Rules](rules-section-structure.md)
+ [Conditions](conditions-section-structure.md)
+ [Transform](transform-section-structure.md)
+ [格式版本](format-version-structure.md)
+ [Description](template-description-structure.md)

# CloudFormation 範本 Resources 語法
<a name="resources-section-structure"></a>

`Resources` 區段是 CloudFormation 範本中所需的頂層區段。它會宣告您希望 CloudFormation 在堆疊中佈建和設定 AWS 的資源。

## 語法
<a name="resources-section-structure-syntax"></a>

`Resources` 區段使用下列語法：

### JSON
<a name="resources-section-structure-syntax.json"></a>

```
"Resources" : {
    "LogicalResourceName1" : {
        "Type" : "AWS::ServiceName::ResourceType",
        "Properties" : {
            "PropertyName1" : "PropertyValue1",
            ...
        }
    },

    "LogicalResourceName2" : {
        "Type" : "AWS::ServiceName::ResourceType",
        "Properties" : {
            "PropertyName1" : "PropertyValue1",
            ...
        }
    }
}
```

### YAML
<a name="resources-section-structure-syntax.yaml"></a>

```
Resources:
  LogicalResourceName1:
    Type: AWS::ServiceName::ResourceType
    Properties:
      PropertyName1: PropertyValue1
      ...

  LogicalResourceName2:
    Type: AWS::ServiceName::ResourceType
    Properties:
      PropertyName1: PropertyValue1
      ...
```

## 邏輯 ID (也稱為*邏輯名稱*)
<a name="resources-section-logical-id"></a>

在 CloudFormation 範本內，資源會以其邏輯資源名稱來識別。這些名稱必須是英數字元 (A-Za-z0-9)，而且在範本內必須是唯一的。邏輯名稱可用於參考範本其他區段的資源。

## Resource Type (資源類型)
<a name="resources-section-resource-type"></a>

每個資源必須有 `Type` 屬性，以定義該 AWS 資源的種類。`Type` 屬性擁有的格式為 `AWS::ServiceName::ResourceType`。例如，Amazon S3 儲存貯體的 `Type` 屬性為 `AWS::S3::Bucket`。

如需受支援資源類型的完整清單，請參閱 [AWS 資源和屬性類型參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)。

## 資源屬性
<a name="resources-section-resource-properties"></a>

資源屬性是您可指定的其他選項，用於定義特定資源類型的組態詳細資訊。有些屬性是必要的，有些則為選用。某些屬性具有預設值，因此指定這些屬性為選用。

如需每個資源類型所支援屬性的詳細資訊，請參閱《[AWS 資源和屬性類型參考》](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)中的主題。

屬性值可以是常值字串、字串清單、動態參考、布林值、參數參考、虛擬參考，或函數所傳回的值。下列範例顯示如何宣告不同的屬性值類型：

### JSON
<a name="resource-properties-example.json"></a>

```
"Properties" : {
    "String" : "A string value",
    "Number" : 123,
    "LiteralList" : [ "first-value", "second-value" ],
    "Boolean" : true
}
```

### YAML
<a name="resource-properties-example.yaml"></a>

```
Properties:
  String: A string value 
  Number: 123
  LiteralList:
    - first-value
    - second-value
  Boolean: true
```

## 實體 ID
<a name="resources-section-physical-id"></a>

除了邏輯 ID 之外，特定資源也會有實體 ID，這是該資源的實際指派名稱 (例如 EC2 執行個體 ID 或 S3 儲存貯體名稱)。使用實體 ID 來識別 CloudFormation 範本外部的資源，但只在建立資源之後。例如，假設您為 EC2 執行個體資源指定邏輯 ID `MyEC2Instance`。當 CloudFormation 建立執行個體時，CloudFormation 會自動產生並指派實體 ID (例如 `i-1234567890abcdef0`) 給執行個體。您可以使用此實體 ID 來識別執行個體，以及使用 Amazon EC2 主控台來檢視其屬性 (例如 DNS 名稱)。

對於 Amazon S3 儲存貯體及許多其他資源，若您未明確指定，CloudFormation 會自動為資源產生唯一的實體名稱。此實體名稱基於 CloudFormation 堆疊的名稱、CloudFormation 範本中指定的資源邏輯名稱，以及唯一 ID 的組合。例如，若您的 Amazon S3 儲存貯體在名為 `MyStack` 的堆疊中具有邏輯名稱 `MyBucket`，CloudFormation 可能會將儲存貯體命名為下列實體名稱 `MyStack-MyBucket-abcdefghijk1`。

針對支援自訂名稱的資源，您可以指派自己的實體名稱，協助您快速識別資源。例如，您可以將存放日誌的 S3 儲存貯體命名為 `MyPerformanceLogs`。如需詳細資訊，請參閱[名稱類型](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-name.html)。

## 參考資源
<a name="using-cross-resource-references"></a>

您通常需要根據另一個資源的名稱或屬性，設定某個資源的屬性。例如，您可建立使用 EC2 安全群組的 EC2 執行個體，或 S3 儲存貯體支援的 CloudFront 分佈。所有這些資源都可在相同的 CloudFormation 範本中建立。

CloudFormation 提供內建函數，您可以用來參考其他資源及其屬性。這些函數可讓您在資源之間建立相依關係，並將值從一個資源傳遞到另一個資源。

### `Ref` 函數
<a name="resource-properties-ref"></a>

`Ref` 函數通常用於擷取相同 CloudFormation 範本中所定義資源的識別屬性。傳回的內容要取決於資源的類型。對於大多數資源，它會傳回資源的實體名稱。然而，對於某些資源類型，它可能會傳回不同的值，例如 `AWS::EC2::EIP` 資源的 IP 位址或 Amazon SNS 主題的 Amazon Resource Name (ARN)。

以下範例會示範屬性中 `Ref` 函數的使用方式。在每個範例中，`Ref` 函數會傳回範本中其他位置所宣告 `LogicalResourceName` 資源的實際名稱。YAML 範例中的 `!Ref` 語法範例只是撰寫 `Ref` 函數的較短方式。

#### JSON
<a name="resource-properties-ref-example.json"></a>

```
"Properties" : {
    "PropertyName" : { "Ref" : "LogicalResourceName" }
}
```

#### YAML
<a name="resource-properties-ref-example.yaml"></a>

```
Properties:
  PropertyName1:
    Ref: LogicalResourceName
  PropertyName2: !Ref LogicalResourceName
```

如需 `Ref` 函數的詳細資訊，請參閱 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-ref.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-ref.html)。

### `Fn::GetAtt` 函數
<a name="resource-properties-getatt"></a>

如果為資源傳回的參數或值完全是您想要的，`Ref` 函數會很有幫助。不過，您可能會需要資源的其他屬性。例如，如果您想要建立有 S3 來源的 CloudFront 分佈，您需要使用 DNS 樣式地址指定儲存貯體位置。多項有其他屬性的資源，其值可用於範本中。您可以使用 `Fn::GetAtt` 函數取得這些屬性。

以下範例會示範屬性中 `GetAtt` 函數的使用方式。`Fn::GetAtt` 函數需要兩個參數擷取資源邏輯名稱及屬性名稱。YAML 範例中的 `!GetAtt` 語法範例只是撰寫 `GetAtt` 函數的較短方式。

#### JSON
<a name="resource-properties-getatt-example.json"></a>

```
"Properties" : {
    "PropertyName" : {
        "Fn::GetAtt" : [ "LogicalResourceName", "AttributeName" ]
    }
}
```

#### YAML
<a name="resource-properties-getatt-example.yaml"></a>

```
Properties:
  PropertyName1:
    Fn::GetAtt:
      - LogicalResourceName
      - AttributeName
  PropertyName2: !GetAtt LogicalResourceName.AttributeName
```

如需 `GetAtt` 函數的詳細資訊，請參閱 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-getatt.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-getatt.html)。

## 範例
<a name="resources-section-structure-examples"></a>

下列範例說明如何宣告資源，以及 CloudFormation 範本如何參考定義在相同範本中的其他資源，以及現有的 AWS 資源。

**Topics**
+ [宣告具有自訂名稱的單一資源](#resources-section-structure-examples-single-resource)
+ [使用 `Ref` 函數參考其他資源](#resources-section-structure-examples-ref)
+ [透過 `Fn::GetAtt` 函數參考資源屬性](#resources-section-structure-examples-getatt)

### 宣告具有自訂名稱的單一資源
<a name="resources-section-structure-examples-single-resource"></a>

以下範例會宣告邏輯名稱為 `MyBucket` 的 `AWS::S3::Bucket` 類型單一資源。`BucketName` 屬性設定為 *amzn-s3-demo-bucket*，您應以 S3 儲存貯體所需的名稱取代。

若您使用此資源宣告來建立堆疊，CloudFormation 將使用預設設定建立 Amazon S3 儲存貯體。至於 Amazon EC2 執行個體或 Auto Scaling 群組等其他資源，CloudFormation 需要更多資訊。

#### JSON
<a name="resources-section-structure-examples-single-resource.json"></a>

```
{
    "Resources": {
        "MyBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": "amzn-s3-demo-bucket"
            }
        }
    }
}
```

#### YAML
<a name="resources-section-structure-examples-single-resource.yaml"></a>

```
Resources:
  MyBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: amzn-s3-demo-bucket
```

### 使用 `Ref` 函數參考其他資源
<a name="resources-section-structure-examples-ref"></a>

下列範例顯示定義 EC2 執行個體與安全群組的資源宣告。`Ec2Instance` 資源會使用 `Ref` 函數參考 `InstanceSecurityGroup` 資源，做為其 `SecurityGroupIds` 屬性的一部分。它還包含了範本中未宣告的現有安全群組 (`sg-12a4c434`)。您要使用文字字串參考現有的 AWS 資源。

#### JSON
<a name="resources-section-structure-examples-ref.json"></a>

```
{
    "Resources": {
        "Ec2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "SecurityGroupIds": [
                    {
                        "Ref": "InstanceSecurityGroup"
                    },
                    "sg-12a4c434"
                ],
                "KeyName": "MyKey",
                "ImageId": "ami-1234567890abcdef0"
            }
        },
        "InstanceSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 22,
                        "ToPort": 22,
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        }
    }
}
```

#### YAML
<a name="resources-section-structure-examples-ref.yaml"></a>

```
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
        - sg-12a4c434
      KeyName: MyKey
      ImageId: ami-1234567890abcdef0
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
```

### 透過 `Fn::GetAtt` 函數參考資源屬性
<a name="resources-section-structure-examples-getatt"></a>

下列範例顯示定義 CloudFront 分佈資源及 S3 儲存貯體的資源宣告。`MyDistribution` 資源會使用 `Fn::GetAtt` 函數取得儲存貯體的 `DomainName` 屬性，以指定 `MyBucket` 資源的 DNS 名稱。您要通知 `Fn::GetAtt` 函數在陣列中列出它的兩個參數。對於需要多個參數的函數，您使用陣列指定它們的參數。

#### JSON
<a name="resources-section-structure-examples-getatt.json"></a>

```
{
  "Resources": {
    "MyBucket": {
      "Type": "AWS::S3::Bucket"
    },
    "MyDistribution": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Origins": [
            {
              "DomainName": {
                "Fn::GetAtt": [
                  "MyBucket",
                  "DomainName"
                ]
              },
              "Id": "MyS3Origin",
              "S3OriginConfig": {}
            }
          ],
          "Enabled": "true",
          "DefaultCacheBehavior": {
            "TargetOriginId": "MyS3Origin",
            "ForwardedValues": {
              "QueryString": "false"
            },
            "ViewerProtocolPolicy": "allow-all"
          }
        }
      }
    }
  }
}
```

#### YAML
<a name="resources-section-structure-examples-getatt.yaml"></a>

```
Resources:
  MyBucket:
    Type: AWS::S3::Bucket
  MyDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
          - DomainName: !GetAtt 
              - MyBucket
              - DomainName
            Id: MyS3Origin
            S3OriginConfig: {}
        Enabled: 'true'
        DefaultCacheBehavior:
          TargetOriginId: MyS3Origin
          ForwardedValues:
            QueryString: 'false'
          ViewerProtocolPolicy: allow-all
```

# CloudFormation 範本 Parameters 語法
<a name="parameters-section-structure"></a>

使用選用的 `Parameters` 區段自訂您的範本。透過參數，您可以在每次建立或更新堆疊時將自訂值輸入至您的範本。透過在範本中使用參數，您能夠建立可重複使用且靈活的範本，這些範本可針對特定案例量身打造。

透過定義適當類型的參數，您可在使用主控台建立堆疊時，從現有資源的識別碼清單中選擇。如需詳細資訊，請參閱[使用 CloudFormation 提供的參數類型，在執行時期指定現有資源](cloudformation-supplied-parameter-types.md)。

參數是指定堆疊資源屬性值的常用方式。但是，有些設定可能依存於區域，或有些複雜，讓使用者因其他條件或依存項目而無法找出。在這些情況下，您可能要在範本本身中放入一些邏輯，讓使用者可以指定簡單的值 (或完全不指定)，以取得他們希望的結果，如透過映射來實現。如需詳細資訊，請參閱[CloudFormation 範本 Mappings 語法](mappings-section-structure.md)。

## 語法
<a name="parameters-section-structure-syntax"></a>

您可在範本的 `Parameters` 區段中宣告參數，該區段使用下列一般語法：

### JSON
<a name="parameters-section-structure-syntax.json"></a>

```
"Parameters" : {
  "ParameterLogicalID" : {
    "Description": "Information about the parameter",
    "Type" : "DataType",
    "Default" : "value",
    "AllowedValues" : ["value1", "value2"]
  }
}
```

### YAML
<a name="parameters-section-structure-syntax.yaml"></a>

```
Parameters:
  ParameterLogicalID:
    Description: Information about the parameter
    Type: DataType
    Default: value
    AllowedValues:
      - value1
      - value2
```

參數包含定義其值的屬性清單以及針對其值的限制條件。唯一的必要屬性是 `Type`，可以是 `String`、`Number` 或 CloudFormation 提供的參數類型。您也可以新增 `Description` 屬性，描述您應該指定的值類型。您使用**建立堆疊**精靈中的範本時，**指定參數**頁面上會出現參數的名稱和描述。

**注意**  
根據預設，CloudFormation 主控台會依據參數的邏輯 ID 字母順序來列出參數。若要覆寫此預設排序，並將相關參數分組在一起，您可在範本中使用 `AWS::CloudFormation::Interface` 中繼資料金鑰。如需詳細資訊，請參閱[使用 `AWS::CloudFormation::Interface` 中繼資料組織 CloudFormation 參數](aws-cloudformation-interface.md)。

針對有預設值的參數，除非使用者指定另一個值，否則 CloudFormation 會使用預設值。若您省略預設屬性，使用者必須指定該參數的值。但是，要求使用者輸入值並不能確保該值有效。若要驗證參數的值，您可以宣告限制條件或指定 AWS特定的參數類型。

對於沒有預設值的參數，使用者必須在建立堆疊時，指定金鑰名稱值。否則，CloudFormation 無法建立堆疊，且會擲出例外狀況：

```
Parameters: [KeyName] must have values
```

## Properties
<a name="parameters-section-structure-properties"></a>

`AllowedPattern`  
規則表達式，代表 `String` 或 `CommaDelimitedList` 類型允許的模式。當套用於類型 `String` 參數時，模式必須匹配提供的整個參數值。當套用於類型 `CommaDelimitedList` 參數時，模式必須匹配清單中的每個值。  
*必要*：否

`AllowedValues`  
陣列，包含參數的允許值清單。當套用於類型 `String` 參數時，參數值必須是允許值之一。當套用於類型 `CommaDelimitedList` 參數時，清單中的每個值必須是指定的允許值之一。  
*必要*：否  
如果您使用 YAML，並且想要將 `Yes` 和 `No` 字串用於 `AllowedValues`，請使用單引號來防止 YAML 剖析器考慮這些布林值。

`ConstraintDescription`  
字串，說明違反限制時的限制。例如，具有允許模式 `[A-Za-z0-9]+` 的參數會在使用者指定無效值時顯示下列錯誤訊息，但沒有限制描述：  
`Malformed input-Parameter MyParameter must match pattern [A-Za-z0-9]+`  
透過新增限制描述，例如*只能包含字母 (大寫和小寫) 及數字*，您可以顯示下列自訂錯誤訊息：  
`Malformed input-Parameter MyParameter must only contain uppercase and lowercase letters and numbers`  
*必要*：否

`Default`  
建立堆疊時，範本要在未指定值時使用的適當類型值。如果您定義參數的限制，則必須指定遵循這些限制的值。  
*必要*：否

`Description`  
多達 4000 個字元的字串，可說明參數。  
*必要*：否

`MaxLength`  
整數值，決定您想要針對 `String` 類型允許的最大字元數。  
*必要*：否

`MaxValue`  
數值，決定您想要針對 `Number` 類型允許的最大數值。  
*必要*：否

`MinLength`  
整數值，決定您想要針對 `String` 類型允許的最小字元數。  
*必要*：否

`MinValue`  
數值，決定您想要針對 `Number` 類型允許的最小數值。  
*必要*：否

`NoEcho`  
是否遮罩參數值以防止其在主控台、命令列工具或 API 中顯示。若您將 `NoEcho` 屬性設為 `true`，CloudFormation 會將任何描述堆疊或堆疊事件呼叫所傳回的參數值以星號 (\$1\$1\$1\$1\$1) 遮罩，但儲存在以下指定位置中的資訊除外。  
*必要*：否  
使用 `NoEcho` 屬性不會遮罩任何儲存在下列資訊中的資訊：  
+ `Metadata` 範本區段。CloudFormation 不會轉換、修改或標記您在 `Metadata` 區段中包含的任何資訊。若要取得更多資訊，請參閱[中繼資料](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html)。
+ `Outputs` 範本區段。如需詳細資訊，請參閱[輸出](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)。
+ 資源定義的 `Metadata` 屬性。如需詳細資訊，請參閱 [`Metadata` 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html)。
我們強烈建議您不要使用這些機制來包含敏感資訊，例如密碼或秘密。
我們建議您不要直接在 CloudFormation 範本中嵌入敏感資訊，而是在堆疊範本中使用動態參數來參考在 CloudFormation 外部存放和管理的敏感資訊，例如在 AWS Systems Manager 參數存放區或 中 AWS Secrets Manager。  
如需詳細資訊，請參閱[請勿在範本中內嵌認證](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/security-best-practices.html#creds)的最佳實務。
強烈建議不要在作為資源主要識別碼一部分的資源屬性中包含 `NoEcho` 參數或任何敏感資料。  
形成主要資源識別碼的屬性中包含 `NoEcho` 參數時，CloudFormation 可使用主要資源識別碼中的*實際純文字值*。此資源 ID 可能會出現在任何衍生輸出或目的地中。  
若要判斷哪些資源屬性組成資源類型的主要識別碼，請參閱 [AWS 資源和屬性類型參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)中該資源的資源參考文件。在 **Return values** (傳回值) 區段中，`Ref` 函數傳回值表示組成資源類型主要識別碼的資源屬性。

`Type`  <a name="parameters-section-structure-properties-type"></a>
參數的資料類型 (`DataType`)。  
*必要*：是  
CloudFormation 支援下列參數類型：    
`String`  
常值字串。您可以使用下列屬性宣告限制條件：`MinLength`、`MaxLength`、`Default`、`AllowedValues` 和 `AllowedPattern`。  
例如，使用者可以指定 `"MyUserName"`。  
`Number`  
整數或浮點數。CloudFormation 會將參數值驗證為數字；不過，當您在範本中的其他位置使用參數時 (例如，使用 `Ref` 內建函數)，參數值會變成字串。  
您可以使用下列屬性宣告限制條件：`MinValue`、`MaxValue`、`Default` 和 `AllowedValues`。  
例如，使用者可以指定 `"8888"`。  
`List<Number>`  
以逗號分隔的整數或浮點數陣列。CloudFormation 會將參數值驗證為數字；不過，當您在範本中的其他位置使用參數時 (例如，使用 `Ref` 內建函數)，參數值會變成字串清單。  
例如，使用者可以指定 `"80,20"`，而 `Ref` 會產生 `["80","20"]`。  
`CommaDelimitedList`  
以逗號分隔的常值字串陣列。字串總數應該比逗號總數多一個。此外，還會裁剪每個成員字串的空格。  
例如，使用者可以指定 `"test,dev,prod"`，而 `Ref` 會產生 `["test","dev","prod"]`。  
AWS特定參數類型  
AWS 值，例如 Amazon EC2 金鑰對名稱和 VPC IDs。如需詳細資訊，請參閱[在執行時期指定現有資源](cloudformation-supplied-parameter-types.md)。  
Systems Manager 參數類型  
對應至 Systems Manager 參數存放區中現有參數的參數。您可以將 Systems Manager 參數索引鍵指定為 Systems Manager 參數類型的值，而 CloudFormation 會擷取參數存放區中的最新值來用於堆疊。如需詳細資訊，請參閱[在執行時期指定現有資源](cloudformation-supplied-parameter-types.md)。

## 參數的一般要求
<a name="parameters-section-structure-requirements"></a>

以下是使用參數時適用的要求：
+ CloudFormation 範本中最多可以有 200 個參數。
+ 每個參數都必須獲指定邏輯名稱 (也稱為邏輯 ID)，其必須為英數字元，而且在範本的所有邏輯名稱之間必須是唯一的。
+ 每個參數都必須獲指派 CloudFormation 所支援的參數類型。如需詳細資訊，請參閱[類型](#parameters-section-structure-properties-type)。
+ 每個參數在執行時期都必須獲指派值，以讓 CloudFormation 成功佈建堆疊。除非提供另一個值，否則您可以選擇性指定預設值以供 CloudFormation 使用。
+ 參數必須在相同的範本內宣告和參考。您可以參考範本之 `Resources` 和 `Outputs` 區段中的參數。

## 範例
<a name="parameters-section-examples"></a>

**Topics**
+ [簡單字串參數](#parameters-section-structure-example-1)
+ [密碼參數](#parameters-section-structure-example-2)
+ [參考參數](#parameters-section-structure-example-3)
+ [逗號分隔清單參數](#parameters-section-structure-example-4)
+ [逗號分隔清單參數的傳回值](#parameters-section-structure-example-5)

### 簡單字串參數
<a name="parameters-section-structure-example-1"></a>

下列範例宣告類型 `String` 名為 `InstanceTypeParameter` 的參數。此參數可讓您指定堆疊的 Amazon EC2 執行個體類型。若在堆疊建立或更新期間未提供任何值，CloudFormation 會使用預設值 `t2.micro`。

#### JSON
<a name="parameters-section-structure-example-1.json"></a>

```
"Parameters" : {
  "InstanceTypeParameter" : {
    "Description" : "Enter t2.micro, m1.small, or m1.large. Default is t2.micro.",
    "Type" : "String",
    "Default" : "t2.micro",
    "AllowedValues" : ["t2.micro", "m1.small", "m1.large"]
  }
}
```

#### YAML
<a name="parameters-section-structure-example-1.yaml"></a>

```
Parameters:
  InstanceTypeParameter:
    Description: Enter t2.micro, m1.small, or m1.large. Default is t2.micro.
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - m1.small
      - m1.large
```

### 密碼參數
<a name="parameters-section-structure-example-2"></a>

下列範例宣告類型 `String` 名為 `DBPwd` 的參數，沒有預設值。`NoEcho` 屬性設定為 `true`，以防止參數值在堆疊描述中顯示。可指定的最小長度為 `1`，而可指定的最大長度為 `41`。此模式允許大小寫字母字元和數字。此範例也說明 `AllowedPattern` 屬性使用規則表達式。

#### JSON
<a name="parameters-section-structure-example-2.json"></a>

```
"Parameters" : {
  "DBPwd" : {
    "NoEcho" : "true",
    "Description" : "The database admin account password",
    "Type" : "String",
    "MinLength" : "1",
    "MaxLength" : "41",
    "AllowedPattern" : "^[a-zA-Z0-9]*$"
  }
}
```

#### YAML
<a name="parameters-section-structure-example-2.yaml"></a>

```
Parameters: 
  DBPwd: 
    NoEcho: true
    Description: The database admin account password
    Type: String
    MinLength: 1
    MaxLength: 41
    AllowedPattern: ^[a-zA-Z0-9]*$
```

### 參考參數
<a name="parameters-section-structure-example-3"></a>

您可以使用 `Ref` 內建函數來參考參數，而 CloudFormation 使用參數值來佈建堆疊。您可以參考相同範本之 `Resources` 和 `Outputs` 區段中的參數。

在下列範例中，EC2 執行個體資源的 `InstanceType` 屬性參考 `InstanceTypeParameter` 參數值：

#### JSON
<a name="parameters-section-structure-example-3.json"></a>

```
"Ec2Instance" : {
  "Type" : "AWS::EC2::Instance",
  "Properties" : {
    "InstanceType" : { "Ref" : "InstanceTypeParameter" },
    "ImageId" : "ami-0ff8a91507f77f867"
  }
}
```

#### YAML
<a name="parameters-section-structure-example-3.yaml"></a>

```
Ec2Instance:
  Type: AWS::EC2::Instance
  Properties:
    InstanceType:
      Ref: InstanceTypeParameter
    ImageId: ami-0ff8a91507f77f867
```

### 逗號分隔清單參數
<a name="parameters-section-structure-example-4"></a>

當您需要為單一屬性提供多個值時，`CommaDelimitedList` 參數類型會非常實用。下列範例宣告名為 `DbSubnetIpBlocks` 的參數，預設值為三個以逗號分隔的 CIDR 區塊。

#### JSON
<a name="parameters-section-structure-example-4.json"></a>

```
"Parameters" : {
  "DbSubnetIpBlocks": {
    "Description": "Comma-delimited list of three CIDR blocks",
    "Type": "CommaDelimitedList",
    "Default": "10.0.48.0/24, 10.0.112.0/24, 10.0.176.0/24"
  }
}
```

#### YAML
<a name="parameters-section-structure-example-4.yaml"></a>

```
Parameters: 
  DbSubnetIpBlocks: 
    Description: "Comma-delimited list of three CIDR blocks"
    Type: CommaDelimitedList
    Default: "10.0.48.0/24, 10.0.112.0/24, 10.0.176.0/24"
```

### 逗號分隔清單參數的傳回值
<a name="parameters-section-structure-example-5"></a>

若要參照的逗號分隔清單中的特定值，請在範本的 `Fn::Select` 區段中使用 `Resources` 內建函數。傳遞所要之物件的索引值和物件清單，如下列範例所示。

#### JSON
<a name="parameters-section-structure-example-5.json"></a>

```
{
    "Parameters": {
        "VPC": {
            "Type": "String",
            "Default": "vpc-123456"
        },
        "VpcAzs": {
            "Type": "CommaDelimitedList",
            "Default": "us-west-2a, us-west-2b, us-west-2c"
        },
        "DbSubnetIpBlocks": {
            "Type": "CommaDelimitedList",
            "Default": "172.16.0.0/26, 172.16.0.64/26, 172.16.0.128/26"
        }
    },
    "Resources": {
        "DbSubnet1": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Fn::Select": [
                      0,
                      { 
                        "Ref": "VpcAzs" 
                      }
                   ]
                },
                "VpcId": {
                    "Ref": "VPC"
                },
                "CidrBlock": {
                    "Fn::Select": [
                        0,
                        { "Ref": "DbSubnetIpBlocks" }
                    ]
                }
            }
        },
        "DbSubnet2": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Fn::Sub": [
                        "${AWS::Region}${AZ}",
                        {
                            "AZ": {
                                "Fn::Select": [
                                    1,
                                    { "Ref": "VpcAzs" }
                                ]
                            }
                        }
                    ]
                },
                "VpcId": {
                    "Ref": "VPC"
                },
                "CidrBlock": {
                    "Fn::Select": [
                        1,
                        { "Ref": "DbSubnetIpBlocks" }
                    ]
                }
            }
        },
        "DbSubnet3": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "AvailabilityZone": {
                    "Fn::Sub": [
                        "${AWS::Region}${AZ}",
                        {
                            "AZ": {
                                "Fn::Select": [
                                    2,
                                    { "Ref": "VpcAzs" }
                                ]
                            }
                        }
                    ]
                },
                "VpcId": {
                    "Ref": "VPC"
                },
                "CidrBlock": {
                    "Fn::Select": [
                        2,
                        { "Ref": "DbSubnetIpBlocks" }
                    ]
                }
            }
        }
    }
}
```

#### YAML
<a name="parameters-section-structure-example-5.yaml"></a>

```
Parameters:
  VPC:
    Type: String
    Default: vpc-123456
  VpcAzs:
    Type: CommaDelimitedList
    Default: us-west-2a, us-west-2b, us-west-2c
  DbSubnetIpBlocks:
    Type: CommaDelimitedList
    Default: 172.16.0.0/26, 172.16.0.64/26, 172.16.0.128/26
Resources:
  DbSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select
        - 0 
        - !Ref VpcAzs
      VpcId: !Ref VPC
      CidrBlock: !Select
        - 0
        - !Ref DbSubnetIpBlocks
  DbSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Sub
        - ${AWS::Region}${AZ}
        - AZ: !Select
            - 1
            - !Ref VpcAzs
      VpcId: !Ref VPC
      CidrBlock: !Select
        - 1
        - !Ref DbSubnetIpBlocks
  DbSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Sub
        - ${AWS::Region}${AZ}
        - AZ: !Select
            - 2
            - !Ref VpcAzs
      VpcId: !Ref VPC
      CidrBlock: !Select
        - 2
        - !Ref DbSubnetIpBlocks
```

## 相關資源
<a name="parameters-section-structure-related-resources"></a>

CloudFormation 也支援使用動態參考來動態指定屬性值。例如，您可能需要參考在 Systems Manager 參數存放區中儲存的安全字串。如需詳細資訊，請參閱[使用動態參考取得存放在其他服務中的值](dynamic-references.md)。

您也可以在 `Ref` 或 `Sub` 函數中，使用虛擬參數來動態填入值。如需詳細資訊，請參閱[使用虛擬參數取得 AWS 值](pseudo-parameter-reference.md)。

# CloudFormation 範本 Outputs 語法
<a name="outputs-section-structure"></a>

選用 `Outputs` 區段會宣告堆疊的輸出值。這些輸出值可透過多種方式使用：
+ **擷取資源的重要詳細資訊** – 輸出是擷取資源重要資訊的便捷方式。例如，您可以輸出堆疊的 S3 儲存貯體名稱，以更輕鬆地找到儲存貯體。您可以在 CloudFormation 主控台的**輸出**索引標籤中檢視輸出值，或使用 [describe-stacks](service_code_examples.md#describe-stacks-sdk) CLI 命令檢視輸出值。
+ **跨堆疊參考** – 您可以將輸出值匯入其他堆疊，以[在堆疊之間建立參考](using-cfn-stack-exports.md)。這在您需要跨多個堆疊共用資源或組態時相當實用。

**重要**  
CloudFormation 不會對您在 `Outputs` 區段中包含的任何資訊進行修改或混淆。我們強烈建議您不要使用此區段來輸出敏感資訊，例如密碼或秘密。  
堆疊操作完成後，可使用輸出值。堆疊狀態處於任何 `IN_PROGRESS` [狀態](view-stack-events.md#cfn-console-view-stack-data-resources-status-codes)時，堆疊輸出值將不可用。我們不建議在服務執行階段和堆疊輸出值之間建立相依性，因為輸出值可能無法在任何時候都可用。

## 語法
<a name="outputs-section-syntax"></a>

`Outputs` 區段由索引鍵名稱 `Outputs` 組成。您最多可以在範本中宣告 200 個輸出。

下列範例示範 `Outputs` 區段的結構。

### JSON
<a name="outputs-section-structure-syntax.json"></a>

使用括號括住所有輸出宣告。使用逗號分隔多個輸出。

```
"Outputs" : {
  "OutputLogicalID" : {
    "Description" : "Information about the value",
    "Value" : "Value to return",
    "Export" : {
      "Name" : "Name of resource to export"
    }
  }
}
```

### YAML
<a name="outputs-section-structure-syntax.yaml"></a>

```
Outputs:
  OutputLogicalID:
    Description: Information about the value
    Value: Value to return
    Export:
      Name: Name of resource to export
```

### 輸出欄位
<a name="outputs-section-structure-output-fields"></a>

`Outputs` 區段可以包含下列欄位。

**邏輯 ID (也稱為*邏輯名稱*)**  
目前輸出的識別碼。邏輯 ID 必須是英數字元 (`a–z`、`A–Z`、`0–9`)，而且在範本內必須是唯一的。

**`Description` (選用)**  
`String` 類型，說明輸出值。描述宣告值的長度必須是介於 0 與 1024 位元組之間的常值字串。您不能使用參數或函數來指定描述。

**`Value` (必要)**  
[describe-stacks](service_code_examples.md#describe-stacks-sdk) 命令所傳回的屬性值。輸出值可以包含常值、參數參考、虛擬參數、映射值或內建函數。

**`Export` (選用)**  
要針對跨堆疊參考匯出的資源輸出名稱。  
您可以使用內部函數來自訂匯出的 `Name` 值。  
如需詳細資訊，請參閱[從部署的 CloudFormation 堆疊取得匯出的輸出](using-cfn-stack-exports.md)。

若要建立條件與輸出的關聯，請在範本的 [Conditions](conditions-section-structure.md) 區段中定義條件。

## 範例
<a name="outputs-section-structure-examples"></a>

下列範例說明堆疊輸出的運作方式。

**Topics**
+ [堆疊輸出](#outputs-section-structure-examples-stack-output)
+ [使用 `Fn::Sub` 自訂匯出名稱](#outputs-section-structure-examples-cross-stack)
+ [使用 `Fn::Join` 自訂匯出名稱](#outputs-section-structure-examples-join-export-name)
+ [傳回使用 `Fn::Join` 建構的 URL](#outputs-section-structure-examples-join-export-url)

### 堆疊輸出
<a name="outputs-section-structure-examples-stack-output"></a>

在下列範例中，只有在 `BackupLoadBalancerDNSName` 條件為 true 時，名為 `BackupLoadBalancer` 的輸出才會傳回邏輯 ID 為 `CreateProdResources` 之資源的 DNS 名稱 名為 `InstanceID` 的輸出會傳回邏輯 ID 為 `EC2Instance` 之 EC2 執行個體的 ID。

#### JSON
<a name="outputs-section-structure-example.json"></a>

```
"Outputs" : {
  "BackupLoadBalancerDNSName" : {
    "Description": "The DNSName of the backup load balancer",  
    "Value" : { "Fn::GetAtt" : [ "BackupLoadBalancer", "DNSName" ]},
    "Condition" : "CreateProdResources"
  },
  "InstanceID" : {
    "Description": "The Instance ID",  
    "Value" : { "Ref" : "EC2Instance" }
  }
}
```

#### YAML
<a name="outputs-section-structure-example.yaml"></a>

```
Outputs:
  BackupLoadBalancerDNSName:
    Description: The DNSName of the backup load balancer
    Value: !GetAtt BackupLoadBalancer.DNSName
    Condition: CreateProdResources
  InstanceID:
    Description: The Instance ID
    Value: !Ref EC2Instance
```

### 使用 `Fn::Sub` 自訂匯出名稱
<a name="outputs-section-structure-examples-cross-stack"></a>

在下列範例中，名為 `StackVPC` 的輸出會傳回 VPC 的 ID，然後匯出跨堆疊參考的值，亦即將名稱 `VPCID` 附加至堆疊名稱。

#### JSON
<a name="outputs-section-structure-cross-stack-example.json"></a>

```
"Outputs" : {
  "StackVPC" : {
    "Description" : "The ID of the VPC",
    "Value" : { "Ref" : "MyVPC" },
    "Export" : {
      "Name" : {"Fn::Sub": "${AWS::StackName}-VPCID" }
    }
  }
}
```

#### YAML
<a name="outputs-section-structure-cross-stack-example.yaml"></a>

```
Outputs:
  StackVPC:
    Description: The ID of the VPC
    Value: !Ref MyVPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCID"
```

如需 `Fn::Sub` 函數的詳細資訊，請參閱「[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html)」。

### 使用 `Fn::Join` 自訂匯出名稱
<a name="outputs-section-structure-examples-join-export-name"></a>

您還可以使用 `Fn::Join` 函數根據參數、資源屬性和其他字串來建構值。

下列範例使用 `Fn::Join` 函數來自訂匯出名稱，而非 `Fn::Sub` 函數。範例 `Fn::Join` 函數使用冒號做為分隔符號，將堆疊名稱與名稱 `VPCID` 串連。

#### JSON
<a name="outputs-section-structure-join-export-name-example.json"></a>

```
"Outputs" : {
  "StackVPC" : {
    "Description" : "The ID of the VPC",
    "Value" : { "Ref" : "MyVPC" },
    "Export" : {
      "Name" : { "Fn::Join" : [ ":", [ { "Ref" : "AWS::StackName" }, "VPCID" ] ] }
    }
  }
}
```

#### YAML
<a name="outputs-section-structure-join-export-name-example.yaml"></a>

```
Outputs:
  StackVPC:
    Description: The ID of the VPC
    Value: !Ref MyVPC
    Export:
      Name: !Join [ ":", [ !Ref "AWS::StackName", VPCID ] ]
```

如需 `Fn::Join` 函數的詳細資訊，請參閱「[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-join.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-join.html)」。

### 傳回使用 `Fn::Join` 建構的 URL
<a name="outputs-section-structure-examples-join-export-url"></a>

在建立 WordPress 網站的範本的下列範例中，`InstallURL` 是 `Fn::Join` 函數呼叫傳回的字串，它會串連 `http://`、資源的 DNS 名稱 `ElasticLoadBalancer`，以及 `/wp-admin/install.php`。輸出值可能類似以下內容：

```
http://mywptests-elasticl-1gb51l6sl8y5v-206169572.aws-region.elb.amazonaws.com/wp-admin/install.php
```

#### JSON
<a name="outputs-section-structure-examples-join-export-url.json"></a>

```
{
    "Outputs": {
        "InstallURL": {
            "Value": {
                "Fn::Join": [
                    "",
                    [
                        "http://",
                        {
                            "Fn::GetAtt": [
                                "ElasticLoadBalancer",
                                "DNSName"
                            ]
                        },
                        "/wp-admin/install.php"
                    ]
                ]
            },
            "Description": "Installation URL of the WordPress website"
        }
    }
}
```

#### YAML
<a name="outputs-section-structure-examples-join-export-url.yaml"></a>

```
Outputs:
  InstallURL:
    Value: !Join 
      - ''
      - - 'http://'
        - !GetAtt 
          - ElasticLoadBalancer
          - DNSName
        - /wp-admin/install.php
    Description: Installation URL of the WordPress website
```

如需 `Fn::Join` 函數的詳細資訊，請參閱「[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-join.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-join.html)」。

# CloudFormation 範本 Mappings 語法
<a name="mappings-section-structure"></a>

選用 `Mappings` 區段可協助您建立索引鍵/值對，用於根據特定條件或依賴關係指定數值。

`Mappings` 區段的一個常見使用案例是根據部署堆疊的 AWS 區域 來設定值。可以透過使用 `AWS::Region` 虛擬參數來實現這一點。`AWS::Region` 虛擬參數是 CloudFormation 解析為堆疊建立區域的值。當您建立堆疊時，CloudFormation 會解析虛擬參數。

要擷取映射中的數值，您可以在範本的 `Resources` 區段內使用 `Fn::FindInMap` 內建函數。

## 語法
<a name="mappings-section-structure-syntax"></a>

`Mappings` 區段使用下列語法：

### JSON
<a name="mappings-section-structure-syntax.json"></a>

```
"Mappings" : {
  "MappingLogicalName" : {
    "Key1" : {
      "Name" : "Value1"
    },
    "Key2" : {
      "Name" : "Value2"
    },
    "Key3" : {
      "Name" : "Value3"
    }
  }
}
```

### YAML
<a name="mappings-section-structure-syntax.yaml"></a>

```
Mappings: 
  MappingLogicalName: 
    Key1: 
      Name: Value1
    Key2: 
      Name: Value2
    Key3: 
      Name: Value3
```
+ `MappingLogicalName` 是映射的邏輯名稱。
+ 在映射內，每個映射都是後面接著另一個映射的索引鍵。
+ 該金鑰必須是名稱值對的映射和映射中唯一的映射。
+ 名稱/值對是一個標籤，也是要映射的值。藉由命名這些值，您可以將多組的值映射至一個索引鍵。
+ 映射中的索引鍵必須是常值字串。
+ 值可以是類型 `String` 或 `List`。

**注意**  
您不能在 `Mappings` 區段中包含參數、虛擬參數或內部函數。  
如果堆疊目前沒有使用映射中的值，您將無法更新映射本身。必須涵蓋新增、修改或刪除資源等變更作業，才能進行更新。

## 範例
<a name="mappings-section-structure-examples"></a>

**Topics**
+ [基本映射](#mappings-section-structure-basic-example)
+ [具有多個值的映射](#mappings-section-structure-multiple-values-example)
+ [從映射傳回值](#mappings-section-structure-return-value-example)
+ [輸入參數和 `Fn::FindInMap`](#mappings-section-structure-input-parameter-example)

### 基本映射
<a name="mappings-section-structure-basic-example"></a>

下列範例顯示具有映射 `Mappings` 的 `RegionToInstanceType` 區段，內含映射至包含單一字串值之名稱值對的五個索引鍵。索引鍵是區域名稱。每個名稱/數值組都是 T 系列的執行個體類型，且在索引鍵所代表的區域中可用。名稱值對會有名稱 (在此範例中為 `InstanceType`) 和值。

#### JSON
<a name="mappings-section-structure-basic-example.json"></a>

```
"Mappings" : {
  "RegionToInstanceType" : {
    "us-east-1"      : { "InstanceType" : "t2.micro" },
    "us-west-1"      : { "InstanceType" : "t2.micro" },
    "eu-west-1"      : { "InstanceType" : "t2.micro" },
    "eu-north-1"     : { "InstanceType" : "t3.micro" },
    "me-south-1"     : { "InstanceType" : "t3.micro" }
  }
}
```

#### YAML
<a name="mappings-section-structure-basic-example.yaml"></a>

```
Mappings:
  RegionToInstanceType:
    us-east-1:
      InstanceType: t2.micro
    us-west-1:
      InstanceType: t2.micro
    eu-west-1:
      InstanceType: t2.micro
    eu-north-1:
      InstanceType: t3.micro
    me-south-1:
      InstanceType: t3.micro
```

### 具有多個值的映射
<a name="mappings-section-structure-multiple-values-example"></a>

下列範例的區域索引鍵映射至兩組值：一個名為 `MyAMI1`，另一個名為 `MyAMI2`。

**注意**  
這些範例中顯示的 AMI ID 是用作示範用途的預留位置。盡可能考慮使用 AWS Systems Manager 參數的動態參考作為 `Mappings` 區段的替代方案。若要避免在每次要使用變更的 AMI 時，使用新 ID 更新所有範本，請在建立或更新堆疊時，使用 AWS Systems Manager 參數擷取最新的 AMI ID。Systems Manager 中也提供最新版本的常用 AMI 作為公有參數。如需詳細資訊，請參閱[使用動態參考取得存放在其他服務中的值](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html)。

#### JSON
<a name="mappings-section-structure-multiple-values-example"></a>

```
"Mappings" : {
  "RegionToAMI" : {
    "us-east-1"        : { "MyAMI1" : "ami-12345678901234567", "MyAMI2" : "ami-23456789012345678" },
    "us-west-1"        : { "MyAMI1" : "ami-34567890123456789", "MyAMI2" : "ami-45678901234567890" },
    "eu-west-1"        : { "MyAMI1" : "ami-56789012345678901", "MyAMI2" : "ami-67890123456789012" },
    "ap-southeast-1"   : { "MyAMI1" : "ami-78901234567890123", "MyAMI2" : "ami-89012345678901234" },
    "ap-northeast-1"   : { "MyAMI1" : "ami-90123456789012345", "MyAMI2" : "ami-01234567890123456" }
  }
}
```

#### YAML
<a name="mappings-section-structure-multiple-values-example.yaml"></a>

```
Mappings:
  RegionToAMI:
    us-east-1:
      MyAMI1: ami-12345678901234567
      MyAMI2: ami-23456789012345678
    us-west-1:
      MyAMI1: ami-34567890123456789
      MyAMI2: ami-45678901234567890
    eu-west-1:
      MyAMI1: ami-56789012345678901
      MyAMI2: ami-67890123456789012
    ap-southeast-1:
      MyAMI1: ami-78901234567890123
      MyAMI2: ami-89012345678901234
    ap-northeast-1:
      MyAMI1: ami-90123456789012345
      MyAMI2: ami-01234567890123456
```

### 從映射傳回值
<a name="mappings-section-structure-return-value-example"></a>

您可以使用 `Fn::FindInMap` 函數，以根據指定的索引鍵來傳回命名值。下列範例範本包含 Amazon EC2 資源，而其 `InstanceType` 屬性是由 `FindInMap` 函數指派。`FindInMap` 函數會將索引鍵指定為建立堆疊 AWS 區域 的 （使用`AWS::Region`虛擬參數），並將索引鍵`InstanceType`指定為要映射的值名稱。`ImageId` 會使用 Systems Manager 參數動態擷取最新的 Amazon Linux 2 AMI。如需這些虛擬參數的詳細資訊，請參閱[使用虛擬參數取得 AWS 值](pseudo-parameter-reference.md)。

#### JSON
<a name="mappings-section-structure-return-value-example.json"></a>

```
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Mappings" : {
    "RegionToInstanceType" : {
      "us-east-1"      : { "InstanceType" : "t2.micro" },
      "us-west-1"      : { "InstanceType" : "t2.micro" },
      "eu-west-1"      : { "InstanceType" : "t2.micro" },
      "eu-north-1"     : { "InstanceType" : "t3.micro" },
      "me-south-1"     : { "InstanceType" : "t3.micro" }
    }
  },
  "Resources" : {
    "myEC2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
        "InstanceType" : { "Fn::FindInMap" : [ "RegionToInstanceType", { "Ref" : "AWS::Region" }, "InstanceType" ]}
      }
    }
  }
}
```

#### YAML
<a name="mappings-section-structure-return-value-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Mappings: 
  RegionToInstanceType: 
    us-east-1:
      InstanceType: t2.micro
    us-west-1:
      InstanceType: t2.micro
    eu-west-1:
      InstanceType: t2.micro
    eu-north-1:
      InstanceType: t3.micro
    me-south-1:
      InstanceType: t3.micro
Resources: 
  myEC2Instance: 
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
      InstanceType: !FindInMap [RegionToInstanceType, !Ref 'AWS::Region', InstanceType]
```

### 輸入參數和 `Fn::FindInMap`
<a name="mappings-section-structure-input-parameter-example"></a>

下列範例範本示範如何使用多個映射建立 EC2 執行個體。範本使用巢狀映射，根據目標和環境類型 (`Dev` 或 ) 自動選取適當的執行個體類型 AWS 區域 和安全群組`Prod`。它也會使用 Systems Manager 參數來動態擷取最新的 Amazon Linux 2 AMI。

#### JSON
<a name="mappings-section-structure-input-parameter-example.json"></a>

```
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Parameters" : {
    "EnvironmentType" : {
      "Description" : "The environment type (Dev or Prod)",
      "Type" : "String",
      "Default" : "Dev",
      "AllowedValues" : [ "Dev", "Prod" ]
    }
  },
  "Mappings" : {
    "RegionAndEnvironmentToInstanceType" : {
      "us-east-1"        : { "Dev" : "t3.micro", "Prod" : "c5.large" },
      "us-west-1"        : { "Dev" : "t2.micro", "Prod" : "m5.large" }
    },
    "RegionAndEnvironmentToSecurityGroup" : {
      "us-east-1"        : { "Dev" : "sg-12345678", "Prod" : "sg-abcdef01" },
      "us-west-1"        : { "Dev" : "sg-ghijkl23", "Prod" : "sg-45678abc" }
    }
  },
  "Resources" : {
    "Ec2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
        "InstanceType" : { "Fn::FindInMap": [ "RegionAndEnvironmentToInstanceType", { "Ref": "AWS::Region" }, { "Ref": "EnvironmentType" } ]},
        "SecurityGroupIds" : [{ "Fn::FindInMap" : [ "RegionAndEnvironmentToSecurityGroup", { "Ref" : "AWS::Region" }, { "Ref" : "EnvironmentType" } ]}]
      }
    }
  }
}
```

#### YAML
<a name="mappings-section-structure-input-parameter-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EnvironmentType: 
    Description: The environment type (Dev or Prod)
    Type: String
    Default: Dev
    AllowedValues: 
      - Dev
      - Prod
Mappings:
  RegionAndEnvironmentToInstanceType:
    us-east-1: 
      Dev: t3.micro
      Prod: c5.large
    us-west-1: 
      Dev: t2.micro
      Prod: m5.large
  RegionAndEnvironmentToSecurityGroup: 
    us-east-1: 
      Dev: sg-12345678
      Prod: sg-abcdef01
    us-west-1: 
      Dev: sg-ghijkl23
      Prod: sg-45678abc
Resources:
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
      InstanceType: !FindInMap [RegionAndEnvironmentToInstanceType, !Ref 'AWS::Region', !Ref EnvironmentType]
      SecurityGroupIds:
        - !FindInMap [RegionAndEnvironmentToSecurityGroup, !Ref 'AWS::Region', !Ref EnvironmentType]
```

## 相關資源
<a name="mappings-section-related-resources"></a>

當您開發使用 `Fn::FindInMap` 函數的範本時，這些相關主題會很有幫助。
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-findinmap.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-findinmap.html)
+ [Fn::FindInMap 增強功能](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-findinmap-enhancements.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html)

# CloudFormation 範本 Metadata 語法
<a name="metadata-section-structure"></a>

`Metadata` 會使用 JSON 或 YAML 物件儲存額外資訊。您可在範本中使用的範本層級中繼資料類型包括：

自訂中繼資料  
儲存使用者定義的索引鍵/值對。例如，您可提供不影響資源建立，但能說明基礎設施、團隊或部署詳情的額外資訊。

`AWS::CloudFormation::Interface`  
定義輸入參數在 CloudFormation 主控台中顯示的群組和排序。根據預設，CloudFormation 主控台會依據參數的邏輯 ID 字母順序來排序參數。

`AWS::CloudFormation::Designer`  
CloudFormation 設計工具 (Designer) 已於 2025 年 2 月 5 日結束生命週期。



**重要**  
在更新堆疊期間，您無法自行更新 `Metadata` 區段。只有在包含可新增、修改或刪除資源的變更時，才能予以更新。  
CloudFormation 不會轉換、修改或標記您在 `Metadata` 區段中包含的任何資訊。因此，我們強烈建議您不要使用此區段來儲存機密資訊，例如密碼或秘密。

## 語法
<a name="metadata-section-structure-syntax"></a>

若要在您的 CloudFormation 範本中宣告自訂中繼資料，請使用下列語法：

### JSON
<a name="metadata-section-structure-syntax.json"></a>

```
"Metadata" : {
  "Instances" : {"Description" : "Information about the instances"},
  "Databases" : {"Description" : "Information about the databases"}
}
```

### YAML
<a name="metadata-section-structure-syntax.yaml"></a>

```
Metadata:
  Instances:
    Description: "Information about the instances"
  Databases: 
    Description: "Information about the databases"
```

如需 `AWS::CloudFormation::Interface` 的語法，請參閱 [使用 `AWS::CloudFormation::Interface` 中繼資料組織 CloudFormation 參數](aws-cloudformation-interface.md)。

# 使用 `AWS::CloudFormation::Interface` 中繼資料組織 CloudFormation 參數
<a name="aws-cloudformation-interface"></a>

`AWS::CloudFormation::Interface` 是一種中繼資料金鑰，可定義參數在 CloudFormation 主控台中的分組和排序方式。預設情況下，當您在主控台中建立或更新堆疊時，主控台會依據輸入參數的邏輯 ID 字母順序來列出參數。使用此金鑰時，您可以定義自己的參數分組和排序，以讓使用者有效地指定參數值。例如，您可以將所有 EC2 相關參數分組為一個群組，而將所有 VPC 相關參數分組為另一個群組。

在中繼資料金鑰中，您可以指定要建立的群組、每個群組中所要包含的參數，以及主控台顯示群組內每個參數的順序。

也可以定義參數的標籤。標籤是要在主控台中顯示的易讀名稱或描述，而非參數的邏輯 ID。標籤有助使用者了解可為每個參數指定的值。例如，您可以為 `KeyPair` 參數設定 `Select an EC2 key pair` 標籤。

您在中繼資料金鑰中參考的所有參數都會宣告於範本的 `Parameters` 區段中。

**注意**  
只有 CloudFormation 主控台會使用`AWS::CloudFormation::Interface`中繼資料金鑰。 AWS CLI 而 API 呼叫不會使用此金鑰。

## 語法
<a name="aws-resource-cloudformation-interface-syntax"></a>

若要在您的 CloudFormation 範本中宣告此實體，請使用下列語法：

### JSON
<a name="aws-resource-cloudformation-interface-syntax.json"></a>

```
"Metadata" : {
  "AWS::CloudFormation::Interface" : {
    "ParameterGroups": [
      {
        "Label": {
          "default": "Group Label"
        },
        "Parameters": [
          "Parameter1",
          "Parameter2"
        ]
      }
    ],
    "ParameterLabels": {
      "Parameter1": {
        "default": "Friendly Name for Parameter1"
      }
    }
  }
}
```

### YAML
<a name="aws-resource-cloudformation-interface-syntax.yaml"></a>

```
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Group Label
        Parameters:
          - Parameter1
          - Parameter2
    ParameterLabels:
      Parameter1:
        default: Friendly Name for Parameter1
```

## Properties
<a name="w2aac11c23c29c17c17"></a>

`ParameterGroups`  
參數群組類型清單；您可以在其中指定群組名稱、每個群組中的參數，以及參數的顯示順序。  
*必要*：否    
`Label`  
參數群組的名稱。  
*必要*：否  
`default`  
CloudFormation 主控台用來命名參數群組的預設標籤。  
*必要*：否  
*類型：*字串  
`Parameters`  
群組要包含之區分大小寫的參數邏輯 ID 清單。這些參數必須已在範本的 `Parameters` 區段內定義。一個參數只能包含在一個參數群組中。  
您不會在 `Other parameters` 群組中，按字母順序建立主控台所列出參數與參數群組的關聯。  
*必要*：否  
*類型*：字串值清單

`ParameterLabels`  
參數和其易讀名稱的映射；在建立或更新堆疊時，CloudFormation 主控台會顯示這些項目。  
*必要*：否    
參數標籤  
參數的標籤。此標籤定義易用的名稱或描述，建立或更新堆疊時，CloudFormation 主控台會在 **Specify Parameters (指定參數)** 頁面上顯示這些名稱或描述。參數標籤必須是有效參數的邏輯 ID (區分大小寫)，而且這些參數必須已在範本的 `Parameters` 區段中宣告。  
*必要*：否  
`default`  
CloudFormation 主控台用來命名參數的預設標籤。  
*必要*：否  
*類型：*字串

## 範例
<a name="w2aac11c23c29c17c19"></a>

下列範例定義兩個參數群組：`Network Configuration` 和 `Amazon EC2 Configuration`。`Network Configuration` 群組包含 `VPCID`、`SubnetId` 和 `SecurityGroupID` 參數，這些參數是在範本的 `Parameters` 區段中定義 (未顯示)。在主控台中，這些參數的顯示順序是由參數的列出順序來定義，從 `VPCID` 參數開始。本範例會以類似方式來分組和排序 `Amazon EC2 Configuration` 參數。

本範例也會定義 `VPCID` 參數的標籤。主控台會顯示 **Which VPC should this be deployed to? (此項目應該部署至哪個 VPC？)** 而非參數的邏輯 ID (`VPCID`)。

### JSON
<a name="aws-cloudformation-interface-example.json"></a>

```
"Metadata" : {
  "AWS::CloudFormation::Interface" : {
    "ParameterGroups" : [
      {
        "Label" : { "default" : "Network Configuration" },
        "Parameters" : [ "VPCID", "SubnetId", "SecurityGroupID" ]
      },
      {
        "Label" : { "default":"Amazon EC2 Configuration" },
        "Parameters" : [ "InstanceType", "KeyName" ]
      }
    ],
    "ParameterLabels" : {
      "VPCID" : { "default" : "Which VPC should this be deployed to?" }
    }
  }
}
```

### YAML
<a name="aws-cloudformation-interface-example.yaml"></a>

```
Metadata: 
  AWS::CloudFormation::Interface: 
    ParameterGroups: 
      - Label: 
          default: "Network Configuration"
        Parameters: 
          - VPCID
          - SubnetId
          - SecurityGroupID
      - Label: 
          default: "Amazon EC2 Configuration"
        Parameters: 
          - InstanceType
          - KeyName
    ParameterLabels: 
      VPCID: 
        default: "Which VPC should this be deployed to?"
```

### 主控台中的參數群組
<a name="w2aac11c23c29c17c19c11"></a>

下圖會使用此範例的中繼資料金鑰來說明建立或更新堆疊時，主控台會如何顯示參數群組：**主控台中的參數群組** 

![\[主控台，其中顯示此範例的參數群組。\]](http://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/images/console-create-stack-parameter-groups.png)


# CloudFormation 範本 Rules 語法
<a name="rules-section-structure"></a>

`Rules` 區段為 CloudFormation 範本的選用部分，可啟用自訂驗證邏輯。若包含此區段，其中的規則函式會在 CloudFormation 建立或更新任何資源前驗證參數值。

當標準參數限制不足時，規則很有用。例如，啟用 SSL 時，必須提供憑證和網域名稱。規則可以確保滿足這些相依性。

## 語法
<a name="template-constraint-rules-syntax"></a>

`Rules` 區段使用下列語法：

### JSON
<a name="rules-section-structure-syntax.json"></a>

範本的 `Rules` 區塊包含了金鑰名稱 `Rules`，後面接著單一冒號。您必須使用大括號來括住所有規則宣告。如果宣告多項規則，這些規則會以逗號分隔。對於每項規則，您會在引號中宣告其邏輯名稱，後面依序接著冒號和括號，括號之中是規則條件與宣告。

```
{
    "Rules": {
        "LogicalRuleName1": {
            "RuleCondition": {
                "rule-specific intrinsic function": "Value"
            },
            "Assertions": [
                {
                    "Assert": {
                        "rule-specific intrinsic function": "Value"
                    },
                    "AssertDescription": "Information about this assert"
                },
                {
                    "Assert": {
                        "rule-specific intrinsic function": "Value"
                    },
                    "AssertDescription": "Information about this assert"
                }
            ]
        },
        "LogicalRuleName2": {
            "Assertions": [
                {
                    "Assert": {
                        "rule-specific intrinsic function": "Value"
                    },
                    "AssertDescription": "Information about this assert"
                }
            ]
        }
    }
}
```

### YAML
<a name="rules-section-structure-syntax.yaml"></a>

```
Rules:
  LogicalRuleName1:
    RuleCondition:
      rule-specific intrinsic function: Value
    Assertions:
      - Assert:
          rule-specific intrinsic function: Value
        AssertDescription: Information about this assert
      - Assert:
          rule-specific intrinsic function: Value
        AssertDescription: Information about this assert
  LogicalRuleName2:
    Assertions:
      - Assert:
          rule-specific intrinsic function: Value
        AssertDescription: Information about this assert
```

### 規則欄位
<a name="rules-section-fields"></a>

`Rules` 區段可以包含下列欄位。

**邏輯 ID (也稱為*邏輯名稱*)**  
每條規則的唯一識別碼。

**`RuleCondition` (選用)**  
決定規則何時生效的屬性。如果您未定義規則條件，則該規則的宣告一律生效。對於每個規則，您只能定義一個規則條件。

**`Assertions` (必要)**  
一個或多個陳述式，指定特定參數的可接受值。

**`Assert`**  
必須等於 `true` 的條件。

**`AssertDescription`**  
宣告失敗時顯示的訊息。

## 規則特定的內部函數
<a name="rules-specific-intrinsic-section-structure"></a>

若要定義您的規則，您必須使用*規則特定的函數*，這些函式只能在範本的 `Rules` 區塊中使用。雖然可以巢狀這些函數，但規則條件或宣告的最終結果必須為 `true` 或 `false`。

現在可以使用下列規則：
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-contains](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-contains)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-eachmemberequals](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-eachmemberequals)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-eachmemberin](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-eachmemberin)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-refall](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-refall)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-valueof](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-valueof)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-valueofall](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-rules.html#fn-valueofall)

這些函數用於規則的條件或宣告中。由條件屬性決定 CloudFormation 是否套用宣告。若條件計算結果為 `true`，CloudFormation 會評估宣告以驗證在佈建產品建立或更新時，某個參數值是否有效。若參數值為無效，CloudFormation 便不會建立或更新堆疊。如果條件評估為 `false`，CloudFormation 便不會檢查參數值，而直接繼續運作堆疊。

## 範例
<a name="template-constraint-rules-example"></a>

**Topics**
+ [有條件地驗證參數值](#template-constraint-rules-example-verify)
+ [交互參數驗證](#template-cross-parameter-rules-example)

### 有條件地驗證參數值
<a name="template-constraint-rules-example-verify"></a>

在下列範例中，兩個規則會檢查 `InstanceType` 參數的值。視環境參數 (`test` 或 `prod`) 的值而定，使用者必須針對 `t3.medium` 參數指定 `t3.large` 或 `InstanceType`。`InstanceType` 與 `Environment` 參數必須在同一個範本的 `Parameters` 區塊中宣告。

#### JSON
<a name="rules-section-example-conditionally-verify.json"></a>

```
{
  "Rules": {
    "testInstanceType": {
      "RuleCondition": {
        "Fn::Equals": [
          {"Ref": "Environment"},
          "test"
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Contains": [
              ["t3.medium"],
              {"Ref": "InstanceType"}
            ]
          },
          "AssertDescription": "For a test environment, the instance type must be t3.medium"
        }
      ]
    },
    "prodInstanceType": {
      "RuleCondition": {
        "Fn::Equals": [
          {"Ref": "Environment"},
          "prod"
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Contains": [
              ["t3.large"],
              {"Ref": "InstanceType"}
            ]
          },
          "AssertDescription": "For a production environment, the instance type must be t3.large"
        }
      ]
    }
  }
}
```

#### YAML
<a name="rules-section-example-conditionally-verify.yaml"></a>

```
Rules:
  testInstanceType:
    RuleCondition: !Equals 
      - !Ref Environment
      - test
    Assertions:
      - Assert:
          'Fn::Contains':
            - - t3.medium
            - !Ref InstanceType
        AssertDescription: 'For a test environment, the instance type must be t3.medium'
  prodInstanceType:
    RuleCondition: !Equals 
      - !Ref Environment
      - prod
    Assertions:
      - Assert:
          'Fn::Contains':
            - - t3.large
            - !Ref InstanceType
        AssertDescription: 'For a production environment, the instance type must be t3.large'
```

### 交互參數驗證
<a name="template-cross-parameter-rules-example"></a>

下列範例範本示範如何使用規則進行跨參數驗證。這些範本會建立一個執行在負載平衡器後方 Auto Scaling 群組上的範例網站。根據輸入參數，網站可透過連接埠 80 或 443 存取。Auto Scaling 群組中的執行個體可設定為接聽任何連接埠 (預設為 8888)。

此範本中的規則會在建立堆疊前驗證輸入參數。其會驗證所有子網路是否屬於指定的 VPC，並確保當 `UseSSL` 參數設定為 `Yes` 時，同時提供 SSL 憑證 ARN 和託管區域名稱。

**注意**  
如果您從此範本建立堆疊，您將需要支付所使用的 AWS 資源費用。

#### JSON
<a name="rules-section-example-cross-parameter-validation.json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters": {
    "VpcId": {
      "Type": "AWS::EC2::VPC::Id",
      "Description": "VpcId of your existing Virtual Private Cloud (VPC)",
      "ConstraintDescription": "must be the VPC Id of an existing Virtual Private Cloud."
    },
    "Subnets": {
      "Type": "List<AWS::EC2::Subnet::Id>",
      "Description": "The list of SubnetIds in your Virtual Private Cloud (VPC)",
      "ConstraintDescription": "must be a list of at least two existing subnets associated with at least two different availability zones."
    },
    "InstanceType": {
      "Description": "WebServer EC2 instance type",
      "Type": "String",
      "Default": "t2.micro",
      "AllowedValues": ["t2.micro", "t3.micro"],
      "ConstraintDescription": "must be a valid EC2 instance type."
    },
    "KeyName": {
      "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances",
      "Type": "AWS::EC2::KeyPair::KeyName",
      "ConstraintDescription": "must be the name of an existing EC2 KeyPair."
    },
    "SSHLocation": {
      "Description": "The IP address range that can be used to SSH to the EC2 instances",
      "Type": "String",
      "MinLength": "9",
      "MaxLength": "18",
      "Default": "0.0.0.0/0",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
    },
    "UseSSL": {
      "AllowedValues": ["Yes", "No"],
      "Default": "No",
      "Description": "Select \"Yes\" to implement SSL, \"No\" to skip (default).",
      "Type": "String"
    },
    "ALBSSLCertificateARN": {
      "Default": "",
      "Description": "[Optional] The ARN of the SSL certificate to be used for the Application Load Balancer",
      "Type": "String"
    },
    "HostedZoneName": {
      "AllowedPattern": "^$|(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$",
      "Default": "",
      "Description": "[Optional] The domain name of a valid Hosted Zone on AWS.",
      "Type": "String"
    }
  },
  "Conditions": {
    "UseALBSSL": {"Fn::Equals": [{"Ref": "UseSSL"}, "Yes"]}
  },
  "Rules": {
    "SubnetsInVPC": {
      "Assertions": [
        {
          "Assert": {"Fn::EachMemberEquals": [{"Fn::ValueOf": ["Subnets", "VpcId"]}, {"Ref": "VpcId"}]},
          "AssertDescription": "All subnets must be in the VPC"
        }
      ]
    },
    "ValidateHostedZone": {
      "RuleCondition": {"Fn::Equals": [{"Ref": "UseSSL"}, "Yes"]},
      "Assertions": [
        {
          "Assert": {"Fn::Not": [{"Fn::Equals": [{"Ref": "ALBSSLCertificateARN"}, ""]}]},
          "AssertDescription": "ACM Certificate value cannot be empty if SSL is required"
        },
        {
          "Assert": {"Fn::Not": [{"Fn::Equals": [{"Ref": "HostedZoneName"}, ""]}]},
          "AssertDescription": "Route53 Hosted Zone Name is mandatory when SSL is required"
        }
      ]
    }
  },
  "Resources": {
    "WebServerGroup": {
      "Type": "AWS::AutoScaling::AutoScalingGroup",
      "Properties": {
        "VPCZoneIdentifier": {"Ref": "Subnets"},
        "LaunchTemplate": {
          "LaunchTemplateId": {"Ref": "LaunchTemplate"},
          "Version": {"Fn::GetAtt": ["LaunchTemplate","LatestVersionNumber"]}
        },
        "MinSize": "2",
        "MaxSize": "2",
        "TargetGroupARNs": [{"Ref": "ALBTargetGroup"}]
      },
      "CreationPolicy": {
        "ResourceSignal": {"Timeout": "PT15M"}
      },
      "UpdatePolicy": {
        "AutoScalingRollingUpdate": {
          "MinInstancesInService": "1",
          "MaxBatchSize": "1",
          "PauseTime": "PT15M",
          "WaitOnResourceSignals": true
        }
      }
    },
    "LaunchTemplate": {
      "Type": "AWS::EC2::LaunchTemplate",
      "Metadata": {
        "Comment": "Install a simple application",
        "AWS::CloudFormation::Init": {
          "config": {
            "packages": {"yum": {"httpd": []}},
            "files": {
              "/var/www/html/index.html": {
                "content": {"Fn::Join": ["\n", ["<h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1>"]]},
                "mode": "000644",
                "owner": "root",
                "group": "root"
              },
              "/etc/cfn/cfn-hup.conf": {
                "content": {"Fn::Join": ["", [
                  "[main]\n",
                  "stack=", {"Ref": "AWS::StackId"}, "\n",
                  "region=", {"Ref": "AWS::Region"}, "\n"
                ]]},
                "mode": "000400",
                "owner": "root",
                "group": "root"
              },
              "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                "content": {"Fn::Join": ["", [
                  "[cfn-auto-reloader-hook]\n",
                  "triggers=post.update\n",
                  "path=Resources.LaunchTemplate.Metadata.AWS::CloudFormation::Init\n",
                  "action=/opt/aws/bin/cfn-init -v ",
                  "         --stack ", {"Ref": "AWS::StackName"},
                  "         --resource LaunchTemplate ",
                  "         --region ", {"Ref": "AWS::Region"}, "\n",
                  "runas=root\n"
                ]]},
                "mode": "000400",
                "owner": "root",
                "group": "root"
              }
            },
            "services": {
              "sysvinit": {
                "httpd": {
                  "enabled": "true",
                  "ensureRunning": "true"
                },
                "cfn-hup": {
                  "enabled": "true",
                  "ensureRunning": "true",
                  "files": [
                    "/etc/cfn/cfn-hup.conf",
                    "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                  ]
                }
              }
            }
          }
        }
      },
      "Properties": {
        "LaunchTemplateName": {"Fn::Sub": "${AWS::StackName}-launch-template"},
        "LaunchTemplateData": {
          "ImageId": "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
          "SecurityGroupIds": [{"Ref": "InstanceSecurityGroup"}],
          "InstanceType": {"Ref": "InstanceType"},
          "KeyName": {"Ref": "KeyName"},
          "UserData": {
            "Fn::Base64": {"Fn::Join": ["", [
              "#!/bin/bash\n",
              "yum install -y aws-cfn-bootstrap\n",
              "/opt/aws/bin/cfn-init -v ",
              "         --stack ", {"Ref": "AWS::StackName"},
              "         --resource LaunchTemplate ",
              "         --region ", {"Ref": "AWS::Region"}, "\n",
              "/opt/aws/bin/cfn-signal -e $? ",
              "         --stack ", {"Ref": "AWS::StackName"},
              "         --resource WebServerGroup ",
              "         --region ", {"Ref": "AWS::Region"}, "\n"
            ]]}
          }
        }
      }
    },
    "ELBSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Allow access to the ELB",
        "VpcId": {"Ref": "VpcId"},
        "SecurityGroupIngress": [{
          "Fn::If": [
            "UseALBSSL",
            {
              "IpProtocol": "tcp",
              "FromPort": 443,
              "ToPort": 443,
              "CidrIp": "0.0.0.0/0"
            },
            {
              "IpProtocol": "tcp",
              "FromPort": 80,
              "ToPort": 80,
              "CidrIp": "0.0.0.0/0"
            }
          ]
        }]
      }
    },
    "ApplicationLoadBalancer": {
      "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties": {
        "Subnets": {"Ref": "Subnets"},
        "SecurityGroups": [{"Ref": "ELBSecurityGroup"}]
      }
    },
    "ALBListener": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Properties": {
        "DefaultActions": [{
          "Type": "forward",
          "TargetGroupArn": {"Ref": "ALBTargetGroup"}
        }],
        "LoadBalancerArn": {"Ref": "ApplicationLoadBalancer"},
        "Port": {"Fn::If": ["UseALBSSL", 443, 80]},
        "Protocol": {"Fn::If": ["UseALBSSL", "HTTPS", "HTTP"]},
        "Certificates": [{
          "Fn::If": [
            "UseALBSSL",
            {"CertificateArn": {"Ref": "ALBSSLCertificateARN"}},
            {"Ref": "AWS::NoValue"}
          ]
        }]
      }
    },
    "ALBTargetGroup": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties": {
        "HealthCheckIntervalSeconds": 30,
        "HealthCheckTimeoutSeconds": 5,
        "HealthyThresholdCount": 3,
        "Port": 80,
        "Protocol": "HTTP",
        "UnhealthyThresholdCount": 5,
        "VpcId": {"Ref": "VpcId"}
      }
    },
    "InstanceSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Enable SSH access and HTTP access on the inbound port",
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 80,
            "ToPort": 80,
            "SourceSecurityGroupId": {"Fn::Select": [0, {"Fn::GetAtt": ["ApplicationLoadBalancer", "SecurityGroups"]}]}
          },
          {
            "IpProtocol": "tcp",
            "FromPort": 22,
            "ToPort": 22,
            "CidrIp": {"Ref": "SSHLocation"}
          }
        ],
        "VpcId": {"Ref": "VpcId"}
      }
    },
    "RecordSet": {
      "Type": "AWS::Route53::RecordSetGroup",
      "Condition": "UseALBSSL",
      "Properties": {
        "HostedZoneName": {"Fn::Join": ["", [{"Ref": "HostedZoneName"}, "."]]},
        "RecordSets": [{
          "Name": {"Fn::Join": ["", [
            {"Fn::Select": ["0", {"Fn::Split": [".", {"Fn::GetAtt": ["ApplicationLoadBalancer", "DNSName"]}]}]},
            ".",
            {"Ref": "HostedZoneName"},
            "."
          ]]},
          "Type": "A",
          "AliasTarget": {
            "DNSName": {"Fn::GetAtt": ["ApplicationLoadBalancer", "DNSName"]},
            "EvaluateTargetHealth": true,
            "HostedZoneId": {"Fn::GetAtt": ["ApplicationLoadBalancer", "CanonicalHostedZoneID"]}
          }
        }]
      }
    }
  },
  "Outputs": {
    "URL": {
      "Description": "URL of the website",
      "Value": {"Fn::Join": ["", [
        {"Fn::If": [
          "UseALBSSL",
          {"Fn::Join": ["", [
            "https://",
            {"Fn::Join": ["", [
              {"Fn::Select": ["0", {"Fn::Split": [".", {"Fn::GetAtt": ["ApplicationLoadBalancer", "DNSName"]}]}]},
              ".",
              {"Ref": "HostedZoneName"},
              "."
            ]]}
          ]]},
          {"Fn::Join": ["", [
            "http://",
            {"Fn::GetAtt": ["ApplicationLoadBalancer", "DNSName"]}
          ]]}
        ]}
      ]]}
    }
  }
}
```

#### YAML
<a name="rules-section-example-syntax.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VpcId of your existing Virtual Private Cloud (VPC)
    ConstraintDescription: must be the VPC Id of an existing Virtual Private Cloud.
  Subnets:
    Type: List<AWS::EC2::Subnet::Id>
    Description: The list of SubnetIds in your Virtual Private Cloud (VPC)
    ConstraintDescription: >-
      must be a list of at least two existing subnets associated with at least
      two different availability zones. They should be residing in the selected
      Virtual Private Cloud.
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - t3.micro
    ConstraintDescription: must be a valid EC2 instance type.
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  UseSSL:
    AllowedValues:
      - 'Yes'
      - 'No'
    ConstraintDescription: Select Yes to create a HTTPS Listener
    Default: 'No'
    Description: 'Select "Yes" to implement SSL, "No" to skip (default).'
    Type: String
  ALBSSLCertificateARN:
    Default: ''
    Description: >-
      [Optional] The ARN of the SSL certificate to be used for the Application
      Load Balancer
    Type: String
  HostedZoneName:
    AllowedPattern: >-
      ^$|(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$
    Default: ''
    Description: '[Optional] The domain name of a valid Hosted Zone on AWS.'
    Type: String
Conditions:
  UseALBSSL: !Equals 
    - !Ref UseSSL
    - 'Yes'
Rules:
  SubnetsInVPC:
    Assertions:
      - Assert:
          'Fn::EachMemberEquals':
            - 'Fn::ValueOf':
                - Subnets
                - VpcId
            - Ref: VpcId
        AssertDescription: All subnets must be in the VPC
  ValidateHostedZone:
    RuleCondition: !Equals 
      - !Ref UseSSL
      - 'Yes'
    Assertions:
      - Assert: !Not 
          - !Equals 
            - !Ref ALBSSLCertificateARN
            - ''
        AssertDescription: ACM Certificate value cannot be empty if SSL is required
      - Assert: !Not 
          - !Equals 
            - !Ref HostedZoneName
            - ''
        AssertDescription: Route53 Hosted Zone Name is mandatory when SSL is required
Resources:
  WebServerGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      VPCZoneIdentifier: !Ref Subnets
      LaunchTemplate:
        LaunchTemplateId: !Ref LaunchTemplate
        Version: !GetAtt LaunchTemplate.LatestVersionNumber
      MinSize: '2'
      MaxSize: '2'
      TargetGroupARNs:
        - !Ref ALBTargetGroup
    CreationPolicy:
      ResourceSignal:
        Timeout: PT15M
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinInstancesInService: '1'
        MaxBatchSize: '1'
        PauseTime: PT15M
        WaitOnResourceSignals: 'true'
  LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Metadata:
      Comment: Install a simple application
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: !Join 
                - |+
                - - >-
                    <h1>Congratulations, you have successfully launched the AWS
                    CloudFormation sample.</h1>
              mode: '000644'
              owner: root
              group: root
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |-
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.LaunchTemplate.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchTemplate --region ${AWS::Region}
                runas=root
              mode: '000400'
              owner: root
              group: root
          services:
            sysvinit:
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
              cfn-hup:
                enabled: 'true'
                ensureRunning: 'true'
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf
    Properties:
      LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
      LaunchTemplateData:
        ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
        SecurityGroupIds:
        - !Ref InstanceSecurityGroup
        InstanceType: !Ref InstanceType
        KeyName: !Ref KeyName
        UserData: !Base64
          Fn::Sub: |
            #!/bin/bash
            yum install -y aws-cfn-bootstrap
            /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchTemplate --region ${AWS::Region}
            /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerGroup --region ${AWS::Region}
  ELBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow access to the ELB
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - !If 
          - UseALBSSL
          - IpProtocol: tcp
            FromPort: 443
            ToPort: 443
            CidrIp: 0.0.0.0/0
          - IpProtocol: tcp
            FromPort: 80
            ToPort: 80
            CidrIp: 0.0.0.0/0
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Subnets: !Ref Subnets
      SecurityGroups:
        - !Ref ELBSecurityGroup
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref ALBTargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: !If
        - UseALBSSL
        - 443
        - 80
      Protocol: !If 
        - UseALBSSL
        - HTTPS
        - HTTP
      Certificates:
        - !If 
          - UseALBSSL
          - CertificateArn: !Ref ALBSSLCertificateARN
          - !Ref 'AWS::NoValue'
  ALBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 3
      Port: 80
      Protocol: HTTP
      UnhealthyThresholdCount: 5
      VpcId: !Ref VpcId
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access and HTTP access on the inbound port
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Select 
            - 0
            - !GetAtt 
              - ApplicationLoadBalancer
              - SecurityGroups
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
      VpcId: !Ref VpcId
  RecordSet:
    Type: AWS::Route53::RecordSetGroup
    Condition: UseALBSSL
    Properties:
      HostedZoneName: !Join 
        - ''
        - - !Ref HostedZoneName
          - .
      RecordSets:
        - Name: !Join 
            - ''
            - - !Select 
                - '0'
                - !Split 
                  - .
                  - !GetAtt 
                    - ApplicationLoadBalancer
                    - DNSName
              - .
              - !Ref HostedZoneName
              - .
          Type: A
          AliasTarget:
            DNSName: !GetAtt 
              - ApplicationLoadBalancer
              - DNSName
            EvaluateTargetHealth: true
            HostedZoneId: !GetAtt 
              - ApplicationLoadBalancer
              - CanonicalHostedZoneID
Outputs:
  URL:
    Description: URL of the website
    Value: !Join 
      - ''
      - - !If 
          - UseALBSSL
          - !Join 
            - ''
            - - 'https://'
              - !Join 
                - ''
                - - !Select 
                    - '0'
                    - !Split 
                      - .
                      - !GetAtt 
                        - ApplicationLoadBalancer
                        - DNSName
                  - .
                  - !Ref HostedZoneName
                  - .
          - !Join 
            - ''
            - - 'http://'
              - !GetAtt 
                - ApplicationLoadBalancer
                - DNSName
```

# CloudFormation 範本 Conditions 語法
<a name="conditions-section-structure"></a>

選用的 `Conditions` 區段包含陳述式來定義在哪些情況下建立或設定實體。例如，您可以建立條件，並將它與資源或輸出建立關聯，使得 CloudFormation 只在條件為 true 時才建立資源或輸出。同樣地，您可以將條件與屬性建立關聯，使得 CloudFormation 只在條件為 true 時才將屬性設為特定的值。如果條件為 false，CloudFormation 會將屬性設為您指定的替代值。

當您想要重複使用範本以在不同的內容 (例如測試環境與生產環境) 中建立資源時，可以使用條件。例如，可以在範本中新增 `EnvironmentType` 輸入參數，此參數接受 `prod` 或 `test` 作為輸入。在 `prod` 環境中，可以包含具有特定功能的 EC2 執行個體；而在 `test` 環境中，就要使用精簡的功能來節省資金。此條件定義可讓您針對每種環境類型來定義要建立哪些資源和其設定方式。

## 語法
<a name="conditions-section-structure-syntax"></a>

`Conditions` 區段由索引鍵名稱 `Conditions` 組成。每個條件宣告都包含邏輯 ID 和一個或多個內建函數。

### JSON
<a name="conditions-section-structure-syntax.json"></a>

```
"Conditions": {
  "LogicalConditionName1": {
    "Intrinsic function": ...[
  },

  "LogicalConditionName2": {
    "Intrinsic function": ...
  }
}
```

### YAML
<a name="conditions-section-structure-syntax.yaml"></a>

```
Conditions:
  LogicalConditionName1:
    Intrinsic function:
      ...

  LogicalConditionName2:
    Intrinsic function:
      ...
```

## 條件的運作方式
<a name="conditions-section-structure-overview"></a>

若要使用條件，請遵循下列步驟：

1. **新增參數定義** – 定義您的條件將在範本的 `Parameters` 區段中評估的輸入。條件會根據這些輸入參數值而評估為 true 或 false。請注意，虛擬參數會自動提供，而且不需要 `Parameters` 區段中的明確定義。如需這些虛擬參數的詳細資訊，請參閱[使用虛擬參數取得 AWS 值](pseudo-parameter-reference.md)。

1. **新增條件定義** – 使用 `Fn::If` 或 `Fn::Equals` 等內建函數，在 `Conditions` 區段中定義條件。這些條件決定 CloudFormation 何時建立相關聯的資源。這些條件的依據為：
   + 輸入或虛擬參數值
   + 其他條件
   + 映射值

   不過，您無法在條件中參考資源邏輯 ID 或其屬性。

1. 將**條件與資源或輸出建立關聯 – **使用 `Condition` 金鑰和條件的邏輯 ID 來參考資源或輸出中的條件。或者，在範本的其他部分 (例如屬性值) 中使用 `Fn::If`，根據條件來設定值。如需詳細資訊，請參閱[使用 `Condition` 金鑰](#using-conditions-in-templates)。

CloudFormation 會在建立或更新堆疊時評估條件。CloudFormation 會建立與 true 條件建立關聯的實體，並忽略與 false 條件建立關聯的實體。在修改任何資源之前，CloudFormation 也會在每次堆疊更新期間重新評估這些條件。會更新與 true 條件保持關聯的實體，而與 false 條件相關聯的實體則會被刪除。

**重要**  
在更新堆疊期間，您無法自行更新條件。唯有涵蓋新增、修改或刪除資源等變更作業時，才能更新條件。

## 條件內部函數
<a name="conditions-section-structure-functions"></a>

您可以使用下列內部函數來定義條件：
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-and)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-equals)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-foreach.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-foreach.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-not)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-or)

**注意**  
只有在範本的 `Resources` 區段和 `Outputs` 區段的中繼資料屬性、更新政策屬性和屬性值中，才支援 `Fn::If`。

## 使用 `Condition` 金鑰
<a name="using-conditions-in-templates"></a>

定義條件後，可以使用 `Condition` 金鑰將其套用至範本中的多個位置，例如 `Resources` 和 `Outputs`。`Condition` 金鑰會參考條件的邏輯名稱，並傳回指定條件的評估結果。

**Topics**
+ [將條件與資源建立關聯](#associate-conditions-with-resources)
+ [將條件與輸出建立關聯](#associate-conditions-with-outputs)
+ [其他條件中的參考條件](#reference-conditions-in-other-conditions)
+ [使用 `Fn::If` 有條件地傳回屬性值](#conditional-return-property-values-using-fn-if)

### 將條件與資源建立關聯
<a name="associate-conditions-with-resources"></a>

若要有條件地建立資源，請將 `Condition` 金鑰和條件的邏輯 ID 新增為資源的屬性。只有當條件評估為 true 時，CloudFormation 才會建立資源。

#### JSON
<a name="associate-conditions-with-resources.json"></a>

```
"NewVolume" : {
  "Type" : "AWS::EC2::Volume",
  "Condition" : "IsProduction",
  "Properties" : {
     "Size" : "100",
     "AvailabilityZone" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ]}
  }
}
```

#### YAML
<a name="associate-conditions-with-resources.yaml"></a>

```
NewVolume:
  Type: AWS::EC2::Volume
  Condition: IsProduction
  Properties:
    Size: 100
    AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone
```

### 將條件與輸出建立關聯
<a name="associate-conditions-with-outputs"></a>

也可以將條件與輸出建立關聯。CloudFormation 只會在關聯條件評估為 true 時建立輸出。

#### JSON
<a name="associate-conditions-with-outputs.json"></a>

```
"Outputs" : {
  "VolumeId" : {
    "Condition" : "IsProduction",
    "Value" : { "Ref" : "NewVolume" }
  }
}
```

#### YAML
<a name="associate-conditions-with-outputs.yaml"></a>

```
Outputs:
  VolumeId:
    Condition: IsProduction
    Value: !Ref NewVolume
```

### 其他條件中的參考條件
<a name="reference-conditions-in-other-conditions"></a>

在 `Conditions` 區段中定義條件時，可以使用 `Condition` 金鑰來參考其他條件。這可讓您結合多個條件來建立更複雜的條件式邏輯。

在下列範例中，只有在 `IsProduction` 和 `IsFeatureEnabled` 條件評估為 true 時，`IsProdAndFeatureEnabled` 條件才會評估為 true。

#### JSON
<a name="reference-conditions-in-other-conditions.json"></a>

```
"Conditions": {
  "IsProduction" : {"Fn::Equals" : [{"Ref" : "Environment"}, "prod"]},
  "IsFeatureEnabled" : { "Fn::Equals" : [{"Ref" : "FeatureFlag"}, "enabled"]},
  "IsProdAndFeatureEnabled" : {
    "Fn::And" : [
      {"Condition" : "IsProduction"},
      {"Condition" : "IsFeatureEnabled"}
    ]
  }
}
```

#### YAML
<a name="reference-conditions-in-other-conditions.yaml"></a>

```
Conditions:
  IsProduction:
    !Equals [!Ref Environment, "prod"]
  IsFeatureEnabled:
    !Equals [!Ref FeatureFlag, "enabled"]
  IsProdAndFeatureEnabled: !And
    - !Condition IsProduction
    - !Condition IsFeatureEnabled
```

### 使用 `Fn::If` 有條件地傳回屬性值
<a name="conditional-return-property-values-using-fn-if"></a>

如需更精細的控制，可以使用 `Fn::If` 內建函數，在資源或輸出中有條件地傳回兩個屬性值的其中之一。此函數會評估條件，如果條件為 true，則傳回一個值，如果條件為 false，則傳回另一個值。

#### 條件式屬性值
<a name="using-fn-if-for-conditional-values"></a>

下列範例示範如何根據環境條件來設定 EC2 執行個體類型。如果 `IsProduction` 條件評估為 true，執行個體類型會設為 `c5.xlarge`。否則，它會設定為 `t3.small`。

##### JSON
<a name="using-fn-if-for-conditional-values.json"></a>

```
"Properties" : {
  "InstanceType" : {
    "Fn::If" : [
      "IsProduction",
      "c5.xlarge",
      "t3.small"
    ]
  }
}
```

##### YAML
<a name="using-fn-if-for-conditional-values.yaml"></a>

```
Properties:
  InstanceType: !If
    - IsProduction
    - c5.xlarge
    - t3.small
```

#### 條件式屬性移除
<a name="using-fn-if-with-novalue"></a>

也可以使用 `AWS::NoValue` 虛擬參數作為傳回值來移除條件為 false 時的對應屬性。

##### JSON
<a name="using-fn-if-with-novalue.json"></a>

```
"DBSnapshotIdentifier" : {
  "Fn::If" : [
    "UseDBSnapshot",
    {"Ref" : "DBSnapshotName"},
    {"Ref" : "AWS::NoValue"}
  ]
}
```

##### YAML
<a name="using-fn-if-with-novalue.yaml"></a>

```
DBSnapshotIdentifier: !If
  - UseDBSnapshot
  - !Ref DBSnapshotName
  - !Ref "AWS::NoValue"
```

## 範例
<a name="conditions-section-structure-examples"></a>

**Topics**
+ [基於環境的資源建立](#environment-based-resource-creation)
+ [多條件資源佈建](#multi-condition-resource-provisioning)

### 基於環境的資源建立
<a name="environment-based-resource-creation"></a>

以下範例會佈建 EC2 執行個體，並且只有在環境類型為 `prod` 時，才會有條件地建立新的 EBS 磁碟區。如果環境為 `test`，則其只會建立沒有額外磁碟區的 EC2 執行個體。

#### JSON
<a name="conditions-section-example-resource-creation.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "EnvType": {
            "Description": "Environment type",
            "Default": "test",
            "Type": "String",
            "AllowedValues": [
                "prod",
                "test"
            ],
            "ConstraintDescription": "must specify prod or test"
        }
    },
    "Conditions": {
        "IsProduction": {
            "Fn::Equals": [
                {
                    "Ref": "EnvType"
                },
                "prod"
            ]
        }
    },
    "Resources": {
        "EC2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": "ami-1234567890abcdef0",
                "InstanceType": "c5.xlarge"
            }
        },
        "MountPoint": {
            "Type": "AWS::EC2::VolumeAttachment",
            "Condition": "IsProduction",
            "Properties": {
                "InstanceId": {
                    "Ref": "EC2Instance"
                },
                "VolumeId": {
                    "Ref": "NewVolume"
                },
                "Device": "/dev/sdh"
            }
        },
        "NewVolume": {
            "Type": "AWS::EC2::Volume",
            "Condition": "IsProduction",
            "Properties": {
                "Size": 100,
                "AvailabilityZone": {
                    "Fn::GetAtt": [
                        "EC2Instance",
                        "AvailabilityZone"
                    ]
                }
            }
        }
    }
}
```

#### YAML
<a name="conditions-section-example-resource-creation.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EnvType:
    Description: Environment type
    Default: test
    Type: String
    AllowedValues:
      - prod
      - test
    ConstraintDescription: must specify prod or test
Conditions:
  IsProduction: !Equals
    - !Ref EnvType
    - prod
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-1234567890abcdef0
      InstanceType: c5.xlarge
  MountPoint:
    Type: AWS::EC2::VolumeAttachment
    Condition: IsProduction
    Properties:
      InstanceId: !Ref EC2Instance
      VolumeId: !Ref NewVolume
      Device: /dev/sdh
  NewVolume:
    Type: AWS::EC2::Volume
    Condition: IsProduction
    Properties:
      Size: 100
      AvailabilityZone: !GetAtt
        - EC2Instance
        - AvailabilityZone
```

### 多條件資源佈建
<a name="multi-condition-resource-provisioning"></a>

以下範例會在提供儲存貯體名稱時有條件地建立 S3 儲存貯體，並只在環境設定為 `prod` 時連接儲存貯體政策。如果未指定儲存貯體名稱或環境為 `test`，則不會建立資源。

#### JSON
<a name="conditions-section-example-multi-condition.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "EnvType": {
            "Type": "String",
            "AllowedValues": [
                "prod",
                "test"
            ]
        },
        "BucketName": {
            "Default": "",
            "Type": "String"
        }
    },
    "Conditions": {
        "IsProduction": {
            "Fn::Equals": [
                {
                    "Ref": "EnvType"
                },
                "prod"
            ]
        },
        "CreateBucket": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "BucketName"
                        },
                        ""
                    ]
                }
            ]
        },
        "CreateBucketPolicy": {
            "Fn::And": [
                {
                    "Condition": "IsProduction"
                },
                {
                    "Condition": "CreateBucket"
                }
            ]
        }
    },
    "Resources": {
        "Bucket": {
            "Type": "AWS::S3::Bucket",
            "Condition": "CreateBucket",
            "Properties": {
                "BucketName": {
                    "Ref": "BucketName"
                }
            }
        },
        "Policy": {
            "Type": "AWS::S3::BucketPolicy",
            "Condition": "CreateBucketPolicy",
            "Properties": {
                "Bucket": {
                    "Ref": "Bucket"
                },
                "PolicyDocument": { ... }
            }
        }
    }
}
```

#### YAML
<a name="conditions-section-example-multi-condition.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EnvType:
    Type: String
    AllowedValues:
      - prod
      - test
  BucketName:
    Default: ''
    Type: String
Conditions:
  IsProduction: !Equals
    - !Ref EnvType
    - prod
  CreateBucket: !Not
    - !Equals
      - !Ref BucketName
      - ''
  CreateBucketPolicy: !And
    - !Condition IsProduction
    - !Condition CreateBucket
Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Condition: CreateBucket
    Properties:
      BucketName: !Ref BucketName
  Policy:
    Type: AWS::S3::BucketPolicy
    Condition: CreateBucketPolicy
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument: ...
```

在此範例中，`CreateBucketPolicy` 條件示範如何使用 `Condition` 金鑰來參考其他條件。只有在 `IsProduction` 和 `CreateBucket` 條件都評估為 true 時，才會建立政策。

**注意**  
如需使用條件的更複雜範例，請參閱《CloudFormation 範本參考指南》**中的 [Condition 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-condition.html)主題。

# CloudFormation 範本 Transform 區段
<a name="transform-section-structure"></a>

選用的 `Transform` 區段指定 CloudFormation 用來以某種方式處理您範本的一或多個巨集。

巨集可執行簡單任務，如文字查詢與替換，也可對整個範本進行更全面的轉換。CloudFormation 會按照巨集的指定順序執行。當您建立變更集時，CloudFormation 產生的變更集會包含處理過的範本內容。然後，您可以檢閱變更並執行變更集。如需有關巨集運作方式的詳細資訊，請參閱 [使用範本巨集在 CloudFormation 範本上執行自訂處理](template-macros.md)。

CloudFormation 亦支援*轉換*，這些是由 CloudFormation 託管的巨集。在執行順序和範圍方面，CloudFormation 對待這些轉換的方式與您建立的任何巨集相同。如需詳細資訊，請參閱[轉換參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-reference.html)。

若要宣告多個巨集，請使用清單格式，並指定一或多個巨集。

例如，在以下範例中，CloudFormation 會評估範本 `MyMacro`，再評估 `AWS::Serverless`，這兩者都可以處理整個範本，因為其都納入 `Transform` 區段中。

```
# Start of processable content for MyMacro and AWS::Serverless
Transform:
  - MyMacro
  - 'AWS::Serverless'
Resources:
  WaitCondition:
    Type: AWS::CloudFormation::WaitCondition
  MyBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: amzn-s3-demo-bucket
      Tags: [{"key":"value"}]
      CorsConfiguration: []
  MyEc2Instance:
    Type: AWS::EC2::Instance 
    Properties:
      ImageId: ami-1234567890abcdef0
# End of processable content for MyMacro and AWS::Serverless
```

# CloudFormation 範本格式版本語法
<a name="format-version-structure"></a>

`AWSTemplateFormatVersion` 區段 (選用) 可識別範本所遵循的範本格式版本。最新的範本格式版本是 `2010-09-09`，而且是目前唯一的有效值。

範本格式版本與 API 版本不同。範本格式版本可以與 API 版本分開變更。

範本格式版本宣告的值必須是常值字串。您不能使用參數或函數來指定範本格式版本。如果未指定值，則 CloudFormation 會採用最新的範本格式版本。下列程式碼片段是有效範本格式版本宣告範例：

## JSON
<a name="format-version-structure-example.json"></a>

```
"AWSTemplateFormatVersion" : "2010-09-09"
```

## YAML
<a name="format-version-structure-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
```

# CloudFormation 範本 Description 語法
<a name="template-description-structure"></a>

`Description` 區段 (選用) 讓您能夠包含描述範本的文字字串。此區段一律必須遵循範本格式版本區段。

描述宣告值的長度必須是介於 0 與 1024 位元組之間的常值字串。您不能使用參數或函數來指定描述。下列程式碼片段是描述宣告範例：

**重要**  
在更新堆疊期間，您無法自行更新 `Description` 區段。只有在包含可新增、修改或刪除資源的變更時，才能予以更新。

## JSON
<a name="template-description-structure-example.json"></a>

```
"Description" : "Here are some details about the template."
```

## YAML
<a name="template-description-structure-example.yaml"></a>

```
Description: > Here are some details about the template.
```

# 透過 Infrastructure Composer 視覺化建立範本
<a name="infrastructure-composer-for-cloudformation"></a>

AWS Infrastructure Composer （先前稱為 **Application Composer**) 可協助您以視覺化方式編寫和設定現代應用程式 AWS。您無需撰寫程式碼，只需拖放不同的資源即可視覺化建立應用程式。

*CloudFormation 主控台模式中的 Infrastructure Composer* 是建議用於視覺化處理 CloudFormation 範本的工具。您可以從 CloudFormation 主控台存取的此 Infrastructure Composer 版本，是從稱為 CloudFormation 設計工具的舊工具進行改善。

透過 CloudFormation 主控台模式中的 Infrastructure Composer，您可以將各種稱為*卡片*的資源拖放、設定並連結至視覺化畫布。這種視覺化方式讓您無需直接操作範本，就能輕鬆設計並編輯應用程式架構。要從 [CloudFormation 主控台](https://console.aws.amazon.com/cloudformation/)存取此模式，請從左側導航選單中選取 **Infrastructure Composer**。

如需詳細資訊，請參閱《*AWS Infrastructure Composer 開發人員指南*》中的[如何在 AWS Infrastructure Composer中編寫](https://docs.aws.amazon.com/infrastructure-composer/latest/dg/using-composer-basics.html)。

## 為何使用 CloudFormation 主控台模式中的 Infrastructure Composer？
<a name="app-composer-for-cloudformation-why-use"></a>

在 Infrastructure Composer 中視覺化呈現範本，可協助您找出 CloudFormation 範本與應用程式架構中的不足之處及待改進之處。Infrastructure Composer 透過視覺化建立及修改 CloudFormation 堆疊的便捷性與效率，提升您的開發體驗。您可以從初步草稿開始，建立可部署的程式碼，並將開發人員工作流程與 Infrastructure Composer 的視覺化設計工具進行整合。

## 此模式與 Infrastructure Composer 主控台有何差異？
<a name="app-composer-for-cloudformation-differences"></a>

儘管 CloudFormation 主控台版本的 Infrastructure Composer 與標準 Infrastructure Composer 主控台具備相似功能，但仍有部分差異。Lambda 相關卡片 (**Lambda 函式**與 **Lambda Layer**) 需要程式碼建置及套件化解決方案，而這些功能在 CloudFormation 主控台模式的 Infrastructure Composer 中並不提供。此模式也不支援本機同步功能。

不過，您可在 [Infrastructure Composer 主控台](https://console.aws.amazon.com/composer/home)或 AWS Toolkit for Visual Studio Code中使用這些 Lambda 相關卡片及本機同步功能。如需詳細資訊，請參閱《AWS Infrastructure Composer 開發人員指南[https://docs.aws.amazon.com/infrastructure-composer/latest/dg/what-is-composer.html](https://docs.aws.amazon.com/infrastructure-composer/latest/dg/what-is-composer.html)》和《AWS Toolkit for Visual Studio Code 使用者指南**》中的 [Infrastructure Composer](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/appcomposer.html)。

# AWS CloudFormation 語言伺服器
<a name="ide-extension"></a>

 AWS CloudFormation 語言伺服器提供加速編寫infrastructure-as-code (IaC) 以及安全且自信地部署 AWS 資源的功能。它遵循[語言伺服器通訊協定](https://microsoft.github.io/language-server-protocol/) (LSP) 來提供有關暫留、自動完成、透過靜態驗證診斷的文件，請前往定義和程式碼動作。除了這些傳統語言伺服器功能之外，伺服器還新增線上功能，以透過 CloudFormation 探索和部署 AWS 資源。這包括使用變更集驗證和部署範本的能力；檢視堆疊差異、事件、資源和輸出；依類型列出堆疊和瀏覽資源；以及將即時資源狀態直接插入 CloudFormation 範本。

**Topics**
+ [IDEs與 AWS CloudFormation 語言伺服器整合](#ide-extension-supported-ides)
+ [開始使用](#ide-extension-getting-started)
+ [在 IDE 中初始化 CloudFormation 專案 （僅限 VS 程式碼）](#ide-extension-initialize-project)
+ [開放原始碼](#ide-extension-open-source)
+ [需要幫助？](#ide-extension-need-help)

## IDEs與 AWS CloudFormation 語言伺服器整合
<a name="ide-extension-supported-ides"></a>

AWS 透過 AWS Toolkit 為下列 IDEs 提供off-the-shelf整合： CloudFormation 
+ [Visual Studio 程式碼](https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.aws-toolkit-vscode)
+ [JetBrains IDEs](https://plugins.jetbrains.com/plugin/11349-aws-toolkit)(2025.3 版或更新版本），包括 IntelliJ IDEA、WebStorm 和 PyCharm

下列 IDEs也支援 CloudFormation 語言伺服器：
+ [開羅](https://kiro.dev/downloads/)
+ [游標](https://cursor.com/)
+ 大多數 VS 程式碼分支和分佈

CloudFormation Language Server 遵循[語言伺服器通訊協定](https://microsoft.github.io/language-server-protocol/) (LSP)，因此其他整合是可設定的。如需將語言伺服器與其他編輯器整合的說明，請參閱 [安裝指南](https://github.com/aws-cloudformation/cloudformation-languageserver/blob/main/INSTALLATION.md)。

## 開始使用
<a name="ide-extension-getting-started"></a>

**Topics**
+ [先決條件](#ide-extension-prerequisites)
+ [步驟 1：安裝或升級 AWS Toolkit](#ide-extension-install-toolkit)
+ [步驟 2：存取 AWS Toolkit 中的 CloudFormation](#ide-extension-access-toolkit-panel)
+ [步驟 3：驗證、測試和精簡您的範本](#ide-extension-validate-test-refine)
+ [步驟 4：導覽範本](#ide-extension-navigate-template)
+ [步驟 5：驗證和部署](#ide-extension-validate-deploy)

### 先決條件
<a name="ide-extension-prerequisites"></a>

在開始之前，請確認：
+ 您在支援的作業系統 (macOS、 Windows或 ) 上使用支援的 IDELinux。
+ 您已為 IDE 安裝或升級至最新版本的 AWS Toolkit。

 AWS CloudFormation 語言伺服器中的某些功能需要作用中 AWS 帳戶 且設定的登入資料。您必須使用有效的登入資料， AWS 帳戶 透過 AWS Toolkit 登入您的 。

### 步驟 1：安裝或升級 AWS Toolkit
<a name="ide-extension-install-toolkit"></a>

從 IDE 的延伸模組或外掛程式管理員安裝或更新至最新版本的 AWS Toolkit，然後重新啟動 IDE。

安裝後， AWS Toolkit 會自動啟用 CloudFormation IDE 支援。當您第一次使用 AWS CloudFormation 語言伺服器安裝或升級 AWS Toolkit 時，系統會提示您授予 AWS 收集匿名使用資料的許可。此資料有助於 AWS 改善 CloudFormation 語言伺服器，並增強撰寫體驗。不會收集任何敏感資訊， AWS 也不會記錄或存放範本內容、資源組態或任何可識別身分的客戶資料。您可以隨時從 IDE 設定變更遙測偏好設定。重新啟動 IDE 以使變更生效。所收集的用量資料僅著重於特徵互動和效能指標。這些洞見有助於 AWS 識別和排定改善的優先順序，例如更快的驗證、增強的自動完成和更好的錯誤診斷。

### 步驟 2：存取 AWS Toolkit 中的 CloudFormation
<a name="ide-extension-access-toolkit-panel"></a>

安裝 AWS Toolkit 之後，請在 IDE 中開啟 CloudFormation 面板。在 VS 程式碼中，從活動列開啟 AWS Toolkit 面板，然後選擇 **CLOUDFORMATION**。在 JetBrains IDEs中，從側邊列開啟 **AWS Toolkit** 工具視窗，然後選取 **CloudFormation** 標籤。

CloudFormation 面板包含下列區段：
+ **區域**：顯示目前的 AWS 區域。在 VS 程式碼中，您可以透過選取區域名稱或使用 **AWS CloudFormation：從命令面板選取區域**命令來變更它。在 JetBrains IDEs中，區域是透過 AWS Toolkit 連線設定來設定。
+ **堆疊**：顯示您帳戶中 CloudFormation 堆疊的分頁清單。展開堆疊以檢視其**變更集**節點，其中列出與該堆疊相關聯的變更集。使用檢視堆疊詳細資訊動作來開啟堆疊詳細資訊檢視，其中會顯示堆疊概觀、事件、輸出和資源。
+ **資源**：新增資源類型之後，面板會在您的帳戶中顯示該類型的 AWS 資源。您可以檢視、重新整理、複製或匯入範本。

在 JetBrains IDEs 中，樹狀目錄上方的工具列可讓您快速存取常見動作，包括**驗證和部署**、**重新執行驗證和部署**、**新增資源類型**和**重新整理**。動作也可以透過在樹狀節點上按一下滑鼠右鍵的內容功能表來使用。

### 步驟 3：驗證、測試和精簡您的範本
<a name="ide-extension-validate-test-refine"></a>

當您撰寫 CloudFormation 範本時，IDE 會提供智慧型撰寫協助，協助您更快速地建立準確且合規的基礎設施。CloudFormation 語言伺服器會在背景執行，並提供下列撰寫功能：
+ 程式碼完成：根據 CloudFormation 結構描述建議資源類型、參數和屬性。
+ 新增現有 AWS 資源：可讓您將現有資源從 匯入 AWS 帳戶 範本。IDE 使用 [AWS 雲端控制 API (CCAPI)](https://docs.aws.amazon.com/cloudcontrolapi/latest/userguide/what-is-cloudcontrolapi.html) 擷取資源的即時組態和屬性，協助您複製或重複使用範本中的現有基礎設施。
+ 擷取至 參數：當您的游標位於範本中的常值 （例如，類似 的字串`t2.micro`) 上時，IDE 會提供重構動作，將值擷取至 `Parameters`區段，並將常值取代`!Ref`為新參數的 。如果相同的常值出現在多個位置，您可以選擇一次擷取所有出現的項目。

#### 將資源新增至範本
<a name="ide-extension-add-resources-to-template"></a>
+ **新增資源類型**：在 AWS 工具組 CloudFormation 面板的資源下****，新增要瀏覽的資源類型。在 VS 程式碼中，按一下**新增 \$1** 圖示，或使用命令調色盤中的**AWS CloudFormation：新增資源類型**命令。在 JetBrains 中，按一下工具列中的**新增資源類型**按鈕，或以滑鼠右鍵按一下**資源**節點。
+ **搜尋資源類型**：在搜尋對話方塊中，輸入您要新增 AWS 的資源類型。範例：
  + `AWS::S3::Bucket`
  + `AWS::Lambda::Function`
+ **瀏覽資源**：在**資源**區段下，會顯示您帳戶中偵測到 AWS 的資源分頁清單。如果您有許多資源，則只會顯示第一頁。使用導覽控制項來瀏覽其他頁面，並檢視所有可用的資源。
+ 選擇您要包含在範本中的資源。
+ 視您的目標而定，您可以透過兩種方式將資源插入範本：
  + **複製現有資源**：使用現有 AWS 資源的即時組態和屬性，在範本中建立新的資源。
  + **匯入現有資源**：使用即時狀態將實際資源新增至您的範本，藉此將實際資源插入您的堆疊。

**提示**
+ 您可以隨時重新整理**資源**區段，以檢視帳戶或區域中可用資源的最新清單。
+ 如果您要匯入資源，請勿新增已屬於相同帳戶中現有 CloudFormation 堆疊的資源。
+ 若要確認資源是否已由 CloudFormation 管理，請使用資源旁邊的資訊動作。在 VS 程式碼中，按一下 **i** 圖示。在 JetBrains IDEs中，在資源上按一下滑鼠右鍵，然後選擇**取得堆疊管理資訊**。

##### 新增相關資源
<a name="ide-extension-add-related-resources"></a>

在 VS 程式碼中，您可以使用命令 **AWS CloudFormation：依類型新增相關資源，將相關資源新增至選取的資源**。從範本中已定義的資源類型中選取資源類型後，IDE 會顯示通常與該類型相關聯或相依的資源清單。例如，如果您選取 `AWS::EC2::Instance`，IDE 可能會建議新增相關資源，例如 `AWS::EC2::SecurityGroup`或 `AWS::EC2::Subnet`。此功能可協助您快速建置連線的基礎設施元件，而無需手動搜尋相容的資源類型。JetBrains IDEs 目前不支援此功能。

#### 靜態驗證
<a name="ide-extension-static-validation"></a>

CloudFormation Language Server 提供內建的靜態驗證，採用 [AWS CloudFormation Linter (cfn-lint)](https://github.com/aws-cloudformation/cfn-lint) 和 技術[AWS CloudFormation Guard](https://docs.aws.amazon.com/cfn-guard/latest/ug/what-is-guard.html)。當您編寫範本時，這些驗證會在幕後執行，協助您在部署之前識別語法錯誤、合規差距和最佳實務問題。

**靜態驗證概觀**

您會在 IDE 中看到兩種類型的即時靜態驗證：
+ CloudFormation Linter (`cfn-lint`)：根據 CloudFormation 資源規格和結構描述規則驗證您的範本。
+ Guard (`cfn-guard`)：根據合規規則和組織政策套件驗證您的範本。

##### CloudFormation Linter (cfn-lint)
<a name="ide-extension-cfn-linter-details"></a>

CloudFormation Linter 已整合至 IDE，可在您輸入時自動檢查範本語法和結構。
+ **結構描述驗證**：偵測語法和結構描述錯誤，以確保您的範本符合 CloudFormation 資源結構描述。
+ **錯誤反白顯示**：在問題下顯示內嵌標記，代表部署封鎖程式或警告。
+ **暫留說明**：當您將滑鼠游標停留在錯誤上時，IDE 會顯示與該問題相關聯的診斷訊息。如果有快速修正，也會提供。

##### Guard 整合
<a name="ide-extension-cfn-guard-integration"></a>

Guard 會根據定義合規和安全性政策的規則集來驗證您的範本。IDE 透過 CloudFormation 語言伺服器即時執行 Guard 驗證，在您撰寫範本時提供立即意見回饋。
+ **預設規則套件**：IDE 包含一組預先註冊的 Guard 規則，著重於資源安全和組態衛生的基礎最佳實務。若要進一步了解，請參閱 [防護規則登錄](https://github.com/aws-cloudformation/aws-guard-rules-registry)檔。
+ **新增規則套件**：若要新增或修改規則集，請開啟 IDE 設定並導覽至 Guard 組態區段，以選取或上傳其他 Guard 規則套件。

**秘訣**：了解診斷指標
+ 藍色指標：最佳實務提示或最佳化建議。
+ 黃色指標：非封鎖問題的警告 （例如，缺少標籤或參數）。
+ 紅色指標：部署封鎖程式，例如無效的屬性名稱、缺少必要欄位或結構描述不相符。

### 步驟 4：導覽範本
<a name="ide-extension-navigate-template"></a>

IDE 提供 CloudFormation 範本的結構化階層檢視，組織成 `Parameters`、`Outputs`、 `Resources`和 等區段`Mappings`，顯示每個資源類型和邏輯 ID。這可讓您輕鬆地快速尋找和導覽至大型範本中的特定資源或參數。在 VS 程式碼中， **Explorer** 邊欄中的**大綱**面板會顯示此結構。在 JetBrains IDEs中，開啟**結構**工具視窗以檢視目前開啟檔案的範本結構。

您可以針對 `GetAtt`和 等內部函數使用 **Go to Definition**`Ref`，可讓您直接跳到範本中參考的資源或參數。這可協助您追蹤相依性、了解資源關係，並更有效率地進行編輯。

### 步驟 5：驗證和部署
<a name="ide-extension-validate-deploy"></a>

當您準備好部署 CloudFormation 範本時，請使用驗證和部署功能來建立變更集。IDE 會驗證您的範本，如果找不到封鎖錯誤，則會繼續建立[偏離感知的變更集](drift-aware-change-sets.md)。IDE 接著會顯示差異檢視，讓您可以在執行變更集之前檢閱所有提議的變更。

在 VS 程式碼中，開啟命令面板並執行 **AWS CloudFormation：驗證和部署**。命令調色盤會逐步引導您選取範本、堆疊名稱、參數、功能和其他部署選項。在 JetBrains IDEs中，使用**驗證和部署**工具列按鈕，在編輯器中的範本檔案上按一下滑鼠右鍵，或在樹狀目錄中的堆疊上按一下滑鼠右鍵。JetBrains 會顯示精靈對話方塊，您可以在其中設定所有部署選項，包括範本選擇、堆疊名稱、參數、功能、標籤和進階選項。

#### 驗證的運作方式
<a name="ide-extension-how-validation-works"></a>

IDE 會在[部署之前自動執行驗證檢查](validate-stack-deployments.md)，並根據常見的失敗原因驗證您的範本，包括：
+ 屬性語法或結構描述不相符無效：這些問題通常在撰寫`cfn-lint`期間由 發現，但如果您繼續部署而不解決，CloudFormation 的部署時間驗證會在建立或更新堆疊之前顯示相同的錯誤。
+ 資源名稱與您帳戶中的現有資源衝突。
+ 服務特定的限制條件，例如 S3 儲存貯體名稱衝突或缺少加密。

如果驗證偵測到錯誤，IDE 會直接在範本中反白問題，並在診斷面板中列出錯誤。每個問題都包含導致失敗的特定屬性或資源，以及建議的修正。如果沒有封鎖錯誤，您可以繼續部署階段。

如果發現警告 （非封鎖問題），則會出現一個對話方塊，允許您繼續部署或取消並進行更正。

IDE 會開啟[偏離感知變更集](drift-aware-change-sets.md)，顯示目前範本與部署堆疊組態之間的任何差異。這可讓您在執行之前檢閱、確認或取消變更集。取消部署會刪除變更集。

偏離感知變更集可讓您安全地處理堆疊偏離，以增強 CloudFormation 部署程序。當資源的實際狀態與 CloudFormation 範本中定義的狀態不同時，就會發生堆疊偏離，通常是由於透過 AWS 管理主控台、CLI 或 SDK 進行的手動變更。CloudFormation [偏離感知變更集](drift-aware-change-sets.md)會比較您處理過的堆疊組態與即時資源狀態，而 IDE 會呈現這些差異，讓您可以在部署之前將資源恢復合規。

#### 檢視堆疊事件
<a name="ide-extension-view-stack-events"></a>

部署開始時，您可以從 CloudFormation 面板即時監控進度。在**堆疊事件**下，您會看到部署期間執行的操作清單。每個事件都包含詳細資訊，例如：
+ **時間戳記**：事件發生的時間
+ **資源**：正在建立、更新或刪除的特定 AWS 資源
+ **狀態**：操作的目前狀態 （例如 `CREATE_IN_PROGRESS`、 `UPDATE_COMPLETE`或 `ROLLBACK_IN_PROGRESS`)
+ **原因**：其他內容或錯誤訊息，如適用

您也可以從此面板檢視堆疊**的資源**和**輸出**。**堆疊事件**檢視可協助您追蹤部署進度、識別潛在問題，並確認堆疊何時成功完成。

## 在 IDE 中初始化 CloudFormation 專案 （僅限 VS 程式碼）
<a name="ide-extension-initialize-project"></a>

在 IDE 中初始化 CloudFormation 專案可協助您設定具有正確資料夾、環境組態和 AWS 憑證的結構化工作區，以便您可以可靠地驗證和部署範本。您可以直接從 IDE 初始化新的 CloudFormation 專案，以建立此建議設定。此功能目前僅適用於 VS 程式碼，JetBrains IDEs 不支援此功能。

**若要初始化 CloudFormation 專案：**
+ **開啟命令調色盤**
  + 從 VS 程式碼中，開啟命令調色盤 (`Ctrl+Shift+P` `Cmd+Shift+P` 上的 或 macOS)。
  + 選擇 **AWS CloudFormation：CFN Init：初始化專案**。
+ **選擇專案目錄**
  + 根據預設，IDE 會使用您目前的工作目錄。
  + 您可以將此路徑變更為您要存放 CloudFormation 範本的任何資料夾。
+ **選取您的 AWS 登入資料設定檔**
  + 系統會提示您選擇 AWS 登入資料設定檔。選取的設定檔用於環境偵測、驗證和部署。
+ **設定您的環境**
  + 系統會提示您建立或選取環境。
  + 環境會定義部署或驗證範本的位置和方式 （例如 dev、beta 或 production)。您可以使用 **AWS CloudFormation：CFN Init：新增環境**來選取或變更您的環境。
  + 您可以使用 **AWS CloudFormation：CFN Init： Remove Environment** 來移除您選取的環境。
+ **（選用） 匯入參數檔案**
  + 如果您已經有現有的參數檔案，IDE 可讓您在初始化期間匯入它們。
  + IDE 會自動偵測相容的檔案，並將其連結至您的專案，以用於範本驗證和部署。
+ **命名並完成專案**
  + 提供專案名稱，例如 beta-environment，並完成設定。
  + IDE 會為您建立初始專案結構和組態檔案。

您可以直接從 IDE 執行驗證、預覽部署或切換環境。

## 開放原始碼
<a name="ide-extension-open-source"></a>

 AWS CloudFormation 語言伺服器是根據 Apache-2.0授權進行開放原始碼，為客戶提供範本診斷、結構描述驗證和靜態分析執行方式的完整透明度。對於在採用工具之前需要來源層級可見性的客戶，這可以減少安全和合規摩擦。

程式碼庫可在 GitHub 上公開取得：https：//[https://github.com/aws-cloudformation/cloudformation-languageserver/](https://github.com/aws-cloudformation/cloudformation-languageserver/)。

## 需要幫助？
<a name="ide-extension-need-help"></a>

試用 [CloudFormation 社群](https://repost.aws/tags/TAm3R3LNU3RfSX9L23YIpo3w) AWS re:Post。

# 使用 IaC 產生器從現有資源中產生範本
<a name="generate-IaC"></a>

使用 CloudFormation 基礎設施做為程式碼產生器 (IaC 產生器），您可以使用您帳戶中佈建但尚未由 CloudFormation 管理 AWS 的資源產生範本。

以下是 IaC 產生器的優點：
+ 將全部應用程式置於 CloudFormation 管理下，或將其移轉至 AWS CDK 應用程式。
+ 產生範本，而不必依屬性來描述資源屬性，然後轉換為 JSON 或 YAML 語法。
+ 使用範本在新帳戶或區域中複寫資源。

IaC 產生程序包含下列步驟：

1. **掃描資源** – 第一步是開始掃描資源。此掃描適用於整個區域，會在 30 天後過期。在此期間，可以從相同的掃描中建立多個範本。

1. **建立範本** – 若要建立範本，可使用兩個選項：
   + 從頭開始建立新範本，並將掃描的資源和相關資源新增至其中。
   + 使用現有的 CloudFormation 堆疊作為起點，並將掃描的資源和相關資源新增至其範本。

1. **匯入資源** – 使用您的範本將資源匯入為 CloudFormation 堆疊，或將其遷移至 AWS CDK 應用程式。

IaC 產生器功能適用於所有商業區域，並支援許多常見的 AWS 資源類型。如需所支援資源的完整清單，請參閱[資源類型支援](resource-import-supported-resources.md)。

**Topics**
+ [考量事項](#iac-generator-considerations)
+ [掃描資源所需的 IAM 許可](#iac-generator-permissions)
+ [範本產生、管理和刪除的常用命令](#iac-generator-commonly-used-commands)
+ [將範本遷移至 AWS CDK](#iac-generator-cdk-migrate)
+ [透過 CloudFormation IaC 產生器啟動資源掃描](iac-generator-start-resource-scan.md)
+ [在 CloudFormation 主控台中檢視掃描摘要](generate-IaC-view-scan-summary.md)
+ [透過 IaC 產生器掃描的資源建立 CloudFormation 範本](iac-generator-create-template-from-scanned-resources.md)
+ [透過掃描的資源建立 CloudFormation 堆疊](iac-generator-create-stack-from-scanned-resources.md)
+ [解決唯寫屬性](generate-IaC-write-only-properties.md)

## 考量事項
<a name="iac-generator-considerations"></a>

您可以為具有讀取存取權 AWS 的資源產生 JSON 或 YAML 範本。IaC 產生器功能的範本能夠可靠且快速地模型化雲端資源，而無需依屬性來描述資源屬性。

下表列出可用於 IaC 產生功能的配額。


| 名稱 | 完整掃描 | 部分掃描 | 
| --- | --- | --- | 
|  掃描中可處理的資源數量上限  |  100,000  |  100,000  | 
|  每天的掃描數 (適用於資源少於 10,000 的掃描)  |  10  |  10  | 
|  每天的掃描數 (適用於資源超過 10,000 的掃描)  |  1  |  1  | 
|  每個帳戶產生的範本並行數量  |  5  |  5  | 
|  針對一個範本產生而建模的資源並行數量  |  5  |  5  | 
|  可在一個範本中建模的資源總數  |  500  |  500  | 
|  每個帳戶產生的範本數量上限  |  1,000  |  1,000  | 

**重要**  
IaC 產生器僅支援 區域中 Cloud Control API 支援 AWS 的資源。如需詳細資訊，請參閱[資源類型支援](resource-import-supported-resources.md)。

## 掃描資源所需的 IAM 許可
<a name="iac-generator-permissions"></a>

若要使用 IaC 產生器來掃描資源，則 IAM 主體 (使用者、角色或群組) 必須擁有下列權限：
+ CloudFormation 掃描許可
+ 目標 AWS 服務的讀取許可

掃描範圍僅限於您有權讀取的資源。缺少許可不會導致掃描失敗，但會排除這些資源。

如需可授予掃描和範本管理許可的 IAM 政策範例，請參閱 [允許所有 IaC 產生器操作](security_iam_id-based-policy-examples.md#iam-policy-example-for-iac-generator)。

## 範本產生、管理和刪除的常用命令
<a name="iac-generator-commonly-used-commands"></a>

使用 IaC 產生器的常用命令包括：
+ [start-resource-scan](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/start-resource-scan.html)，開始掃描 AWS 區域中帳戶的資源。
+ [describe-resource-scan](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-resource-scan.html)，監控資源掃描的進度。
+ [list-resource-scans](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-resource-scans.html)，列出 AWS 區域中的資源掃描。
+ [list-resource-scan-resources](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-resource-scan-resources.html)，列出資源掃描期間找到的資源。
+  [list-resource-scan-related-resources](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-resource-scan-related-resources.html)，列出與掃描資源相關的資源。
+ [create-generated-template](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-generated-template.html)，從一組掃描的資源中產生 CloudFormation 範本。
+ [update-generated-template](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/update-generated-template.html)，更新產生的範本。
+ [describe-generated-template](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-generated-template.html)，傳回所產生範本的相關資訊。
+ [list-generated-templates](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-generated-templates.html)，列出帳戶和目前區域中所有產生的範本。
+ [delete-generated-template](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/delete-generated-template.html)，刪除產生的範本。

## 將範本遷移至 AWS CDK
<a name="iac-generator-cdk-migrate"></a>

 AWS Cloud Development Kit (AWS CDK) 是開放原始碼軟體開發架構，可讓您使用熱門的程式設計語言來開發、管理和部署 CloudFormation 資源。

CLI AWS CDK 提供與 IaC 產生器的整合。使用 AWS CDK CLI `cdk migrate`命令來轉換 CloudFormation 範本，並建立新的 CDK 應用程式，其中包含您的 資源。然後，您可以使用 AWS CDK 來管理您的 資源並部署到 CloudFormation。

如需詳細資訊，請參閱《AWS Cloud Development Kit (AWS CDK) 開發人員指南**》中的[移轉至 AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/migrate.html)。

# 透過 CloudFormation IaC 產生器啟動資源掃描
<a name="iac-generator-start-resource-scan"></a>

從現有資源建立範本前，您必須先啟動資源掃描，以探索目前的資源及其彼此間的關係。

您可以透過下列其中一種方式啟動資源掃描。對於 IaC 產生器的首次使用者，建議選擇第一種方式。
+ **掃描所有資源 (完整掃描)** – 掃描目前帳戶和區域中的所有現有資源。對於 1,000 個資源，此掃描程序可能需要長達 10 分鐘。
+ **掃描特定資源 (部分掃描)** – 手動選擇要在目前帳戶和區域中掃描的資源類型。此選項提供更快且更具針對性的掃描程序，非常適用於反覆式範本開發。

掃描完成後，您可以選擇要在產生範本時納入哪些資源及其相關資源。使用部分掃描時，相關資源僅在下列任一情況下會在範本產生期間可供使用：
+ 您在啟動掃描前已明確選取它們，或
+ 它們是探索您所選資源類型必需的資源。

例如，若您選取 `AWS::EKS::Nodegroup`，但未選取 `AWS::EKS::Cluster`，IaC 產生器會自動將 `AWS::EKS::Cluster` 資源納入掃描，因為探索節點群組需先探索叢集。在所有其他情況下，掃描僅會包含您明確選取的資源。

**注意**  
繼續操作之前，請確認您具備使用 IaC 產生器所需的許可。如需詳細資訊，請參閱[掃描資源所需的 IAM 許可](generate-IaC.md#iac-generator-permissions)。

**Topics**
+ [啟動資源掃描 (主控台)](#start-resource-scan-console)
+ [啟動資源掃描 (AWS CLI)](#start-resource-scan-cli)

## 啟動資源掃描 (主控台)
<a name="start-resource-scan-console"></a>

**啟動所有資源類型的資源掃描 (完整掃描)**

1. 開啟 CloudFormation 主控台的 [IaC 產生器頁面](https://console.aws.amazon.com/cloudformation/home?#iac-generator)。

1. 在畫面頂端的導覽列上，選擇包含掃描資源的 AWS 區域 。

1. 從**掃描**面板中，選擇**開始新的掃描**，再選擇**掃描所有資源**。

**啟動特定資源類型的資源掃描 (部分掃描)**

1. 開啟 CloudFormation 主控台的 [IaC 產生器頁面](https://console.aws.amazon.com/cloudformation/home?#iac-generator)。

1. 在畫面頂端的導覽列上，選擇包含掃描資源的 AWS 區域 。

1. 從**掃描**面板中，選擇**啟動新的掃描**，再選擇**掃描特定資源**。

1. 在**啟動部分掃描**對話方塊中，選取最多 100 種資源類型，然後選擇**啟動掃描**。

## 啟動資源掃描 (AWS CLI)
<a name="start-resource-scan-cli"></a>

**啟動所有資源類型的資源掃描 (完整掃描)**  
使用以下 [start-resource-scan](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/start-resource-scan.html) 命令。將 *us-east-1* 取代 AWS 區域 為包含要掃描之資源的 。

```
aws cloudformation start-resource-scan --region us-east-1
```

如果成功，此命令會傳回掃描的 ARN。請注意 `ResourceScanId` 屬性中的 ARN。您建立範本時會需要用到它。

```
{
    "ResourceScanId":
      "arn:aws:cloudformation:region:account-id:resourceScan/0a699f15-489c-43ca-a3ef-3e6ecfa5da60"
}
```

**啟動特定資源類型的資源掃描 (部分掃描)**

1. 使用下列 [cat](https://en.wikipedia.org/wiki/Cat_(Unix)) 命令，將要掃描的資源類型儲存至主目錄中名為 `config.json` 的 JSON 檔案。下列是掃描設定範例，會掃描 Amazon EC2 執行個體、安全群組及所有 Amazon S3 資源。

   ```
   $ cat > config.json
   [
     {
       "Types":[
         "AWS::EC2::Instance",
         "AWS::EC2::SecurityGroup",
         "AWS::S3::*"
       ]
     }
   ]
   ```

1. 使用 [start-resource-scan](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/start-resource-scan.html) 命令，搭配 `--scan-filters` 選項和您建立的 `config.json` 檔案，以啟動部分掃描。將 *us-east-1* 取代為包含要掃描資源的 AWS 區域 。

   ```
   aws cloudformation start-resource-scan --scan-filters file://config.json --region us-east-1
   ```

   如果成功，此命令會傳回掃描的 ARN。請注意 `ResourceScanId` 屬性中的 ARN。您建立範本時會需要用到它。

   ```
   {
       "ResourceScanId":
         "arn:aws:cloudformation:region:account-id:resourceScan/0a699f15-489c-43ca-a3ef-3e6ecfa5da60"
   }
   ```

**監控資源掃描的進度**  
使用 [describe-resource-scan](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-resource-scan.html) 命令。對於 `--resource-scan-id` 選項，請將範例 ARN 取代為實際 ARN。

```
aws cloudformation describe-resource-scan --region us-east-1 \
  --resource-scan-id arn:aws:cloudformation:us-east-1:123456789012:resourceScan/0a699f15-489c-43ca-a3ef-3e6ecfa5da60
```

如果此命令成功執行，您會看到類似如下的輸出傳回：

```
{
    "ResourceScanId": "arn:aws:cloudformation:region:account-id:resourceScan/0a699f15-489c-43ca-a3ef-3e6ecfa5da60",
    "Status": "COMPLETE",
    "StartTime": "2023-08-21T03:10:38.485000+00:00",
    "EndTime": "2023-08-21T03:20:28.485000+00:00",
    "PercentageCompleted": 100.0,
    "ResourceTypes": [
        "AWS::CloudFront::CachePolicy",
        "AWS::CloudFront::OriginRequestPolicy",
        "AWS::EC2::DHCPOptions",
        "AWS::EC2::InternetGateway",
        "AWS::EC2::KeyPair",
        "AWS::EC2::NetworkAcl",
        "AWS::EC2::NetworkInsightsPath",
        "AWS::EC2::NetworkInterface",
        "AWS::EC2::PlacementGroup",
        "AWS::EC2::Route",
        "AWS::EC2::RouteTable",
        "AWS::EC2::SecurityGroup",
        "AWS::EC2::Subnet",
        "AWS::EC2::SubnetCidrBlock",
        "AWS::EC2::SubnetNetworkAclAssociation",
        "AWS::EC2::SubnetRouteTableAssociation",
        ...
    ],
    "ResourcesRead": 676
}
```

如需部分掃描，輸出格式應類似以下內容：

```
{
    "ResourceScanId": "arn:aws:cloudformation:region:account-id:resourceScan/0a699f15-489c-43ca-a3ef-3e6ecfa5da60",
    "Status": "COMPLETE",
    "StartTime": "2025-03-06T18:24:19.542000+00:00",
    "EndTime": "2025-03-06T18:25:23.142000+00:00",
    "PercentageCompleted": 100.0,
    "ResourceTypes": [
        "AWS::EC2::Instance",
        "AWS::EC2::SecurityGroup",
        "AWS::S3::Bucket",
        "AWS::S3::BucketPolicy"
    ],
    "ResourcesRead": 65,
    "ScanFilters": [
        {
            "Types": [
                "AWS::EC2::Instance",
                "AWS::EC2::SecurityGroup",
                "AWS::S3::*"
            ]
        }
    ]
}
```

如需輸出中欄位的說明，請參閱《AWS CloudFormation API 參考**》中的 [DescribeResourceScan](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeResourceScan.html)。

# 在 CloudFormation 主控台中檢視掃描摘要
<a name="generate-IaC-view-scan-summary"></a>

掃描完成後，可以檢視掃描期間找到的資源視覺化，以協助您識別不同產品類型的資源集中度。

**檢視掃描期間找到之資源的相關資訊**

1. 開啟 CloudFormation 主控台的 [IaC 產生器頁面](https://console.aws.amazon.com/cloudformation/home?#iac-generator)。

1. 在畫面頂端的導覽列上，選擇包含要檢視之資源掃描 AWS 區域 的 。

1. 在導覽窗格中，選擇 **IaC 產生器**。

1. 在**掃描資源明細**中，可以依產品類型找到掃描資源的視覺化明細，例如**運算**和**儲存**。

1. 若要自訂顯示的產品類型數量，請選擇**篩選顯示的資料**。這可協助您量身打造視覺化效果，以專注於您最感興趣的產品類型。

1. 頁面右側是**掃描摘要詳細資訊**面板。如要開啟該面板，請選擇**開啟面板**圖示。

![\[IaC 產生器主控台可提供掃描資源的視覺化明細。\]](http://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/images/IaC-generator-scan-summary.png)


# 透過 IaC 產生器掃描的資源建立 CloudFormation 範本
<a name="iac-generator-create-template-from-scanned-resources"></a>

本主題說明如何從透過 IaC 產生器功能掃描的資源建立範本。

## 透過掃描的資源建立範本 (主控台)
<a name="create-template-from-scanned-resources-console"></a>

**透過掃描的資源建立堆疊範本**

1. 開啟 CloudFormation 主控台的 [IaC 產生器頁面](https://console.aws.amazon.com/cloudformation/home?#iac-generator)。

1. 在畫面頂端的導覽列上，選擇包含掃描資源的 AWS 區域 。

1. 從**範本**區段，選擇**建立範本**。

1. 選擇**從新範本開始**。

   1. 對於**範本名稱**，提供範本的名稱。

   1. (選用) 設定**您的刪除政策和****更新取代政策**。

   1. 選擇**下一步**，將掃描的資源新增至範本。

1. 對於**新增掃描的資源**，瀏覽掃描的資源清單，並選取您要新增至範本的資源。您可以依據資源識別碼、資源類型或標籤篩選資源。這些篩選條件是相互包含的。

1. 將所有需要的資源新增至範本後，選擇**下一步**以離開**新增掃描的資源**頁面，然後繼續前往**新增相關資源**頁面。

1. 檢閱建議的相關資源清單。Amazon EC2 執行個體與安全群組等相關資源是相互依存的，通常歸屬於相同的工作負載。選取您要納入產生範本的相關資源。
**注意**  
建議您將所有相關資源新增至此範本。

1. 檢閱範本詳細資訊、掃描的資源及相關資源。

1. 選擇**建立範本**，以離開**檢閱和建立**頁面，並建立範本。

## 透過掃描的資源建立範本 (AWS CLI)
<a name="create-template-from-scanned-resources-cli"></a>

**透過掃描的資源建立堆疊範本**

1. 使用 [list-resource-scan-resources](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-resource-scan-resources.html) 命令列出掃描期間找到的資源，並可選擇性指定限制輸出的 `--resource-identifier` 選項。對於 `--resource-scan-id` 選項，請將範例 ARN 取代為實際 ARN。

   ```
   aws cloudformation list-resource-scan-resources \
     --resource-scan-id arn:aws:cloudformation:us-east-1:123456789012:resourceScan/0a699f15-489c-43ca-a3ef-3e6ecfa5da60 \
     --resource-identifier MyApp
   ```

   下列是回應範例，其中 `ManagedByStack` 表示 CloudFormation 是否已管理該資源。複製輸出內容。下一個步驟需要此值。

   ```
   {
       "Resources": [
           {
               "ResourceType": "AWS::EKS::Cluster",
               "ResourceIdentifier": {
                   "ClusterName": "MyAppClusterName"
               },
               "ManagedByStack": false
           },
           {
               "ResourceType": "AWS::AutoScaling::AutoScalingGroup",
               "ResourceIdentifier": {
                   "AutoScalingGroupName": "MyAppASGName"
               },
               "ManagedByStack": false
           }
       ]
   }
   ```

   如需輸出中欄位的說明，請參閱《*AWS CloudFormation API 參考*》中的 [ScannedResource](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ScannedResource.html)。

1. 使用 `cat` 命令，將資源類型和識別碼儲存至主目錄中名為 `resources.json` 的 JSON 檔案。以下是基於上述步驟中範例命令的範例 JSON。

   ```
   $ cat > resources.json
   [
       {
           "ResourceType": "AWS::EKS::Cluster",
           "ResourceIdentifier": {
               "ClusterName": "MyAppClusterName"
           }
       },
       {
           "ResourceType": "AWS::AutoScaling::AutoScalingGroup",
           "ResourceIdentifier": {
               "AutoScalingGroupName": "MyAppASGName"
           }
       }
   ]
   ```

1. 使用 [list-resource-scan-related-resources](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-resource-scan-related-resources.html) 命令，搭配您建立的 `resources.json` 檔案，列出與您掃描資源相關的資源。

   ```
   aws cloudformation list-resource-scan-related-resources \
     --resource-scan-id arn:aws:cloudformation:us-east-1:123456789012:resourceScan/0a699f15-489c-43ca-a3ef-3e6ecfa5da60 \
     --resources file://resources.json
   ```

   下列是回應範例，其中 `ManagedByStack` 表示 CloudFormation 是否已管理該資源。將這些資源新增至您在上一步驟建立的 JSON 檔案。您建立範本時會需要用到它。

   ```
   {
       "RelatedResources": [
           {
               "ResourceType": "AWS::EKS::Nodegroup",
               "ResourceIdentifier": {
                   "NodegroupName": "MyAppNodegroupName"
               },
               "ManagedByStack": false
           },
           {
               "ResourceType": "AWS::IAM::Role",
               "ResourceIdentifier": {
                   "RoleId": "arn:aws::iam::account-id:role/MyAppIAMRole"
               },
               "ManagedByStack": false
           }
       ]
   }
   ```

   如需輸出中欄位的說明，請參閱《*AWS CloudFormation API 參考*》中的 [ScannedResource](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ScannedResource.html)。
**注意**  
輸入的資源清單長度不得超過 100。若要列出超過 100 個資源的相關資源，請以每批次 100 個的方式執行 **list-resource-scan-related-resources** 命令，並合併結果。  
請注意，輸出清單中可能包含重複的資源。

1. 若要建立新的啟動範本，請按如下所示使用 [create-generated-template](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-generated-template.html) 命令，且進行這些修改：
   + `us-east-1` 將 取代 AWS 區域 為包含掃描資源的 。
   + 將 `MyTemplate` 取代為要建立的範本名稱。

   ```
   aws cloudformation create-generated-template --region us-east-1 \
    --generated-template-name MyTemplate \
     --resources file://resources.json
   ```

   以下是範例 `resources.json` 檔案。

   ```
   [
       {
           "ResourceType": "AWS::EKS::Cluster",
           "LogicalResourceId":"MyCluster",
           "ResourceIdentifier": {
               "ClusterName": "MyAppClusterName"
           }
       },
       {
           "ResourceType": "AWS::AutoScaling::AutoScalingGroup",
           "LogicalResourceId":"MyASG",
           "ResourceIdentifier": {
               "AutoScalingGroupName": "MyAppASGName"
           }
       },
       {
           "ResourceType": "AWS::EKS::Nodegroup",
           "LogicalResourceId":"MyNodegroup",
           "ResourceIdentifier": {
               "NodegroupName": "MyAppNodegroupName"
           }
       },
       {
           "ResourceType": "AWS::IAM::Role",
           "LogicalResourceId":"MyRole",
           "ResourceIdentifier": {
               "RoleId": "arn:aws::iam::account-id:role/MyAppIAMRole"
           }
       }
   ]
   ```

   如果成功，此命令會傳回下列內容：

   ```
   {
     "Arn":
       "arn:aws:cloudformation:region:account-id:generatedtemplate/7fc8512c-d8cb-4e02-b266-d39c48344e48",
     "Name": "MyTemplate"
   }
   ```

# 透過掃描的資源建立 CloudFormation 堆疊
<a name="iac-generator-create-stack-from-scanned-resources"></a>

建立範本後，您可在建立堆疊和匯入掃描的資源之前，透過 Infrastructure Composer 預覽產生的範本。這能協助您視覺化完整的應用程式架構，以及資源與其彼此間的關係。如需有關 Infrastructure Composer 的更多資訊，請參閱 [透過 Infrastructure Composer 視覺化建立範本](infrastructure-composer-for-cloudformation.md)。

**建立堆疊並匯入掃描的資源**

1. 開啟 CloudFormation 主控台的 [IaC 產生器頁面](https://console.aws.amazon.com/cloudformation/home?#iac-generator)。

1. 在畫面頂端的導覽列上， AWS 區域 為您的範本選擇 。

1. 選擇**範本**索引標籤，然後您的範本名稱以檢視更多資訊。您的範本名稱以檢視更多資訊。

1. 在**範本定義**索引標籤的**範本**區段頂端，您可根據偏好設定，將範本語法在 YAML 和 JSON 之間切換。

1. 檢閱範本的詳細資訊，確保所有設定皆正確無誤。為了便於檢閱和理解範本，您可以透過 Infrastructure Composer 將預設的程式碼檢視切換為範本中所描述基礎設施的圖形化檢視。為此，請在**範本**下選擇**畫布**，而不是**範本**。

    **畫面動作** 
   + 若要著重檢視範本中特定資源的詳細資訊，請按兩下卡片以開啟**資源屬性**面板。
   + 若要在畫布上視覺化排列和整理卡片，請從畫布左上角選擇**排列**。
   + 要放大和縮小畫布，請使用畫布右下角的縮放控制項。

1. 要在主控台中檢視特定資源，請選擇**範本資源**索引標籤，然後選擇要查看的資源實體 ID。這會將您導向該特定資源的主控台。您也可以透過**範本資源**索引標籤，在範本定義中新增、移除和重新同步資源。

1. 在**範本定義**索引標籤上，IaC 產生器可能會對包含唯寫屬性的資源發出警告。檢閱警告後，您可下載產生的範本並進行任何必要變更。如需詳細資訊，請參閱[解決唯寫屬性](generate-IaC-write-only-properties.md)。

1. 當您對範本定義感到滿意時，在**範本定義**索引標籤上，選擇**匯入至堆疊**，然後選擇**下一步**。

1. 在**指定堆疊****詳細資訊頁面的指定堆疊**面板中，輸入您 的堆疊的名稱，然後選擇**下一步**。

1. 檢閱並輸入堆疊的參數。選擇**下一步**。

1. 在**檢閱變更**頁面上檢閱您的選項，然後選擇**下一步**。

1. 在**檢閱和匯入**頁面上檢閱您的詳細資訊，然後選擇**匯入資源**。

# 解決唯寫屬性
<a name="generate-IaC-write-only-properties"></a>

使用 CloudFormation IaC 產生器，您可以使用已在帳戶中佈建且尚未由 CloudFormation 管理的資源來產生範本。不過，某些資源屬性會指定為*唯寫*，這表示其可以寫入，但 CloudFormation 無法讀取，例如資料庫密碼。

透過現有資源產生 CloudFormation 範本時，唯寫屬性會帶來挑戰。在大多數情況下，CloudFormation 會將這些屬性轉換為所產生範本中的參數。這可讓您在匯入操作期間將屬性輸入為參數值。不過，在某些情況下無法進行此轉換，CloudFormation 會以不同的方式處理這些案例。

## 互斥屬性
<a name="write-only-mutually-exclusive-properties"></a>

有些資源有多個互斥屬性集，其中至少有些是唯讀屬性。在這些情況下，IaC 產生器無法判斷在建立期間將哪組專用屬性套用至資源。例如，可以使用其中一個屬性集來提供 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) 的程式碼。
+ `Code/S3Bucket`、`Code/S3Key` 和可選的 `Code/S3ObjectVersion`
+ `Code/ImageUri`
+ `Code/ZipFile`

所有這些屬性都是唯寫屬性。IaC 產生器會選取其中一個專用屬性集，並將其新增至產生的範本。系統會為每個唯寫屬性新增參數。參數名稱包含 `OneOf`，參數說明指出對應的屬性可以取代為其他專用屬性。IaC 產生器會為包含的屬性設定 `MUTUALLY_EXCLUSIVE_PROPERTIES` 的警告類型。

## 互斥類型
<a name="write-only-mutually-exclusive-types"></a>

在某些情況下，唯寫屬性可以是多種資料類型。例如，[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-restapi.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-restapi.html) 的 `Body` 屬性可以是 `object` 或 `string`。在這種情況下，IaC 產生器會使用 `string` 的類型在產生的範本中包含屬性，並設定 `MUTUALLY_EXCLUSIVE_TYPES` 的警告類型。

## Array 屬性
<a name="write-only-array-properties"></a>

如果唯寫屬性具有 `array` 類型，則 IaC 產生器無法將其包含在產生的範本中，因為參數只能是純量值。在此情況下，會從範本中省略該屬性，並設定 `UNSUPPORTED_PROPERTIES` 的警告類型。

## 可選屬性
<a name="write-only-optional-properties"></a>

對於選用的唯寫屬性，IaC 產生器無法偵測在設定資源時是否使用屬性。在此情況下，會從產生的範本中省略該屬性，並設定 `UNSUPPORTED_PROPERTIES` 的警告類型。

## 警告和後續步驟
<a name="write-only-properties-warnings-and-next-steps"></a>

若要確定哪些屬性為唯讀屬性，必須查看 IaC 產生器主控台傳回的警告。[AWS 資源和屬性類型參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)不會指出屬性是否為唯讀屬性，或者它是否支援多種類型。

或者，可以從資源提供者結構描述中查看哪些屬性是唯讀屬性。若要下載資源提供者結構描述，請參閱 [CloudFormation 資源提供者結構描述](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/resource-type-schemas.html)。

**若要解決唯寫屬性的問題**

1. 開啟 CloudFormation 主控台的 [IaC 產生器頁面](https://console.aws.amazon.com/cloudformation/home?#iac-generator)。

1. 在畫面頂端的導覽列上， AWS 區域 為您的範本選擇 。

1. 選擇**範本**索引標籤，然後選擇建立的範本名稱。

1. 在**範本定義**索引標籤中，當產生的範本包含具有唯寫屬性的資源時，IaC 產生器主控台會顯示警告，其中包含問題類型的摘要。例如：  
![\[有關所產生範本中唯寫屬性的 IaC 產生器主控台警告\]](http://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/images/IaC-generator-write-only-property-warning.png)

1. 選擇**檢視警告詳細資訊**以取得更多詳細資訊。由所產生的範本和資源類型中使用的邏輯 ID 來識別具有唯寫屬性的資源。

   使用警告清單來識別具有唯寫屬性的資源，並查看每個資源，以確定需要對產生的範本進行哪些變更 (如果有的話)。  
![\[有關所產生範本中唯寫屬性的 IaC 產生器主控台詳細警告\]](http://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/images/IaC-generator-write-only-property-resource-warning.png)

1. 如果必須更新範本以解決唯寫屬性的問題，請執行下列動作：

   1. 選擇**下載**以下載範本副本。

   1. 編輯範本。

   1. 變更完成後，可以選擇**匯入已編輯的範本**按鈕以繼續匯入程序。

# 如何解決 AWS::ApiGateway::RestAPI 資源中唯寫屬性的問題
<a name="generate-IaC-apigateway-restapi"></a>

本主題說明如何在使用 IaC 產生器時解決 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-restapi.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-restapi.html) 資源中唯寫屬性的問題。

## 問題
<a name="apigateway-restapi-write-only-properties-issue"></a>

當產生的範本包含 `AWS::ApiGateway::RestApi` 資源時，會產生警告，指出 `Body`、`BodyS3Location`和 `CloneFrom` 屬性已標識為 `UNSUPPORTED_PROPERTIES`。這是因為其是選用的唯寫屬性。IaC 產生器不知道這些屬性是否曾經套用至資源。因此，它會在產生的範本中忽略這些屬性。

## Resolution
<a name="apigateway-restapi-write-only-properties-resolution"></a>

若要設定 REST API 的 `Body` 屬性，請更新產生的範本。

1. 使用 Amazon API Gateway [https://docs.aws.amazon.com/apigateway/latest/api/API_GetExport.html](https://docs.aws.amazon.com/apigateway/latest/api/API_GetExport.html) API 動作來下載 API。例如，使用 [https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-export.html](https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-export.html) AWS CLI 命令。如需詳細資訊，請參閱《API Gateway 開發人員指南》**中的[從 API Gateway 匯出 REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html)。

1. 從 `GetExport` API 動作的回應中擷取 `Body` 屬性。將其上傳至 Amazon S3 儲存貯體。

1. 下載產生的範本。

1. 將 `BodyS3Location/Bucket` 和 `BodyS3Location/Key` 屬性新增至範本，指定存放 `Body` 的儲存貯體名稱和金鑰。

1. 在 IaC 產生器主控台中開啟產生的範本，然後選擇**匯入已編輯的範本**。

# 如何解決 AWS::Lambda::Function 資源中唯寫屬性的問題
<a name="generate-IaC-lambda-function"></a>

本主題說明如何在使用 IaC 產生器時解決 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) 資源中唯寫屬性的問題。

## 問題
<a name="lambda-function-mutually-exclusive-properties-issue"></a>

`AWS::Lambda::Function` 資源有三個互斥的屬性集，用於指定 Lambda 程式碼：
+ `Code/S3Bucket` 和 `Code/S3Key` 屬性，以及選用的 `Code/S3ObjectVersion` 屬性
+ `Code/ImageUri` 屬性
+ `Code/ZipFile` 屬性

只有其中一個集合可用於指定的 `AWS::Lambda::Function` 資源。

IaC 產生器無法確定用於建立或更新資源的專屬唯寫屬性集。因此，它只會在產生的範本中包含第一組屬性。忽略 `Code/ImageUri` 和 `Code/ZipFile` 屬性。

此外，IaC 產生器會發出下列警告：
+ **`MUTUALLY_EXCLUSIVE_PROPERTIES`** – 警告 `Code/S3Bucket` 和 `Code/S3Key` 被標識為互斥屬性。
+ **`UNSUPPORTED_PROPERTIES`** – 警告 `Code/S3ObjectVersion` 屬性不受支援。

若要在產生的範本中包含 `AWS::Lambda::Function` 資源，必須下載並更新具有正確程式碼屬性的範本。

## Resolution
<a name="lambda-function-mutually-exclusive-properties-resolution"></a>

**如果將 Lambda 程式碼存放在 Amazon S3 儲存貯體中，但不使用 `S3ObjectVersion` 屬性**，可以匯入產生的範本，無需進行任何修改。在匯入操作期間，IaC 產生器會要求您使用 Amazon S3 儲存貯體和金鑰作為範本參數。

****如果將 Lambda 程式碼儲存為 Amazon ECR 儲存庫**，可以使用下列指示來更新範本：**

1. 下載產生的範本。

1. 從產生的範本中移除 `Code/S3Bucket` 和 `Code/S3Key` 屬性的屬性和對應參數。

1. 使用 `Code/ImageUri` 屬性取代所產生範本中已移除的屬性，指定 Amazon ECR 儲存庫的 URL。

1. 在 IaC 產生器主控台中開啟產生的範本，然後選擇**匯入已編輯的範本**按鈕。

****如果將 Lambda 程式碼儲存為 zip 檔案**，可以使用下列指示來更新範本：**

1. 下載產生的範本。

1. 從產生的範本中移除 `Code/S3Bucket` 和 `Code/S3Key` 屬性的屬性和對應參數。

1. 使用 `Code/ZipFile` 屬性來取代所產生範本中已移除的屬性。

1. 在 IaC 產生器主控台中開啟產生的範本，然後選擇**匯入已編輯的範本**按鈕。

****如果沒有 Lambda 程式碼的副本**，可以使用下列指示來更新範本：**

1. 使用 API AWS Lambda [https://docs.aws.amazon.com/lambda/latest/api/API_GetFunction.html](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunction.html)動作 （例如，使用 [https://docs.aws.amazon.com/cli/latest/reference/lambda/get-function.html](https://docs.aws.amazon.com/cli/latest/reference/lambda/get-function.html) AWS CLI 命令。

1. 在回應中，如果程式碼位於 Amazon S3 儲存貯體中，則 `RepositoryType` 參數為 `S3`，如果程式碼位於 Amazon ECR 儲存庫中，則為 `ECR`。

1. 在回應中，`Location` 參數包含預先簽章的 URL，可用來下載部署套件，時長 10 分鐘。下載程式碼。

1. 將程式碼上傳至 Amazon S3 儲存貯體。

1. 使用產生的範本來執行匯入操作，並提供儲存貯體名稱和金鑰作為參數值。

# 使用動態參考取得存放在其他服務中的值
<a name="dynamic-references"></a>

動態參考可讓您方便地指定在其他服務中存放且管理的外部值，並從基礎設施即程式碼範本中分離敏感資訊。在堆疊和變更集操作期間，CloudFormation 會在必要時擷取指定參考的值。

透過動態參考，您可以：
+ **使用安全字串** – 對於敏感資料，請一律使用 AWS Systems Manager 參數存放區中的安全字串參數或 中的秘密 AWS Secrets Manager ，以確保靜態加密您的資料。
+ **限制存取** – 僅將 Parameter Store 參數或 Secrets Manager 秘密的存取權限制給已授權的主體和角色。
+ **輪換憑證** – 定期輪換儲存在 Parameter Store 或 Secrets Manager 中的敏感資料，以維持高層級的安全性。
+ **自動化輪換** – 利用 Secrets Manager 的自動輪換功能，在應用程式和環境中定期更新和分發敏感資料。

## 一般考量事項
<a name="dynamic-references-considerations"></a>

以下是在 CloudFormation 範本中指定動態參考之前要考慮的一般考量事項：
+ 不要在作為資源主識別碼一部分的資源屬性中包含動態引用或任何敏感資料。CloudFormation 可能會在主要資源識別符中使用實際的純文字值，這可能是安全風險。此資源 ID 可能會出現在任何衍生輸出或目的地中。

  若要確定哪些資源屬性組成資源類型的主要識別碼，請參閱 [AWS 資源和屬性類型參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)中該資源的資源參考文件。在 **Return values** (傳回值) 區段中，`Ref` 函數傳回值表示組成資源類型主要識別碼的資源屬性。
+ 您在一個堆疊範本中最多可以包含 60 個動態參考。
+ 如果使用轉換 (例如 `AWS::Include` 或 `AWS::Serverless`)，CloudFormation 不會在套用轉換之前解析動態參考。反之，它會將動態參考的常值字串傳遞至轉換，並在您使用範本執行變更集時解析參考。
+ 動態參考無法用於自訂資源中的安全值 (例如儲存在 Parameter Store 或 Secrets Manager 中的值)。
+ `AWS::CloudFormation::Init` 中繼資料和 Amazon EC2 `UserData` 屬性也不支援動態參考。
+ 請勿建立以反斜線 (\$1) 結尾的動態參考。CloudFormation 無法解析這些參考，這會導致堆疊操作失敗。

下列主題提供使用動態參考的資訊和其他考量事項。

**Topics**
+ [一般考量事項](#dynamic-references-considerations)
+ [從 Systems Manager Parameter Store 取得純文字值](dynamic-references-ssm.md)
+ [從 Systems Manager Parameter Store 中取得安全字串值](dynamic-references-ssm-secure-strings.md)
+ [從 Secrets Manager 中取得秘密或秘密值](dynamic-references-secretsmanager.md)

# 從 Systems Manager Parameter Store 取得純文字值
<a name="dynamic-references-ssm"></a>

建立 CloudFormation 範本時，建議您使用儲存在參數存放區中的純文字值。參數存放區是 的功能 AWS Systems Manager。如需 Parameter Store 的簡介，請參閱《AWS Systems Manager 使用者指南》中的 [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)。**

若要在範本中使用 Parameter Store 的純文字值，請使用 `ssm` 動態參考。此參考可讓您存取 Parameter Store 中 `String` 或 `StringList` 參數類型的值。

若要驗證將在堆疊操作中使用的 `ssm` 動態參考版本，請為堆疊操作建立變更集。然後，在**範本**索引標籤中檢閱已處理的範本。如需詳細資訊，請參閱[建立 CloudFormation 堆疊的變更集](using-cfn-updating-stacks-changesets-create.md)。

使用 `ssm` 動態參考時，需要謹記幾個重要事項：
+ CloudFormation 不支援動態參考的偏離偵測。對於尚未指定參數版本的 `ssm` 動態參考，如果更新 Systems Manager 中的參數版本，建議也可以對包含 `ssm` 動態參考的任何堆疊執行堆疊更新操作，以便擷取最新的參數版本。
+ 若要在 CloudFormation 範本的 `Parameters` 區段中使用 `ssm` 動態參考，必須包含版本編號。CloudFormation 不允許您在本節中參考沒有版本號碼的參數存放區值。或者，可以在範本中將參數定義為 Systems Manager 參數類型。執行此操作時，可以將 Systems Manager 參數金鑰指定為參數的預設值。然後，CloudFormation 將從 Parameter Store 中擷取參數值的最新版本，而無需指定版本編號。這可讓您的範本更簡單且更容易維護。如需詳細資訊，請參閱[使用 CloudFormation 提供的參數類型，在執行時期指定現有資源](cloudformation-supplied-parameter-types.md)。
+ 對於自訂資源，CloudFormation 在將請求傳送到自訂資源之前會解析 `ssm` 動態參考。
+ CloudFormation 不支援使用動態參考來參考從另一個 AWS 帳戶共用的參數。
+ CloudFormation 在動態參考中不支援使用 Systems Manager 參數標籤。

## 許可
<a name="dynamic-references-ssm-permissions"></a>

若要指定存放在 Systems Manager 參數存放區的參數，您必須擁有許可才能呼叫 [https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetParameter.html](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetParameter.html) 以取得指定的參數。若要了解如何建立可提供特定 Systems Manager 參數存取權的 IAM 政策，請參閱**《AWS Systems Manager 使用者指南》中的[使用 IAM 政策限制對 Systems Manager 參數的存取](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-access.html)。

## 參考模式
<a name="dynamic-references-ssm-pattern"></a>

若要在 CloudFormation 範本中參考存放在 Systems Manager Parameter Store 中的純文字值，請使用下列 `ssm` 參考模式。

```
{{resolve:ssm:parameter-name:version}}
```

針對 parameter-name 和 version，您的參考必須遵守下列規則表達式模式：

```
{{resolve:ssm:[a-zA-Z0-9_.\-/]+(:\d+)?}}
```

`parameter-name`  
 參數存放區中的參數名稱。函數名稱區分大小寫。  
必要.

`version`  
整數，指定要使用的參數版本。如果您沒有指定確切的版本，CloudFormation 會在您建立或更新堆疊時使用最新版本的參數。如需詳細資訊，請參閱《AWS Systems Manager 使用者指南》中的[使用參數版本](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-versions.html)。**  
選用。

## 範例
<a name="dynamic-references-ssm-examples"></a>

**Topics**
+ [公有 AMI ID 參數](#dynamic-references-ssm-public-ami-example)
+ [自訂 AMI ID 參數](#dynamic-references-ssm-custom-ami-example)

### 公有 AMI ID 參數
<a name="dynamic-references-ssm-public-ami-example"></a>

下列範例會建立參考公有 AMI 參數的 EC2 執行個體。動態參考會從公有參數中擷取最新的 Amazon Linux 2023 AMI ID。如需公有參數的詳細資訊，請參閱**《AWS Systems Manager 使用者指南》中的[探索參數存放區中的公有參數](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)。

#### JSON
<a name="dynamic-references-ssm-public-ami-example.json"></a>

```
{
    "Resources": {
        "MyInstance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64}}",
                "InstanceType": "t2.micro"
            }
        }
    }
}
```

#### YAML
<a name="dynamic-references-ssm-public-ami-example.yaml"></a>

```
Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64}}'
      InstanceType: t2.micro
```

### 自訂 AMI ID 參數
<a name="dynamic-references-ssm-custom-ami-example"></a>

下列範例會建立 EC2 啟動範本，它可參考儲存在 Parameter Store 中的自訂 AMI ID。動態參考會在執行個體從啟動範本啟動時，從 `golden-ami` 參數的 *`2`* 版本中擷取 AMI ID。

#### JSON
<a name="dynamic-references-ssm-custom-ami-example.json"></a>

```
{
    "Resources": {
        "MyLaunchTemplate": {
            "Type": "AWS::EC2::LaunchTemplate",
            "Properties": {
                "LaunchTemplateName": {
                    "Fn::Sub": "${AWS::StackName}-launch-template"
                },
                "LaunchTemplateData": {
                    "ImageId": "{{resolve:ssm:golden-ami:2}}",
                    "InstanceType": "t2.micro"
                }
            }
        }
    }
}
```

#### YAML
<a name="dynamic-references-ssm-custom-ami-example.yaml"></a>

```
Resources:
  MyLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties: 
      LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
      LaunchTemplateData:
        ImageId: '{{resolve:ssm:golden-ami:2}}'
        InstanceType: t2.micro
```

# 從 Systems Manager Parameter Store 中取得安全字串值
<a name="dynamic-references-ssm-secure-strings"></a>

在 CloudFormation 中，您可以將敏感資料儲存為 AWS Systems Manager 參數存放區中的「安全字串」，以使用密碼或授權金鑰等敏感資料，而無需直接在範本中公開。如需 Parameter Store 的簡介，請參閱《AWS Systems Manager 使用者指南》中的 [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)。**

若要在範本中使用 Parameter Store 安全字串，請使用 `ssm-secure` 動態參考。CloudFormation 永遠不會存放實際的安全字串值。相反，它僅存放文字動態參考，其中包含安全字串的純文字參數名稱。

在堆疊建立或更新期間，CloudFormation 會視需要存取安全字串值，而不會公開實際值。安全字串僅用於有支援 `ssm-secure` 動態參考模式的資源屬性。如需詳細資訊，請參閱[對安全字串支援動態參數模式的資源](#template-parameters-dynamic-patterns-resources)。

CloudFormation 不會在任何 API 呼叫中傳回安全字串的實際參數值。它只會傳回常值動態參考。使用變更集來比較變更時，CloudFormation 只會比較文字動態參考字串。它不會解析和比較實際安全字串值。

使用 `ssm-secure` 動態參考時，需要謹記幾個重要事項：
+ CloudFormation 無法從其他 AWS 帳戶中存取 Parameter Store 值。
+ CloudFormation 在動態參考中不支援使用 Systems Manager 參數標籤或公有參數。
+ 在 `cn-north-1` 和 `cn-northwest-1` 區域中，Systems Manager 不支援安全字串。
+ 自訂資源中目前不支援安全值的動態參考，例如 `ssm-secure`。
+ 如果 CloudFormation 需要復原堆疊更新，且之前指定的安全字串參數版本不再可用，則復原操作將失敗。在這種情況下，您有兩個選項：
  + 使用 `CONTINUE_UPDATE_ROLLBACK` 略過資源。
  + 在 Systems Manager 參數存放區中重新建立安全字串參數，並更新它，直到參數版本達到範本中使用的版本。然後，在不跳過資源的情況下使用 `CONTINUE_UPDATE_ROLLBACK`。

## 對安全字串支援動態參數模式的資源
<a name="template-parameters-dynamic-patterns-resources"></a>

支援 `ssm-secure` 動態參考模式的資源包括：


| 資源 | 屬性類型 | Properties | 
| --- | --- | --- | 
| [AWS::DirectoryService::MicrosoftAD](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-directoryservice-microsoftad.html) |  | `Password` | 
| [AWS::DirectoryService::SimpleAD](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-directoryservice-simplead.html) |  | `Password` | 
| [AWS::ElastiCache::ReplicationGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticache-replicationgroup.html) |  | `AuthToken` | 
| [AWS::IAM::User](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html) | [LoginProfile](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-iam-user-loginprofile.html) | `Password` | 
| [AWS::KinesisFirehose::DeliveryStream](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-kinesisfirehose-deliverystream.html) | [RedshiftDestinationConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-kinesisfirehose-deliverystream-redshiftdestinationconfiguration.html) | `Password` | 
| [AWS::OpsWorks::App](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-opsworks-app.html) | [來源](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-opsworks-app-source.html) | `Password` | 
| [AWS::OpsWorks::Stack](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-opsworks-stack.html) | [CustomCookbooksSource](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-opsworks-stack-source.html) | `Password` | 
| [AWS::OpsWorks::Stack](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-opsworks-stack.html) | [RdsDbInstances](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-opsworks-stack-rdsdbinstance.html) | `DbPassword` | 
| [AWS::RDS::DBCluster](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbcluster.html) |  | `MasterUserPassword` | 
| [AWS::RDS::DBInstance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html) |  | `MasterUserPassword`  | 
| [AWS::Redshift::Cluster](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-redshift-cluster.html) |  | `MasterUserPassword` | 

## 參考模式
<a name="dynamic-references-ssm-secure-pattern"></a>

若要在 CloudFormation 範本中參考 Systems Manager Parameter Store 的安全字串值，請使用下列 `ssm-secure` 參考模式。

```
{{resolve:ssm-secure:parameter-name:version}}
```

針對 parameter-name 和 version，您的參考必須遵守下列規則表達式模式：

```
{{resolve:ssm-secure:[a-zA-Z0-9_.\-/]+(:\d+)?}}
```

`parameter-name`  
 參數存放區中的參數名稱。函數名稱區分大小寫。  
必要.

`version`  
整數，指定要使用的參數版本。如果您沒有指定確切的版本，CloudFormation 會在您建立或更新堆疊時使用最新版本的參數。如需詳細資訊，請參閱《AWS Systems Manager 使用者指南》中的[使用參數版本](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-versions.html)。**  
選用。

## 範例
<a name="dynamic-references-ssm-secure-example"></a>

以下範例使用 `ssm-secure` 動態參考，將 IAM 使用者的密碼設為存放在 Parameter Store 的安全字串。依規定，CloudFormation 會使用 `IAMUserPassword` 參數的 *`10`* 版本，用於堆疊和變更集操作。

### JSON
<a name="dynamic-references-ssm-secure-example.json"></a>

```
  "MyIAMUser": {
    "Type": "AWS::IAM::User",
    "Properties": {
      "UserName": "MyUserName",
      "LoginProfile": {
        "Password": "{{resolve:ssm-secure:IAMUserPassword:10}}"
      }
    }
  }
```

### YAML
<a name="dynamic-references-ssm-secure-example.yaml"></a>

```
  MyIAMUser:
    Type: AWS::IAM::User
    Properties:
      UserName: 'MyUserName'
      LoginProfile:
        Password: '{{resolve:ssm-secure:IAMUserPassword:10}}'
```

# 從 Secrets Manager 中取得秘密或秘密值
<a name="dynamic-references-secretsmanager"></a>

Secrets Manager 是一項服務，可讓您安全地存放和管理秘密，例如資料庫憑證、密碼和第三方 API 金鑰。您可以使用 Secrets Manage 集中存放或控制對這些秘密的存取，因此您可以將程式碼中的硬式編碼憑證 (包括密碼)，取代為對 Secrets Manager 的 API 呼叫，以程式設計方式擷取秘密。如需詳細資訊，請參閱*AWS Secrets Manager 《 使用者指南*》中的[什麼是 AWS Secrets Manager？](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)。

若要在 CloudFormation 範本內使用存放於 Secrets Manager 中的全部秘密或秘密值，您可使用 `secretsmanager` 動態參考。

## 最佳實務
<a name="dynamic-references-secretsmanager-best-practices"></a>

在 CloudFormation 範本中使用 Secrets Manager 動態參考時，請遵循下列最佳實務：
+ **使用 CloudFormation 範本的無版本參考** – 將憑證儲存在 Secrets Manager 中，並使用動態參考，而不指定 `version-stage` 或 `version-id` 參數，以支援適當的秘密輪換工作流程。
+ **利用自動輪換** – 搭配使用 Secrets Manager 的自動輪換功能與無版本動態參考，進行憑證管理。這可確保定期更新憑證，而不需要變更範本。如需詳細資訊，請參閱[輪換 AWS Secrets Manager 秘密](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html)。
+ **謹慎使用版本控制的參考** – 僅針對特定案例指定明確的 `version-stage` 或 `version-id` 參數，例如測試或復原情況。

## 考量事項
<a name="dynamic-references-secretsmanager-considerations"></a>

使用 `secretsmanager` 動態參考時，請注意以下重要考量：
+ CloudFormation 不會追蹤先前部署中使用的秘密版本。在實作動態參考之前，請仔細規劃您的秘密管理策略。盡可能使用無版本參考，以利用自動秘密輪換。在變更動態參考組態時 (例如從未版本化動態參考轉換為版本化動態參考時) 監控和驗證資源更新，反之亦然。
+ 僅更新 Secrets Manager 中的秘密值不會自動導致 CloudFormation 擷取新值。CloudFormation 只會在修改包含動態參考之資源的資源建立或更新期間擷取秘密值。

  例如，假設範本包含 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html) 資源，其中 `MasterPassword` 屬性設定為 Secrets Manager 動態參考。從此範本建立堆疊後，可以在 Secrets Manager 中更新秘密的值。不過，`MasterPassword` 屬性會保留舊密碼值。

  若要套用新的秘密值，需要修改 CloudFormation 範本中的 `AWS::RDS::DBInstance` 資源，並執行堆疊更新。

  為了避免未來出現此手動程序，請考慮使用 Secrets Manager 自動輪換秘密。
+ 自訂資源中目前不支援安全值的動態參考，例如 `secretsmanager`。
+ 所有資源屬性中可以使用 `secretsmanager` 動態參考。使用 `secretsmanager` 動態參考表明 Secrets Manager 和 CloudFormation Logs 都不應存留任何已解析的秘密值。但是，秘密值在服務的資源中使用時，秘密值就可能出現在此服務中。檢閱您的使用情況，以避免洩露秘密資料。

## 許可
<a name="dynamic-references-secretsmanager-permissions"></a>

若要指定存放在 Secrets Manager 中的秘密，您必須擁有許可才能呼叫 [https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html) 以取得秘密。

## 參考模式
<a name="dynamic-references-secretsmanager-pattern"></a>

若要在 CloudFormation 範本中參考 Secrets Manager 秘密，請使用下列 `secretsmanager` 參考模式。

```
{{resolve:secretsmanager:secret-id:secret-string:json-key:version-stage:version-id}}
```

`secret-id`  
秘密的名稱或 ARN。  
若要存取 中的秘密 AWS 帳戶，您只需指定秘密名稱。若要存取不同 中的秘密 AWS 帳戶，請指定秘密的完整 ARN。  
必要.

`secret-string`  
唯一支援的值為 `SecretString`。預設值為 `SecretString`。

`json-key`  
您要擷取值的鍵值組的索引鍵名稱。如果您不指定 `json-key`，CloudFormation 會擷取整個秘密文字。  
此區段可能不可包含冒號字元 (`:`)。

`version-stage`  
要使用的秘密版本之預備標籤。Secrets Manager 在輪換程序期間使用預備標籤來追蹤不同版本。如果您使用 `version-stage`，請不要指定 `version-id`。如果您未指定 `version-stage` 或 `version-id`，則預設為 `AWSCURRENT` 版本。  
此區段可能不可包含冒號字元 (`:`)。

`version-id`  
您要使用的秘密版本的唯一識別碼。如果您指定 `version-id`，則請不要指定 `version-stage`。如果您未指定 `version-stage` 或 `version-id`，則預設為 `AWSCURRENT` 版本。  
此區段可能不可包含冒號字元 (`:`)。

## 範例
<a name="dynamic-references-secretsmanager-examples"></a>

**Topics**
+ [從秘密中擷取使用者名稱和密碼值](#dynamic-references-secretsmanager-examples-user-name-and-password)
+ [擷取整個 SecretString](#dynamic-references-secretsmanager-examples-entire-secretstring)
+ [從特定版本的秘密中擷取值](#dynamic-references-secretsmanager-examples-specific-version)
+ [從另一個 擷取秘密 AWS 帳戶](#dynamic-references-secretsmanager-examples-secrets-from-another-account)

### 從秘密中擷取使用者名稱和密碼值
<a name="dynamic-references-secretsmanager-examples-user-name-and-password"></a>

以下 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html) 範例會擷取存放在 `MySecret` 秘密中的使用者名稱和密碼值。此範例顯示無版本動態參考的建議模式，它會自動使用 `AWSCURRENT` 版本並支援 Secrets Manager 輪換工作流程，而不需要變更範本。

#### JSON
<a name="dynamic-references-secretsmanager-examples-user-name-and-password.json"></a>

```
{
    "MyRDSInstance": {
        "Type": "AWS::RDS::DBInstance",
        "Properties": {
            "DBName": "MyRDSInstance",
            "AllocatedStorage": "20",
            "DBInstanceClass": "db.t2.micro",
            "Engine": "mysql",
            "MasterUsername": "{{resolve:secretsmanager:MySecret:SecretString:username}}",
            "MasterUserPassword": "{{resolve:secretsmanager:MySecret:SecretString:password}}"
        }
    }
}
```

#### YAML
<a name="dynamic-references-secretsmanager-examples-user-name-and-password.yaml"></a>

```
  MyRDSInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBName: MyRDSInstance
      AllocatedStorage: '20'
      DBInstanceClass: db.t2.micro
      Engine: mysql
      MasterUsername: '{{resolve:secretsmanager:MySecret:SecretString:username}}'
      MasterUserPassword: '{{resolve:secretsmanager:MySecret:SecretString:password}}'
```

### 擷取整個 SecretString
<a name="dynamic-references-secretsmanager-examples-entire-secretstring"></a>

下列動態參考會擷取 `MySecret` 的 `SecretString`。

```
{{resolve:secretsmanager:MySecret}}
```

或使用：

```
{{resolve:secretsmanager:MySecret::::}}
```

### 從特定版本的秘密中擷取值
<a name="dynamic-references-secretsmanager-examples-specific-version"></a>

下列動態參考會擷取 `MySecret` 的 `AWSPREVIOUS` 版本的 `password` 值。

```
{{resolve:secretsmanager:MySecret:SecretString:password:AWSPREVIOUS}}
```

### 從另一個 擷取秘密 AWS 帳戶
<a name="dynamic-references-secretsmanager-examples-secrets-from-another-account"></a>

下列動態參考會擷取另一個 AWS 帳戶中 `MySecret` 的 `SecretString`。您必須指定完整的秘密 ARN，才能存取另一個秘密 AWS 帳戶。

```
{{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789012:secret:MySecret}}
```

下列動態參考會擷取另一個 AWS 帳戶中 `MySecret` 的 `password` 值。您必須指定完整的秘密 ARN，才能存取另一個秘密 AWS 帳戶。

```
{{resolve:secretsmanager:arn:aws:secretsmanager:us-west-2:123456789012:secret:MySecret:SecretString:password}}
```

# 使用虛擬參數取得 AWS 值
<a name="pseudo-parameter-reference"></a>

虛擬參數是內建變數，可讓您存取重要的 AWS 環境資訊，例如帳戶 IDs、區域名稱，以及可在部署或環境之間變更的堆疊詳細資訊。

您可以使用虛擬參數，而不是硬式編碼值，讓您的範本更方便攜帶，並更輕鬆地在不同 AWS 帳戶 和 區域重複使用。

## 語法
<a name="pseudo-parameter-syntax"></a>

您可以透過 `Ref` 內建函數或 `Fn::Sub` 內建函數參考虛擬參數。

### Ref
<a name="pseudo-parameter-ref-syntax"></a>

`Ref` 內建函數使用下列一般語法。如需詳細資訊，請參閱 [Ref](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-ref.html)。

#### JSON
<a name="pseudo-parameter-ref-syntax.json"></a>

```
{ "Ref" : "AWS::PseudoParameter" }
```

#### YAML
<a name="pseudo-parameter-ref-syntax.yaml"></a>

```
!Ref AWS::PseudoParameter
```

### Fn::Sub
<a name="pseudo-parameter-sub-syntax"></a>

`Fn::Sub` 內建函數使用不同格式，在虛擬參數前後加上 `${}` 語法。如需詳細資訊，請參閱 [Fn::Sub](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-sub.html)。

#### JSON
<a name="pseudo-parameter-sub-syntax.json"></a>

```
{ "Fn::Sub" : "${AWS::PseudoParameter}" }
```

#### YAML
<a name="pseudo-parameter-sub-syntax.yaml"></a>

```
!Sub '${AWS::PseudoParameter}'
```

## 可用的虛擬參數
<a name="available-pseudo-parameters"></a>

### `AWS::AccountId`
<a name="cfn-pseudo-param-accountid"></a>

傳回要在其中建立堆疊之帳戶的 AWS 帳戶 ID，例如 `123456789012`。

此虛擬參數常用於定義 IAM 角色、原則及其他涉及帳戶專屬 ARN 的資源原則。

### `AWS::NotificationARNs`
<a name="cfn-pseudo-param-notificationarns"></a>

傳回接收堆疊事件通知的 Amazon SNS 主題對應的 Amazon Resource Name (ARN) 清單。您可以在建立 AWS CLI 或更新堆疊時，透過 中的 `--notification-arns`選項或透過 主控台指定這些 ARNs。

不同於其他傳回單一數值的虛擬參數，`AWS::NotificationARNs` 會傳回 ARN 清單。要存取清單中的特定 ARN，請使用 `Fn::Select` 內建函數。如需詳細資訊，請參閱[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-select.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-select.html)。

### `AWS::NoValue`
<a name="cfn-pseudo-param-novalue"></a>

若在 `Fn::If` 內部函數中將此參數指定為傳回值，則系統會移除對應的資源屬性。如需詳細資訊，請參閱[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if)。

此虛擬參數在建立僅需於特定條件下納入的條件式資源屬性時特別實用。

### `AWS::Partition`
<a name="cfn-pseudo-param-partition"></a>

傳回資源所在的分割區。對於標準 AWS 區域，分割區為 `aws`。如果資源處於其他分割區，則會傳回 `aws-`*partitionname* 分割區。例如，中國 （北京和寧夏） 區域中資源的分割區為 ，`aws-cn`G AWS GovCloud （美國西部） 區域中資源的分割區為 `aws-us-gov`。

分區是資源 ARN 的一部分。使用 `AWS::Partition`可確保您的範本在不同 AWS 分割區之間正確運作。

### `AWS::Region`
<a name="cfn-pseudo-param-region"></a>

傳回建立包容性資源區域的代表字串，例如：`us-west-2`。

這是最常用的虛擬參數之一，因為它允許範本在不修改 AWS 區域 的情況下適應不同的參數。

### `AWS::StackId`
<a name="cfn-pseudo-param-stackid"></a>

傳回堆疊的 ID (ARN)，例如 `arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123`。

### `AWS::StackName`
<a name="cfn-pseudo-param-stackname"></a>

傳回堆疊的名稱，例如 `teststack`。

堆疊名稱常用於建立獨特的資源名稱，這類名稱易於識別為屬於特定堆疊。

### `AWS::URLSuffix`
<a name="cfn-pseudo-param-urlsuffix"></a>

在部署 AWS 區域 堆疊的 中，傳回 AWS 網域的尾碼。尾碼通常為 `amazonaws.com`，但對於中國 (北京) 區域，尾碼為 `amazonaws.com.cn`。

此參數在建構 AWS 服務端點URLs 時特別有用。

## 範例
<a name="pseudo-parameter-examples"></a>

**Topics**
+ [基本使用](#pseudo-parameter-basic-example)
+ [使用 AWS::NotificationARNs](#pseudo-parameter-notification-example)
+ [具備 AWS::NoValue 的條件屬性](#pseudo-parameter-novalue-example)

### 基本使用
<a name="pseudo-parameter-basic-example"></a>

下列範例建立兩個資源：一個 Amazon SNS 主題，以及一個向該主題傳送通知的 CloudWatch 警示。它們使用 `AWS::StackName`、 `AWS::Region`和 `AWS::AccountId` 將堆疊名稱、目前 AWS 區域和帳戶 ID 動態插入資源名稱、描述和 ARNs。

#### JSON
<a name="pseudo-parameter-basic-example.json"></a>

```
{
    "Resources": {
        "MyNotificationTopic": {
            "Type": "AWS::SNS::Topic",
            "Properties": {
                "DisplayName": { "Fn::Sub": "Notifications for ${AWS::StackName}" }
            }
        },
        "CPUAlarm": {
            "Type": "AWS::CloudWatch::Alarm",
            "Properties": {
                "AlarmDescription": { "Fn::Sub": "Alarm for high CPU in ${AWS::Region}" },
                "AlarmName": { "Fn::Sub": "${AWS::StackName}-HighCPUAlarm" },
                "MetricName": "CPUUtilization",
                "Namespace": "AWS/EC2",
                "Statistic": "Average",
                "Period": 300,
                "EvaluationPeriods": 1,
                "Threshold": 80,
                "ComparisonOperator": "GreaterThanThreshold",
                "AlarmActions": [{ "Fn::Sub": "arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${MyNotificationTopic}" }]
            }
        }
    }
}
```

#### YAML
<a name="pseudo-parameter-basic-example.yaml"></a>

```
Resources:
  MyNotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: !Sub Notifications for ${AWS::StackName}
  CPUAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: !Sub Alarm for high CPU in ${AWS::Region}
      AlarmName: !Sub ${AWS::StackName}-HighCPUAlarm
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Statistic: Average
      Period: 300
      EvaluationPeriods: 1
      Threshold: 80
      ComparisonOperator: GreaterThanThreshold
      AlarmActions:
        - !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${MyNotificationTopic}
```

### 使用 AWS::NotificationARNs
<a name="pseudo-parameter-notification-example"></a>

下列範例設定 Auto Scaling 群組，以便在執行個體啟動事件及啟動錯誤時傳送通知。此設定使用 `AWS::NotificationARNs` 虛擬參數，該參數提供建立堆疊時指定的 Amazon SNS 主題 ARN 清單。`Fn::Select` 函數會從該清單中選擇第一個 ARN。

#### JSON
<a name="pseudo-parameter-notification-example.json"></a>

```
"myASG": {
   "Type": "AWS::AutoScaling::AutoScalingGroup",
   "Properties": {
      "LaunchTemplate": {
         "LaunchTemplateId": { "Ref": "myLaunchTemplate" },
         "Version": { "Fn::GetAtt": [ "myLaunchTemplate", "LatestVersionNumber" ] }
       },
       "MaxSize": "1",
       "MinSize": "1",
       "VPCZoneIdentifier": [
          "subnetIdAz1",
          "subnetIdAz2",
          "subnetIdAz3"
      ],
      "NotificationConfigurations" : [{
         "TopicARN" : { "Fn::Select" : [ "0", { "Ref" : "AWS::NotificationARNs" } ] },
         "NotificationTypes" : [ "autoscaling:EC2_INSTANCE_LAUNCH", "autoscaling:EC2_INSTANCE_LAUNCH_ERROR" ]
      }]
   }
}
```

#### YAML
<a name="pseudo-parameter-notification-example.yaml"></a>

```
myASG:
  Type: AWS::AutoScaling::AutoScalingGroup
  Properties:
    LaunchTemplate:
      LaunchTemplateId: !Ref myLaunchTemplate
      Version: !GetAtt myLaunchTemplate.LatestVersionNumber
    MinSize: '1'
    MaxSize: '1'
    VPCZoneIdentifier:
      - subnetIdAz1
      - subnetIdAz2
      - subnetIdAz3
    NotificationConfigurations:
      - TopicARN:
          Fn::Select:
          - '0'
          - Ref: AWS::NotificationARNs
        NotificationTypes:
        - autoscaling:EC2_INSTANCE_LAUNCH
        - autoscaling:EC2_INSTANCE_LAUNCH_ERROR
```

### 具備 AWS::NoValue 的條件屬性
<a name="pseudo-parameter-novalue-example"></a>

下列範例會建立 Amazon RDS 資料庫執行個體，僅在提供快照 ID 時才使用快照。若 `UseDBSnapshot` 條件評估為 true，CloudFormation 會對 `DBSnapshotIdentifier` 屬性使用 `DBSnapshotName` 參數值。若條件評估為 false，CloudFormation 即會移除 `DBSnapshotIdentifier` 屬性。

#### JSON
<a name="pseudo-parameter-novalue-example.json"></a>

```
"MyDB" : {
  "Type" : "AWS::RDS::DBInstance",
  "Properties" : {
    "AllocatedStorage" : "5",
    "DBInstanceClass" : "db.t2.small",
    "Engine" : "MySQL",
    "EngineVersion" : "5.5",
    "MasterUsername" : { "Ref" : "DBUser" },
    "MasterUserPassword" : { "Ref" : "DBPassword" },
    "DBParameterGroupName" : { "Ref" : "MyRDSParamGroup" },
    "DBSnapshotIdentifier" : {
      "Fn::If" : [
        "UseDBSnapshot",
        {"Ref" : "DBSnapshotName"},
        {"Ref" : "AWS::NoValue"}
      ]
    }
  }
}
```

#### YAML
<a name="pseudo-parameter-novalue-example.yaml"></a>

```
MyDB:
  Type: AWS::RDS::DBInstance
  Properties:
    AllocatedStorage: '5'
    DBInstanceClass: db.t2.small
    Engine: MySQL
    EngineVersion: '5.5'
    MasterUsername:
      Ref: DBUser
    MasterUserPassword:
      Ref: DBPassword
    DBParameterGroupName:
      Ref: MyRDSParamGroup
    DBSnapshotIdentifier:
      Fn::If:
        - UseDBSnapshot
        - Ref: DBSnapshotName
        - Ref: AWS::NoValue
```

# 從部署的 CloudFormation 堆疊取得匯出的輸出
<a name="using-cfn-stack-exports"></a>

當您在相同 AWS 帳戶 和 區域中有多個堆疊時，您可能想要在它們之間共用資訊。當一個堆疊需要使用另一個堆疊建立的資源時，這項功能相當實用。

例如，您可能有一個堆疊專門為 Web 伺服器建立網路資源，如子網路和安全群組。而建立實際 Web 伺服器的其他堆疊，就能使用第一個堆疊建立的網路資源。您不必在堆疊範本中硬式編碼資源 ID，也不需要以輸入參數形式傳遞 ID。

若要在堆疊之間共用資訊，可從一個堆疊*匯出*輸出值，再將其*匯入*另一個堆疊。以下是其運作方式：

1. 在第一個堆疊的範本 (例如，聯網堆疊) 中，可使用 `Outputs` 區段的 `Export` 欄位來定義匯出的特定值。如需詳細資訊，請參閱[CloudFormation 範本 Outputs 語法](outputs-section-structure.md)。

1. 當您建立或更新該堆疊時，CloudFormation 會匯出輸出值，使其可供相同 AWS 帳戶 和 區域中的其他堆疊使用。

1. 在另一個堆疊的範本中，您可以使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-importvalue.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-importvalue.html) 函數從第一個堆疊匯入匯出的值。

1. 建立或更新第二個堆疊 (例如 Web 伺服器堆疊) 時，CloudFormation 會自動從第一個堆疊擷取已匯出的值並套用。

如需演練和範例範本，請參閱[參考在另一個 CloudFormation 堆疊中的資源輸出](walkthrough-crossstackref.md)。

## 匯出堆疊輸出值與使用巢狀堆疊的比較
<a name="output-vs-nested"></a>

巢狀堆疊是指藉由使用 `AWS::CloudFormation::Stack` 資源在另一個堆疊中建立的堆疊。使用巢狀堆疊時，您可以透過單一堆疊來部署和管理所有資源。您可以將巢狀堆疊群組中某個堆疊的輸出，作為群組中其他堆疊的輸入。這與匯出值的情況不同。

如果您想要將資訊的共享隔離在巢狀堆疊群組內，則建議您使用巢狀堆疊。若要與其他堆疊 (而不只是在巢狀堆疊的群組內) 共享資訊，則匯出值。例如，您可以建立含子網路的單一堆疊，然後匯出其 ID。其他堆疊可透過匯入該 ID 來使用該子網路。每個堆疊無需單獨建立子網路。只要有堆疊匯入子網路 ID，您就無法變更或刪除該 ID。

如需巢狀堆疊的詳細資訊，請參閱 [運用巢狀堆疊，將範本分割成可重複使用的部分](using-cfn-nested-stacks.md)。

## 考量事項
<a name="using-cfn-stack-exports-considerations"></a>

下列限制適用於跨堆疊參考：
+ 對於每個名稱 AWS 帳戶，`Export`名稱在區域中必須是唯一的。
+ 您無法跨區域建立跨堆疊參考。您可以使用內部函數 `Fn::ImportValue`，僅匯入已在同一區域內匯出的值。
+ 對於輸出，`Export` 的 `Name` 屬性值無法使用依賴某個資源的 `Ref` 或者 `GetAtt` 函數。

  同樣，`ImportValue` 函數不能包含依賴某個資源的 `Ref` 或 `GetAtt` 函數。
+ 當其他堆疊匯入輸出值之後，您就無法刪除匯出輸出值的堆疊，也無法修改匯出的輸出值。您必須先移除所有匯入，之後才可以刪除匯出堆疊或修改輸出值。

## 列出已匯出的輸出值
<a name="using-cfn-stack-exports-listing"></a>

若需檢視堆疊已匯出的輸出值，可使用下列其中一種方法：

**列出已匯出的輸出值 (主控台)**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 在畫面上方的導覽列上，選擇 AWS 區域。

1. 在左側導覽窗格中，選擇**匯出**。

**列出已匯出的輸出值 (AWS CLI)**  
使用下列 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-exports.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-exports.html) 命令。將 *us-east-1* 取代為您的 AWS 區域。

```
aws cloudformation list-exports --region us-east-1
```

以下為範例輸出。

```
{
    "Exports": [
        {
            "ExportingStackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/private-vpc/99764070-b56c-xmpl-bee8-062a88d1d800",
            "Name": "private-vpc-subnet-a",
            "Value": "subnet-07b410xmplddcfa03"
        },
        {
            "ExportingStackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/private-vpc/99764070-b56c-xmpl-bee8-062a88d1d800",
            "Name": "private-vpc-subnet-b",
            "Value": "subnet-075ed3xmplebd2fb1"
        },
        {
            "ExportingStackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/private-vpc/99764070-b56c-xmpl-bee8-062a88d1d800",
            "Name": "private-vpc-vpcid",
            "Value": "vpc-011d7xmpl100e9841"
        }
    ]
}
```

CloudFormation 會針對目前匯出的區域和堆疊，顯示已匯出的輸出名稱和值。若要使用其他堆疊範本中的已匯出輸出值，請使用匯出名稱和 `Fn::ImportValue` 函數進行參考。

## 列出匯入匯出的輸出值的堆疊
<a name="using-cfn-stack-imports"></a>

若要刪除或變更匯出的輸出值，必須先找出哪些堆疊正在匯入輸出值。

若需檢視匯入已匯出輸出值的堆疊，可使用下列其中一種方法：

**列出匯入匯出的輸出值的堆疊 (主控台)**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 在左側導覽窗格中，選擇**匯出**。

1. 若要查看匯入指定匯出值的堆疊，請選擇該匯出值的 **Export Name** (匯出名稱)。CloudFormation 會顯示匯出詳細資訊頁面，列出匯入該值的所有堆疊。

**列出匯入匯出的輸出值的堆疊 (AWS CLI)**  
使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-imports.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/list-imports.html) 命令。將 *us-east-1* 取代為您的 AWS 區域 ，並將 `private-vpc-vpcid`取代為匯出輸出值的名稱。

```
aws cloudformation list-imports --region us-east-1 \
    --export-name private-vpc-vpcid
```

CloudFormation 傳回匯入該值的堆疊清單。

```
{
    "Imports": [
        "my-app-stack"
    ]
}
```

確認哪些堆疊正在匯入特定已匯出值後，您需要修改這些堆疊，移除參考該輸出值的 `Fn::ImportValue` 函數。您必須移除所有參考匯出的輸出值的匯入，才能刪除或修改匯出的輸出值。

# 使用 CloudFormation 提供的參數類型，在執行時期指定現有資源
<a name="cloudformation-supplied-parameter-types"></a>

建立範本時，您可以使用 CloudFormation 提供的專用參數類型，建立參數，要求使用者輸入現有 AWS 資源或 Systems Manager 參數的識別符。

**Topics**
+ [概觀](#cloudformation-supplied-parameter-types-overview)
+ [範例](#cloudformation-supplied-parameter-types-example)
+ [考量事項](#cloudformation-supplied-parameter-types-considerations)
+ [支援 AWS的特定參數類型](#aws-specific-parameter-types-supported)
+ [支援的 Systems Manager 參數類型](#systems-manager-parameter-types-supported)
+ [不支援的 Systems Manager 參數類型](#systems-manager-parameter-types-unsupported)

## 概觀
<a name="cloudformation-supplied-parameter-types-overview"></a>

在 CloudFormation 中，可以透過在堆疊建立或更新期間提供輸入值，使用參數來自訂堆疊。此功能使得您的範本在不同案例中可重複使用且靈活。

在 CloudFormation 範本的 `Parameters` 區段中定義參數。每個參數都有名稱和類型，並且可以有額外的設定，例如預設值和允許的值。如需詳細資訊，請參閱[CloudFormation 範本 Parameters 語法](parameters-section-structure.md)。

參數類型會決定參數可以接受的輸入值類型。例如，`Number` 只接受數值，而 `String` 接受文字輸入。

CloudFormation 提供數種額外的參數類型，您可以在範本中用來參考現有的 AWS 資源和 Systems Manager 參數。

這些參數類型分為兩個類別：
+ **AWS特定參數類型** – CloudFormation 提供一組參數類型，可協助在建立或更新堆疊時擷取無效的值。當您使用這些參數類型時，使用範本的任何人都必須從他們建立堆疊所在的 AWS 帳戶 和 區域指定有效值。

  如果他們使用 AWS 管理主控台，CloudFormation 會提供其帳戶和區域中現有值的預先填入清單。這樣，使用者不需要記住和正確輸入特定名稱或 ID。相反，他們只需從下拉式清單中選取值。在某些情況下，他們甚至可以依 ID、名稱或 `Name` 標籤值來搜尋值。
+ **Systems Manager 參數類型** – CloudFormation 也提供對應於 Systems Manager 參數存放區中現有參數的參數類型。當您使用這些參數類型時，使用範本的任何人都必須指定參數存放區金鑰作為 Systems Manager 參數類型的值，然後 CloudFormation 會從參數存放區擷取最新的值，以便在其堆疊中使用。當您需要使用新的屬性值 (例如新的 Amazon Machine Image (AMI) ID) 來頻繁更新應用程式時，這會很有用。如需參數存放區的相關資訊，請參閱 [Systems Manager 參數存放區](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)。

在 `Parameters` 區段中定義參數後，可以使用 `Ref` 函數在整個 CloudFormation 範本中參考參數值。

## 範例
<a name="cloudformation-supplied-parameter-types-example"></a>

下列範例顯示使用下列參數類型的範本。
+ `AWS::EC2::VPC::Id`
+ `AWS::EC2::Subnet::Id`
+ `AWS::EC2::KeyPair::KeyName`
+ `AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>`

若要從此範本中建立堆疊，必須在您的帳戶中指定現有的 VPC ID、子網路 ID 和金鑰對名稱。也可以指定參考所需 AMI ID 的現有參數存放區金鑰，或保留預設值 `/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2`。此公有參數是最新 Amazon Linux 2 AMI 的區域 AMI ID 別名。如需公有參數的詳細資訊，請參閱**《AWS Systems Manager 使用者指南》中的[探索參數存放區中的公有參數](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)。

### JSON
<a name="cloudformation-supplied-parameter-types-example.json"></a>

```
{
    "Parameters": {
        "VpcId": {
            "Description": "ID of an existing Virtual Private Cloud (VPC).",
            "Type": "AWS::EC2::VPC::Id"
        },
        "PublicSubnetId": {
            "Description": "ID of an existing public subnet within the specified VPC.",
            "Type": "AWS::EC2::Subnet::Id"
        },
        "KeyName": {
            "Description": "Name of an existing EC2 key pair to enable SSH access to the instance.",
            "Type": "AWS::EC2::KeyPair::KeyName"
        },
        "AMIId": {
            "Description": "Name of a Parameter Store parameter that stores the ID of the Amazon Machine Image (AMI).",
            "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
            "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
        }
    },
    "Resources": {
        "InstanceSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "VpcId": { "Ref": "VpcId" },
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 22,
                        "ToPort": 22,
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        },
        "Ec2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "KeyName": { "Ref": "KeyName" },
                "ImageId": { "Ref": "AMIId" },
                "NetworkInterfaces": [
                    {
                        "AssociatePublicIpAddress": "true",
                        "DeviceIndex": "0",
                        "SubnetId": { "Ref": "PublicSubnetId" },
                        "GroupSet": [{ "Ref": "InstanceSecurityGroup" }]
                    }
                ]
            }
        }
    },
    "Outputs": {
        "InstanceId": {
            "Value": { "Ref": "Ec2Instance" }
        }
    }
}
```

### YAML
<a name="cloudformation-supplied-parameter-types-example.yaml"></a>

```
Parameters:
  VpcId:
    Description: ID of an existing Virtual Private Cloud (VPC).
    Type: AWS::EC2::VPC::Id
  PublicSubnetId:
    Description: ID of an existing public subnet within the specified VPC.
    Type: AWS::EC2::Subnet::Id
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance.
    Type: AWS::EC2::KeyPair::KeyName
  AMIId:
    Description: Name of a Parameter Store parameter that stores the ID of the Amazon Machine Image (AMI).
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access via port 22
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      KeyName: !Ref KeyName
      ImageId: !Ref AMIId
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PublicSubnetId
          GroupSet:
            - !Ref InstanceSecurityGroup
Outputs:
  InstanceId:
    Value: !Ref Ec2Instance
```

### AWS CLI 命令來建立堆疊
<a name="cloudformation-supplied-parameter-types-cli-command"></a>

下列 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html) 命令會根據範例範本來建立堆疊。

```
aws cloudformation create-stack --stack-name MyStack \
  --template-body file://sampletemplate.json \
  --parameters \
ParameterKey="VpcId",ParameterValue="vpc-a123baa3" \
ParameterKey="PublicSubnetId",ParameterValue="subnet-123a351e" \
ParameterKey="KeyName",ParameterValue="MyKeyName" \
ParameterKey="AMIId",ParameterValue="MyParameterKey"
```

若要使用接受字串清單的參數類型，例如 `List<AWS::EC2::Subnet::Id>`，您必須使用雙反斜線來轉義 `ParameterValue` 內的逗號，如下列範例所示。

```
--parameters ParameterKey="SubnetIDs",ParameterValue="subnet-5ea0c127\\,subnet-6194ea3b\\,subnet-c87f2be0"
```

## 考量事項
<a name="cloudformation-supplied-parameter-types-considerations"></a>

強烈建議您使用動態參考來限制存取敏感組態定義，例如第三方憑證。如需詳細資訊，請參閱[使用動態參考取得存放在其他服務中的值](dynamic-references.md)。

如果您想要允許範本使用者指定來自不同 的值 AWS 帳戶，請勿使用 AWS特定的參數類型。反之，請定義類型 `String` 或 `CommaDelimitedList` 的參數。

使用 Systems Manager 參數類型時需要記住幾件事：
+ 可以在主控台中或透過執行 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) 或 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-change-set.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-change-set.html)，查看堆疊的**參數**索引標籤中的已解析參數值。請謹記，這些值是在建立或更新堆疊時所設定，因此可能會與參數存放區中的最新值不同。
+ 對於堆疊更新，當您使用**使用現有值**選項 (或 `UsePreviousValue` 設定為 true) 時，這表示您想要繼續使用相同的參數存放區金鑰，而不是其值。CloudFormation 始終會擷取最新的值。
+ 如果您指定任何允許的值或其他限制條件，CloudFormation 會根據您指定的參數索引鍵進行驗證，但不會驗證其值。您應該驗證參數存放區本身中的值。
+ 當您建立或更新堆疊並建立變更集時，CloudFormation 會使用參數存放區中當時存在的任何值。如果指定的參數不存在於發起人的 參數存放區中 AWS 帳戶，CloudFormation 會傳回驗證錯誤。
+ 當您執行變更集時，CloudFormation 會使用變更集中所指定的值。您應該先檢閱這些值，再執行變更集，因為它們可能會在您建立變更集與執行變更集之間於參數存放區中變更。
+ 對於存放在相同 中的參數存放區參數 AWS 帳戶，您必須提供參數名稱。對於另一個 AWS 帳戶共用的參數存放區參數，必須提供完整的參數 ARN。

## 支援 AWS的特定參數類型
<a name="aws-specific-parameter-types-supported"></a>

CloudFormation AWS支援下列特定類型：

`AWS::EC2::AvailabilityZone::Name`  
可用區域，例如 `us-west-2a`。

`AWS::EC2::Image::Id`  
Amazon EC2 映像 ID，例如 `ami-0ff8a91507f77f867`。請注意，CloudFormation 主控台不會顯示此參數類型的下拉式值清單。

`AWS::EC2::Instance::Id`  
Amazon EC2 執行個體 ID，例如 `i-1e731a32`。

`AWS::EC2::KeyPair::KeyName`  
Amazon EC2 金鑰對名稱。

`AWS::EC2::SecurityGroup::GroupName`  
預設 VPC 安全群組名稱，例如 `my-sg-abc`。

`AWS::EC2::SecurityGroup::Id`  
安全群組 ID，例如 `sg-a123fd85`。

`AWS::EC2::Subnet::Id`  
子網路 ID，例如 `subnet-123a351e`。

`AWS::EC2::Volume::Id`  
Amazon EBS 磁碟區 ID，例如 `vol-3cdd3f56`。

`AWS::EC2::VPC::Id`  
VPC ID，例如 `vpc-a123baa3`。

`AWS::Route53::HostedZone::Id`  
Amazon Route 53 託管區域 ID，例如 `Z23YXV4OVPL04A`。

`List<AWS::EC2::AvailabilityZone::Name>`  
區域的可用區域陣列，例如 `us-west-2a, us-west-2b`。

`List<AWS::EC2::Image::Id>`  
Amazon EC2 映像 ID 陣列，例如 `ami-0ff8a91507f77f867, ami-0a584ac55a7631c0c`。請注意，CloudFormation 主控台不會顯示此參數類型的下拉式值清單。

`List<AWS::EC2::Instance::Id>`  
Amazon EC2 執行個體 ID 陣列，例如 `i-1e731a32, i-1e731a34`。

`List<AWS::EC2::SecurityGroup::GroupName>`  
預設 VPC 安全群組名稱陣列，例如 `my-sg-abc, my-sg-def`。

`List<AWS::EC2::SecurityGroup::Id>`  
安全群組 ID 陣列，例如 `sg-a123fd85, sg-b456fd85`。

`List<AWS::EC2::Subnet::Id>`  
子網路 ID 陣列，例如 `subnet-123a351e, subnet-456b351e`。

`List<AWS::EC2::Volume::Id>`  
Amazon EBS 磁碟區 ID 陣列，例如 `vol-3cdd3f56, vol-4cdd3f56`。

`List<AWS::EC2::VPC::Id>`  
VPC ID 陣列，例如 `vpc-a123baa3, vpc-b456baa3`。

`List<AWS::Route53::HostedZone::Id>`  
Amazon Route 53 託管區域 ID 陣列，例如 `Z23YXV4OVPL04A, Z23YXV4OVPL04B`。

## 支援的 Systems Manager 參數類型
<a name="systems-manager-parameter-types-supported"></a>

CloudFormation 支援下列 Systems Manager 參數類型：

`AWS::SSM::Parameter::Name`  
Systems Manager 參數索引鍵的名稱。僅使用此參數類型來檢查必要的參數是否存在。CloudFormation 不會擷取與參數相關聯的實際值。

`AWS::SSM::Parameter::Value<String>`  
值為字串的 Systems Manager 參數。這對應至參數存放區中的 `String` 參數類型。

`AWS::SSM::Parameter::Value<List<String>>` 或 `AWS::SSM::Parameter::Value<CommaDelimitedList>`  
值為字串清單的 Systems Manager 參數。這對應至參數存放區中的 `StringList` 參數類型。

`AWS::SSM::Parameter::Value<AWS-specific parameter type>`  
值為 AWS特定參數類型的 Systems Manager 參數。  
例如，以下指定 `AWS::EC2::KeyPair::KeyName` 類型：  
+ `AWS::SSM::Parameter::Value<AWS::EC2::KeyPair::KeyName>`

`AWS::SSM::Parameter::Value<List<AWS-specific parameter type>>`  
Systems Manager 參數，其值是 AWS特定參數類型的清單。  
例如，以下指定 `AWS::EC2::KeyPair::KeyName` 類型清單：  
+ `AWS::SSM::Parameter::Value<List<AWS::EC2::KeyPair::KeyName>>`

## 不支援的 Systems Manager 參數類型
<a name="systems-manager-parameter-types-unsupported"></a>

CloudFormation 不支援下列 Systems Manager 參數類型：
+ Systems Manager 參數類型清單 — 例如：`List<AWS::SSM::Parameter::Value<String>>`

此外，CloudFormation 不支援將範本參數定義為 `SecureString` Systems Manager 參數類型。不過，您可以將安全字串指定為某些資源的參數*值*。如需詳細資訊，請參閱[使用動態參考取得存放在其他服務中的值](dynamic-references.md)。

# CloudFormation 逐步解說
<a name="walkthroughs"></a>

本文件提供一系列逐步解說，旨在讓您透過實際操作練習堆疊部署。
+ [參考在另一個 CloudFormation 堆疊中的資源輸出](walkthrough-crossstackref.md) – 此逐步解說說明如何在一個 CloudFormation 堆疊中參考另一個堆疊的輸出內容。您可以在個別堆疊中建立相關 AWS 資源，以建立更模組化且可重複使用的範本，而不是將所有資源包含在單一堆疊中。
+ [在 Amazon EC2 上部署應用程式](deploying.applications.md) – 了解如何使用 CloudFormation 自動安裝、設定和啟動 Amazon EC2 執行個體上的應用程式。這樣可讓您輕鬆地重複部署和更新現有安裝，無需直接連接到執行個體。
+ [更新 CloudFormation 堆疊](updating.stacks.walkthrough.md) – 您可以使用 CloudFormation，逐步完成更新運作中堆疊的簡易程序。
+ [建置擴展和負載平衡的應用程式](walkthrough-autoscaling.md) – 了解如何使用 CloudFormation 建立可擴展且負載平衡的應用程式。本逐步解說涵蓋建立 Auto Scaling 群組、負載平衡器及其他相關資源，以確保您的應用程式能應對變化的流量負載並保持高可用性。
+ [在另一個 中使用 VPC 的對等 AWS 帳戶](peer-with-vpc-in-another-account.md) – 此演練會引導您完成在不同 VPCs 之間建立虛擬私有雲端 (VPC) 對等互連的程序 AWS 帳戶。VPC 對等互連可協助您在兩個 VPC 之間路由流量，並像存取同一網路中的資源一樣存取這些資源。
+ [使用 CloudFormation 透過 CodeDeploy 進行 ECS 藍色/綠色部署](blue-green.md) – 探索如何使用 CloudFormation 在 Amazon ECS 上執行 AWS CodeDeploy 藍/綠部署。藍綠部署是一種以最短的停機時間更新應用程式或服務的方式。

# 參考在另一個 CloudFormation 堆疊中的資源輸出
<a name="walkthrough-crossstackref"></a>

此逐步解說說明如何在一個 CloudFormation 堆疊中參考另一個堆疊的輸出內容，以建立更模組化且可重複使用的範本。

您可以在個別堆疊中建立相關 AWS 資源，而不是將所有資源包含在單一堆疊中。然後，您可以從其他堆疊參考必要的資源輸出。透過將跨堆疊參考限制在輸出，您可以控制堆疊中由其他堆疊參考的部分。

例如，您可能有一個使用 VPC、安全群組，以及公有 Web 應用程式子網路的網路堆疊，以及另一個公有 Web 應用程式堆疊。若要確保 Web 應用程式使用來自網路堆疊的安全群組和子網路，您可以建立跨堆疊參考，允許 Web 應用程式堆疊參考網路堆疊的資源輸出。使用跨堆疊參考，Web 應用程式堆疊的擁有者便不需要建立或維護網路規則或資產。

若要建立跨堆疊參考，請使用 `Export` 輸出欄位，標記要匯出的資源輸出值。然後，使用 `Fn::ImportValue` 內部函數匯入值。如需詳細資訊，請參閱[從部署的 CloudFormation 堆疊取得匯出的輸出](using-cfn-stack-exports.md)。

**注意**  
CloudFormation 是免費服務。不過，您需要按目前費率支付堆疊中包含 AWS 的資源費用。如需 AWS 定價的詳細資訊，請參閱[各項產品的詳細資訊頁面](https://aws.amazon.com/)。

**Topics**
+ [使用範例範本建立網路堆疊](#walkthrough-crossstackref-create-vpc-stack)
+ [使用範例範本建立 Web 應用程式堆疊](#walkthrough-crossstackref-create-ec2-stack)
+ [驗證堆疊是否按設計運作](#walkthrough-crossstackref-verify)
+ [疑難排解 AMI 映射錯誤](#walkthrough-crossstackref-troubleshooting-ami)
+ [清除您的資源](#walkthrough-crossstackref-clean-up)

## 使用範例範本建立網路堆疊
<a name="walkthrough-crossstackref-create-vpc-stack"></a>

在您開始此演練前，請確認您已有使用下列所有服務的 IAM 許可：Amazon VPC、Amazon EC2 和 CloudFormation。

網路堆疊包含您會在 Web 應用程式堆疊中使用的 VPC、安全群組和子網路。除了這些資源之外，網路堆疊也會建立網際網路閘道及路由表，以啟用公有存取。

您必須在您建立 Web 應用程式堆疊前建立此堆疊。若您先建立 Web 應用程式堆疊，它將不會擁有安全群組或子網路。

堆疊範本可在以下 URL 中找到：[https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleNetworkCrossStack.template](https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleNetworkCrossStack.template)。若要查看堆疊建立的資源，請選擇連結，開啟範本。在 `Outputs` 區段中，您可以查看範例範本匯出的網路資源。匯出資源的名稱會加上堆疊名稱的字首，以在您從其他堆疊匯出網路資源時進行區別。當使用者匯入網路資源時，他們便可以指定要匯入哪些堆疊的資源。

**建立網路堆疊**

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 在**堆疊**頁面的右上角，選擇**建立堆疊**，並選擇**使用新資源 (標準)**。

1. 選擇**選擇現有範本**，然後在**指定範本**區段中選擇 **Amazon S3 URL**。

1. 對於 **Amazon S3 URL**，貼上下列 URL：**https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleNetworkCrossStack.template**。

1. 選擇**下一步**。

1. 針對 **Stack name (堆疊名稱)**，輸入 **SampleNetworkCrossStack**，然後選擇 **Next (下一步)**。
**注意**  
記錄此堆疊的名稱。當您在啟動 Web 應用程式堆疊時，您將會需要堆疊名稱。

1. 選擇**下一步**。針對此演練，您不需要新增標籤或指定進階設定。

1. 確認堆疊名稱和範本 URL 正確，然後選擇 **Create stack (建立堆疊)**。

   CloudFormation 可能需要幾分鐘的時間來建立您的堆疊。等待所有資源成功建立，再繼續建立 Web 應用程式堆疊。

1. 若要監控進度，請檢視堆疊事件。如需詳細資訊，請參閱[監控堆疊進度](monitor-stack-progress.md)。

## 使用範例範本建立 Web 應用程式堆疊
<a name="walkthrough-crossstackref-create-ec2-stack"></a>

Web 應用程式堆疊會建立使用網路堆疊之安全群組和子網路的 EC2 執行個體。

您必須在與網路堆疊 AWS 區域 相同的 中建立此堆疊。

堆疊範本可在以下 URL 中找到：[https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template](https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template)。若要查看堆疊建立的資源，請選擇連結，開啟範本。在 `Resources` 區段中，檢視 EC2 執行個體的屬性。您可以使用 `Fn::ImportValue` 函數查看從另一個堆疊匯入網路資源的方式。

**建立 Web 應用程式堆疊**

1. 從**堆疊**頁面的右上角，選擇**建立堆疊**，並選擇**使用新資源 (標準)**。

1. 選擇**選擇現有範本**，然後在**指定範本**區段中選擇 **Amazon S3 URL**。

1. 對於 **Amazon S3 URL**，貼上下列 URL：**https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template**。

1. 選擇**下一步**。

1. 在 **Stack Name** (堆疊名稱) 中輸入 **SampleWebAppCrossStack**。在 **Parameters (參數)** 區段中，針對 **NetworkStackName** 參數使用預設值，然後選擇 **Next (下一步)**。

   範例範本會使用參數值指定要從哪個堆疊匯入值。

1. 選擇**下一步**。針對此演練，您不需要新增標籤或指定進階設定。

1. 確認堆疊名稱和範本 URL 正確，然後選擇 **Create stack (建立堆疊)**。

   CloudFormation 可能需要幾分鐘的時間來建立您的堆疊。

## 驗證堆疊是否按設計運作
<a name="walkthrough-crossstackref-verify"></a>

在堆疊建立之後，檢視其資源並注意執行個體 ID。如需檢視堆疊資源的詳細資訊，請參閱[在 CloudFormation 主控台中檢視堆疊資訊](cfn-console-view-stack-data-resources.md)。

若要驗證執行個體的安全群組和子網路，請在 [Amazon EC2 主控台](https://console.aws.amazon.com/ec2/)檢視執行個體的屬性。若執行個體使用來自 `SampleNetworkCrossStack` 堆疊的安全群組和子網路，表示您已成功建立跨堆疊參考。

使用主控台檢視堆疊輸出和範例網站 URL，驗證 Web 應用程式已在執行中。如需詳細資訊，請參閱[在 CloudFormation 主控台中檢視堆疊資訊](cfn-console-view-stack-data-resources.md)。

## 疑難排解 AMI 映射錯誤
<a name="walkthrough-crossstackref-troubleshooting-ami"></a>

若您收到錯誤，`Template error: Unable to get mapping for AWSRegionArch2AMI::[region]::HVM64` 範本不會包含您 AWS 區域的 AMI 映射。我們建議使用 Systems Manager 公有參數動態參考最新的 AMI，而非更新映射：

1. 從以下網址下載 `SampleWebAppCrossStack` 範本到您的本機電腦：https：//[https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template](https://s3.amazonaws.com/cloudformation-examples/user-guide/cross-stack/SampleWebAppCrossStack.template)。

1. 刪除整個 `AWSRegionArch2AMI` 映射區段。

1. 新增下列 Systems Manager 參數：

   ```
   "LatestAmiId": {
     "Description": "The latest Amazon Linux 2 AMI from the Parameter Store",
       "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
       "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
     }
   ```

1. 取代現有的 `ImageId` 參考：

   ```
   "ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" } , "HVM64" ] }, 
   ```

   取代為：

   ```
   "ImageId": { "Ref": "LatestAmiId" },
   ```

   此參數會自動解析為您部署堆疊所在區域的最新 Amazon Linux 2 AMI。

   對於其他 Linux 發行版本，請使用對應的參數路徑。如需詳細資訊，請參閱《*AWS Systems Manager 使用者指南*》中的[探索參數存放區中的公有參數](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)。

1. 將修改的範本上傳至您帳戶中的 S3 儲存貯體：

   ```
   aws s3 cp SampleWebAppCrossStack.template s3://amzn-s3-demo-bucket/
   ```

1. 建立堆疊時，指定您的 S3 範本 URL，而非範例 URL。

## 清除您的資源
<a name="walkthrough-crossstackref-clean-up"></a>

為了確保您不需要為不必要的服務支付費用，請刪除堆疊。

**刪除堆疊**

1. 在 CloudFormation 主控台中，選擇 `SampleWebAppCrossStack` 堆疊。

1. 選擇 **Actions (動作)**，然後選擇 **Delete stack (刪除堆疊)**。

1. 在確認訊息中，選擇 **Delete (刪除)**。

1. 在堆疊刪除後，為 `SampleNetworkCrossStack` 堆疊重複相同的步驟。
**注意**  
等到 CloudFormation 完全刪除 `SampleWebAppCrossStack` 堆疊。若 EC2 執行個體仍在 VPC 中執行，CloudFormation 不會刪除 `SampleNetworkCrossStack` 堆疊中的 VPC。

# 在 Amazon EC2 上部署應用程式
<a name="deploying.applications"></a>

可以使用 CloudFormation 自動安裝、設定和啟動 Amazon EC2 執行個體上的應用程式。這樣可讓您輕鬆地重複部署和更新現有安裝，無需直接連接到執行個體，為您節省了許多時間和精力。

CloudFormation 包含一組以 `cloud-init` 為基礎的協助程式指令碼 (`cfn-init`、`cfn-signal`、`cfn-get-metadata` 和 `cfn-hup`)。您從 CloudFormation 範本呼叫這些協助程式指令碼，在相同範本中的 Amazon EC2 執行個體上安裝、設定和更新應用程式。如需詳細資訊，請參閱《CloudFormation 範本參考指南》中的 [CloudFormation 協助程式指令碼參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/cfn-helper-scripts-reference.html)。**

在[入門教學課程](gettingstarted.walkthrough.md)中，搭配使用 `UserData` 與基礎 bash 指令碼來建立簡單的 Web 伺服器。這僅適用於簡單的「Hello World」頁面，真正的應用程式通常需要更複雜的組態，包括：
+ 以正確的順序安裝多個軟體套件。
+ 使用特定內容建立的複雜組態檔案。
+ 服務已啟動並設定為自動執行。
+ 設定程序的錯誤處理和驗證。

相較於 `UserData` 中的基礎 bash 指令碼，CloudFormation 的協助程式指令碼可提供更強大且可維護的方式來設定 EC2 執行個體。`cfn-init` 協助程式指令碼會從範本的中繼資料中讀取組態資料，並以系統化的方式將其套用至執行個體。

在本教學課程中，您將了解如何使用 `cfn-init` 協助程式指令碼並監控引導程序。

**注意**  
CloudFormation 是免費的，但需要為您建立的 Amazon EC2 資源付費。不過，如果您是新手 AWS，則可以利用 [免費方案](https://aws.amazon.com/free/)，在此學習過程中將成本降至最低或消除。

**Topics**
+ [先決條件](#bootstrapping-tutorial-prerequisites)
+ [了解引導概念](#bootstrapping-tutorial-understand-concepts)
+ [從簡單的引導範例開始](#bootstrapping-tutorial-simple-example)
+ [新增檔案和命令](#bootstrapping-tutorial-add-complexity)
+ [新增網路安全](#bootstrapping-tutorial-security-group)
+ [完整的引導範本](#bootstrapping-tutorial-complete-template)
+ [使用主控台建立堆疊](#bootstrapping-tutorial-create-stack)
+ [監控引導程序](#bootstrapping-tutorial-validate-bootstrap)
+ [測試引導的 Web 伺服器](#bootstrapping-tutorial-test-web-server)
+ [對引導問題進行疑難排解](#bootstrapping-tutorial-troubleshooting)
+ [清除資源](#bootstrapping-tutorial-clean-up)
+ [後續步驟](#bootstrapping-tutorial-next-steps)

## 先決條件
<a name="bootstrapping-tutorial-prerequisites"></a>
+ 您必須已完成 [建立您的第一個堆疊](gettingstarted.walkthrough.md) 教學課程，或具有 CloudFormation 基礎知識的同等經驗。
+ 您必須具有具有 IAM 使用者或角色 AWS 帳戶 的 存取權，該角色具有使用 Amazon EC2 和 CloudFormation 的許可，或管理使用者存取權。
+ 必須擁有可存取網際網路的虛擬私有雲端 (VPC)。此教學範本需要預設 VPC，它會自動隨附較新的 AWS 帳戶。如果您沒有預設 VPC，或已刪除它，請參閱 [建立您的第一個堆疊](gettingstarted.walkthrough.md) 教學課程中的疑難排解一節，了解替代解決方案。

## 了解引導概念
<a name="bootstrapping-tutorial-understand-concepts"></a>

讓我們先了解讓引導運作的關鍵概念，然後再建立範本。

### `cfn-init` helper 指令碼
<a name="bootstrapping-tutorial-cfn-init-overview"></a>

CloudFormation 提供 Python 協助程式指令碼，您可以使用其在 Amazon EC2 執行個體上安裝軟體及啟動服務。`cfn-init` 指令碼會從範本中讀取資源中繼資料，並將組態套用至執行個體。

程序的運作方式如下：

1. 可以在 EC2 資源的 `Metadata` 區段中定義組態。

1. 可以透過 `UserData` 指令碼呼叫 `cfn-init`。

1. `cfn-init` 會讀取中繼資料並套用組態。

1. 根據您的規格設定您的執行個體。

### 中繼資料結構
<a name="bootstrapping-tutorial-metadata-structure"></a>

在 EC2 執行個體中的特定結構中定義組態。

```
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Metadata:                       # Metadata section for the resource
      AWS::CloudFormation::Init:    # Required key that cfn-init looks for
        config:                     # Configuration name (you can have multiple)
          packages:                 # Install packages
          files:                    # Create files
          commands:                 # Run commands
          services:                 # Start/stop services
```

`cfn-init` 指令碼會按照特定順序處理這些區段：packages、groups、users、sources、files、commands、services。

## 從簡單的引導範例開始
<a name="bootstrapping-tutorial-simple-example"></a>

讓我們從安裝和啟動 Apache 的最低引導範例開始。

```
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:                 # Install Apache web server
            yum:
              httpd: []
          services:                 # Start Apache and enable it to start on boot
            systemd:
              httpd:
                enabled: true
                ensureRunning: true
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      UserData: !Base64             # Script that runs when instance starts
        Fn::Sub: |
          #!/bin/bash
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource EC2Instance --region ${AWS::Region}
```

這個簡單的範例示範了核心概念：
+ `packages` 區段會使用 yum 安裝 `httpd` 套件。這適用於 Amazon Linux 和使用 yum 的其他 Linux 發行版本。
+ `services` 區段可確保 `httpd` 自動啟動和執行。
+ `UserData` 安裝最新的引導工具並呼叫 `cfn-init`。

## 新增檔案和命令
<a name="bootstrapping-tutorial-add-complexity"></a>

現在，讓我們透過在 EC2 執行個體的 `/var/log` 目錄中新增自訂網頁和日誌檔案來增強我們的範例。

### 建立檔案
<a name="bootstrapping-tutorial-files-section"></a>

`files` 區段可讓您在具有特定內容的執行個體上建立檔案。垂直管道 (`|`) 可讓您傳遞文字區塊 (HTML 程式碼） 作為檔案的內容 (`/var/www/html/index.html`)。

```
files:
  /var/www/html/index.html:
    content: |
      <body>
        <h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1>
      </body>
```

### 執行命令
<a name="bootstrapping-tutorial-commands-section"></a>

`commands` 區段可讓您在引導程序期間執行 Shell 命令。此命令會在 EC2 執行個體上的 `/var/log/welcome.txt` 建立日誌檔案。若要檢視它，需要 Amazon EC2 金鑰對來用於 SSH 存取，以及可用於 SSH 到執行個體的 IP 位址範圍 (此處未涵蓋)。

```
commands:
  createWelcomeLog:
    command: "echo 'cfn-init ran successfully!' > /var/log/welcome.txt"
```

## 新增網路安全
<a name="bootstrapping-tutorial-security-group"></a>

由於我們正在設定 Web 伺服器，我們需要允許 Web 流量 (HTTP) 來連接我們的 EC2 執行個體。因此，我們會建立一個安全群組，它允許來自 IP 位址的連接埠 80 的傳入流量。EC2 執行個體也需要將流量傳送到網際網路，例如安裝套件更新。根據預設，安全群組允許所有傳出流量。然後，我們將使用 `SecurityGroupIds` 屬性來關聯此安全群組與 EC2 執行個體。

```
WebServerSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Allow HTTP access from my IP address
    SecurityGroupIngress:
      - IpProtocol: tcp
        Description: HTTP
        FromPort: 80
        ToPort: 80
        CidrIp: !Ref MyIP
```

## 完整的引導範本
<a name="bootstrapping-tutorial-complete-template"></a>

現在，讓我們將所有部分放在一起。以下是合併我們討論的所有概念的完整範本。

```
AWSTemplateFormatVersion: 2010-09-09
Description: Bootstrap an EC2 instance with Apache web server using cfn-init

Parameters:
  LatestAmiId:
    Description: The latest Amazon Linux 2 AMI from the Parameter Store
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'

  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
      - t3.micro
      - t2.micro
    ConstraintDescription: must be a valid EC2 instance type.

  MyIP:
    Description: Your IP address in CIDR format (e.g. 203.0.113.1/32)
    Type: String
    MinLength: 9
    MaxLength: 18
    Default: 0.0.0.0/0
    AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.

Resources:
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTP access from my IP address
      SecurityGroupIngress:
        - IpProtocol: tcp
          Description: HTTP
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref MyIP

  WebServer:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: |
                <body>
                  <h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1>
                </body>
          commands:
            createWelcomeLog:
              command: "echo 'cfn-init ran successfully!' > /var/log/welcome.txt"
          services:
            systemd:
              httpd:
                enabled: true
                ensureRunning: true
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      UserData: !Base64
        Fn::Sub: |
          #!/bin/bash
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServer --region ${AWS::Region}
      Tags:
        - Key: Name
          Value: Bootstrap Tutorial Web Server

Outputs:
  WebsiteURL:
    Value: !Sub 'http://${WebServer.PublicDnsName}'
    Description: EC2 instance public DNS name
```

## 使用主控台建立堆疊
<a name="bootstrapping-tutorial-create-stack"></a>

下列程序涉及從檔案上傳範例堆疊範本。在本機電腦上打開文字編輯器，並新增範本。儲存檔案，並將其命名為 `samplelinux2stack.template`。

**啟動堆疊範本**

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選擇 **Create stack (建立堆疊)**、**With new resources (standard) (使用新資源 (標準))**。

1. 在**指定範本**下，選擇**上傳範本檔案**，然後選擇**選擇檔案**以上傳 `samplelinux2stack.template` 檔案。

1. 選擇**下一步**。

1. 在**指定詳細資訊**頁面上，輸入 **BootstrapTutorialStack** 作為堆疊名稱。

1. 在**參數**中，請執行下列動作。
   + **LatestAmiId**：保留預設值。
   + **InstanceType**：為 EC2 執行個體類型選擇 **t2.micro** 或 **t3.micro**。
   + **MyIP**：輸入尾碼為 `/32` 的公有 IP 位址。

1. 選擇**下一步**兩次，然後選擇**提交**以建立堆疊。

## 監控引導程序
<a name="bootstrapping-tutorial-validate-bootstrap"></a>

引導程序需要的時間比簡單的 EC2 啟動時間更長，因為正在安裝和設定其他軟體。

**若要監控引導進度**

1. 在 CloudFormation 主控台中，選取堆疊並開啟**事件**索引標籤。

1. 請留意 `WebServer CREATE_IN_PROGRESS` 事件。引導程序會在執行個體啟動後開始。

1. 引導程序通常需要幾分鐘時間。您會在完成後看到 `WebServer CREATE_COMPLETE`。

如果想要查看引導程序期間發生的情況，可以檢查執行個體日誌。

**若要檢視引導日誌 (選用)**

1. 開啟 [EC2 主控台](https://console.aws.amazon.com/ec2/)並找到執行個體。

1. 選取執行個體，然後再依序選擇**動作**、**監控和故障診斷**、**取得系統日誌**，以查看引導進度。

1. 如果沒有立即看到日誌，請等待並重新整理頁面。

## 測試引導的 Web 伺服器
<a name="bootstrapping-tutorial-test-web-server"></a>

當堆疊顯示 `CREATE_COMPLETE` 時，請測試 Web 伺服器。

**若要測試 Web 伺服器**

1. 在 CloudFormation 主控台中，前往堆疊的**輸出**索引標籤。

1. 按一下**網站 URL** 值，在新索引標籤中開啟您的 Web 伺服器。

1. 應該會看到包含訊息 `Congratulations, you have successfully launched the AWS CloudFormation sample` 的自訂網頁。

**注意**  
如果頁面未立即載入，請等待一分鐘，然後再試一次。即使堆疊顯示 `CREATE_COMPLETE`，引導程序仍可能正在完成。

## 對引導問題進行疑難排解
<a name="bootstrapping-tutorial-troubleshooting"></a>

如果引導程序失敗或 Web 伺服器無法運作，以下是常見問題和解決方案。

### 常見問題
<a name="bootstrapping-tutorial-common-issues"></a>
+ **堆疊建立失敗** – 檢查**事件**索引標籤是否有特定錯誤訊息。
+ **無法存取 Web 伺服器** – 在 `MyIP` 參數中確認 IP 位址正確。請記得在結尾包含 `/32`。
+ **引導程序失敗** – 執行個體可能會啟動，但 `cfn-init` 失敗。如監控章節所述，檢查系統日誌。

## 清除資源
<a name="bootstrapping-tutorial-clean-up"></a>

若要避免持續收費，可以透過刪除堆疊及其資源來清除。

**刪除堆疊及其資源**

1. 開啟 [CloudFormation 主控台](https://console.aws.amazon.com/cloudformation/)。

1. 在**堆疊**頁面中，選取您所建立堆疊名稱旁的選項 (**BootstrapTutorialStack**)，然後選擇**刪除**。

1. 出現確認提示時，請選擇**刪除**。

1. 在**事件**索引標籤中監控堆疊刪除程序的進度。**BootstrapTutorialStack** 的狀態會變更為 `DELETE_IN_PROGRESS`。當 CloudFormation 完成刪除堆疊時，它會從清單移除堆疊。

## 後續步驟
<a name="bootstrapping-tutorial-next-steps"></a>

恭喜您！您已成功了解如何使用 CloudFormation 來啟動 EC2 執行個體。您現在了解：
+ 如何使用 `cfn-init` 協助程式指令碼
+ 如何建構用於引導的中繼資料
+ 如何安裝套件、建立檔案、執行命令和管理服務
+ 如何監控引導問題

若要繼續學習：
+ 了解如何更新執行中的堆疊並使用`cfn-hup`協助程式指令碼。如需詳細資訊，請參閱[更新 CloudFormation 堆疊](updating.stacks.walkthrough.md)。
+ 了解如何引導 Windows 堆疊。如需詳細資訊，請參閱[引導 Windows 型 CloudFormation 堆疊](cfn-windows-stacks-bootstrapping.md)。
+ 探索具有多個組態集的更複雜引導案例。如需詳細資訊，請參閱《CloudFormation 範本參考指南》中的 [cfn-init](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/cfn-init.html) 和 [AWS::CloudFormation::Init](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-init.html)。**
+ 了解有關用於報告引導完成狀態的 `cfn-signal`。如需詳細資訊，請參閱《CloudFormation 範本參考指南》**中的 [cfn-signal](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/cfn-signal.html)。

# 更新 CloudFormation 堆疊
<a name="updating.stacks.walkthrough"></a>

**注意**  
本教學課程以[在 Amazon EC2 上部署應用程式](deploying.applications.md)教學課程中的概念為基礎。如果您尚未完成該教學課程，建議您先了解使用 CloudFormation 的 EC2 引導。

本主題示範了對執行中堆疊的簡單更新進度。我們將逐步解說以下步驟：

1. **建立初始堆疊** – 使用基本 Amazon Linux 2 AMI 建立堆疊，並使用 CloudFormation 協助程式指令碼安裝 Apache Web Server和簡單的 PHP 應用程式。

1. **更新應用程式** – 更新應用程式中的其中一個檔案，並使用 CloudFormation 部署軟體。

1. **新增金鑰對** – 將 Amazon EC2 金鑰對新增至執行個體，然後更新安全群組以允許 SSH 存取執行個體。

1. **更新執行個體類型** – 變更基礎 Amazon EC2 執行個體的執行個體類型。

1. **更新 AMI** – 變更堆疊中 Amazon EC2 執行個體的 Amazon Machine Image (AMI)。

**注意**  
CloudFormation 是免費的，但需要為您建立的 Amazon EC2 資源付費。不過，如果您是新手 AWS，則可以利用 [免費方案](https://aws.amazon.com/free/)，在此學習過程中將成本降至最低或消除。

**Topics**
+ [步驟 1：建立初始堆疊](#update-stack-initial-stack)
+ [步驟 2：更新應用程式](#update-stack-update-application)
+ [步驟 3：使用金鑰對新增 SSH 存取](#update-stack-add-key-pair)
+ [步驟 4：更新執行個體類型](#update-stack-update-instance-type)
+ [步驟 5：更新 AMI](#update-stack-update-ami)
+ [可用性與影響考量事項](#update.walkthrough.impact)
+ [相關資源](#update.walkthrough.related)

## 步驟 1：建立初始堆疊
<a name="update-stack-initial-stack"></a>

首先，我們會建立堆疊，供本主題的其餘部分使用。我們提供了簡單的範本，可啟動託管在 上的單一執行個體 PHP Web 應用程式，Apache Web Server並在 Amazon Linux 2 AMI 上執行。

Apache Web Server、PHP 和簡單的 PHP 應用程式都是由預設安裝在 Amazon Linux 2 AMI 上的 CloudFormation 協助程式指令碼所安裝。下列範本程式碼片段顯示描述要安裝的套件和檔案的中繼資料，在此情況下，Amazon Linux 2 AMI 儲存Yum庫中的 Apache Web Server和 PHP 基礎設施。程式碼片段也會顯示 `Services`區段，這可確保 Apache Web Server 正在執行 。

```
WebServerInstance:
  Type: AWS::EC2::Instance
  Metadata:
    AWS::CloudFormation::Init:
      config:
        packages:
          yum:
            httpd: []
            php: []
        files:
          /var/www/html/index.php:
            content: |
              <?php
              echo '<h1>Hello World!</h1>';
              ?>
            mode: '000644'
            owner: apache
            group: apache
        services:
          systemd:
            httpd:
              enabled: true
              ensureRunning: true
```

應用程式本身是完全在範本中定義的「Hello World」範例。若是實際的應用程式，系統可能會將檔案存放在 Amazon S3、GitHub 或其他儲存庫上，並參考範本的內容。CloudFormation 能夠下載 RPM 或 RubyGems 等套件、參考個別檔案以及解壓縮 `.zip` 與 `.tar` 檔案，藉此在 Amazon EC2 執行個體上建立應用程式成品。

範本會啟用並設定`cfn-hup`協助程式，以接聽 Amazon EC2 執行個體中繼資料中定義的組態變更。透過使用 `cfn-hup` 協助程式，您可以更新應用程式軟體，例如 Apache 或 PHP 的版本，也可以從 CloudFormation 更新 PHP 應用程式檔案本身。範本中相同 Amazon EC2 資源的下列程式碼片段顯示設定 `cfn-init` 每兩分鐘`cfn-hup`呼叫 以通知中繼資料並套用更新所需的片段。否則， `cfn-init`只會在啟動時執行一次。

```
files:
  /etc/cfn/cfn-hup.conf:
    content: !Sub |
      [main]
      stack=${AWS::StackId}
      region=${AWS::Region}
      # The interval used to check for changes to the resource metadata in minutes. Default is 15
      interval=2
    mode: '000400'
    owner: root
    group: root
  /etc/cfn/hooks.d/cfn-auto-reloader.conf:
    content: !Sub |
      [cfn-auto-reloader-hook]
      triggers=post.update
      path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init
      action=/opt/aws/bin/cfn-init -s ${AWS::StackId} -r WebServerInstance --region ${AWS::Region}
      runas=root
services:
  systemd:
    cfn-hup:
      enabled: true
      ensureRunning: true
      files:
        - /etc/cfn/cfn-hup.conf
        - /etc/cfn/hooks.d/cfn-auto-reloader.conf
```

為了完成堆疊，在 Amazon EC2 執行個體定義的 `Properties`區段中， `UserData` 屬性包含呼叫 `cfn-init` 來安裝套件和檔案的`cloud-init`指令碼。如需詳細資訊，請參閱《CloudFormation 範本參考指南》中的 [CloudFormation 協助程式指令碼參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/cfn-helper-scripts-reference.html)。**範本也會建立 Amazon EC2 安全群組。

```
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  LatestAmiId:
    Description: The latest Amazon Linux 2 AMI from the Parameter Store
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'

  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.nano
      - t3.micro
      - t3.small
      - t3.medium
      - t3a.nano
      - t3a.micro
      - t3a.small
      - t3a.medium
      - m5.large
      - m5.xlarge
      - m5.2xlarge
      - m5a.large
      - m5a.xlarge
      - m5a.2xlarge
      - c5.large
      - c5.xlarge
      - c5.2xlarge
      - r5.large
      - r5.xlarge
      - r5.2xlarge
      - r5a.large
      - r5a.xlarge
      - r5a.2xlarge
    ConstraintDescription: must be a valid EC2 instance type.
    
Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          # Get the latest CloudFormation package
          yum update -y aws-cfn-bootstrap
          # Run cfn-init
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region} || error_exit 'Failed to run cfn-init'        
          # Start up the cfn-hup daemon to listen for changes to the EC2 instance metadata
          /opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'
          # Signal success or failure
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region}
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
              php: []
          files:
            /var/www/html/index.php:
              content: |
                <?php
                echo "<h1>Hello World!</h1>";
                ?>
              mode: '000644'
              owner: apache
              group: apache
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                # The interval used to check for changes to the resource metadata in minutes. Default is 15
                interval=2
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -s ${AWS::StackId} -r WebServerInstance --region ${AWS::Region}
                runas=root
          services:
            systemd:
              httpd:
                enabled: true
                ensureRunning: true
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M

  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

Outputs:
  WebsiteURL:
    Value: !Sub 'http://${WebServerInstance.PublicDnsName}'
    Description: URL of the web application
```

**從此範本啟動堆疊**

1. 複製範本，並將其儲存為文字檔案於本機系統。請記下檔案位置，因為後續步驟仍需使用到該檔案。

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選擇使用**新資源建立堆疊 （標準）**。

1. 選擇**選擇現有的範本**。

1. 在**指定範本**下，選擇**上傳範本檔案**，然後瀏覽至您在第一個步驟中建立的檔案，然後選擇**下一步**。

1. 在**指定堆疊詳細資訊**頁面上，輸入 **UpdateTutorial**做為堆疊名稱。

1. 在**參數**下，保持所有參數相同，然後選擇**下一步**兩次。

1. 在**檢閱和建立**畫面上，選擇**提交**。

堆疊的狀態為 之後`CREATE_COMPLETE`，**輸出**索引標籤會顯示您網站的 URL。如果您選擇`WebsiteURL`輸出的值，您會看到新的 PHP 應用程式正在運作。

## 步驟 2：更新應用程式
<a name="update-stack-update-application"></a>

既然我們已經將堆疊部署完成，接下來便要更新應用程式。我們會簡單地更改應用程式所印出的文字。若要執行此作業，便需要將 echo 命令新增至 index.php 檔案，如下列範本程式碼片段所示：

```
files:
  /var/www/html/index.php:
    content: |
      <?php
      echo "<h1>Hello World!</h1>";
      echo "<p>This is an updated version of our application.</p>";
      ?>
    mode: '000644'
    owner: apache
    group: apache
```

透過文字編輯器，即可手動編輯儲存在本機上的範本檔案。

現在，請更新堆疊。

**使用已更新的範本更新堆疊**

1. 在 CloudFormation 主控台中，選取您的**UpdateTutorial**堆疊。

1. 選擇**更新，直接更新**。

1. 選擇**取代現有範本**。

1. 在**指定範本**下，選擇**上傳範本檔案**並上傳修改後的範本檔案，然後選擇**下一步**。

1. 在**指定堆疊詳細資訊**頁面上，保持所有參數相同，然後選擇**下一步**兩次。

1. 在**檢閱**頁面上，檢閱變更。在**變更**下，您應該會看到 CloudFormation 會更新`WebServerInstance`資源。

1. 選擇**提交**。

當您的堆疊處於 `UPDATE_COMPLETE` 狀態時，您可以再次選擇`WebsiteURL`輸出值，以確認應用程式的變更已生效。`cfn-hup` 協助程式每 2 分鐘執行一次，因此更新堆疊後，應用程式最多可能需要 2 分鐘才能變更。

前往 CloudFormation 主控台，即可查看更新後的資源集。您可以在 **Events** (事件) 標籤上檢視堆疊事件。在此情況下，Amazon EC2 執行個體的中繼資料`WebServerInstance`已更新，這會導致 CloudFormation 也重新評估其他資源 (`WebServerSecurityGroup`)，以確保沒有其他變更。系統並不會修改其他堆疊資源。唯有堆疊中的資源受到任何堆疊變更影響時，CloudFormation 才會更新這些資源。這類變更可以是直接的，例如屬性或中繼資料變更，也可能是由於相依性或透過 `Ref`、 `GetAtt`或其他內部範本函數的資料流程所造成。如需詳細資訊，請參閱[內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)。

這個簡單的更新說明了程序。不過，您可以對部署到 Amazon EC2 執行個體的檔案和套件進行更複雜的變更。例如，您可能會認為需要將 MySQL 與 MySQL 的 PHP 支援新增至執行個體。若要執行此作業，只需將其他套件、檔案與任何其他服務一併新增至組態，接著更新堆疊，即可部署變更。

```
packages:
  yum:
    httpd: []
    php: []
    mysql: []
    php-mysql: []
    mysql-server: []
    mysql-libs: []

  ...

services:
  systemd:
    httpd:
      enabled: true
      ensureRunning: true
    cfn-hup:
      enabled: true
      ensureRunning: true
      files:
        - /etc/cfn/cfn-hup.conf
        - /etc/cfn/hooks.d/cfn-auto-reloader.conf
    mysqld:
      enabled: true
      ensureRunning: true
```

您可以更新 CloudFormation 中繼資料，藉此將應用程式所使用的套件更新至新版本。在上述範例中，每個套件的版本屬性都是空的，表示 `cfn-init`應該安裝最新版本的套件。

```
packages:
  yum:
    httpd: []
    php: []
```

您可以選擇指定套件的版本字串；若您在後續的更新堆疊呼叫中更改該版本字串，則系統將部署新版本的套件。下方為使用 RubyGems 套件版本編號的範例。而支援版本控制的任何套件皆可擁有特定版本。

```
packages:
  rubygems:
    mysql: []
    rubygems-update:
      - "1.6.2"
    rake:
      - "0.8.7"
    rails:
      - "2.3.11"
```

## 步驟 3：使用金鑰對新增 SSH 存取
<a name="update-stack-add-key-pair"></a>

您也可以更新範本中的資源，以新增最初未在範本中指定的屬性。為了說明這一點，我們會將 Amazon EC2 金鑰對新增至現有的 EC2 執行個體，然後在 Amazon EC2 安全群組中開啟連接埠 22，以便您可以使用 Secure Shell (SSH) 存取執行個體。

**在現有的 Amazon EC2 執行個體中新增 SSH 存取**

1. 將兩個額外參數新增至範本，藉此傳遞現有的 Amazon EC2 金鑰對名稱與 SSH 位置。

   ```
   Parameters:
     KeyName:
       Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
       Type: AWS::EC2::KeyPair::KeyName
       ConstraintDescription: must be the name of an existing EC2 KeyPair.
   
     SSHLocation:
       Description: The IP address that can be used to SSH to the EC2 instances in CIDR format (e.g. 203.0.113.1/32)
       Type: String
       MinLength: 9
       MaxLength: 18
       Default: 0.0.0.0/0
       AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$'
       ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
   ```

1. 將 `KeyName` 屬性新增至 Amazon EC2 執行個體。

   ```
   WebServerInstance:
     Type: AWS::EC2::Instance
     Properties:
       ImageId: !Ref LatestAmiId
       InstanceType: !Ref InstanceType
       KeyName: !Ref KeyName
       SecurityGroupIds:
         - !Ref WebServerSecurityGroup
   ```

1. 將連接埠 22 與 SSH 位置新增至 Amazon EC2 安全群組的輸入規則。

   ```
   WebServerSecurityGroup:
     Type: AWS::EC2::SecurityGroup
     Properties:
       GroupDescription: Enable HTTP access via port 80 and SSH access via port 22
       SecurityGroupIngress:
         - IpProtocol: tcp
           FromPort: 80
           ToPort: 80
           CidrIp: 0.0.0.0/0
         - IpProtocol: tcp
           FromPort: 22
           ToPort: 22
           CidrIp: !Ref SSHLocation
   ```

1. 使用與 中說明的相同步驟來更新堆疊[步驟 2：更新應用程式](#update-stack-update-application)。

## 步驟 4：更新執行個體類型
<a name="update-stack-update-instance-type"></a>

現在，讓我們示範如何透過變更執行個體類型來更新基礎基礎設施。

到目前為止，我們建置的堆疊使用 t3.micro Amazon EC2 執行個體。假設您新建立的網站取得的流量超過 t3.micro 執行個體可以處理的流量，現在您想要移至 m5.large Amazon EC2 執行個體類型。如果執行個體類型的架構變更，則必須使用不同的 AMI 建立執行個體。不過，t3.micro 和 m5.large 都使用相同的 CPU 架構，並執行 Amazon Linux 2 (x86\$164) AMIs。如需詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的[變更執行個體類型的相容性](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/resize-limitations.html)。

讓我們使用我們在上一個步驟中修改的範本來變更執行個體類型。由於 `InstanceType` 是範本的輸入參數，因此我們不需要修改範本；我們可以在**指定堆疊詳細資訊**頁面上變更 參數的值。

**使用新的參數值更新堆疊**

1. 在 CloudFormation 主控台中，選取您的**UpdateTutorial**堆疊。

1. 選擇**更新，直接更新**。

1. 選擇**使用現有範本**，然後選擇**下一步**。

1. 在**指定堆疊詳細資訊**頁面上，將 **InstanceType** 文字方塊的值從 `t3.micro`變更為 `m5.large`。然後，選擇**下一步**兩次。

1. 在**檢閱**頁面上，檢閱變更。在**變更**下，您應該會看到 CloudFormation 會更新`WebServerInstance`資源。

1. 選擇**提交**。

透過啟動和停用執行個體，即可動態變更 EBS 後端 Amazon EC2 執行個體的執行個體類型。CloudFormation 會更新執行個體類型並重新啟動該執行個體，藉此嘗試將變更內容最佳化，讓執行個體 ID 不會因而改變。然而，重新啟動執行個體時，該執行個體的公有 IP 地址會隨之變更。為了確保彈性 IP 位址在變更後仍能正確繫結，CloudFormation 將一併更新彈性 IP 地址。您可以在 **CloudFormation** CloudFormation 主控台的事件索引標籤上查看變更。

若要從 檢查執行個體類型 AWS 管理主控台，請開啟 Amazon EC2 主控台，並在該處找到您的執行個體。

## 步驟 5：更新 AMI
<a name="update-stack-update-ami"></a>

現在，讓我們更新堆疊以使用 Amazon Linux 2023，這是新一代的 Amazon Linux。

更新 AMI 是一項需要取代執行個體的主要變更。我們不能只啟動和停止執行個體來修改 AMI；CloudFormation 會將此視為對資源不可變屬性的變更。CloudFormation 必須啟動替代資源，才能更改不可變屬性；此處將以新的 Amazon EC2 執行個體執行新的 AMI 為例。

我們來看看如何更新堆疊範本以使用 Amazon Linux 2023。關鍵變更包括更新 AMI 參數，以及從 `yum` 變更為`dnf`套件管理員。

```
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  LatestAmiId:
    Description: The latest Amazon Linux 2023 AMI from the Parameter Store
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64'

  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.nano
      - t3.micro
      - t3.small
      - t3.medium
      - t3a.nano
      - t3a.micro
      - t3a.small
      - t3a.medium
      - m5.large
      - m5.xlarge
      - m5.2xlarge
      - m5a.large
      - m5a.xlarge
      - m5a.2xlarge
      - c5.large
      - c5.xlarge
      - c5.2xlarge
      - r5.large
      - r5.xlarge
      - r5.2xlarge
      - r5a.large
      - r5a.xlarge
      - r5a.2xlarge
    ConstraintDescription: must be a valid EC2 instance type.

  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.

  SSHLocation:
    Description: The IP address that can be used to SSH to the EC2 instances in CIDR format (e.g. 203.0.113.1/32)
    Type: String
    MinLength: 9
    MaxLength: 18
    Default: 0.0.0.0/0
    AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
    
Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      KeyName: !Ref KeyName
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          # Get the latest CloudFormation package
          dnf update -y aws-cfn-bootstrap
          # Run cfn-init
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region} || error_exit 'Failed to run cfn-init'        
          # Start up the cfn-hup daemon to listen for changes to the EC2 instance metadata
          /opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'
          # Signal success or failure
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region}
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            dnf:
              httpd: []
              php: []
          files:
            /var/www/html/index.php:
              content: |
                <?php
                echo "<h1>Hello World!</h1>";
                echo "<p>This is an updated version of our application.</p>";
                echo "<p>Running on Amazon Linux 2023!</p>";
                ?>
              mode: '000644'
              owner: apache
              group: apache
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                # The interval used to check for changes to the resource metadata in minutes. Default is 15
                interval=2
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -s ${AWS::StackId} -r WebServerInstance --region ${AWS::Region}
                runas=root
          services:
            systemd:
              httpd:
                enabled: true
                ensureRunning: true
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M

  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80 and SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation

Outputs:
  WebsiteURL:
    Value: !Sub 'http://${WebServerInstance.PublicDnsName}'
    Description: URL of the web application
```

使用與 中說明的相同步驟來更新堆疊[步驟 2：更新應用程式](#update-stack-update-application)。

新的執行個體開始運作後，CloudFormation 即會更新堆疊中的其他資源，進而指向新資源。系統會進行稱為 `UPDATE_CLEANUP` 的程序，藉此建立新資源、刪除舊資源。此時，堆疊中執行個體的執行個體 ID 與應用程式 URL，皆會因更新作業而有所變更。**事件**資料表中的事件包含描述「請求的更新已變更不可變屬性，因此建立新的實體資源」，以指出資源已取代。

或者：如果您將應用程式碼寫入您要更新的 AMI，您可以使用相同的堆疊更新機制來更新 AMI 以載入新的應用程式。

**使用自訂應用程式碼更新 AMI**

1. 建立包含應用程式或作業系統變更的新 AMI。如需詳細資訊，請參閱[《Amazon EC2 使用者指南》中的建立 Amazon EBS 後端 AMI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html)。 *Amazon EC2 *

1. 更新您的範本以納入新的 AMI ID。

1. 使用與 中說明的相同步驟來更新堆疊[步驟 2：更新應用程式](#update-stack-update-application)。

更新堆疊時，CloudFormation 即會偵測到 AMI ID 有所變更，然後啟動堆疊更新作業 (與上述更新的觸發方式相同)。

## 可用性與影響考量事項
<a name="update.walkthrough.impact"></a>

不同屬性會對堆疊中的資源造成不同影響。您可以善用 CloudFormation 來更新任何屬性；但進行任何變更之前，應考量下列問題：

1. 更新作業對資源本身有何影響？ 舉例來說，更新警示閾值會導致警示在更新期間處於非作用中狀態。正如我們在本章所見，您需要停用並重新啟動執行個體，才能變更執行個體類型。CloudFormation 會透過基礎資源的更新或修改動作來更改資源。如需了解更新造成的影響，請查閱特定資源的文件。

1. 更改內容屬於可變或不可變項目？ 基礎服務並不支援部分資源屬性變更操作，例如：更改 Amazon EC2 執行個體上的 AMI。如果更改內容屬於可變項目，CloudFormation 將針對基礎資源使用 Update (更新) 或 Modify (修改) 類型的 API。如果屬性更改屬於不可變項目，則 CloudFormation 會使用更新後的屬性來建立新資源，並將這些資源連結至堆疊，接著刪除舊資源。雖然 CloudFormation 會嘗試縮短堆疊資源的停機時間，但替換資源屬於多步驟程序，需要一些時間才能完成。重新設定堆疊期間，應用程式將無法完全正常運作。例如，應用程式可能無法處理請求或存取資料庫；

## 相關資源
<a name="update.walkthrough.related"></a>

如需使用 CloudFormation 啟動應用程式以及與其他組態和部署服務整合的詳細資訊，例如 Puppet和 Opscode Chef，請參閱下列白皮書：
+ [透過 CloudFormation 引導應用程式](https://s3.amazonaws.com/cloudformation-examples/BoostrappingApplicationsWithAWSCloudFormation.pdf)
+ [將 CloudFormation 與 整合 Opscode Chef](https://s3.amazonaws.com/cloudformation-examples/IntegratingAWSCloudFormationWithOpscodeChef.pdf)
+ [將 CloudFormation 與 整合 Puppet](https://s3.amazonaws.com/cloudformation-examples/IntegratingAWSCloudFormationWithPuppet.pdf)

# 建置擴展和負載平衡的應用程式
<a name="walkthrough-autoscaling"></a>

在此逐步解說中，您將建立可協助您設定已擴展和已負載平衡應用程式的堆疊。逐步解說提供您將用於建立堆疊的範例範本。範例範本佈建 Auto Scaling 群組、Application Load Balancer、控制負載平衡器和 Auto Scaling 群組流量的安全群組，以及用以發布擴展活動相關通知的 Amazon SNS 通知組態。

此範本會建立一或多個 Amazon EC2 執行個體和一個 Application Load Balancer。若您從此範本建立堆疊，您必須為使用的 AWS 資源支付費用。

## 完整堆疊範本
<a name="example-templates-autoscaling-full-stack-template"></a>

讓我們從範本開始。

**YAML**

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  InstanceType:
    Description: The EC2 instance type
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium
  KeyName:
    Description: Name of an existing EC2 key pair to allow SSH access to the instances
    Type: AWS::EC2::KeyPair::KeyName
  LatestAmiId:
    Description: The latest Amazon Linux 2 AMI from the Parameter Store
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
  OperatorEmail:
    Description: The email address to notify when there are any scaling activities
    Type: String
  SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: 9
    MaxLength: 18
    Default: 0.0.0.0/0
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  Subnets:
    Type: 'List<AWS::EC2::Subnet::Id>'
    Description: At least two public subnets in different Availability Zones in the selected VPC
  VPC:
    Type: AWS::EC2::VPC::Id
    Description: A virtual private cloud (VPC) that enables resources in public subnets to connect to the internet
Resources:
  ELBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: ELB Security Group
      VpcId: !Ref VPC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: EC2 Security Group
      VpcId: !Ref VPC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        SourceSecurityGroupId:
          Fn::GetAtt:
          - ELBSecurityGroup
          - GroupId
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: !Ref SSHLocation
  EC2TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 30
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 15
      HealthyThresholdCount: 5
      Matcher:
        HttpCode: '200'
      Name: EC2TargetGroup
      Port: 80
      Protocol: HTTP
      TargetGroupAttributes:
      - Key: deregistration_delay.timeout_seconds
        Value: '20'
      UnhealthyThresholdCount: 3
      VpcId: !Ref VPC
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref EC2TargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      Subnets: !Ref Subnets
      SecurityGroups:
        - !GetAtt ELBSecurityGroup.GroupId
  LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties: 
      LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
      LaunchTemplateData:
        ImageId: !Ref LatestAmiId
        InstanceType: !Ref InstanceType
        KeyName: !Ref KeyName
        SecurityGroupIds: 
          - !Ref EC2SecurityGroup
        UserData:
          Fn::Base64: !Sub |
            #!/bin/bash
            yum update -y
            yum install -y httpd
            systemctl start httpd
            systemctl enable httpd
            echo "<h1>Hello World!</h1>" > /var/www/html/index.html
  NotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref OperatorEmail
          Protocol: email
  WebServerGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      LaunchTemplate:
        LaunchTemplateId: !Ref LaunchTemplate
        Version: !GetAtt LaunchTemplate.LatestVersionNumber
      MaxSize: '3'
      MinSize: '1'
      NotificationConfigurations:
        - TopicARN: !Ref NotificationTopic
          NotificationTypes: ['autoscaling:EC2_INSTANCE_LAUNCH', 'autoscaling:EC2_INSTANCE_LAUNCH_ERROR', 'autoscaling:EC2_INSTANCE_TERMINATE', 'autoscaling:EC2_INSTANCE_TERMINATE_ERROR']
      TargetGroupARNs:
        - !Ref EC2TargetGroup
      VPCZoneIdentifier: !Ref Subnets
```

**JSON**

```
{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Parameters":{
    "InstanceType":{
      "Description":"The EC2 instance type",
      "Type":"String",
      "Default":"t3.micro",
      "AllowedValues":[
        "t3.micro",
        "t3.small",
        "t3.medium"
      ]
    },
    "KeyName":{
      "Description":"Name of an existing EC2 key pair to allow SSH access to the instances",
      "Type":"AWS::EC2::KeyPair::KeyName"
    },
    "LatestAmiId":{
      "Description":"The latest Amazon Linux 2 AMI from the Parameter Store",
      "Type":"AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
      "Default":"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
    },
    "OperatorEmail":{
      "Description":"The email address to notify when there are any scaling activities",
      "Type":"String"
    },
    "SSHLocation":{
      "Description":"The IP address range that can be used to SSH to the EC2 instances",
      "Type":"String",
      "MinLength":9,
      "MaxLength":18,
      "Default":"0.0.0.0/0",
      "ConstraintDescription":"Must be a valid IP CIDR range of the form x.x.x.x/x."
    },
    "Subnets":{
      "Type":"List<AWS::EC2::Subnet::Id>",
      "Description":"At least two public subnets in different Availability Zones in the selected VPC"
    },
    "VPC":{
      "Type":"AWS::EC2::VPC::Id",
      "Description":"A virtual private cloud (VPC) that enables resources in public subnets to connect to the internet"
    }
  },
  "Resources":{
    "ELBSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"ELB Security Group",
        "VpcId":{
          "Ref":"VPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":80,
            "ToPort":80,
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
    "EC2SecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"EC2 Security Group",
        "VpcId":{
          "Ref":"VPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":80,
            "ToPort":80,
            "SourceSecurityGroupId":{
              "Fn::GetAtt":[
                "ELBSecurityGroup",
                "GroupId"
              ]
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":22,
            "ToPort":22,
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          }
        ]
      }
    },
    "EC2TargetGroup":{
      "Type":"AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties":{
        "HealthCheckIntervalSeconds":30,
        "HealthCheckProtocol":"HTTP",
        "HealthCheckTimeoutSeconds":15,
        "HealthyThresholdCount":5,
        "Matcher":{
          "HttpCode":"200"
        },
        "Name":"EC2TargetGroup",
        "Port":80,
        "Protocol":"HTTP",
        "TargetGroupAttributes":[
          {
            "Key":"deregistration_delay.timeout_seconds",
            "Value":"20"
          }
        ],
        "UnhealthyThresholdCount":3,
        "VpcId":{
          "Ref":"VPC"
        }
      }
    },
    "ALBListener":{
      "Type":"AWS::ElasticLoadBalancingV2::Listener",
      "Properties":{
        "DefaultActions":[
          {
            "Type":"forward",
            "TargetGroupArn":{
              "Ref":"EC2TargetGroup"
            }
          }
        ],
        "LoadBalancerArn":{
          "Ref":"ApplicationLoadBalancer"
        },
        "Port":80,
        "Protocol":"HTTP"
      }
    },
    "ApplicationLoadBalancer":{
      "Type":"AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties":{
        "Scheme":"internet-facing",
        "Subnets":{
          "Ref":"Subnets"
        },
        "SecurityGroups":[
          {
            "Fn::GetAtt":[
              "ELBSecurityGroup",
              "GroupId"
            ]
          }
        ]
      }
    },
    "LaunchTemplate":{
      "Type":"AWS::EC2::LaunchTemplate",
      "Properties":{
        "LaunchTemplateName":{
          "Fn::Sub":"${AWS::StackName}-launch-template"
        },
        "LaunchTemplateData":{
          "ImageId":{
            "Ref":"LatestAmiId"
          },
          "InstanceType":{
            "Ref":"InstanceType"
          },
          "KeyName":{
            "Ref":"KeyName"
          },
          "SecurityGroupIds":[
            {
              "Ref":"EC2SecurityGroup"
            }
          ],
          "UserData":{
            "Fn::Base64":{
              "Fn::Join":[
                "",
                [
                  "#!/bin/bash\n",
                  "yum update -y\n",
                  "yum install -y httpd\n",
                  "systemctl start httpd\n",
                  "systemctl enable httpd\n",
                  "echo \"<h1>Hello World!</h1>\" > /var/www/html/index.html"
                ]
              ]
            }
          }
        }
      }
    },
    "NotificationTopic":{
      "Type":"AWS::SNS::Topic",
      "Properties":{
        "Subscription":[
          {
            "Endpoint":{
              "Ref":"OperatorEmail"
            },
            "Protocol":"email"
          }
        ]
      }
    },
    "WebServerGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "LaunchTemplate":{
          "LaunchTemplateId":{
            "Ref":"LaunchTemplate"
          },
          "Version":{
            "Fn::GetAtt":[
              "LaunchTemplate",
              "LatestVersionNumber"
            ]
          }
        },
        "MaxSize":"3",
        "MinSize":"1",
        "NotificationConfigurations":[
          {
            "TopicARN":{
              "Ref":"NotificationTopic"
            },
            "NotificationTypes":[
              "autoscaling:EC2_INSTANCE_LAUNCH",
              "autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
              "autoscaling:EC2_INSTANCE_TERMINATE",
              "autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
            ]
          }
        ],
        "TargetGroupARNs":[
          {
            "Ref":"EC2TargetGroup"
          }
        ],
        "VPCZoneIdentifier":{
          "Ref":"Subnets"
        }
      }
    }
  }
}
```

## 範本演練
<a name="example-templates-autoscaling-description"></a>

此範本的第一部分會指定 `Parameters`。每個參數都必須在執行時間指派一個值， CloudFormation 才能成功佈建堆疊。在範本中稍後指定的資源會參考這些值並使用資料。
+ `InstanceType`：Amazon EC2 Auto Scaling 佈建的 EC2 執行個體類型。如果未指定，則會使用預設的 `t3.micro`。
+ `KeyName`：允許 SSH 存取執行個體的現有 EC2 金鑰對。
+ `LatestAmiId`：執行個體的 Amazon Machine Image (AMI)。如果未指定，您的執行個體會使用 維護的公有 AWS Systems Manager 參數，透過 Amazon Linux 2 AMI 啟動 AWS。如需詳細資訊，請參閱《AWS Systems Manager 使用者指南》**中的[尋找公有參數](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)。
+ `OperatorEmail`：您要傳送擴展活動通知的電子郵件地址。
+ `SSHLocation`：可用於對執行個體進行 SSH 存取的 IP 地址範圍。
+ `Subnets`：至少兩個公有子網路位於不同的可用區域。
+ `VPC`：您帳戶中的虛擬私有雲端 (VPC)，可讓公有子網路中的資源連線至網際網路。
**注意**  
您可以使用預設 VPC 和預設子網路，以允許執行個體存取網際網路。在使用自己的 VPC 的情況下，請確定您的 VPC 有一個子網路映射到您正在使用之區域的每個可用區域。必須至少有兩個可用的公有子網路，您才能建立負載平衡器。

此範本的下一部分會指定 `Resources`。此區段指定堆疊資源及其屬性。

[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源 `ELBSecurityGroup` 
+ `SecurityGroupIngress` 包含 TCP 輸入規則，以允許從連接埠 80 上的*所有 IP 地址*進行存取 ("CidrIp" : "0.0.0.0/0")。

[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源 `EC2SecurityGroup` 
+ `SecurityGroupIngress`包含兩條輸入規則：1) 一條允許從您為 `SSHLocation` 輸入參數提供的 IP 地址範圍進行 SSH 存取 (連接埠 22) 的 TCP 輸入規則，以及 2) 一條透過指定負載平衡器的安全群組允許從負載平衡器進行存取的 TCP 輸入規則。[GetAtt](resources-section-structure.md#resource-properties-getatt) 函數用於獲取具有邏輯名稱 `ELBSecurityGroup` 的安全群組的 ID。

[AWS::ElasticLoadBalancingV2::TargetGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) 資源 `EC2TargetGroup`
+ `Port`、`Protocol` 和 `HealthCheckProtocol` 指定 EC2 執行個體連接埠 (80) 和協定 (HTTP)，`ApplicationLoadBalancer` 向該連接埠和協定路由流量而 Elastic Load Balancing 使用它們來檢查 EC2 執行個體的運作狀態。
+ `HealthCheckIntervalSeconds` 指定 EC2 執行個體在運作狀態檢查間具有 30 秒的間隔。`HealthCheckTimeoutSeconds` 的定義為 Elastic Load Balancing 等待來自運作狀態檢查目標回應的時間長度 (此範例中為 15 秒)。在逾時期間過後，Elastic Load Balancing 便會將 EC2 執行個體的運作狀態檢查標記為不良。當 EC2 執行個體連續三次運作狀態檢查失敗時 (`UnhealthyThresholdCount`)，Elastic Load Balancing 將停止將流量路由到該 EC2 執行個體，直到其連續五次運作狀態檢查的結果為狀態良好為止 (`HealthyThresholdCount`)。此時，Elastic Load Balancing 會將執行個體視為狀態良好，並再次開始將流量路由到該執行個體。
+ `TargetGroupAttributes` 將目標群組的取消註冊延遲值更新為 20 秒。依預設，Elastic Load Balancing 會等待 300 秒，然後再完成取消註冊程序。

[AWS::ElasticLoadBalancingV2::Listener](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-listener.html) 資源 `ALBListener`
+ `DefaultActions` 指定負載平衡器監聽的連接埠、負載平衡器轉寄請求的目標群組，以及用來路由請求的通訊協定。

[AWS::ElasticLoadBalancingV2::LoadBalancer](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-loadbalancer.html) 資源 `ApplicationLoadBalancer`
+ `Subnets` 將 `Subnets` 輸入參數的值做為公有子網路的清單，負載平衡器節點將在該清單中建立。
+ `SecurityGroup` 獲取安全群組的 ID，該安全群組充當您的負載平衡器節點的虛擬防火牆，以控制傳入的流量。[GetAtt](resources-section-structure.md#resource-properties-getatt) 函數用於獲取具有邏輯名稱 `ELBSecurityGroup` 的安全群組的 ID。

[AWS::EC2::LaunchTemplate](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html) 資源 `LaunchTemplate`
+ `ImageId` 將 `LatestAmiId` 輸入參數的值做為要使用的 AMI。
+ `KeyName` 將 `KeyName` 輸入參數的值做為要使用的 EC2 金鑰對。
+ `SecurityGroupIds` 獲取具有邏輯名稱 `EC2SecurityGroup` 安全群組 ID，該安全群組充當您的 EC2 執行個體的虛擬防火牆，以控制傳入的流量。
+ `UserData` 是在執行個體啟動並運行後執行的組態指令碼。在此範例中，指令碼會安裝 Apache，並建立 index.html 檔案。

[AWS::SNS::Topic](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topic.html) 資源 `NotificationTopic`
+ 當有任何擴展活動時，`Subscription` 會將 `OperatorEmail` 輸入參數的值做為通知收件人的電子郵件地址。

[AWS::AutoScaling::AutoScalingGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 資源 `WebServerGroup`
+ `MinSize` 及 `MaxSize` 設定 Auto Scaling 群組中 EC2 執行個體的最小及最大數。
+ `TargetGroupARNs` 將接受具有邏輯名稱 `EC2TargetGroup` 的目標群組 ARN。當此 Auto Scaling 群組擴展時，它會自動向此目標群組註冊和取消註冊執行個體。
+ `VPCZoneIdentifier` 將 `Subnets` 輸入參數的值做為公有子網路的清單，EC2 執行個體將在該清單中建立。

## 步驟 1：啟動堆疊
<a name="example-templates-autoscaling-launch-stack"></a>

啟動堆疊之前，請檢查您是否具有使用下列所有服務的 AWS Identity and Access Management (IAM) 許可：Amazon EC2、Amazon EC2 Auto Scaling AWS Systems Manager、Elastic Load Balancing、Amazon SNS 和 CloudFormation。

下列程序涉及從檔案上傳範例堆疊範本。在本機電腦上打開文字編輯器，然後新增其中一個範本。儲存檔案，並將其命名為 `sampleloadbalancedappstack.template`。

**啟動堆疊範本**

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選擇 **Create stack (建立堆疊)**、**With new resources (standard) (使用新資源 (標準))**。

1. 在**指定範本**下，選擇**上傳範本檔案**，然後選擇**選擇檔案**以上傳 `sampleloadbalancedappstack.template` 檔案。

1. 選擇**下一步**。

1. 在**指定詳細資訊**頁面上，輸入堆疊名稱 (例如 **SampleLoadBalancedAppStack**)。

1. 在**參數**下，檢閱堆疊的參數並為無預設值的所有參數提供值，包括 **OperatorEmail**、**SSHLocation**、**KeyName**、**VPC** 和 **Subnets**。

1. 選擇 **Next** (下一步) 兩次。

1. 在**檢視** 頁面上，檢視和確認的設定。

1. 選擇**提交**。

   您可以在狀態欄的 CloudFormation 主控台中檢視堆疊**的狀態**。當 CloudFormation 成功建立堆疊時，您會收到 **CREATE\$1COMPLETE** 狀態。
**注意**  
在建立堆疊之後，您必須先確認訂閱，電子郵件地址才能開始接收通知。如需詳細資訊，請參閱《*Amazon EC2 Auto Scaling 使用者指南*》中的[在 Auto Scaling 群組擴展時取得 Amazon SNS 通知](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-sns-notifications.html)。

## 步驟 2：清除您的資源範例
<a name="example-templates-autoscaling-clean-up"></a>

若要確保您不會為未使用的資源範例付費，請刪除堆疊。

**刪除堆疊**

1. 在 CloudFormation 主控台中，選取 **SampleLoadBalancedAppStack** 堆疊。

1. 選擇 **刪除**。

1. 在確認訊息中，選擇**刪除堆疊**。

   **SampleLoadBalancedAppStack** 的狀態變更為 **DELETE\$1IN\$1PROGRESS**。當 CloudFormation 完成刪除堆疊時，會從清單中移除堆疊。

使用此逐步解說的範例範本建置您自己的堆疊範本。如需詳細資訊，請參閱《Amazon EC2 Auto Scaling 使用者指南》**中的[教程：設定擴展和負載平衡的應用程式](https://docs.aws.amazon.com/autoscaling/ec2/userguide/tutorial-ec2-auto-scaling-load-balancer.html)。

# 在另一個 中使用 VPC 的對等 AWS 帳戶
<a name="peer-with-vpc-in-another-account"></a>

您可以使用 與其他虛擬私有雲端 (VPC) AWS 帳戶 對等[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-vpcpeeringconnection.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-vpcpeeringconnection.html)。這會在兩個 VPC 之間建立網路連線，讓您能在兩者之間路由流量，使其如同在相同的網路中通訊。VPC 對等互連有助於促進資料存取和資料傳輸。

若要建立 VPC 對等互連，您需要在單一 CloudFormation 堆疊內授權兩個獨立 AWS 帳戶 帳戶。

如需詳細資訊，請參閱《[Amazon VPC 互連指南](https://docs.aws.amazon.com/vpc/latest/peering/)》中的 VPC 互連限制。

## 先決條件
<a name="peer-with-vpc-in-another-account-prerequisites"></a>

1. 您需要對等互連的對等 VPC ID、對等 AWS 帳戶 ID 和[跨帳戶存取角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_aws-accounts.html)。
**注意**  
本演練涉及兩個帳戶：第一個是允許跨帳戶對等的帳戶 (「接受者帳戶」**)。第二個是請求對等連線的帳戶 (「請求者帳戶」**)。

1. 若要接受 VPC 對等互連，您必須擔任跨帳戶存取角色。該資源的行為方式與同一帳戶中的 VPC 對等互連資源相同。如需有關 IAM 管理員如何授予許可以擔任跨帳戶角色的資訊，請參閱《IAM 使用者指南**》中的[向使用者授予切換角色的許可](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_permissions-to-switch.html)。

## 步驟 1：建立 VPC 和跨帳戶角色
<a name="step-1-create-vpc-and-cross-account-role"></a>

在此步驟中，您需要在「接受者帳戶」** 中建立 VPC 和角色。

**建立 VPC 和跨帳戶存取權角色**

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 從**堆疊**頁面的右上角，選擇**建立堆疊**，並選擇**使用新資源 (標準)**。

1. 對於**先決條件 - 準備範本**，選擇**選擇現有範本**，然後選擇**上傳範本檔案**、**選擇檔案**。

1. 在本機電腦上打開文字編輯器，然後新增其中一個下列範本。儲存檔案，並返回主控台將其選為範本檔案。  
**Example JSON**  

   ```
   {
     "AWSTemplateFormatVersion": "2010-09-09",
     "Description": "Create a VPC and an assumable role for cross account VPC peering.",
     "Parameters": {
       "PeerRequesterAccountId": {
         "Type": "String"
       }
     },
     "Resources": {
       "vpc": {
         "Type": "AWS::EC2::VPC",
         "Properties": {
           "CidrBlock": "10.1.0.0/16",
           "EnableDnsSupport": false,
           "EnableDnsHostnames": false,
           "InstanceTenancy": "default"
         }
       },
       "peerRole": {
         "Type": "AWS::IAM::Role",
         "Properties": {
           "AssumeRolePolicyDocument": {
             "Statement": [
               {
                 "Principal": {
                   "AWS": {
                     "Ref": "PeerRequesterAccountId"
                   }
                 },
                 "Action": [
                   "sts:AssumeRole"
                 ],
                 "Effect": "Allow"
               }
             ]
           },
           "Path": "/",
           "Policies": [
             {
               "PolicyName": "root",
               "PolicyDocument": {
                 "Version": "2012-10-17",		 	 	 
                 "Statement": [
                   {
                     "Effect": "Allow",
                     "Action": "ec2:AcceptVpcPeeringConnection",
                     "Resource": "*"
                   }
                 ]
               }
             }
           ]
         }
       }
     },
     "Outputs": {
       "VPCId": {
         "Value": {
           "Ref": "vpc"
         }
       },
       "RoleARN": {
         "Value": {
           "Fn::GetAtt": [
             "peerRole",
             "Arn"
           ]
         }
       }
     }
   }
   ```  
**Example YAML**  

   ```
   AWSTemplateFormatVersion: 2010-09-09
   Description: Create a VPC and an assumable role for cross account VPC peering.
   Parameters:
     PeerRequesterAccountId:
       Type: String
   Resources:
     vpc:
       Type: AWS::EC2::VPC
       Properties:
         CidrBlock: 10.1.0.0/16
         EnableDnsSupport: false
         EnableDnsHostnames: false
         InstanceTenancy: default
     peerRole:
       Type: AWS::IAM::Role
       Properties:
         AssumeRolePolicyDocument:
           Statement:
             - Principal:
                 AWS: !Ref PeerRequesterAccountId
               Action:
                 - 'sts:AssumeRole'
               Effect: Allow
         Path: /
         Policies:
           - PolicyName: root
             PolicyDocument:
               Version: 2012-10-17 		 	 	 
               Statement:
                 - Effect: Allow
                   Action: 'ec2:AcceptVpcPeeringConnection'
                   Resource: '*'
   Outputs:
     VPCId:
       Value: !Ref vpc
     RoleARN:
       Value: !GetAtt 
         - peerRole
         - Arn
   ```

1. 選擇**下一步**。

1. 為堆疊命名 （例如，**VPC-owner**)，然後在 **PeerRequesterAccountId** 欄位中輸入*請求者帳戶的* AWS 帳戶 ID。

1. 接受預設值，然後選擇 **Next (下一步)**。

1. 選擇**我確認 CloudFormation 可能會建立 IAM 資源**，然後選擇**建立堆疊**。

## 步驟 2：建立包含 `AWS::EC2::VPCPeeringConnection` 的範本
<a name="step-2-create-template-for-vpc-peering-connection-owner"></a>

現在您已建立 VPC 和跨帳戶角色，您可以使用另一個 AWS 帳戶 (*申請者帳戶*) 與 VPC 對等。

**建立其中包含 [AWS::EC2::VPCPeeringConnection](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-vpcpeeringconnection.html) 資源的範本**

1. 返回 CloudFormation 主控台首頁。

1. 從**堆疊**頁面的右上角，選擇**建立堆疊**，並選擇**使用新資源 (標準)**。

1. 對於**先決條件 - 準備範本**，選擇**選擇現有範本**，然後選擇**上傳範本檔案**、**選擇檔案**。

1. 在本機電腦上打開文字編輯器，然後新增其中一個下列範本。儲存檔案，並返回主控台將其選為範本檔案。  
**Example JSON**  

   ```
   {
     "AWSTemplateFormatVersion": "2010-09-09",
     "Description": "Create a VPC and a VPC Peering connection using the PeerRole to accept.",
     "Parameters": {
       "PeerVPCAccountId": {
         "Type": "String"
       },
       "PeerVPCId": {
         "Type": "String"
       },
       "PeerRoleArn": {
         "Type": "String"
       }
     },
     "Resources": {
       "vpc": {
         "Type": "AWS::EC2::VPC",
         "Properties": {
           "CidrBlock": "10.2.0.0/16",
           "EnableDnsSupport": false,
           "EnableDnsHostnames": false,
           "InstanceTenancy": "default"
         }
       },
       "vpcPeeringConnection": {
         "Type": "AWS::EC2::VPCPeeringConnection",
         "Properties": {
           "VpcId": {
             "Ref": "vpc"
           },
           "PeerVpcId": {
             "Ref": "PeerVPCId"
           },
           "PeerOwnerId": {
             "Ref": "PeerVPCAccountId"
           },
           "PeerRoleArn": {
             "Ref": "PeerRoleArn"
           }
         }
       }
     },
     "Outputs": {
       "VPCId": {
         "Value": {
           "Ref": "vpc"
         }
       },
       "VPCPeeringConnectionId": {
         "Value": {
           "Ref": "vpcPeeringConnection"
         }
       }
     }
   }
   ```  
**Example YAML**  

   ```
   AWSTemplateFormatVersion: 2010-09-09
   Description: Create a VPC and a VPC Peering connection using the PeerRole to accept.
   Parameters:
     PeerVPCAccountId:
       Type: String
     PeerVPCId:
       Type: String
     PeerRoleArn:
       Type: String
   Resources:
     vpc:
       Type: AWS::EC2::VPC
       Properties:
         CidrBlock: 10.2.0.0/16
         EnableDnsSupport: false
         EnableDnsHostnames: false
         InstanceTenancy: default
     vpcPeeringConnection:
       Type: AWS::EC2::VPCPeeringConnection
       Properties:
         VpcId: !Ref vpc
         PeerVpcId: !Ref PeerVPCId
         PeerOwnerId: !Ref PeerVPCAccountId
         PeerRoleArn: !Ref PeerRoleArn
   Outputs:
     VPCId:
       Value: !Ref vpc
     VPCPeeringConnectionId:
       Value: !Ref vpcPeeringConnection
   ```

1. 選擇**下一步**。

1. 命名堆疊 (例如 **VPC-peering-connection**)。

1. 接受預設值，然後選擇 **Next (下一步)**。

1. 選擇**我確認 CloudFormation 可能會建立 IAM 資源**，然後選擇**建立堆疊**。

## 建立具有高度限制政策的範本
<a name="create-template-with-highly-restrictive-policy"></a>

在將您的 VPC 與另一個 AWS 帳戶對等時，您可能需要建立高度限制的政策。

下列範例範本說明如何變更 VPC 對等擁有者範本 (在上述步驟 1 中建立的*接受者帳戶*)，使其限制更嚴格。

**Example JSON**  

```
{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Create a VPC and an assumable role for cross account VPC peering.",
  "Parameters":{
    "PeerRequesterAccountId":{
      "Type":"String"
    }
  },
  "Resources":{
    "peerRole":{
      "Type":"AWS::IAM::Role",
      "Properties":{
        "AssumeRolePolicyDocument":{
          "Statement":[
            {
              "Action":[
                "sts:AssumeRole"
              ],
              "Effect":"Allow",
              "Principal":{
                "AWS":{
                  "Ref":"PeerRequesterAccountId"
                }
              }
            }
          ]
        },
        "Path":"/",
        "Policies":[
          {
            "PolicyDocument":{
              "Statement":[
                {
                  "Action":"ec2:acceptVpcPeeringConnection",
                  "Effect":"Allow",
                  "Resource":{
                    "Fn::Sub":"arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}"
                  }
                },
                {
                  "Action":"ec2:acceptVpcPeeringConnection",
                  "Condition":{
                    "StringEquals":{
                      "ec2:AccepterVpc":{
                        "Fn::Sub":"arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}"
                      }
                    }
                  },
                  "Effect":"Allow",
                  "Resource":{
                    "Fn::Sub":"arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc-peering-connection/*"
                  }
                }
              ],
              "Version":"2012-10-17" 		 	 	 
            },
            "PolicyName":"root"
          }
        ]
      }
    },
    "vpc":{
      "Type":"AWS::EC2::VPC",
      "Properties":{
        "CidrBlock":"10.1.0.0/16",
        "EnableDnsHostnames":false,
        "EnableDnsSupport":false,
        "InstanceTenancy":"default"
      }
    }
  },
  "Outputs":{
    "RoleARN":{
      "Value":{
        "Fn::GetAtt":[
          "peerRole",
          "Arn"
        ]
      }
    },
    "VPCId":{
      "Value":{
        "Ref":"vpc"
      }
    }
  }
}
```

**Example YAML**  

```
AWSTemplateFormatVersion: 2010-09-09
Description: Create a VPC and an assumable role for cross account VPC peering.
Parameters:
  PeerRequesterAccountId:
    Type: String
Resources:
  peerRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              AWS:
                Ref: PeerRequesterAccountId
      Path: /
      Policies:
        - PolicyDocument:
            Statement:
              - Action: 'ec2:acceptVpcPeeringConnection'
                Effect: Allow
                Resource:
                  'Fn::Sub': 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}'
              - Action: 'ec2:acceptVpcPeeringConnection'
                Condition:
                  StringEquals:
                    'ec2:AccepterVpc':
                      'Fn::Sub': 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}'
                Effect: Allow
                Resource:
                  'Fn::Sub': >-
                    arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc-peering-connection/*
            Version: 2012-10-17 		 	 	 
          PolicyName: root
  vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.1.0.0/16
      EnableDnsHostnames: false
      EnableDnsSupport: false
      InstanceTenancy: default
Outputs:
  RoleARN:
    Value:
      'Fn::GetAtt':
        - peerRole
        - Arn
  VPCId:
    Value:
      Ref: vpc
```

若要存取 VPC，您可以使用上述步驟 2 中使用的請求者範本。

如需詳細資訊，請參閱《*Amazon VPC 對等互連指南*》中的[適用於 VPC 對等互連的身分與存取管理](https://docs.aws.amazon.com/vpc/latest/peering/security-iam.html)。

# 使用 CloudFormation 透過 CodeDeploy 進行 ECS 藍色/綠色部署
<a name="blue-green"></a>

若要更新在 Amazon Elastic Container Service (Amazon ECS) 上執行的應用程式，可以使用 CodeDeploy 藍/綠部署策略。此策略有助於將變更應用程式版本所造成的中斷降至最低。

在藍/綠部署中，可在目前的即時環境 (稱為*藍色*) 旁邊建立新的應用程式環境 (稱為*綠色*)。這可讓您監控和測試綠色環境，然後再將即時流量從藍色環境路由到綠色環境。在綠色環境提供即時流量之後，您可以安全地終止藍色環境。

若要使用 CloudFormation 在 ECS 上執行 CodeDeploy 藍綠部署，請在堆疊範本中包含下列資訊：
+ 描述 `AWS::CodeDeploy::BlueGreen` 勾點的 `Hooks` 區段。
+  指定 `AWS::CodeDeployBlueGreen` 轉換的 `Transform` 區段。

下列主題會引導您在 ECS 上設定藍/綠部署的 CloudFormation 範本。

**Topics**
+ [關於藍/綠部署](about-blue-green-deployments.md)
+ [使用 CloudFormation 管理 ECS 藍/綠部署時的考量事項](blue-green-considerations.md)
+ [`AWS::CodeDeploy::BlueGreen` 勾點語法](blue-green-hook-syntax.md)
+ [藍/綠部署範本範例](blue-green-template-example.md)

# 關於藍/綠部署
<a name="about-blue-green-deployments"></a>

本主題概述如何使用 CloudFormation 執行藍/綠部署。它還說明如何為藍/綠部署準備 CloudFormation 範本。

**Topics**
+ [運作方式](#blue-green-how-it-works)
+ [啟動綠色部署的資源更新](#blue-green-resources)
+ [準備範本](#blue-green-setup)
+ [建模您的藍/綠部署](#blue-green-required)
+ [變更集](#blue-green-changesets)
+ [監控堆疊事件](#blue-green-events)
+ [IAM 許可](#blue-green-iam)

## 運作方式
<a name="blue-green-how-it-works"></a>

使用 CloudFormation 透過 CodeDeploy 執行 ECS 藍/綠部署時，首先要建立可定義藍色和藍/綠應用程式環境資源的堆疊範本，包括指定要使用的流量路由和穩定設定。接著，從該範本中建立堆疊。這會產生您的藍色 (目前) 應用程式。CloudFormation 只會在堆疊建立期間建立藍色資源。綠色部署的資源必須等到有需要時才會建立。

然後，如果在未來的堆疊更新中更新藍色應用程式中的工作定義或工作集資源，CloudFormation 會執行下列動作：
+ 產生所有必要的綠色應用程式環境資源
+ 根據指定的流量路由參數轉移流量
+ 刪除藍色資源

如果在綠色部署成功並完成之前的任何時間點發生錯誤，CloudFormation 會將堆疊復原為起始整個綠色部署之前的狀態。

## 啟動綠色部署的資源更新
<a name="blue-green-resources"></a>

當您執行更新特定 ECS 資源特定屬性的堆疊更新時，CloudFormation 會啟動綠色部署程序。啟動此程序的資源包括：
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskdefinition.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskdefinition.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskset.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskset.html) 

不過，如果這些資源的更新不涉及需要取代的屬性變更，則不會啟動綠色部署。如需詳細資訊，請參閱[了解更新堆疊資源的行為](using-cfn-updating-stacks-update-behaviors.md)。

無法在同一堆疊更新中包含上述資源的更新與其他資源的更新。如果需要同時更新列出的資源和相同堆疊中的其他資源，您有兩個選項：
+ 執行兩個獨立的堆疊更新操作：一個只包含上述資源的更新，另一個包含任何其他資源變更的單獨堆疊更新。
+ 從範本中移除 `Transform` 和 `Hooks` 區段，然後執行堆疊更新。在此情況下，CloudFormation 將不會執行綠色部署。

## 準備範本以執行 ECS 藍/綠部署
<a name="blue-green-setup"></a>

若要在堆疊上啟用藍/綠部署，請在執行堆疊更新之前，在堆疊範本中包含下列區段。
+ 將對 `AWS::CodeDeployBlueGreen` 轉換的參考新增到您的範本中：

  ```
  "Transform": [
    "AWS::CodeDeployBlueGreen"
  ],
  ```
+ 加入可叫用 `AWS::CodeDeploy::BlueGreen` 掛接的 `Hooks` 區段，並指定部署的內容。如需詳細資訊，請參閱[`AWS::CodeDeploy::BlueGreen` 勾點語法](blue-green-hook-syntax.md)。
+ 在 `Resources` 區段中定義了您部署的藍色和綠色資源。

您可以在第一次建立範本時 (也就是在建立堆疊本身之前) 加入這些區段，也可以在執行堆疊更新之前將這些區段加入至現有範本。如果您為新堆疊指定藍/綠部署，則 CloudFormation 只會在堆疊建立期間建立藍色資源 - 在堆疊更新期間需要綠色部署的資源前，系統不會建立這些資源。

## 使用 CloudFormation 資源建模您的藍/綠部署
<a name="blue-green-required"></a>

若要在 ECS 上執行 CodeDeploy 藍/綠部署，您的 CloudFormation 範本需要包含模型部署的資源，例如 Amazon ECS 服務和負載平衡器。如需有關這些資源所代表內容的詳細資訊，請見《AWS CodeDeploy 使用者指南》**中[在開始 Amazon ECS 部署之前](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-steps-ecs.html#deployment-steps-prerequisites-ecs)。


| 需求 | 資源 | 必要/選用 | 取代時是否啟動藍/綠部署？ | 
| --- | --- | --- | --- | 
| Amazon ECS 叢集 | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-cluster.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-cluster.html) | 選用。可以使用預設叢集。 | 否 | 
| Amazon ECS 服務 | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-service.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-service.html) | 必要. | 否 | 
| 應用程式或 Network Load Balancer | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-ecs-service-loadbalancer.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-ecs-service-loadbalancer.html) | 必要. | 否 | 
| 生產接聽程式 | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-listener.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-listener.html) | 必要. | 否 | 
| 測試接聽程式  | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-listener.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-listener.html) | 選用。 | 否 | 
| 兩個目標群組 | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) | 必要. | 否 | 
| Amazon ECS 任務定義  | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskdefinition.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskdefinition.html) | 必要. | 是 | 
| Amazon ECS 應用程式的容器 | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-ecs-taskdefinition-containerdefinition.html#cfn-ecs-taskdefinition-containerdefinition-name](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-ecs-taskdefinition-containerdefinition.html#cfn-ecs-taskdefinition-containerdefinition-name) | 必要. | 否 | 
| 取代任務集的連接埠 | [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-ecs-taskdefinition-portmapping.html#cfn-ecs-taskdefinition-portmapping-containerport](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-ecs-taskdefinition-portmapping.html#cfn-ecs-taskdefinition-portmapping-containerport) | 必要. | 否 | 

## 變更集
<a name="blue-green-changesets"></a>

強烈建議您在執行將起始綠色部署的堆疊更新之前建立變更集。這可讓您在執行堆疊更新前，查看將對堆疊所做的實際變更。請注意，資源變更可能不會以堆疊更新期間執行的順序列出。如需詳細資訊，請參閱[透過變更集更新 CloudFormation 堆疊](using-cfn-updating-stacks-changesets.md)。

## 監控堆疊事件
<a name="blue-green-events"></a>

您可以使用 AWS CLI，在 **Stack** (堆疊) 頁面的 **Events** (事件) 索引標籤上檢視 ECS 部署每個步驟所產生的堆疊事件。如需詳細資訊，請參閱[監控堆疊進度](monitor-stack-progress.md)。

## 藍/綠部署的 IAM 許可
<a name="blue-green-iam"></a>

為了讓 CloudFormation 成功執行藍/綠部署，您必須具有以下 CodeDeploy 許可：
+ `codedeploy:Get*`
+ `codedeploy:CreateCloudFormationDeployment`

如需詳細資訊，請參閱*服務授權參考*中的 [CodeDeploy 的動作、資源和條件索引鍵](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awscodedeploy.html)。

# 使用 CloudFormation 管理 ECS 藍/綠部署時的考量事項
<a name="blue-green-considerations"></a>

使用 CloudFormation 透過 CodeDeploy 來執行 ECS 藍/綠部署的程序與僅使用 CodeDeploy 的標準 ECS 部署不同。如需詳細了解這些差異，請參閱**《AWS CodeDeploy 使用者指南》中的[透過 CodeDeploy 和 CloudFormation進行 Amazon ECS 藍/綠部署之間的差異](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-create-ecs-cfn.html#differences-ecs-bg-cfn)。

使用 CloudFormation 管理藍/綠部署時，請注意特定限制和考量事項：
+ 只有特定資源的更新才會啟動綠色部署。如需詳細資訊，請參閱[啟動綠色部署的資源更新](about-blue-green-deployments.md#blue-green-resources)。
+ 無法在相同堆疊更新中包含觸發藍/綠部署的資源更新以及對其他資源的更新。如需詳細資訊，請參閱[啟動綠色部署的資源更新](about-blue-green-deployments.md#blue-green-resources)。
+ 您只能指定單一 ECS 服務作為部署目標。
+ CodeDeploy 無法在綠色部署期間更新其值被 CloudFormation 模糊化的參數，這會導致錯誤和堆疊更新失敗。其中包含：
  + 使用 `NoEcho` 屬性定義的參數。
  + 使用動態參照從外部服務擷取其值的參數。如需動態參考的詳細資訊，請參閱 [使用動態參考取得存放在其他服務中的值](dynamic-references.md)。
+ 若要取消仍在進行中的綠色部署，請取消 CloudFormation 中的堆疊更新，而不是 CodeDeploy 或 ECS。如需詳細資訊，請參閱[取消堆疊更新](using-cfn-stack-update-cancel.md)。更新完成之後，您便無法將其取消。不過，您可以使用任何之前的設定重新更新堆疊。
+ 對於定義 ECS 藍/綠部署的範本，目前不支援下列 CloudFormation 功能：
  + 宣告[輸出](outputs-section-structure.md)或使用 [Fn::ImportValue](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-importvalue.html)，從其他堆疊中匯入值。
  + 匯入資源。如需有關匯入資源的詳細資訊，請參閱 [將 AWS 資源匯入 CloudFormation 堆疊](import-resources.md)。
  + 在包含巢狀堆疊資源的範本中使用 `AWS::CodeDeploy::BlueGreen` 勾點。如需巢狀堆疊的詳細資訊，請參閱[運用巢狀堆疊，將範本分割成可重複使用的部分](using-cfn-nested-stacks.md)。
  + 在巢狀堆疊中使用 `AWS::CodeDeploy::BlueGreen` 勾點。

# `AWS::CodeDeploy::BlueGreen` 勾點語法
<a name="blue-green-hook-syntax"></a>

下列語法說明 ECS 藍/綠部署的 `AWS::CodeDeploy::BlueGreen` 勾點結構。

## 語法
<a name="cfn-blue-green-hook-syntax"></a>

```
"Hooks": {
  "Logical ID": {
    "Type": "AWS::CodeDeploy::BlueGreen",
    "Properties": {
      "TrafficRoutingConfig": {
        "Type": "Traffic routing type",
        "TimeBasedCanary": {
          "StepPercentage": Integer,
          "BakeTimeMins": Integer
        },
        "TimeBasedLinear": {
          "StepPercentage": Integer,
          "BakeTimeMins": Integer
        }
      },
      "AdditionalOptions": {"TerminationWaitTimeInMinutes": Integer},
      "LifecycleEventHooks": {
        "BeforeInstall": "FunctionName",
        "AfterInstall": "FunctionName",
        "AfterAllowTestTraffic": "FunctionName",
        "BeforeAllowTraffic": "FunctionName",
        "AfterAllowTraffic": "FunctionName"
      },
      "ServiceRole": "CodeDeployServiceRoleName",
      "Applications": [
        {
          "Target": {
            "Type": "AWS::ECS::Service",
            "LogicalID": "Logical ID of AWS::ECS::Service"
          },
          "ECSAttributes": {
            "TaskDefinitions": [
              "Logical ID of AWS::ECS::TaskDefinition (Blue)",
              "Logical ID of AWS::ECS::TaskDefinition (Green)"
            ],
            "TaskSets": [
              "Logical ID of AWS::ECS::TaskSet (Blue)",
              "Logical ID of AWS::ECS::TaskSet (Green)"
            ],
            "TrafficRouting": {
              "ProdTrafficRoute": {
                "Type": "AWS::ElasticLoadBalancingV2::Listener",
                "LogicalID": "Logical ID of AWS::ElasticLoadBalancingV2::Listener (Production)"
              },
              "TestTrafficRoute": {
                "Type": "AWS::ElasticLoadBalancingV2::Listener",
                "LogicalID": "Logical ID of AWS::ElasticLoadBalancingV2::Listener (Test)"
              },
              "TargetGroups": [
                "Logical ID of AWS::ElasticLoadBalancingV2::TargetGroup (Blue)",
                "Logical ID of AWS::ElasticLoadBalancingV2::TargetGroup (Green)"
              ]
            }
          }
        }
      ]
    }
  }
}
```

## Properties
<a name="cfn-blue-green-hook-properties"></a>

邏輯 ID (也稱為*邏輯名稱*)  
範本的 `Hooks` 區段中宣告之勾點的邏輯 ID。邏輯 ID 必須是英數字元 (A-Za-z0-9)，而且在範本內必須是唯一的。  
*必要*：是    
`Type`  
掛接的類型。`AWS::CodeDeploy::BlueGreen`  
*必要*：是  
`Properties`  
掛接的屬性。  
*必要*：是    
`TrafficRoutingConfig`  
流量路由組態設定。  
*必要*：否  
預設組態是以時間為基礎的 Canary 流量轉移，具有 15% 步驟百分比和 5 分鐘的封裝時間。    
`Type`  
部署組態所使用的流量轉移類型。  
有效值：AllAtOnce \$1 TimeBasedCanary \$1 TimeBasedLinear  
*必要*：是    
`TimeBasedCanary`  
指定將流量以兩個增量為單位，從一個版本的部署轉移到另一個版本的規劃。  
*必要*：有條件：如果您將 `TimeBasedCanary` 指定為流量路由類型，則必須包含 `TimeBasedCanary` 參數。    
`StepPercentage`  
在 `TimeBasedCanary` 部署的第一個增量中，要轉移的流量百分比。步驟百分比必須是 14% 或更大。  
*必要*：否  
`BakeTimeMins`  
`TimeBasedCanary` 部署第一次和第二次流量轉移之間的分鐘數。  
*必要*：否  
`TimeBasedLinear`  
指定將流量從一個版本的部署轉移到另一個版本的組態，每個增量之間的分鐘數相等。  
*必要*：有條件：如果您將 `TimeBasedLinear` 指定為流量路由類型，則必須包含 `TimeBasedLinear` 參數。    
`StepPercentage`  
每個 `TimeBasedLinear` 部署增量開始時移動的流量百分比。步驟百分比必須是 14% 或更大。  
*必要*：否  
`BakeTimeMins`  
`TimeBasedLinear` 部署的每個遞增流量轉移之間的分鐘數。  
*必要*：否  
`AdditionalOptions`  
藍/綠部署的其他選項。  
*必要*：否    
`TerminationWaitTimeInMinutes`  
指定終止藍色資源之前的等待時間 (以分鐘為單位)。  
*必要*：否  
`LifecycleEventHooks`  
使用生命週期事件掛接來指定 CodeDeploy 可呼叫以驗證部署的 Lambda 函數。針對部署生命週期事件，您可以使用相同的函數或不同的函數。完成驗證測試後，Lambda `AfterAllowTraffic` 函數會回呼 CodeDeploy，並傳送 `Succeeded` 或 `Failed` 的結果。如需詳細資訊，請參閱[《AWS CodeDeploy 使用者指南》](https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html)中的 *AppSpec 「勾點」* 章節。  
*必要*：否    
`BeforeInstall`  
在建立替換任務之前，用來執行任務的函數。  
*必要*：否  
`AfterInstall`  
建立替代任務集後，用來執行任務，且與其中一個目標群組相關的函數。  
*必要*：否  
`AfterAllowTestTraffic`  
在測試接聽程式將流量轉發至替換任務集後，用來執行任務的函數。  
*必要*：否  
`BeforeAllowTraffic`  
在第二個目標群組與替換任務集建立關聯後，但在流量轉移到替換任務集前，用來執行任務的函數。  
*必要*：否  
`AfterAllowTraffic`  
在第二個目標群組將流量轉發至替換任務集後，用來執行任務的函數。  
*必要*：否  
`ServiceRole`  
CloudFormation 用來執行藍/綠部署的執行角色。如需必要許可的清單，請參閱 [藍/綠部署的 IAM 許可](about-blue-green-deployments.md#blue-green-iam)。  
*必要*：否  
`Applications`  
指定 Amazon ECS 應用程式的屬性。  
*必要*：是    
`Target`  
  
*必要*：是    
`Type`  
資源的類型。  
*必要*：是  
`LogicalID`  
資源的邏輯 ID。  
*必要*：是  
`ECSAttributes`  
代表 Amazon ECS 應用程式部署各種需求的資源。  
*必要*：是    
`TaskDefinitions`  
[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskdefinition.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskdefinition.html) 資源的邏輯 ID，以執行包含 Amazon ECS 應用程式的 Docker 容器。  
*必要*：是  
`TaskSets`  
用作應用程式任務集的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskset.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-taskset.html) 資源邏輯 ID。  
*必要*：是  
`TrafficRouting`  
指定用於流量路由的資源。  
*必要*：是    
`ProdTrafficRoute`  
供負載平衡器用來將流量導向到您目標群組的接聽程式。  
*必要*：是    
`Type`  
資源的類型。`AWS::ElasticLoadBalancingV2::Listener`  
*必要*：是  
`LogicalID`  
資源的邏輯 ID。  
*必要*：是  
`TestTrafficRoute`  
供負載平衡器用來將流量導向到您目標群組的接聽程式。  
*必要*：是    
`Type`  
資源的類型。`AWS::ElasticLoadBalancingV2::Listener`  
*必要*：是  
`LogicalID`  
資源的邏輯 ID。  
*必要*：否  
`TargetGroups`  
用作目標群組的資源邏輯 ID，以將流量路由至已登記的目標。  
*必要*：是

# 藍/綠部署範本範例
<a name="blue-green-template-example"></a>

下列範例範本在 ECS 上設定 CodeDeploy 藍/綠部署，流量路由進度為每步驟 15%，每個步驟之間的穩定期間為 5 分鐘。

使用範本建立堆疊將佈建部署的初始組態。如果隨後對需要取代該資源之 `BlueTaskSet` 資源中的屬性進行任何變更，則 CloudFormation 將啟動綠色部署作為堆疊更新的一部分。

## JSON
<a name="blue-green-template-example.json"></a>

```
{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Parameters":{
    "Vpc":{ "Type":"AWS::EC2::VPC::Id" },
    "Subnet1":{ "Type":"AWS::EC2::Subnet::Id" },
    "Subnet2":{ "Type":"AWS::EC2::Subnet::Id" }
  },
  "Transform":[ "AWS::CodeDeployBlueGreen" ],
  "Hooks":{
    "CodeDeployBlueGreenHook":{
      "Type":"AWS::CodeDeploy::BlueGreen",
      "Properties":{
        "TrafficRoutingConfig":{
          "Type":"TimeBasedCanary",
          "TimeBasedCanary":{
            "StepPercentage":15,
            "BakeTimeMins":5
          }
        },
        "Applications":[
          {
            "Target":{
              "Type":"AWS::ECS::Service",
              "LogicalID":"ECSDemoService"
            },
            "ECSAttributes":{
              "TaskDefinitions":[ "BlueTaskDefinition","GreenTaskDefinition" ],
              "TaskSets":[ "BlueTaskSet","GreenTaskSet" ],
              "TrafficRouting":{
                "ProdTrafficRoute":{
                  "Type":"AWS::ElasticLoadBalancingV2::Listener",
                  "LogicalID":"ALBListenerProdTraffic"
                },
                "TargetGroups":[ "ALBTargetGroupBlue","ALBTargetGroupGreen" ]
              }
            }
          }
        ]
      }
    }
  },
  "Resources":{
    "ExampleSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Security group for ec2 access",
        "VpcId":{ "Ref":"Vpc" },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":80,
            "ToPort":80,
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":8080,
            "ToPort":8080,
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":22,
            "ToPort":22,
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
    "ALBTargetGroupBlue":{
      "Type":"AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties":{
        "HealthCheckIntervalSeconds":5,
        "HealthCheckPath":"/",
        "HealthCheckPort":"80",
        "HealthCheckProtocol":"HTTP",
        "HealthCheckTimeoutSeconds":2,
        "HealthyThresholdCount":2,
        "Matcher":{ "HttpCode":"200" },
        "Port":80,
        "Protocol":"HTTP",
        "Tags":[{ "Key":"Group","Value":"Example" }],
        "TargetType":"ip",
        "UnhealthyThresholdCount":4,
        "VpcId":{ "Ref":"Vpc" }
      }
    },
    "ALBTargetGroupGreen":{
      "Type":"AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties":{
        "HealthCheckIntervalSeconds":5,
        "HealthCheckPath":"/",
        "HealthCheckPort":"80",
        "HealthCheckProtocol":"HTTP",
        "HealthCheckTimeoutSeconds":2,
        "HealthyThresholdCount":2,
        "Matcher":{ "HttpCode":"200" },
        "Port":80,
        "Protocol":"HTTP",
        "Tags":[{ "Key":"Group","Value":"Example" }],
        "TargetType":"ip",
        "UnhealthyThresholdCount":4,
        "VpcId":{ "Ref":"Vpc" }
      }
    },
    "ExampleALB":{
      "Type":"AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties":{
        "Scheme":"internet-facing",
        "SecurityGroups":[{ "Ref":"ExampleSecurityGroup" }],
        "Subnets":[{ "Ref":"Subnet1" },{ "Ref":"Subnet2" }],
        "Tags":[{ "Key":"Group","Value":"Example" }],
        "Type":"application",
        "IpAddressType":"ipv4"
      }
    },
    "ALBListenerProdTraffic":{
      "Type":"AWS::ElasticLoadBalancingV2::Listener",
      "Properties":{
        "DefaultActions":[
          {
            "Type":"forward",
            "ForwardConfig":{
              "TargetGroups":[
                {
                  "TargetGroupArn":{ "Ref":"ALBTargetGroupBlue" },
                  "Weight":1
                }
              ]
            }
          }
        ],
        "LoadBalancerArn":{ "Ref":"ExampleALB" },
        "Port":80,
        "Protocol":"HTTP"
      }
    },
    "ALBListenerProdRule":{
      "Type":"AWS::ElasticLoadBalancingV2::ListenerRule",
      "Properties":{
        "Actions":[
          {
            "Type":"forward",
            "ForwardConfig":{
              "TargetGroups":[
                {
                  "TargetGroupArn":{ "Ref":"ALBTargetGroupBlue" },
                  "Weight":1
                }
              ]
            }
          }
        ],
        "Conditions":[
          {
            "Field":"http-header",
            "HttpHeaderConfig":{
              "HttpHeaderName":"User-Agent",
              "Values":[ "Mozilla" ]
            }
          }
        ],
        "ListenerArn":{ "Ref":"ALBListenerProdTraffic" },
        "Priority":1
      }
    },
    "ECSTaskExecutionRole":{
      "Type":"AWS::IAM::Role",
      "Properties":{
        "AssumeRolePolicyDocument":{
          "Version": "2012-10-17",		 	 	 
          "Statement":[
            {
              "Sid":"",
              "Effect":"Allow",
              "Principal":{
                "Service":"ecs-tasks.amazonaws.com"
              },
              "Action":"sts:AssumeRole"
            }
          ]
        },
        "ManagedPolicyArns":[ "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" ]
      }
    },
    "BlueTaskDefinition":{
      "Type":"AWS::ECS::TaskDefinition",
      "Properties":{
        "ExecutionRoleArn":{
          "Fn::GetAtt":[ "ECSTaskExecutionRole","Arn" ]
        },
        "ContainerDefinitions":[
          {
            "Name":"DemoApp",
            "Image":"nginxdemos/hello:latest",
            "Essential":true,
            "PortMappings":[
              {
                "HostPort":80,
                "Protocol":"tcp",
                "ContainerPort":80
              }
            ]
          }
        ],
        "RequiresCompatibilities":[ "FARGATE" ],
        "NetworkMode":"awsvpc",
        "Cpu":"256",
        "Memory":"512",
        "Family":"ecs-demo"
      }
    },
    "ECSDemoCluster":{
      "Type":"AWS::ECS::Cluster",
      "Properties":{}
    },
    "ECSDemoService":{
      "Type":"AWS::ECS::Service",
      "Properties":{
        "Cluster":{ "Ref":"ECSDemoCluster" },
        "DesiredCount":1,
        "DeploymentController":{ "Type":"EXTERNAL" }
      }
    },
    "BlueTaskSet":{
      "Type":"AWS::ECS::TaskSet",
      "Properties":{
        "Cluster":{ "Ref":"ECSDemoCluster" },
        "LaunchType":"FARGATE",
        "NetworkConfiguration":{
          "AwsVpcConfiguration":{
            "AssignPublicIp":"ENABLED",
            "SecurityGroups":[{ "Ref":"ExampleSecurityGroup" }],
            "Subnets":[{ "Ref":"Subnet1" },{ "Ref":"Subnet2" }]
          }
        },
        "PlatformVersion":"1.4.0",
        "Scale":{
          "Unit":"PERCENT",
          "Value":100
        },
        "Service":{ "Ref":"ECSDemoService"},
        "TaskDefinition":{ "Ref":"BlueTaskDefinition" },
        "LoadBalancers":[
          {
            "ContainerName":"DemoApp",
            "ContainerPort":80,
            "TargetGroupArn":{ "Ref":"ALBTargetGroupBlue" }
          }
        ]
      }
    },
    "PrimaryTaskSet":{
      "Type":"AWS::ECS::PrimaryTaskSet",
      "Properties":{
        "Cluster":{ "Ref":"ECSDemoCluster" },
        "Service":{ "Ref":"ECSDemoService" },
        "TaskSetId":{ "Fn::GetAtt":[ "BlueTaskSet","Id" ]
        }
      }
    }
  }
}
```

## YAML
<a name="blue-green-template-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  Vpc:
    Type: AWS::EC2::VPC::Id
  Subnet1:
    Type: AWS::EC2::Subnet::Id
  Subnet2:
    Type: AWS::EC2::Subnet::Id
Transform:
  - 'AWS::CodeDeployBlueGreen'
Hooks:
  CodeDeployBlueGreenHook:
    Type: AWS::CodeDeploy::BlueGreen
    Properties:
      TrafficRoutingConfig:
        Type: TimeBasedCanary
        TimeBasedCanary:
          StepPercentage: 15
          BakeTimeMins: 5
      Applications:
        - Target:
            Type: AWS::ECS::Service
            LogicalID: ECSDemoService
          ECSAttributes:
            TaskDefinitions:
              - BlueTaskDefinition
              - GreenTaskDefinition
            TaskSets:
              - BlueTaskSet
              - GreenTaskSet
            TrafficRouting:
              ProdTrafficRoute:
                Type: AWS::ElasticLoadBalancingV2::Listener
                LogicalID: ALBListenerProdTraffic
              TargetGroups:
                - ALBTargetGroupBlue
                - ALBTargetGroupGreen
Resources:
  ExampleSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for ec2 access
      VpcId: !Ref Vpc
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
  ALBTargetGroupBlue:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 5
      HealthCheckPath: /
      HealthCheckPort: '80'
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 2
      HealthyThresholdCount: 2
      Matcher:
        HttpCode: '200'
      Port: 80
      Protocol: HTTP
      Tags:
        - Key: Group
          Value: Example
      TargetType: ip
      UnhealthyThresholdCount: 4
      VpcId: !Ref Vpc
  ALBTargetGroupGreen:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 5
      HealthCheckPath: /
      HealthCheckPort: '80'
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 2
      HealthyThresholdCount: 2
      Matcher:
        HttpCode: '200'
      Port: 80
      Protocol: HTTP
      Tags:
        - Key: Group
          Value: Example
      TargetType: ip
      UnhealthyThresholdCount: 4
      VpcId: !Ref Vpc
  ExampleALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      SecurityGroups:
        - !Ref ExampleSecurityGroup
      Subnets:
        - !Ref Subnet1
        - !Ref Subnet2
      Tags:
        - Key: Group
          Value: Example
      Type: application
      IpAddressType: ipv4
  ALBListenerProdTraffic:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          ForwardConfig:
            TargetGroups:
              - TargetGroupArn: !Ref ALBTargetGroupBlue
                Weight: 1
      LoadBalancerArn: !Ref ExampleALB
      Port: 80
      Protocol: HTTP
  ALBListenerProdRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: forward
          ForwardConfig:
            TargetGroups:
              - TargetGroupArn: !Ref ALBTargetGroupBlue
                Weight: 1
      Conditions:
        - Field: http-header
          HttpHeaderConfig:
            HttpHeaderName: User-Agent
            Values:
              - Mozilla
      ListenerArn: !Ref ALBListenerProdTraffic
      Priority: 1
  ECSTaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: ''
            Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
  BlueTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      ExecutionRoleArn: !GetAtt 
        - ECSTaskExecutionRole
        - Arn
      ContainerDefinitions:
        - Name: DemoApp
          Image: 'nginxdemos/hello:latest'
          Essential: true
          PortMappings:
            - HostPort: 80
              Protocol: tcp
              ContainerPort: 80
      RequiresCompatibilities:
        - FARGATE
      NetworkMode: awsvpc
      Cpu: '256'
      Memory: '512'
      Family: ecs-demo
  ECSDemoCluster:
    Type: AWS::ECS::Cluster
    Properties: {}
  ECSDemoService:
    Type: AWS::ECS::Service
    Properties:
      Cluster: !Ref ECSDemoCluster
      DesiredCount: 1
      DeploymentController:
        Type: EXTERNAL
  BlueTaskSet:
    Type: AWS::ECS::TaskSet
    Properties:
      Cluster: !Ref ECSDemoCluster
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsVpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - !Ref ExampleSecurityGroup
          Subnets:
            - !Ref Subnet1
            - !Ref Subnet2
      PlatformVersion: 1.4.0
      Scale:
        Unit: PERCENT
        Value: 100
      Service: !Ref ECSDemoService
      TaskDefinition: !Ref BlueTaskDefinition
      LoadBalancers:
        - ContainerName: DemoApp
          ContainerPort: 80
          TargetGroupArn: !Ref ALBTargetGroupBlue
  PrimaryTaskSet:
    Type: AWS::ECS::PrimaryTaskSet
    Properties:
      Cluster: !Ref ECSDemoCluster
      Service: !Ref ECSDemoService
      TaskSetId: !GetAtt 
        - BlueTaskSet
        - Id
```

# CloudFormation 範本程式碼片段
<a name="template-snippets"></a>

本節提供數個範例藍本，可用來了解如何宣告各種 CloudFormation 範本部分。您也可以使用程式碼片段做為自訂範本各區段的起點。

**Topics**
+ [一般範本程式碼片段](quickref-general.md)
+ [自動擴展 CloudFormation 範本程式碼片段](quickref-autoscaling.md)
+ [AWS 帳單主控台範本程式碼片段](quickref-billingconductor.md)
+ [CloudFormation 範本程式碼片段](quickref-cloudformation.md)
+ [Amazon CloudFront 範本程式碼片段](quickref-cloudfront.md)
+ [Amazon CloudWatch 範本程式碼片段](quickref-cloudwatch.md)
+ [Amazon CloudWatch Logs 範本程式碼片段](quickref-cloudwatchlogs.md)
+ [Amazon DynamoDB 範本程式碼片段](quickref-dynamodb.md)
+ [Amazon EC2 CloudFormation 範本程式碼片段](quickref-ec2.md)
+ [Amazon Elastic Container Service 範例範本](quickref-ecs.md)
+ [Amazon Elastic File System 範例範本](quickref-efs.md)
+ [Elastic Beanstalk 範本程式碼片段](quickref-elasticbeanstalk.md)
+ [Elastic Load Balancing 範本程式碼片段](quickref-elb.md)
+ [AWS Identity and Access Management 範本程式碼片段](quickref-iam.md)
+ [AWS Lambda 範本](quickref-lambda.md)
+ [Amazon Redshift 範本程式碼片段](quickref-redshift.md)
+ [Amazon RDS 範本程式碼片段](quickref-rds.md)
+ [Route 53 範本程式碼片段](quickref-route53.md)
+ [Amazon S3 範本程式碼片段](quickref-s3.md)
+ [Amazon SNS 範本程式碼片段](quickref-sns.md)
+ [Amazon SQS 範本程式碼片段](scenario-sqs-queue.md)
+ [Amazon Timestream 範本程式碼片段](scenario-timestream-queue.md)

# 一般範本程式碼片段
<a name="quickref-general"></a>

以下範例說明非 AWS 服務專屬的不同 CloudFormation 範本功能。

**Topics**
+ [經 Base64 編碼的 UserData 屬性](#scenario-userdata-base64)
+ [經 Base64 編碼的 UserData 屬性，包含 AccessKey 和 SecretKey](#scenario-userdata-base64-with-keys)
+ [具有一個文字字串參數的 Parameters 區段](#scenario-one-string-parameter)
+ [字串參數使用一般表達式限制條件的 Parameters 區段](#scenario-constraint-string-parameter)
+ [數值參數使用 MinValue 和 MaxValue 限制條件的 Parameters 區段](#scenario-one-number-min-parameter)
+ [數值參數使用 AllowedValues 限制條件的 Parameters 區段](#scenario-one-number-parameter)
+ [具有一個文字 CommaDelimitedList 參數的 Parameters 區段](#scenario-one-list-parameter)
+ [參數值以虛擬參數為基礎的 Parameters 區段](#scenario-one-pseudo-parameter)
+ [具有三個映射的 Mapping 區段](#scenario-mapping-with-four-maps)
+ [根據常值字串的 Description](#scenario-description-from-literal-string)
+ [具有一個文字字串輸出的 Outputs 區段](#scenario-output-with-literal-string)
+ [具有一個資源參考和一個虛擬參考輸出的 Outputs 區段](#scenario-output-with-ref-and-pseudo-ref)
+ [具有輸出的 Outputs 區段，此輸出以函數、文字字串、參考和虛擬參數為基礎](#scenario-output-with-complex-spec)
+ [範本格式版本](#scenario-format-version)
+ [AWS Tags 屬性](#scenario-format-aws-tag)

## 經 Base64 編碼的 UserData 屬性
<a name="scenario-userdata-base64"></a>

此範例示範使用 `Fn::Base64` 和 `Fn::Join` 函數的 `UserData` 屬性。參考 `MyValue` 和 `MyName` 是必須在範本 `Parameters` 區段中定義的參數。文字字串 `Hello World` 只是本範例傳入，屬於 `UserData` 的另一個值。

### JSON
<a name="quickref-general-example-1.json"></a>

```
1. "UserData" : {
2.     "Fn::Base64" : {
3.         "Fn::Join" : [ ",", [
4.             { "Ref" : "MyValue" },
5.             { "Ref" : "MyName" },
6.             "Hello World" ] ]
7.     }
8. }
```

### YAML
<a name="quickref-general-example-1.yaml"></a>

```
1. UserData:
2.   Fn::Base64: !Sub |
3.      Ref: MyValue
4.      Ref: MyName
5.      Hello World
```

## 經 Base64 編碼的 UserData 屬性，包含 AccessKey 和 SecretKey
<a name="scenario-userdata-base64-with-keys"></a>

此範例示範使用 `Fn::Base64` 和 `Fn::Join` 函數的 `UserData` 屬性。它包含 `AccessKey` 和 `SecretKey` 資訊。參考 `AccessKey` 和 `SecretKey` 是必須在範本 Parameters (參數) 區段中定義的參數。

### JSON
<a name="quickref-general-example-2.json"></a>

```
1. "UserData" : {
2.     "Fn::Base64" : {
3.         "Fn::Join" : [ "", [
4.             "ACCESS_KEY=", { "Ref" : "AccessKey" },
5.             "SECRET_KEY=", { "Ref" : "SecretKey" } ]
6.         ]
7.     }
8. }
```

### YAML
<a name="quickref-general-example-2.yaml"></a>

```
1. UserData:
2.   Fn::Base64: !Sub |
3.      ACCESS_KEY=${AccessKey}
4.      SECRET_KEY=${SecretKey}
```

## 具有一個文字字串參數的 Parameters 區段
<a name="scenario-one-string-parameter"></a>

下列範例說明有效的 Parameters (參數) 區段宣告，在此宣告單一 `String` 類型參數。

### JSON
<a name="quickref-general-example-3.json"></a>

```
1. "Parameters" : {
2.     "UserName" : {
3.         "Type" : "String",
4.         "Default" : "nonadmin",
5.         "Description" : "Assume a vanilla user if no command-line spec provided"
6.     }
7. }
```

### YAML
<a name="quickref-general-example-3.yaml"></a>

```
1. Parameters:
2.   UserName:
3.     Type: String
4.     Default: nonadmin
5.     Description: Assume a vanilla user if no command-line spec provided
```

## 字串參數使用一般表達式限制條件的 Parameters 區段
<a name="scenario-constraint-string-parameter"></a>

下列範例說明有效的 Parameters (參數) 區段宣告，在此宣告單一 `String` 類型參數。`AdminUserAccount` 參數的預設值為 `admin`。此參數值長度下限為 1 個字元、長度上限為 16 個字元，而且包含英數字元，但必須以字母字元開頭。

### JSON
<a name="quickref-general-example-4.json"></a>

```
 1. "Parameters" : {
 2.     "AdminUserAccount": {
 3.       "Default": "admin",
 4.       "NoEcho": "true",
 5.       "Description" : "The admin account user name",
 6.       "Type": "String",
 7.       "MinLength": "1",
 8.       "MaxLength": "16",
 9.       "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*"
10.     }
11. }
```

### YAML
<a name="quickref-general-example-4.yaml"></a>

```
1. Parameters:
2.   AdminUserAccount:
3.     Default: admin
4.     NoEcho: true
5.     Description: The admin account user name
6.     Type: String
7.     MinLength: 1
8.     MaxLength: 16
9.     AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
```

## 數值參數使用 MinValue 和 MaxValue 限制條件的 Parameters 區段
<a name="scenario-one-number-min-parameter"></a>

下列範例說明有效的 Parameters (參數) 區段宣告，在此宣告單一 `Number` 類型參數。`WebServerPort` 參數的預設值為 80，最小值 1 和最大值 65535。

### JSON
<a name="quickref-general-example-5.json"></a>

```
1. "Parameters" : {
2.     "WebServerPort": {
3.       "Default": "80",
4.       "Description" : "TCP/IP port for the web server",
5.       "Type": "Number",
6.       "MinValue": "1",
7.       "MaxValue": "65535"
8.     }
9. }
```

### YAML
<a name="quickref-general-example-5.yaml"></a>

```
1. Parameters:
2.   WebServerPort:
3.     Default: 80
4.     Description: TCP/IP port for the web server
5.     Type: Number
6.     MinValue: 1
7.     MaxValue: 65535
```

## 數值參數使用 AllowedValues 限制條件的 Parameters 區段
<a name="scenario-one-number-parameter"></a>

下列範例說明有效的 Parameters (參數) 區段宣告，在此宣告單一 `Number` 類型參數。`WebServerPort` 參數的預設值為 80，僅允許值 80 和 8888。

### JSON
<a name="quickref-general-example-6.json"></a>

```
1. "Parameters" : {
2.     "WebServerPortLimited": {
3.       "Default": "80",
4.       "Description" : "TCP/IP port for the web server",
5.       "Type": "Number",
6.       "AllowedValues" : ["80", "8888"]
7.     }
8. }
```

### YAML
<a name="quickref-general-example-6.yaml"></a>

```
1. Parameters:
2.   WebServerPortLimited:
3.     Default: 80
4.     Description: TCP/IP port for the web server
5.     Type: Number
6.     AllowedValues:
7.     - 80
8.     - 8888
```

## 具有一個文字 CommaDelimitedList 參數的 Parameters 區段
<a name="scenario-one-list-parameter"></a>

下列範例說明有效的 `Parameters` 區段宣告，在此宣告單一 `CommaDelimitedList` 類型參數。`NoEcho` 屬性被設定為 `TRUE`，這將在 **describe-stacks** 輸出中使用星號 (\$1\$1\$1\$1\$1) 遮罩其值，但儲存在下列指定位置的資訊除外。

**重要**  
使用 `NoEcho` 屬性不會遮罩任何儲存在下列資訊中的資訊：  
`Metadata` 範本區段。CloudFormation 不會轉換、修改或標記您在 `Metadata` 區段中包含的任何資訊。若要取得更多資訊，請參閱[中繼資料](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html)。
`Outputs` 範本區段。如需詳細資訊，請參閱[輸出](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)。
資源定義的 `Metadata` 屬性。如需詳細資訊，請參閱 [`Metadata` 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html)。
我們強烈建議您不要使用這些機制來包含敏感資訊，例如密碼或秘密。

**重要**  
我們建議您不要直接在 CloudFormation 範本中嵌入敏感資訊，而是在堆疊範本中使用動態參數來參考在 CloudFormation 外部存放和管理的敏感資訊，例如在 AWS Systems Manager 參數存放區或 中 AWS Secrets Manager。  
如需詳細資訊，請參閱[請勿在範本中內嵌認證](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/security-best-practices.html#creds)的最佳實務。

### JSON
<a name="quickref-general-example-7.json"></a>

```
1. "Parameters" : {
2.     "UserRoles" : {
3.         "Type" : "CommaDelimitedList",
4.         "Default" : "guest,newhire",
5.         "NoEcho" : "TRUE"
6.     }
7. }
```

### YAML
<a name="quickref-general-example-7.yaml"></a>

```
1. Parameters:
2.   UserRoles:
3.     Type: CommaDelimitedList
4.     Default: "guest,newhire"
5.     NoEcho: true
```

## 參數值以虛擬參數為基礎的 Parameters 區段
<a name="scenario-one-pseudo-parameter"></a>

以下範例顯示 EC2 使用者資料中使用虛擬參數 `AWS::StackName` 和 `AWS::Region` 的命令。如需這些虛擬參數的詳細資訊，請參閱[使用虛擬參數取得 AWS 值](pseudo-parameter-reference.md)。

### JSON
<a name="quickref-general-example-10.json"></a>

```
 1.           "UserData"       : { "Fn::Base64" : { "Fn::Join" : ["", [
 2.              "#!/bin/bash -xe\n",
 3.              "yum install -y aws-cfn-bootstrap\n",
 4. 
 5.              "/opt/aws/bin/cfn-init -v ",
 6.              "         --stack ", { "Ref" : "AWS::StackName" },
 7.              "         --resource LaunchConfig ",
 8.              "         --region ", { "Ref" : "AWS::Region" }, "\n",
 9. 
10.              "/opt/aws/bin/cfn-signal -e $? ",
11.              "         --stack ", { "Ref" : "AWS::StackName" },
12.              "         --resource WebServerGroup ",
13.              "         --region ", { "Ref" : "AWS::Region" }, "\n"
14.         ]]}}
15.       }
```

### YAML
<a name="quickref-general-example-10.yaml"></a>

```
1. UserData:
2.   Fn::Base64: !Sub |
3.      #!/bin/bash -xe
4.      yum update -y aws-cfn-bootstrap
5.      /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --region ${AWS::Region}
6.      /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerGroup --region ${AWS::Region}
```

## 具有三個映射的 Mapping 區段
<a name="scenario-mapping-with-four-maps"></a>

以下範例說明包含三個映射之有效的 `Mapping` 區段宣告。符合 `Stop`、`SlowDown` 或 `Go` 映射金鑰時，映射會提供指派給所對應 `RGBColor` 屬性的 RGB 值。

### JSON
<a name="quickref-general-example-11.json"></a>

```
 1. "Mappings" : {
 2.     "LightColor" : {
 3.         "Stop" : {
 4.             "Description" : "red",
 5.             "RGBColor" : "RED 255 GREEN 0 BLUE 0"
 6.         },
 7.         "SlowDown" : {
 8.             "Description" : "yellow",
 9.             "RGBColor" : "RED 255 GREEN 255 BLUE 0"
10.         },
11.         "Go" : {
12.             "Description" : "green",
13.             "RGBColor" : "RED 0 GREEN 128 BLUE 0"
14.         }
15.     }
16. }
```

### YAML
<a name="quickref-general-example-11.yaml"></a>

```
 1. Mappings:
 2.   LightColor:
 3.     Stop:
 4.       Description: red
 5.       RGBColor: "RED 255 GREEN 0 BLUE 0"
 6.     SlowDown:
 7.       Description: yellow
 8.       RGBColor: "RED 255 GREEN 255 BLUE 0"
 9.     Go:
10.       Description: green
11.       RGBColor: "RED 0 GREEN 128 BLUE 0"
```

## 根據常值字串的 Description
<a name="scenario-description-from-literal-string"></a>

以下範例說明有效的 `Description` 區段宣告，其值是以文字字串為基礎。此程式碼片段適用於範本、參數、資源、屬性或輸出。

### JSON
<a name="quickref-general-example-8.json"></a>

```
1. "Description" : "Replace this value"
```

### YAML
<a name="quickref-general-example-8.yaml"></a>

```
1. Description: "Replace this value"
```

## 具有一個文字字串輸出的 Outputs 區段
<a name="scenario-output-with-literal-string"></a>

此範例示範以文字字串為基礎的輸出指派。

### JSON
<a name="quickref-general-example-12.json"></a>

```
1. "Outputs" : {
2.     "MyPhone" : {
3.         "Value" : "Please call 555-5555",
4.         "Description" : "A random message for aws cloudformation describe-stacks"
5.     }
6. }
```

### YAML
<a name="quickref-general-example-12.yaml"></a>

```
1. Outputs:
2.   MyPhone:
3.     Value: Please call 555-5555
4.     Description: A random message for aws cloudformation describe-stacks
```

## 具有一個資源參考和一個虛擬參考輸出的 Outputs 區段
<a name="scenario-output-with-ref-and-pseudo-ref"></a>

此範例示範具有兩個輸出指派的 `Outputs` 區段。一個以資源為基礎，另一個以虛擬參考為基礎。

### JSON
<a name="quickref-general-example-13.json"></a>

```
1. "Outputs" : {
2.    "SNSTopic" : { "Value" : { "Ref" : "MyNotificationTopic" } },
3.    "StackName" : { "Value" : { "Ref" : "AWS::StackName" } }
4. }
```

### YAML
<a name="quickref-general-example-13.yaml"></a>

```
1. Outputs:
2.   SNSTopic:
3.     Value: !Ref MyNotificationTopic
4.   StackName:
5.     Value: !Ref AWS::StackName
```

## 具有輸出的 Outputs 區段，此輸出以函數、文字字串、參考和虛擬參數為基礎
<a name="scenario-output-with-complex-spec"></a>

此範例示範具有一個輸出指派的 Outputs (輸出) 區段。使用 Join 函數串連值，百分比符號為分隔符號。

### JSON
<a name="quickref-general-example-14.json"></a>

```
1. "Outputs" : {
2.     "MyOutput" : {
3.         "Value" : { "Fn::Join" :
4.             [ "%", [ "A-string", {"Ref" : "AWS::StackName" } ] ]
5.         }
6.     }
7. }
```

### YAML
<a name="quickref-general-example-14.yaml"></a>

```
1. Outputs:
2.   MyOutput:
3.     Value: !Join [ %, [ 'A-string', !Ref 'AWS::StackName' ]]
```

## 範本格式版本
<a name="scenario-format-version"></a>

下列程式碼片段說明有效的 `AWSTemplateFormatVersion` 區段宣告。

### JSON
<a name="quickref-general-example-9.json"></a>

```
1. "AWSTemplateFormatVersion" : "2010-09-09"
```

### YAML
<a name="quickref-general-example-9.yaml"></a>

```
1. AWSTemplateFormatVersion: '2010-09-09'
```

## AWS Tags 屬性
<a name="scenario-format-aws-tag"></a>

此範例顯示 屬性 AWS `Tags`。您可以在資源的 Properties (屬性) 區段內指定此屬性。資源建立後，會以您宣告的標籤標記。

### JSON
<a name="quickref-general-example-15.json"></a>

```
 1. "Tags" : [
 2.       {
 3.         "Key" : "keyname1",
 4.         "Value" : "value1"
 5.       },
 6.       {
 7.         "Key" : "keyname2",
 8.         "Value" : "value2"
 9.       }
10.     ]
```

### YAML
<a name="quickref-general-example-15.yaml"></a>

```
1. Tags: 
2.   - 
3.     Key: "keyname1"
4.     Value: "value1"
5.   - 
6.     Key: "keyname2"
7.     Value: "value2"
```

# 自動擴展 CloudFormation 範本程式碼片段
<a name="quickref-autoscaling"></a>

藉助 Amazon EC2 Auto Scaling，您可以透過擴展政策或排程擴展來自動擴展 Amazon EC2 執行個體。Auto Scaling 群組是 Amazon EC2 執行個體的集合，可支援自動擴展和機群管理功能，例如擴展政策、排程動作、運作狀態檢查、lifecycle hook 和負載均衡。

Application Auto Scaling 可透過擴展政策或排程擴展，提供 Amazon EC2 以外的不同資源的自動擴展。

您可以使用 CloudFormation 範本建立和設定 Auto Scaling 群組、擴展政策、排程動作和其他自動擴展資源，做為基礎設施的一部分。範本可讓您以可重複且一致的方式，輕鬆管理和自動化自動擴展資源的部署。

下列範例範本程式碼片段說明 Amazon EC2 Auto Scaling 和 Application Auto Scaling CloudFormation 的資源或元件。這些程式碼片段設計用於整合至範本中，而且並非設計為獨立執行。

**Topics**
+ [設定 Amazon EC2 Auto Scaling 資源](quickref-ec2-auto-scaling.md)
+ [設定 Application Auto Scaling 資源](quickref-application-auto-scaling.md)

# 使用 設定 Amazon EC2 Auto Scaling 資源 CloudFormation
<a name="quickref-ec2-auto-scaling"></a>

下列範例示範要在範本中包含的不同程式碼片段，以與 Amazon EC2 Auto Scaling 搭配使用。

**Topics**
+ [建立單一執行個體 Auto Scaling 群組](#scenario-single-instance-as-group)
+ [透過連接的負載平衡器建立 Auto Scaling 群組](#scenario-as-group)
+ [透過通知建立 Auto Scaling 群組](#scenario-as-notification)
+ [建立使用 `CreationPolicy` 和 `UpdatePolicy` 的 Auto Scaling 群組](#scenario-as-updatepolicy)
+ [建立步驟擴展政策](#scenario-step-scaling-policy)
+ [混合執行個體群組範例](#scenario-mixed-instances-group-template-examples)
+ [啟動組態範例](#scenario-launch-config-template-examples)

## 建立單一執行個體 Auto Scaling 群組
<a name="scenario-single-instance-as-group"></a>

此範例顯示具有單一執行個體的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 資源，以協助您開始使用。Auto Scaling 群組的 `VPCZoneIdentifier` 屬性指定三個不同可用區域中的現有子網路清單。您必須先從帳戶指定適用的子網路 ID，然後才能建立堆疊。`LaunchTemplate` 屬性參考 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html) 資源，該資源具有範本中其他處所定義的邏輯名稱 `myLaunchTemplate`。

**注意**  
如需啟動範本的範例，請參閱 Amazon EC2 程式碼片段章節中的 [透過 CloudFormation 建立啟動範本](quickref-ec2-launch-templates.md)，以及 `AWS::EC2::LaunchTemplate` 資源中的[範例](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html#aws-resource-ec2-launchtemplate--examples)章節。

### JSON
<a name="quickref-autoscaling-example-1.json"></a>

```
 1. "myASG" : {
 2.    "Type" : "AWS::AutoScaling::AutoScalingGroup",
 3.    "Properties" : {
 4.       "VPCZoneIdentifier" : [ "subnetIdAz1", "subnetIdAz2", "subnetIdAz3" ],
 5.       "LaunchTemplate" : {
 6.         "LaunchTemplateId" : {
 7.           "Ref" : "myLaunchTemplate"
 8.         },
 9.         "Version" : {
10.           "Fn::GetAtt" : [
11.             "myLaunchTemplate",
12.             "LatestVersionNumber"
13.           ]
14.         }
15.       },
16.       "MaxSize" : "1",
17.       "MinSize" : "1"
18.    }
19. }
```

### YAML
<a name="quickref-autoscaling-example-1.yaml"></a>

```
 1. myASG:
 2.   Type: AWS::AutoScaling::AutoScalingGroup
 3.   Properties:
 4.     VPCZoneIdentifier:
 5.       - subnetIdAz1
 6.       - subnetIdAz2
 7.       - subnetIdAz3
 8.     LaunchTemplate:
 9.       LaunchTemplateId: !Ref myLaunchTemplate
10.       Version: !GetAtt myLaunchTemplate.LatestVersionNumber
11.     MaxSize: '1'
12.     MinSize: '1'
```

## 透過連接的負載平衡器建立 Auto Scaling 群組
<a name="scenario-as-group"></a>

此範例顯示 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 資源，適用於多個伺服器之間的負載平衡。它指定在相同範本中其他位置宣告 AWS 的資源邏輯名稱。

1. `VPCZoneIdentifier` 屬性指定兩個 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-subnet.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-subnet.html) 資源的邏輯名稱 (將在其中建立 Auto Scaling 群組的 EC2 執行個體)：`myPublicSubnet1` 和 `myPublicSubnet2`。

1. `LaunchTemplate` 屬性指定 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html) 資源，該資源具有邏輯名稱 `myLaunchTemplate`。

1. `TargetGroupARNs` 屬性針對將流量路由到 Auto Scaling 群組所使用的 Application Load Balancer 或 Network Load Balancer，列出目標群組。在此範例中，指定了一個目標群組，[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) 資源，該資源具有邏輯名稱 `myTargetGroup`。

### JSON
<a name="quickref-autoscaling-example-2.json"></a>

```
 1. "myServerGroup" : {
 2.    "Type" : "AWS::AutoScaling::AutoScalingGroup",
 3.    "Properties" : {
 4.       "VPCZoneIdentifier" : [ { "Ref" : "myPublicSubnet1" }, { "Ref" : "myPublicSubnet2" } ],
 5.       "LaunchTemplate" : {
 6.         "LaunchTemplateId" : {
 7.           "Ref" : "myLaunchTemplate"
 8.         },
 9.         "Version" : {
10.           "Fn::GetAtt" : [
11.             "myLaunchTemplate",
12.             "LatestVersionNumber"
13.           ]
14.         }
15.       },
16.       "MaxSize" : "5",
17.       "MinSize" : "1",
18.       "TargetGroupARNs" : [ { "Ref" : "myTargetGroup" } ]
19.    }
20. }
```

### YAML
<a name="quickref-autoscaling-example-2.yaml"></a>

```
 1. myServerGroup:
 2.   Type: AWS::AutoScaling::AutoScalingGroup
 3.   Properties:
 4.     VPCZoneIdentifier:
 5.       - !Ref myPublicSubnet1
 6.       - !Ref myPublicSubnet2
 7.     LaunchTemplate:
 8.       LaunchTemplateId: !Ref myLaunchTemplate
 9.       Version: !GetAtt myLaunchTemplate.LatestVersionNumber
10.     MaxSize: '5'
11.     MinSize: '1'
12.     TargetGroupARNs:
13.       - !Ref myTargetGroup
```

### 另請參閱
<a name="scenario-as-group-see-also"></a>

如需根據適用於 Application Load Balancer 的 `ALBRequestCountPerTarget` 預先定義指標建立具有目標追蹤擴展政策之 Auto Scaling 群組的詳細範例，請參閱 `AWS::AutoScaling::ScalingPolicy` 資源中的[範例](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-scalingpolicy.html#aws-resource-autoscaling-scalingpolicy--examples)章節。

## 透過通知建立 Auto Scaling 群組
<a name="scenario-as-notification"></a>

此範例顯示的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 資源會在指定的事件發生時傳送 Amazon SNS 通知。`NotificationConfigurations` 屬性指定 SNS 主題，其中 CloudFormation 會傳送通知，以及會導致 CloudFormation 傳送通知的事件。當 指定的事件`NotificationTypes`發生時， CloudFormation 會傳送通知至 指定的 SNS 主題`TopicARN`。當您啟動堆疊時， CloudFormation 會建立在相同範本中宣告[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-subscription.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-subscription.html)的資源 (`snsTopicForAutoScalingGroup`)。

Auto Scaling 群組的 `VPCZoneIdentifier` 屬性指定三個不同可用區域中的現有子網路清單。您必須先從帳戶指定適用的子網路 ID，然後才能建立堆疊。`LaunchTemplate` 屬性參考在相同範本中其他位置宣告的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html) 資源邏輯名稱。

### JSON
<a name="quickref-autoscaling-example-3.json"></a>

```
 1. "myASG" : {
 2.   "Type" : "AWS::AutoScaling::AutoScalingGroup",
 3.   "DependsOn": [
 4.     "snsTopicForAutoScalingGroup"
 5.   ],
 6.   "Properties" : {
 7.     "VPCZoneIdentifier" : [ "subnetIdAz1", "subnetIdAz2", "subnetIdAz3" ],
 8.     "LaunchTemplate" : {
 9.       "LaunchTemplateId" : {
10.         "Ref" : "logicalName"
11.       },
12.       "Version" : {
13.         "Fn::GetAtt" : [
14.           "logicalName",
15.           "LatestVersionNumber"
16.         ]
17.       }
18.     },
19.     "MaxSize" : "5",
20.     "MinSize" : "1",
21.     "NotificationConfigurations" : [
22.       {
23.         "TopicARN" : { "Ref" : "snsTopicForAutoScalingGroup" },
24.         "NotificationTypes" : [
25.           "autoscaling:EC2_INSTANCE_LAUNCH",
26.           "autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
27.           "autoscaling:EC2_INSTANCE_TERMINATE",
28.           "autoscaling:EC2_INSTANCE_TERMINATE_ERROR",
29.           "autoscaling:TEST_NOTIFICATION"
30.         ]
31.       }
32.     ]
33.   }
34. }
```

### YAML
<a name="quickref-autoscaling-example-3.yaml"></a>

```
 1. myASG:
 2.   Type: AWS::AutoScaling::AutoScalingGroup
 3.   DependsOn:
 4.     - snsTopicForAutoScalingGroup
 5.   Properties:
 6.     VPCZoneIdentifier:
 7.       - subnetIdAz1
 8.       - subnetIdAz2
 9.       - subnetIdAz3
10.     LaunchTemplate:
11.       LaunchTemplateId: !Ref logicalName
12.       Version: !GetAtt logicalName.LatestVersionNumber
13.     MaxSize: '5'
14.     MinSize: '1'
15.     NotificationConfigurations:
16.       - TopicARN: !Ref snsTopicForAutoScalingGroup
17.         NotificationTypes:
18.           - autoscaling:EC2_INSTANCE_LAUNCH
19.           - autoscaling:EC2_INSTANCE_LAUNCH_ERROR
20.           - autoscaling:EC2_INSTANCE_TERMINATE
21.           - autoscaling:EC2_INSTANCE_TERMINATE_ERROR
22.           - autoscaling:TEST_NOTIFICATION
```

## 建立使用 `CreationPolicy` 和 `UpdatePolicy` 的 Auto Scaling 群組
<a name="scenario-as-updatepolicy"></a>

下列範例顯示如何將 `CreationPolicy` 和 `UpdatePolicy` 屬性新增至 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 資源。

範例建立政策可防止 Auto Scaling 群組達到`CREATE_COMPLETE`狀態，直到群組準備就緒時 CloudFormation 收到成功訊號`Count`的數量為止。若要發出 Auto Scaling 群組已就緒的訊號，需在執行個體上執行新增到啟動範本使用者資料 (未顯示) 的 `cfn-signal` 協助程式指令碼。如果執行個體未在指定的 `Timeout` 內傳送訊號，CloudFormation 將假設未建立執行個體、資源建立失敗，且 CloudFormation 將復原堆疊。

範例更新政策使用 `AutoScalingRollingUpdate` 屬性指示 CloudFormation，以執行滾動更新。滾動更新根據 `MaxBatchSize` 和以 `PauseTime` 為基礎的更新批次間的暫停時間，小量批次變更 Auto Scaling 群組 (在此範例中為依執行個體逐一變更)。`MinInstancesInService` 屬性指定在 CloudFormation 更新舊執行個體時，Auto Scaling 群組中必須為服務中的執行個體的最少數量。

`WaitOnResourceSignals` 屬性會設定為 `true`。CloudFormation 必須在指定的 `PauseTime` 內先接到每個新執行個體的訊號，才會繼續更新。當堆疊正在更新時，會暫停以下 EC2 Auto Scaling 程序：`HealthCheck`、`ReplaceUnhealthy`、`AZRebalance`、`AlarmNotification` 和 `ScheduledActions`。注意：請勿暫停 `Launch`、`Terminate` 或 `AddToLoadBalancer` (如果 Auto Scaling 群組與 Elastic Load Balancing 搭配使用) 程序類型，因為這麼做會讓滾動更新無法正常運作。

Auto Scaling 群組的 `VPCZoneIdentifier` 屬性指定三個不同可用區域中的現有子網路清單。您必須先從帳戶指定適用的子網路 ID，然後才能建立堆疊。`LaunchTemplate` 屬性參考在相同範本中其他位置宣告的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html) 資源邏輯名稱。

如需 `CreationPolicy` 和 `UpdatePolicy` 屬性的詳細資訊，請參閱[資源屬性參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-product-attribute-reference.html)。

### JSON
<a name="quickref-autoscaling-example-4.json"></a>

```
{
  "Resources":{
    "myASG":{
      "CreationPolicy":{
        "ResourceSignal":{
          "Count":"3",
          "Timeout":"PT15M"
        }
      },
      "UpdatePolicy":{
        "AutoScalingRollingUpdate":{
          "MinInstancesInService":"3",
          "MaxBatchSize":"1",
          "PauseTime":"PT12M5S",
          "WaitOnResourceSignals":"true",
          "SuspendProcesses":[
            "HealthCheck",
            "ReplaceUnhealthy",
            "AZRebalance",
            "AlarmNotification",
            "ScheduledActions",
            "InstanceRefresh"
          ]
        }
      },
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "VPCZoneIdentifier":[ "subnetIdAz1", "subnetIdAz2", "subnetIdAz3" ],
        "LaunchTemplate":{
          "LaunchTemplateId":{
            "Ref":"logicalName"
          },
          "Version":{
            "Fn::GetAtt":[
              "logicalName",
              "LatestVersionNumber"
            ]
          }
        },
        "MaxSize":"5",
        "MinSize":"3"
      }
    }
  }
}
```

### YAML
<a name="quickref-autoscaling-example-4.yaml"></a>

```
---
Resources:
  myASG:
    CreationPolicy:
      ResourceSignal:
        Count: '3'
        Timeout: PT15M
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinInstancesInService: '3'
        MaxBatchSize: '1'
        PauseTime: PT12M5S
        WaitOnResourceSignals: true
        SuspendProcesses:
          - HealthCheck
          - ReplaceUnhealthy
          - AZRebalance
          - AlarmNotification
          - ScheduledActions
          - InstanceRefresh
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      VPCZoneIdentifier:
        - subnetIdAz1
        - subnetIdAz2
        - subnetIdAz3
      LaunchTemplate:
        LaunchTemplateId: !Ref logicalName
        Version: !GetAtt logicalName.LatestVersionNumber
      MaxSize: '5'
      MinSize: '3'
```

## 建立步驟擴展政策
<a name="scenario-step-scaling-policy"></a>

此範例顯示使用步進擴展政策擴增 Auto Scaling 群組的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-scalingpolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-scalingpolicy.html) 資源。`AdjustmentType` 屬性指定 `ChangeInCapacity`，這表示 `ScalingAdjustment` 代表要新增 (如果 `ScalingAdjustment` 為正數) 或要刪除 (如果該屬性為負數) 的執行個體數量。在本範例中，`ScalingAdjustment` 為 1。因此，在超過警示閾值時，政策即會在群組中逐次遞增 1 個 EC2 執行個體。

[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudwatch-alarm.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudwatch-alarm.html) 資源 `CPUAlarmHigh` 可指定擴展政策 `ASGScalingPolicyHigh` 作為警示處於 ALARM 狀態時要執行的動作 (`AlarmActions`)。`Dimensions` 屬性參考在相同範本中其他位置宣告的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 資源邏輯名稱。

### JSON
<a name="quickref-autoscaling-example-5.json"></a>

```
 1. {
 2.   "Resources":{
 3.     "ASGScalingPolicyHigh":{
 4.       "Type":"AWS::AutoScaling::ScalingPolicy",
 5.       "Properties":{
 6.         "AutoScalingGroupName":{ "Ref":"logicalName" },
 7.         "PolicyType":"StepScaling",
 8.         "AdjustmentType":"ChangeInCapacity",
 9.         "StepAdjustments":[
10.           {
11.             "MetricIntervalLowerBound":0,
12.             "ScalingAdjustment":1
13.           }
14.         ]
15.       }
16.     },
17.     "CPUAlarmHigh":{
18.       "Type":"AWS::CloudWatch::Alarm",
19.       "Properties":{
20.         "EvaluationPeriods":"2",
21.         "Statistic":"Average",
22.         "Threshold":"90",
23.         "AlarmDescription":"Scale out if CPU > 90% for 2 minutes",
24.         "Period":"60",
25.         "AlarmActions":[ { "Ref":"ASGScalingPolicyHigh" } ],
26.         "Namespace":"AWS/EC2",
27.         "Dimensions":[
28.           {
29.             "Name":"AutoScalingGroupName",
30.             "Value":{ "Ref":"logicalName" }
31.           }
32.         ],
33.         "ComparisonOperator":"GreaterThanThreshold",
34.         "MetricName":"CPUUtilization"
35.       }
36.     }
37.   }
38. }
```

### YAML
<a name="quickref-autoscaling-example-5.yaml"></a>

```
 1. ---
 2. Resources:
 3.   ASGScalingPolicyHigh:
 4.     Type: AWS::AutoScaling::ScalingPolicy
 5.     Properties:
 6.       AutoScalingGroupName: !Ref logicalName
 7.       PolicyType: StepScaling
 8.       AdjustmentType: ChangeInCapacity
 9.       StepAdjustments: 
10.         - MetricIntervalLowerBound: 0
11.           ScalingAdjustment: 1
12.   CPUAlarmHigh:
13.     Type: AWS::CloudWatch::Alarm
14.     Properties:
15.       EvaluationPeriods: 2
16.       Statistic: Average
17.       Threshold: 90
18.       AlarmDescription: 'Scale out if CPU > 90% for 2 minutes'
19.       Period: 60
20.       AlarmActions:
21.         - !Ref ASGScalingPolicyHigh
22.       Namespace: AWS/EC2
23.       Dimensions:
24.         - Name: AutoScalingGroupName
25.           Value:
26.             !Ref logicalName
27.       ComparisonOperator: GreaterThanThreshold
28.       MetricName: CPUUtilization
```

### 另請參閱
<a name="scenario-as-policy-see-also"></a>

如需更多擴展政策的範例範本，請參閱 `AWS::AutoScaling::ScalingPolicy` 資源中的[範例](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-scalingpolicy.html#aws-resource-autoscaling-scalingpolicy--examples)章節。

## 混合執行個體群組範例
<a name="scenario-mixed-instances-group-template-examples"></a>

### 使用屬性型執行個體類型選取範圍來建立 Auto Scaling 群組
<a name="scenario-mixed-instances-group-instance-requirements"></a>

此範例顯示 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 資源，該資源包含使用基於屬性的執行個體類型選擇啟動混合執行個體群組之資訊。您需指定 `VCpuCount` 屬性的下限值和上限值，以及 `MemoryMiB` 屬性的下限值。Auto Scaling 群組使用的任何執行個體類型都必須與所需執行個體屬性相符。

Auto Scaling 群組的 `VPCZoneIdentifier` 屬性指定三個不同可用區域中的現有子網路清單。您必須先從帳戶指定適用的子網路 ID，然後才能建立堆疊。`LaunchTemplate` 屬性參考在相同範本中其他位置宣告的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html) 資源邏輯名稱。

#### JSON
<a name="quickref-mixed-instances-group-example-2.json"></a>

```
 1. {
 2.   "Resources":{
 3.     "myASG":{
 4.       "Type":"AWS::AutoScaling::AutoScalingGroup",
 5.       "Properties":{
 6.         "VPCZoneIdentifier":[
 7.           "subnetIdAz1",
 8.           "subnetIdAz2",
 9.           "subnetIdAz3"
10.         ],
11.         "MixedInstancesPolicy":{
12.           "LaunchTemplate":{
13.             "LaunchTemplateSpecification":{
14.               "LaunchTemplateId":{
15.                 "Ref":"logicalName"
16.               },
17.               "Version":{
18.                 "Fn::GetAtt":[
19.                   "logicalName",
20.                   "LatestVersionNumber"
21.                 ]
22.               }
23.             },
24.             "Overrides":[
25.               {
26.                 "InstanceRequirements":{
27.                   "VCpuCount":{
28.                     "Min":2,
29.                     "Max":4
30.                   },
31.                   "MemoryMiB":{
32.                     "Min":2048
33.                   }
34.                 }
35.               }
36.             ]
37.           }
38.         },
39.         "MaxSize":"5",
40.         "MinSize":"1"
41.       }
42.     }
43.   }
44. }
```

#### YAML
<a name="quickref-mixed-instances-group-example-1.yaml"></a>

```
 1. ---
 2. Resources:
 3.   myASG:
 4.     Type: AWS::AutoScaling::AutoScalingGroup
 5.     Properties:
 6.       VPCZoneIdentifier:
 7.         - subnetIdAz1
 8.         - subnetIdAz2
 9.         - subnetIdAz3
10.       MixedInstancesPolicy:
11.         LaunchTemplate:
12.           LaunchTemplateSpecification:
13.             LaunchTemplateId: !Ref logicalName
14.             Version: !GetAtt logicalName.LatestVersionNumber
15.           Overrides:
16.             - InstanceRequirements:
17.                 VCpuCount:
18.                   Min: 2
19.                   Max: 4
20.                 MemoryMiB:
21.                   Min: 2048
22.       MaxSize: '5'
23.       MinSize: '1'
```

## 啟動組態範例
<a name="scenario-launch-config-template-examples"></a>

### 建立啟動組態
<a name="scenario-as-launch-config"></a>

此範例顯示 Auto Scaling 群組的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-launchconfiguration.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-launchconfiguration.html) 資源，您在此資源中為 `ImageId`、`InstanceType` 和 `SecurityGroups` 屬性指定值。`SecurityGroups` 屬性指定範本中其他處指定之 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源的邏輯名稱，以及名為 `myExistingEC2SecurityGroup` 的現有 EC2 安全群組。

#### JSON
<a name="quickref-launch-config-example-1.json"></a>

```
1. "mySimpleConfig" : {
2.    "Type" : "AWS::AutoScaling::LaunchConfiguration",
3.    "Properties" : {
4.       "ImageId" : "ami-02354e95b3example",
5.       "InstanceType" : "t3.micro",
6.       "SecurityGroups" : [ { "Ref" : "logicalName" }, "myExistingEC2SecurityGroup" ]
7.    }
8. }
```

#### YAML
<a name="quickref-launch-config-example-1.yaml"></a>

```
1. mySimpleConfig:
2.   Type: AWS::AutoScaling::LaunchConfiguration
3.   Properties:
4.     ImageId: ami-02354e95b3example
5.     InstanceType: t3.micro
6.     SecurityGroups:
7.       - !Ref logicalName
8.       - myExistingEC2SecurityGroup
```

### 使用啟動組態建立 Auto Scaling 群組
<a name="scenario-single-instance-as-group-launch-configuration"></a>

此範例顯示具有單一執行個體的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 資源。Auto Scaling 群組的 `VPCZoneIdentifier` 屬性指定三個不同可用區域中的現有子網路清單。您必須先從帳戶指定適用的子網路 ID，然後才能建立堆疊。`LaunchConfigurationName` 屬性參考 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-launchconfiguration.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-launchconfiguration.html) 資源，該資源具有範本中所定義的邏輯名稱 `mySimpleConfig`。

#### JSON
<a name="quickref-launch-config-example-2.json"></a>

```
1. "myASG" : {
2.    "Type" : "AWS::AutoScaling::AutoScalingGroup",
3.    "Properties" : {
4.       "VPCZoneIdentifier" : [ "subnetIdAz1", "subnetIdAz2", "subnetIdAz3" ],
5.       "LaunchConfigurationName" : { "Ref" : "mySimpleConfig" },
6.       "MaxSize" : "1",
7.       "MinSize" : "1"
8.    }
9. }
```

#### YAML
<a name="quickref-launch-config-example-2.yaml"></a>

```
 1. myASG:
 2.   Type: AWS::AutoScaling::AutoScalingGroup
 3.   Properties:
 4.     VPCZoneIdentifier:
 5.       - subnetIdAz1
 6.       - subnetIdAz2
 7.       - subnetIdAz3
 8.     LaunchConfigurationName: !Ref mySimpleConfig
 9.     MaxSize: '1'
10.     MinSize: '1'
```

# 使用 設定 Application Auto Scaling 資源 CloudFormation
<a name="quickref-application-auto-scaling"></a>

本節提供 Application Auto Scaling 擴展政策和不同 AWS 資源排程動作的 CloudFormation 範本範例。

**重要**  
範本中包含 Application Auto Scaling 程式碼片段時，您可能需要使用 `DependsOn` 屬性宣告對透過範本建立之特定可擴展資源的相依性。這會覆寫預設平行處理原則，並引導 CloudFormation 依指定順序在資源上操作。否則，擴展組態可能會在完全設定資源前套用。  
如需詳細資訊，請參閱 [DependsOn 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-dependson.html)。

**Topics**
+ [建立 AppStream 機群的擴展政策](#w2aac11c41c15c19b9)
+ [建立 Aurora 資料庫叢集的擴展原則](#w2aac11c41c15c19c11)
+ [建立 DynamoDB 資料表的擴展政策](#w2aac11c41c15c19c13)
+ [建立 Amazon ECS 服務的擴展政策 (指標：平均 CPU 和記憶體)](#w2aac11c41c15c19c15)
+ [建立 Amazon ECS 服務的擴展政策 (指標：每個目標的平均請求計數)](#w2aac11c41c15c19c17)
+ [使用 Cron 表達式建立 Lambda 函式的排程動作](#w2aac11c41c15c19c19)
+ [使用 `at` 表達式建立 Spot 機群的排程動作](#w2aac11c41c15c19c21)

## 建立 AppStream 機群的擴展政策
<a name="w2aac11c41c15c19b9"></a>

此程式碼片段示範如何使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalingpolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalingpolicy.html) 資源建立政策，並將其套用到 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-appstream-fleet.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-appstream-fleet.html) 資源。[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html) 資源宣告將套用此政策的可擴展目標。Application Auto Scaling 可擴展的機群執行個體數量下限為 1 個執行個體、上限為 20 個執行個體。該政策使機群的平均容量使用率保持在 75%，擴增和縮減的冷卻時間為 300 秒 (5 分鐘)。

其使用 `Fn::Join` 和 `Rev` 內建函數來建構 `ResourceId` 屬性，該屬性具有相同範本中指定的 `AWS::AppStream::Fleet` 資源的邏輯名稱。如需詳細資訊，請參閱[內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)。

### JSON
<a name="quickref-autoscaling-example-6.json"></a>

```
{
  "Resources" : {
    "ScalableTarget" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalableTarget",
      "Properties" : {
        "MaxCapacity" : 20,
        "MinCapacity" : 1,
        "RoleARN" : { "Fn::Sub" : "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/appstream.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_AppStreamFleet" },
        "ServiceNamespace" : "appstream",
        "ScalableDimension" : "appstream:fleet:DesiredCapacity",
        "ResourceId" : {
          "Fn::Join" : [
            "/",
            [
              "fleet",
              {
                "Ref" : "logicalName"
              }
            ]
          ]
        }
      }
    },
    "ScalingPolicyAppStreamFleet" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalingPolicy",
      "Properties" : {
        "PolicyName" : { "Fn::Sub" : "${AWS::StackName}-target-tracking-cpu75" },
        "PolicyType" : "TargetTrackingScaling",
        "ServiceNamespace" : "appstream",
        "ScalableDimension" : "appstream:fleet:DesiredCapacity",
        "ResourceId" : {
          "Fn::Join" : [
            "/",
            [
              "fleet",
              {
                "Ref" : "logicalName"
              }
            ]
          ]
        },
        "TargetTrackingScalingPolicyConfiguration" : {
          "TargetValue" : 75,
          "PredefinedMetricSpecification" : {
            "PredefinedMetricType" : "AppStreamAverageCapacityUtilization"
          },
          "ScaleInCooldown" : 300,
          "ScaleOutCooldown" : 300
        }
      }
    } 
  }
}
```

### YAML
<a name="quickref-autoscaling-example-6.yaml"></a>

```
---
Resources:
  ScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: 20
      MinCapacity: 1
      RoleARN: 
        Fn::Sub: 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/appstream.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_AppStreamFleet'
      ServiceNamespace: appstream
      ScalableDimension: appstream:fleet:DesiredCapacity
      ResourceId: !Join
        - /
        - - fleet
          - !Ref logicalName
  ScalingPolicyAppStreamFleet:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: !Sub ${AWS::StackName}-target-tracking-cpu75
      PolicyType: TargetTrackingScaling
      ServiceNamespace: appstream
      ScalableDimension: appstream:fleet:DesiredCapacity
      ResourceId: !Join
        - /
        - - fleet
          - !Ref logicalName
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: 75
        PredefinedMetricSpecification:
          PredefinedMetricType: AppStreamAverageCapacityUtilization
        ScaleInCooldown: 300
        ScaleOutCooldown: 300
```

## 建立 Aurora 資料庫叢集的擴展原則
<a name="w2aac11c41c15c19c11"></a>

在此程式碼片段中，您將註冊 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbcluster.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbcluster.html) 資源。[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html) 資源表明應該動態縮放資料庫叢集，使其具有 1 到 8 個 Aurora 複本。您也可使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalingpolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalingpolicy.html) 資源將目標追蹤擴展政策套用至叢集。

在此組態中，會使用 `RDSReaderAverageCPUUtilization` 這個預先定義的指標，根據 Aurora 資料庫叢集中所有 Aurora 複本平均 CPU 使用率百分之 40，來調整 Aurora 資料庫叢集。這個組態設定分別提供了 10 分鐘的規模縮減冷卻時間，和 5 分鐘的規模擴展冷卻時間。

此範例使用 `Fn::Sub` 內建函數來建構 `ResourceId` 屬性，該屬性具有相同範本中指定的 `AWS::RDS::DBCluster` 資源的邏輯名稱。如需詳細資訊，請參閱[內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)。

### JSON
<a name="quickref-autoscaling-example-7.json"></a>

```
{
  "Resources" : {
    "ScalableTarget" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalableTarget",
      "Properties" : {
        "MaxCapacity" : 8,
        "MinCapacity" : 1,
        "RoleARN" : { "Fn::Sub" : "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/rds.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_RDSCluster" },
        "ServiceNamespace" : "rds",
        "ScalableDimension" : "rds:cluster:ReadReplicaCount",
        "ResourceId" : { "Fn::Sub" : "cluster:${logicalName}" }
      }
    },
    "ScalingPolicyDBCluster" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalingPolicy",
      "Properties" : {
        "PolicyName" : { "Fn::Sub" : "${AWS::StackName}-target-tracking-cpu40" },
        "PolicyType" : "TargetTrackingScaling",
        "ServiceNamespace" : "rds",
        "ScalableDimension" : "rds:cluster:ReadReplicaCount",
        "ResourceId" : { "Fn::Sub" : "cluster:${logicalName}" }, 
        "TargetTrackingScalingPolicyConfiguration" : {
          "TargetValue" : 40,
          "PredefinedMetricSpecification" : {
            "PredefinedMetricType" : "RDSReaderAverageCPUUtilization"
          },
          "ScaleInCooldown" : 600,
          "ScaleOutCooldown" : 300
        }
      }
    }
  }
}
```

### YAML
<a name="quickref-autoscaling-example-7.yaml"></a>

```
---
Resources:
  ScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: 8
      MinCapacity: 1
      RoleARN: 
        Fn::Sub: 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/rds.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_RDSCluster'
      ServiceNamespace: rds
      ScalableDimension: rds:cluster:ReadReplicaCount
      ResourceId: !Sub cluster:${logicalName}
  ScalingPolicyDBCluster:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: !Sub ${AWS::StackName}-target-tracking-cpu40
      PolicyType: TargetTrackingScaling
      ServiceNamespace: rds
      ScalableDimension: rds:cluster:ReadReplicaCount
      ResourceId: !Sub cluster:${logicalName}
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: 40
        PredefinedMetricSpecification:
          PredefinedMetricType: RDSReaderAverageCPUUtilization
        ScaleInCooldown: 600
        ScaleOutCooldown: 300
```

## 建立 DynamoDB 資料表的擴展政策
<a name="w2aac11c41c15c19c13"></a>

此程式碼片段示範如何使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalingpolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalingpolicy.html) 資源建立 `TargetTrackingScaling` 政策類型的政策，並將其套用到 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-dynamodb-table.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-dynamodb-table.html) 資源。[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html) 資源會宣告要將此政策套用至哪個可擴展的目標，下限為五個寫入容量單位，上限為 15 個。此擴展政策會根據 `DynamoDBWriteCapacityUtilization` 預先定義指標擴展資料表的寫入容量輸送量，以將目標使用率維持在 50%。

其使用 `Fn::Join` 和 `Ref` 內建函數來建構 `ResourceId` 屬性，該屬性具有相同範本中指定的 `AWS::DynamoDB::Table` 資源的邏輯名稱。如需詳細資訊，請參閱[內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)。

**注意**  
如需如何建立 DynamoDB 資源 CloudFormation 範本的詳細資訊，請參閱 資料庫部落格上的部落格文章[如何使用 CloudFormation 設定 Amazon DynamoDB 資料表和索引的自動擴展](https://aws.amazon.com/blogs/database/how-to-use-aws-cloudformation-to-configure-auto-scaling-for-amazon-dynamodb-tables-and-indexes/) AWS 。

### JSON
<a name="quickref-autoscaling-example-8.json"></a>

```
{
  "Resources" : {
    "WriteCapacityScalableTarget" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalableTarget",
      "Properties" : {
        "MaxCapacity" : 15,
        "MinCapacity" : 5,
        "RoleARN" : { "Fn::Sub" : "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable" },
        "ServiceNamespace" : "dynamodb",
        "ScalableDimension" : "dynamodb:table:WriteCapacityUnits",
        "ResourceId" : {
          "Fn::Join" : [
            "/",
            [
              "table",
              {
                "Ref" : "logicalName"
              }
            ]
          ]
        }
      }
    },
    "WriteScalingPolicy" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalingPolicy",
      "Properties" : {
        "PolicyName" : "WriteScalingPolicy",
        "PolicyType" : "TargetTrackingScaling",
        "ScalingTargetId" : { "Ref" : "WriteCapacityScalableTarget" },
        "TargetTrackingScalingPolicyConfiguration" : {
          "TargetValue" : 50.0,
          "ScaleInCooldown" : 60,
          "ScaleOutCooldown" : 60,
          "PredefinedMetricSpecification" : {
            "PredefinedMetricType" : "DynamoDBWriteCapacityUtilization"
          }
        }
      }
    }
  }
}
```

### YAML
<a name="quickref-autoscaling-example-8.yaml"></a>

```
---
Resources:
  WriteCapacityScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: 15
      MinCapacity: 5
      RoleARN: 
        Fn::Sub: 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable'
      ServiceNamespace: dynamodb
      ScalableDimension: dynamodb:table:WriteCapacityUnits
      ResourceId: !Join
        - /
        - - table
          - !Ref logicalName
  WriteScalingPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: WriteScalingPolicy
      PolicyType: TargetTrackingScaling
      ScalingTargetId: !Ref WriteCapacityScalableTarget
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: 50.0
        ScaleInCooldown: 60
        ScaleOutCooldown: 60
        PredefinedMetricSpecification:
          PredefinedMetricType: DynamoDBWriteCapacityUtilization
```

## 建立 Amazon ECS 服務的擴展政策 (指標：平均 CPU 和記憶體)
<a name="w2aac11c41c15c19c15"></a>

此程式碼片段示範如何使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalingpolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalingpolicy.html) 資源建立政策，並將其套用到 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-service.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-service.html) 資源。[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html) 資源宣告將套用此政策的可擴展目標。Application Auto Scaling 可擴展的任務數量下限為 1 個任務、上限為 6 個任務。

這會建立兩個具有 `TargetTrackingScaling` 政策類型的擴展政策。這些政策用於根據服務的平均 CPU 和記憶體用量，以擴展 ECS 服務。其使用 `Fn::Join` 和 `Ref` 內建函數來建構 `ResourceId` 屬性，該屬性具有相同範本中指定的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-cluster.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ecs-cluster.html) (`myContainerCluster`) 和 `AWS::ECS::Service` (`myService`) 資源之邏輯名稱。如需詳細資訊，請參閱[內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)。

### JSON
<a name="quickref-autoscaling-example-9.json"></a>

```
{
  "Resources" : {
    "ECSScalableTarget" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalableTarget",
      "Properties" : {
        "MaxCapacity" : "6",
        "MinCapacity" : "1",
        "RoleARN" : { "Fn::Sub" : "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService" },
        "ServiceNamespace" : "ecs",
        "ScalableDimension" : "ecs:service:DesiredCount",
        "ResourceId" : {
          "Fn::Join" : [
            "/",
            [
              "service",
              {
                "Ref" : "myContainerCluster"
              },
              {
                "Fn::GetAtt" : [
                  "myService",
                  "Name"
                ]
              }
            ]
          ]
        }
      }
    },
    "ServiceScalingPolicyCPU" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalingPolicy",
      "Properties" : {
        "PolicyName" : { "Fn::Sub" : "${AWS::StackName}-target-tracking-cpu70" },
        "PolicyType" : "TargetTrackingScaling",
        "ScalingTargetId" : { "Ref" : "ECSScalableTarget" },
        "TargetTrackingScalingPolicyConfiguration" : {
          "TargetValue" : 70.0,
          "ScaleInCooldown" : 180,
          "ScaleOutCooldown" : 60,
          "PredefinedMetricSpecification" : {
            "PredefinedMetricType" : "ECSServiceAverageCPUUtilization"
          }
        }
      }
    },
    "ServiceScalingPolicyMem" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalingPolicy",
      "Properties" : {
        "PolicyName" : { "Fn::Sub" : "${AWS::StackName}-target-tracking-mem90" },
        "PolicyType" : "TargetTrackingScaling",
        "ScalingTargetId" : { "Ref" : "ECSScalableTarget" },
        "TargetTrackingScalingPolicyConfiguration" : {
          "TargetValue" : 90.0,
          "ScaleInCooldown" : 180,
          "ScaleOutCooldown" : 60,
          "PredefinedMetricSpecification" : {
            "PredefinedMetricType" : "ECSServiceAverageMemoryUtilization"
          }
        }
      }
    }
  }
}
```

### YAML
<a name="quickref-autoscaling-example-9.yaml"></a>

```
---
Resources:
  ECSScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: 6
      MinCapacity: 1  
      RoleARN: 
        Fn::Sub: 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService'
      ServiceNamespace: ecs
      ScalableDimension: 'ecs:service:DesiredCount'
      ResourceId: !Join 
        - /
        - - service
          - !Ref myContainerCluster
          - !GetAtt myService.Name
  ServiceScalingPolicyCPU:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: !Sub ${AWS::StackName}-target-tracking-cpu70
      PolicyType: TargetTrackingScaling
      ScalingTargetId: !Ref ECSScalableTarget
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: 70.0
        ScaleInCooldown: 180
        ScaleOutCooldown: 60
        PredefinedMetricSpecification:
          PredefinedMetricType: ECSServiceAverageCPUUtilization
  ServiceScalingPolicyMem:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: !Sub ${AWS::StackName}-target-tracking-mem90
      PolicyType: TargetTrackingScaling
      ScalingTargetId: !Ref ECSScalableTarget
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: 90.0
        ScaleInCooldown: 180
        ScaleOutCooldown: 60
        PredefinedMetricSpecification:
          PredefinedMetricType: ECSServiceAverageMemoryUtilization
```

## 建立 Amazon ECS 服務的擴展政策 (指標：每個目標的平均請求計數)
<a name="w2aac11c41c15c19c17"></a>

下列範例會將具有 `ALBRequestCountPerTarget` 預先定義指標的目標追蹤擴展政策套用至 ECS 服務。當每一目標 (每分鐘) 的請求計數超過目標值時，此政策會新增 ECS 服務的容量。因為 `DisableScaleIn` 的值設為 `true`，所以目標追蹤政策不會從可擴展的目標移除容量。

其使用 `Fn::Join` 和 `Fn::GetAtt` 內建函數來建構 `ResourceLabel` 屬性，該屬性具有相同範本中指定的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-loadbalancer.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-loadbalancer.html) (`myLoadBalancer`) 和 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) (`myTargetGroup`) 資源之邏輯名稱。如需詳細資訊，請參閱[內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)。

可擴展目標的 `MaxCapacity` 和 `MinCapacity` 屬性和擴展政策的 `TargetValue` 屬性會參考建立或更新堆疊時傳遞至範本的參數值。

### JSON
<a name="quickref-autoscaling-example-10.json"></a>

```
{
  "Resources" : {
    "ECSScalableTarget" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalableTarget",
      "Properties" : {
        "MaxCapacity" : { "Ref" : "MaxCount" },
        "MinCapacity" : { "Ref" : "MinCount" },
        "RoleARN" : { "Fn::Sub" : "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService" },
        "ServiceNamespace" : "ecs",
        "ScalableDimension" : "ecs:service:DesiredCount",
        "ResourceId" : {
          "Fn::Join" : [
            "/",
            [
              "service",
              {
                "Ref" : "myContainerCluster"
              },
              {
                "Fn::GetAtt" : [
                  "myService",
                  "Name"
                ]
              }
            ]
          ]
        }
      }
    },
    "ServiceScalingPolicyALB" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalingPolicy",
      "Properties" : {
        "PolicyName" : "alb-requests-per-target-per-minute",
        "PolicyType" : "TargetTrackingScaling",
        "ScalingTargetId" : { "Ref" : "ECSScalableTarget" },
        "TargetTrackingScalingPolicyConfiguration" : {
          "TargetValue" : { "Ref" : "ALBPolicyTargetValue" },
          "ScaleInCooldown" : 180,
          "ScaleOutCooldown" : 30,
          "DisableScaleIn" : true,
          "PredefinedMetricSpecification" : {
            "PredefinedMetricType" : "ALBRequestCountPerTarget",
            "ResourceLabel" : {
              "Fn::Join" : [
                "/",
                [
                  {
                    "Fn::GetAtt" : [
                      "myLoadBalancer",
                      "LoadBalancerFullName"
                    ]
                  },
                  {
                    "Fn::GetAtt" : [
                      "myTargetGroup",
                      "TargetGroupFullName"
                    ]
                  }
                ]
              ]
            }
          }
        }
      }
    }
  }
}
```

### YAML
<a name="quickref-autoscaling-example-10.yaml"></a>

```
---
Resources:
  ECSScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: !Ref MaxCount
      MinCapacity: !Ref MinCount  
      RoleARN: 
        Fn::Sub: 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService'
      ServiceNamespace: ecs
      ScalableDimension: 'ecs:service:DesiredCount'
      ResourceId: !Join 
        - /
        - - service
          - !Ref myContainerCluster
          - !GetAtt myService.Name
  ServiceScalingPolicyALB:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: alb-requests-per-target-per-minute
      PolicyType: TargetTrackingScaling
      ScalingTargetId: !Ref ECSScalableTarget
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: !Ref ALBPolicyTargetValue
        ScaleInCooldown: 180
        ScaleOutCooldown: 30
        DisableScaleIn: true
        PredefinedMetricSpecification:
          PredefinedMetricType: ALBRequestCountPerTarget
          ResourceLabel: !Join 
            - '/' 
            - - !GetAtt myLoadBalancer.LoadBalancerFullName
              - !GetAtt myTargetGroup.TargetGroupFullName
```

## 使用 Cron 表達式建立 Lambda 函式的排程動作
<a name="w2aac11c41c15c19c19"></a>

此程式碼片段會使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html) 資源，為名為 `BLUE` 的函數別名 ([https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-alias.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-alias.html)) 註冊佈建並行。還建立排程動作，並使用 Cron 運算式設定重複排程。重複排程的時區為 UTC。

它會使用 `RoleARN` 屬性中的 `Fn::Join` 與 `Ref` 內建函數來指定服務連結角色的 ARN。其使用 `Fn::Sub` 內建函數來建構 `ResourceId` 屬性，該屬性具有相同範本中指定的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) 或 [https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) 資源的邏輯名稱。如需詳細資訊，請參閱[內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)。

**注意**  
您無法在指向未發佈版本 (`$LATEST`) 的別名上配置佈建並行。  
如需如何建立 Lambda 資源 CloudFormation 範本的詳細資訊，請參閱 AWS 運算部落格上的[部落格文章排程 AWS Lambda 佈建並行的週期性尖峰用量](https://aws.amazon.com/blogs/compute/scheduling-aws-lambda-provisioned-concurrency-for-recurring-peak-usage/)。

### JSON
<a name="quickref-autoscaling-example-11.json"></a>

```
{
  "ScalableTarget" : {
    "Type" : "AWS::ApplicationAutoScaling::ScalableTarget",
    "Properties" : {
      "MaxCapacity" : 250,
      "MinCapacity" : 0,
      "RoleARN" : {
        "Fn::Join" : [
          ":",
          [
            "arn:aws:iam:",
            {
              "Ref" : "AWS::AccountId"
            },
            "role/aws-service-role/lambda.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_LambdaConcurrency"
          ]
        ]
      },
      "ServiceNamespace" : "lambda",
      "ScalableDimension" : "lambda:function:ProvisionedConcurrency",
      "ResourceId" : { "Fn::Sub" : "function:${logicalName}:BLUE" },
      "ScheduledActions" : [
        {
          "ScalableTargetAction" : {
            "MinCapacity" : "250"
          },
          "ScheduledActionName" : "my-scale-out-scheduled-action",
          "Schedule" : "cron(0 18 * * ? *)",
          "EndTime" : "2022-12-31T12:00:00.000Z"
        }
      ]
    }
  }
}
```

### YAML
<a name="quickref-autoscaling-example-11.yaml"></a>

```
ScalableTarget:
  Type: AWS::ApplicationAutoScaling::ScalableTarget
  Properties:
    MaxCapacity: 250
    MinCapacity: 0
    RoleARN: !Join 
      - ':'
      - - 'arn:aws:iam:'
        - !Ref 'AWS::AccountId'
        - role/aws-service-role/lambda.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_LambdaConcurrency
    ServiceNamespace: lambda
    ScalableDimension: lambda:function:ProvisionedConcurrency
    ResourceId: !Sub function:${logicalName}:BLUE
    ScheduledActions:
      - ScalableTargetAction:
          MinCapacity: 250
        ScheduledActionName: my-scale-out-scheduled-action
        Schedule: 'cron(0 18 * * ? *)'
        EndTime: '2022-12-31T12:00:00.000Z'
```

## 使用 `at` 表達式建立 Spot 機群的排程動作
<a name="w2aac11c41c15c19c21"></a>

此程式碼片段示範如何使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-applicationautoscaling-scalabletarget.html) 資源，為 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-spotfleet.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-spotfleet.html) 資源建立僅發生一次的兩個排程動作。每個一次性排程動作的時區都是 UTC。

其使用 `Fn::Join` 和 `Ref` 內建函數來建構 `ResourceId` 屬性，該屬性具有相同範本中指定的 `AWS::EC2::SpotFleet` 資源的邏輯名稱。如需詳細資訊，請參閱[內建函數參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)。

**注意**  
Spot 機群請求必須具有 `maintain` 的請求類型。一次性請求或 Spot 區塊不支援自動擴展功能。

### JSON
<a name="quickref-autoscaling-example-12.json"></a>

```
{
  "Resources" : {
    "SpotFleetScalableTarget" : {
      "Type" : "AWS::ApplicationAutoScaling::ScalableTarget",
      "Properties" : {
        "MaxCapacity" : 0,
        "MinCapacity" : 0,
        "RoleARN" : { "Fn::Sub" : "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ec2.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_EC2SpotFleetRequest" },
        "ServiceNamespace" : "ec2",
        "ScalableDimension" : "ec2:spot-fleet-request:TargetCapacity",
        "ResourceId" : {
          "Fn::Join" : [
            "/",
            [
              "spot-fleet-request",
              {
                "Ref" : "logicalName"
              }
            ]
          ]
        },
        "ScheduledActions" : [
          {
            "ScalableTargetAction" : {
              "MaxCapacity" : "10",
              "MinCapacity" : "10"
            },
            "ScheduledActionName" : "my-scale-out-scheduled-action",
            "Schedule" : "at(2022-05-20T13:00:00)"
          },
          {
            "ScalableTargetAction" : {
              "MaxCapacity" : "0",
              "MinCapacity" : "0"
            },
            "ScheduledActionName" : "my-scale-in-scheduled-action",
            "Schedule" : "at(2022-05-20T21:00:00)"
          }
        ]
      }
    }
  }
}
```

### YAML
<a name="quickref-autoscaling-example-12.yaml"></a>

```
---
Resources:
  SpotFleetScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: 0
      MinCapacity: 0
      RoleARN: 
        Fn::Sub: 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ec2.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_EC2SpotFleetRequest'
      ServiceNamespace: ec2
      ScalableDimension: 'ec2:spot-fleet-request:TargetCapacity'
      ResourceId: !Join 
        - /
        - - spot-fleet-request
          - !Ref logicalName
      ScheduledActions:
        - ScalableTargetAction:
            MaxCapacity: 10
            MinCapacity: 10
          ScheduledActionName: my-scale-out-scheduled-action
          Schedule: 'at(2022-05-20T13:00:00)'
        - ScalableTargetAction:
            MaxCapacity: 0
            MinCapacity: 0
          ScheduledActionName: my-scale-in-scheduled-action
          Schedule: 'at(2022-05-20T21:00:00)'
```

# AWS 帳單主控台範本程式碼片段
<a name="quickref-billingconductor"></a>

此範例會建立一個包含 10% 全域標記定價規則的定價計劃。此定價計劃會連接至帳單群組。此帳單群組也有兩個自訂明細項目，在帳單群組總成本之上收取 10 美元的費用和 10% 的費用。

## JSON
<a name="quickref-billingconductor-example-1.json"></a>

```
 1. {
 2.    "Parameters": {
 3.       "LinkedAccountIds": {
 4.          "Type": "ListNumber"
 5.       },
 6.       "PrimaryAccountId": {
 7.          "Type": "Number"
 8.       }
 9.    },
10.    "Resources": {
11.       "TestPricingRule": {
12.          "Type": "AWS::BillingConductor::PricingRule",
13.          "Properties": {
14.             "Name": "TestPricingRule",
15.             "Description": "Test pricing rule created through Cloudformation. Mark everything by 10%.",
16.             "Type": "MARKUP",
17.             "Scope": "GLOBAL",
18.             "ModifierPercentage": 10
19.          }
20.       },
21.       "TestPricingPlan": {
22.          "Type": "AWS::BillingConductor::PricingPlan",
23.          "Properties": {
24.             "Name": "TestPricingPlan",
25.             "Description": "Test pricing plan created through Cloudformation.",
26.             "PricingRuleArns": [
27.                {"Fn::GetAtt": ["TestPricingRule", "Arn"]}
28.             ]
29.          }
30.       },
31.       "TestBillingGroup": {
32.          "Type": "AWS::BillingConductor::BillingGroup",
33.          "Properties": {
34.             "Name": "TestBillingGroup",
35.             "Description": "Test billing group created through Cloudformation with 1 linked account. The linked account is also the primary account.",
36.             "PrimaryAccountId": {
37.                "Ref": "PrimaryAccountId"
38.             },
39.             "AccountGrouping": {
40.                "LinkedAccountIds": null
41.             },
42.             "ComputationPreference": {
43.                "PricingPlanArn": {
44.                  "Fn::GetAtt": ["TestPricingPlan", "Arn"]
45.                }
46.             }
47.          }
48.       },
49.       "TestFlatCustomLineItem": {
50.          "Type": "AWS::BillingConductor::CustomLineItem",
51.          "Properties": {
52.             "Name": "TestFlatCustomLineItem",
53.             "Description": "Test flat custom line item created through Cloudformation for a $10 charge.",
54.             "BillingGroupArn": {
55.               "Fn::GetAtt": ["TestBillingGroup", "Arn"]
56.             },
57.             "CustomLineItemChargeDetails": {
58.                "Flat": {
59.                   "ChargeValue": 10
60.                },
61.                "Type": "FEE"
62.             }
63.          }
64.       },
65.       "TestPercentageCustomLineItem": {
66.          "Type": "AWS::BillingConductor::CustomLineItem",
67.          "Properties": {
68.             "Name": "TestPercentageCustomLineItem",
69.             "Description": "Test percentage custom line item created through Cloudformation for a %10 additional charge on the overall total bill of the billing group.",
70.             "BillingGroupArn": {
71.               "Fn::GetAtt": ["TestBillingGroup", "Arn"]
72.             },
73.             "CustomLineItemChargeDetails": {
74.                "Percentage": {
75.                   "PercentageValue": 10,
76.                   "ChildAssociatedResources": [
77.                      {"Fn::GetAtt": ["TestBillingGroup", "Arn"]}
78.                   ]
79.                },
80.                "Type": "FEE"
81.             }
82.          }
83.       }
84.    }
85. }
```

## YAML
<a name="quickref-billingconductor-example-1.yaml"></a>

```
 1. Parameters:
 2.   LinkedAccountIds:
 3.     Type: ListNumber
 4.   PrimaryAccountId:
 5.     Type: Number
 6. Resources:
 7.   TestPricingRule:
 8.     Type: AWS::BillingConductor::PricingRule
 9.     Properties:
10.       Name: 'TestPricingRule'
11.       Description: 'Test pricing rule created through Cloudformation. Mark everything by 10%.'
12.       Type: 'MARKUP'
13.       Scope: 'GLOBAL'
14.       ModifierPercentage: 10
15.   TestPricingPlan:
16.     Type: AWS::BillingConductor::PricingPlan
17.     Properties:
18.       Name: 'TestPricingPlan'
19.       Description: 'Test pricing plan created through Cloudformation.'
20.       PricingRuleArns:
21.         - !GetAtt TestPricingRule.Arn
22.   TestBillingGroup:
23.     Type: AWS::BillingConductor::BillingGroup
24.     Properties:
25.       Name: 'TestBillingGroup'
26.       Description: 'Test billing group created through Cloudformation with 1 linked account. The linked account is also the primary account.'
27.       PrimaryAccountId: !Ref PrimaryAccountId
28.       AccountGrouping:
29.         LinkedAccountIds: !Ref LinkedAccountIds
30.       ComputationPreference:
31.         PricingPlanArn: !GetAtt TestPricingPlan.Arn
32.   TestFlatCustomLineItem:
33.     Type: AWS::BillingConductor::CustomLineItem
34.     Properties:
35.       Name: 'TestFlatCustomLineItem'
36.       Description: 'Test flat custom line item created through Cloudformation for a $10 charge.'
37.       BillingGroupArn: !GetAtt TestBillingGroup.Arn
38.       CustomLineItemChargeDetails:
39.         Flat:
40.           ChargeValue: 10
41.         Type: 'FEE'
42.   TestPercentageCustomLineItem:
43.     Type: AWS::BillingConductor::CustomLineItem
44.     Properties:
45.       Name: 'TestPercentageCustomLineItem'
46.       Description: 'Test percentage custom line item created through Cloudformation for a %10 additional charge on the overall total bill of the billing group.'
47.       BillingGroupArn: !GetAtt TestBillingGroup.Arn
48.       CustomLineItemChargeDetails:
49.         Percentage:
50.           PercentageValue: 10
51.           ChildAssociatedResources:
52.             - !GetAtt TestBillingGroup.Arn
53.         Type: 'FEE'
```

# CloudFormation 範本程式碼片段
<a name="quickref-cloudformation"></a>

**Topics**
+ [巢狀堆疊](#w2aac11c41c23b5)
+ [等待條件](#w2aac11c41c23b7)

## 巢狀堆疊
<a name="w2aac11c41c23b5"></a>

### 在範本中建立巢狀堆疊
<a name="scenario-stack"></a>

本範例範本中包含名稱為 `myStack` 的巢狀堆疊資源；當 從範本 CloudFormation 建立堆疊時，它會建立 `myStack`，其範本是在 `TemplateURL` 屬性中指定。輸出值 `StackRef` 會傳回 `myStack` 的堆疊 ID，值 `OutputFromNestedStack` 則會從 `myStack` 資源中傳回輸出值 `BucketName`。保留 `Outputs.nestedstackoutputname` 格式以供您指定巢狀堆疊中的輸出值，且隨時隨地都能在涵蓋範本中使用該格式。

如需詳細資訊，請參閱[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-stack.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-stack.html)。

#### JSON
<a name="quickref-cloudformation-example-1.json"></a>

```
 1. {
 2.     "AWSTemplateFormatVersion" : "2010-09-09",
 3.     "Resources" : {
 4.         "myStack" : {
 5. 	       "Type" : "AWS::CloudFormation::Stack",
 6. 	       "Properties" : {
 7. 	        "TemplateURL" : "https://s3.amazonaws.com/cloudformation-templates-us-east-1/S3_Bucket.template",
 8.               "TimeoutInMinutes" : "60"
 9. 	       }
10.         }
11.     },
12.     "Outputs": {
13.        "StackRef": {"Value": { "Ref" : "myStack"}},
14.        "OutputFromNestedStack" : {
15.              "Value" : { "Fn::GetAtt" : [ "myStack", "Outputs.BucketName" ] }
16.        }
17.     }
18. }
```

#### YAML
<a name="quickref-cloudformation-example-1.yaml"></a>

```
 1. AWSTemplateFormatVersion: '2010-09-09'
 2. Resources:
 3.   myStack:
 4.     Type: AWS::CloudFormation::Stack
 5.     Properties:
 6.       TemplateURL: https://s3.amazonaws.com/cloudformation-templates-us-east-1/S3_Bucket.template
 7.       TimeoutInMinutes: '60'
 8. Outputs:
 9.   StackRef:
10.     Value: !Ref myStack
11.   OutputFromNestedStack:
12.     Value: !GetAtt myStack.Outputs.BucketName
```

### 在範本中使用輸入參數建立巢狀堆疊
<a name="scenario-stack-parameters"></a>

本範例範本所包含的堆疊資源會指定輸入參數；當 從此範本 CloudFormation 建立堆疊時，它會使用 `Parameters` 屬性中宣告的值對，做為用於建立`myStackWithParams`堆疊之範本的輸入參數。本範例指定的參數為 `InstanceType` 與 `KeyName`。

如需詳細資訊，請參閱[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-stack.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-stack.html)。

#### JSON
<a name="quickref-cloudformation-example-2.json"></a>

```
 1. {
 2.     "AWSTemplateFormatVersion" : "2010-09-09",
 3.     "Resources" : {
 4.         "myStackWithParams" : {
 5.   	       "Type" : "AWS::CloudFormation::Stack",
 6. 	       "Properties" : {
 7. 	           "TemplateURL" : "https://s3.amazonaws.com/cloudformation-templates-us-east-1/EC2ChooseAMI.template",
 8. 	           "Parameters" : {
 9. 	               "InstanceType" : "t2.micro",
10. 	               "KeyName" : "mykey"
11. 	           }
12.    	       }
13.         }
14.     }
15. }
```

#### YAML
<a name="quickref-cloudformation-example-2.yaml"></a>

```
1. AWSTemplateFormatVersion: '2010-09-09'
2. Resources:
3.   myStackWithParams:
4.     Type: AWS::CloudFormation::Stack
5.     Properties:
6.       TemplateURL: https://s3.amazonaws.com/cloudformation-templates-us-east-1/EC2ChooseAMI.template
7.       Parameters:
8.         InstanceType: t2.micro
9.         KeyName: mykey
```

## 等待條件
<a name="w2aac11c41c23b7"></a>

### 使用 Amazon EC2 執行個體的等待條件
<a name="scenario-waitcondition"></a>

**重要**  
針對 Amazon EC2 和 Auto Scaling 資源，我們建議您使用 CreationPolicy 屬性，而非等待條件。請將 CreationPolicy 屬性新增至這類資源，並使用 cfn-signal 的 helper 指令碼在執行個體建立流程成功完成後發出訊號。

如果您無法使用建立政策，請檢視以下宣告 Amazon EC2 執行個體等待條件的範例範本。`myWaitCondition` 等待條件會使用 `myWaitConditionHandle` 來發送訊號，並使用 `DependsOn` 屬性來指定 Amazon EC2 執行個體資源成功建立後，系統會觸發的等待條件；其亦會採用 `Timeout` 屬性將等待條件的持續期間指定為 4500 秒。此外，系統會透過 `Ec2Instance` 資源的 `UserData` 屬性，將發出等待條件訊號的預先簽章之 URL 傳遞至 Amazon EC2 執行個體，因此該 Amazon EC2 執行個體上執行的應用程式或指令碼皆可擷取預先簽章的 URL，並使用此 URL 發出等待條件的成功或失敗訊號。您需要使用 `cfn-signal`，或您所建立的應用程式或指令碼必須能發出等待條件訊號。而輸出值 `ApplicationData` 將包含等待條件訊號傳回的資料。

如需詳細資訊，請參閱[在 CloudFormation 範本中建立等待條件](using-cfn-waitcondition.md)。

#### JSON
<a name="quickref-cloudformation-example-3.json"></a>

```
 1. {
 2.     "AWSTemplateFormatVersion" : "2010-09-09",
 3.     "Mappings" : {
 4.         "RegionMap" : {
 5.             "us-east-1" : {
 6.                 "AMI" : "ami-0123456789abcdef0"
 7.             },
 8.             "us-west-1" : {
 9.                 "AMI" : "ami-0987654321fedcba0"
10.             },
11.             "eu-west-1" : {
12.                 "AMI" : "ami-0abcdef123456789a"
13.             },
14.             "ap-northeast-1" : {
15.                 "AMI" : "ami-0fedcba987654321b"
16.             },
17.             "ap-southeast-1" : {
18.                 "AMI" : "ami-0c1d2e3f4a5b6c7d8"
19.             }
20.         }
21.     },
22.     "Resources" : {
23.         "Ec2Instance" : {
24.             "Type" : "AWS::EC2::Instance",
25.             "Properties" : {
26.                 "UserData" : { "Fn::Base64" : {"Ref" : "myWaitHandle"}},
27.                 "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}
28.             }
29.         },
30.         "myWaitHandle" : {
31.             "Type" : "AWS::CloudFormation::WaitConditionHandle",
32.             "Properties" : {
33.             }
34.         },
35.         "myWaitCondition" : {
36.             "Type" : "AWS::CloudFormation::WaitCondition",
37.             "DependsOn" : "Ec2Instance",
38.             "Properties" : {
39.                 "Handle" : { "Ref" : "myWaitHandle" },
40.                 "Timeout" : "4500"
41.             }
42.         }
43.     },
44.     "Outputs" : {
45.         "ApplicationData" : {
46.             "Value" : { "Fn::GetAtt" : [ "myWaitCondition", "Data" ]},
47.             "Description" : "The data passed back as part of signalling the WaitCondition."
48.         }
49.     }
50. }
```

#### YAML
<a name="quickref-cloudformation-example-3.yaml"></a>

```
 1. AWSTemplateFormatVersion: '2010-09-09'
 2. Mappings:
 3.   RegionMap:
 4.     us-east-1:
 5.       AMI: ami-0123456789abcdef0
 6.     us-west-1:
 7.       AMI: ami-0987654321fedcba0
 8.     eu-west-1:
 9.       AMI: ami-0abcdef123456789a
10.     ap-northeast-1:
11.       AMI: ami-0fedcba987654321b
12.     ap-southeast-1:
13.       AMI: ami-0c1d2e3f4a5b6c7d8
14. Resources:
15.   Ec2Instance:
16.     Type: AWS::EC2::Instance
17.     Properties:
18.       UserData:
19.         Fn::Base64: !Ref myWaitHandle
20.       ImageId:
21.         Fn::FindInMap:
22.         - RegionMap
23.         - Ref: AWS::Region
24.         - AMI
25.   myWaitHandle:
26.     Type: AWS::CloudFormation::WaitConditionHandle
27.     Properties: {}
28.   myWaitCondition:
29.     Type: AWS::CloudFormation::WaitCondition
30.     DependsOn: Ec2Instance
31.     Properties:
32.       Handle: !Ref myWaitHandle
33.       Timeout: '4500'
34. Outputs:
35.   ApplicationData:
36.     Value: !GetAtt myWaitCondition.Data
37.     Description: The data passed back as part of signalling the WaitCondition.
```

### 使用 cfn-signal 協助程式指令碼發出等待條件訊號
<a name="scenario-waitcondition-cfn-signal"></a>

本範例所顯示的 `cfn-signal` 命令列會發出等待條件的成功訊號。您需要在 EC2 執行個體的 `UserData` 屬性中定義命令列。

#### JSON
<a name="w2aac11c41c23b7b4b4"></a>

```
"UserData": {
  "Fn::Base64": {
    "Fn::Join": [
      "", 
      [
         "#!/bin/bash -xe\n",
         "/opt/aws/bin/cfn-signal --exit-code 0 '", 
         {
           "Ref": "myWaitHandle"
         },
         "'\n"
      ]   
    ]
  }
}
```

#### YAML
<a name="w2aac11c41c23b7b4b6"></a>

```
UserData:
  Fn::Base64: !Sub |
    #!/bin/bash -xe
    /opt/aws/bin/cfn-signal --exit-code 0 '${myWaitHandle}'
```

### 使用 Curl 發出等待條件訊號
<a name="scenario-waitcondition-curl"></a>

本範例所顯示的 Curl 命令列會發出等待條件的成功訊號。

```
1. curl -T /tmp/a "https://cloudformation-waitcondition-test.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A034017226601%3Astack%2Fstack-gosar-20110427004224-test-stack-with-WaitCondition--VEYW%2Fe498ce60-70a1-11e0-81a7-5081d0136786%2FmyWaitConditionHandle?Expires=1303976584&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=ik1twT6hpS4cgNAw7wyOoRejVoo%3D"
```

其中 /tmp/a 檔案包含下列 JSON 結構：

```
1. {
2.   "Status" : "SUCCESS",
3.   "Reason" : "Configuration Complete",
4.   "UniqueId" : "ID1234",
5.   "Data" : "Application has completed configuration."
6. }
```

本範例所顯示的 Curl 命令列將傳送相同的成功訊號，但會傳送 JSON 作為命令列中的參數。

```
1. curl -X PUT -H 'Content-Type:' --data-binary '{"Status" : "SUCCESS","Reason" : "Configuration Complete","UniqueId" : "ID1234","Data" : "Application has completed configuration."}' "https://cloudformation-waitcondition-test.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A034017226601%3Astack%2Fstack-gosar-20110427004224-test-stack-with-WaitCondition--VEYW%2Fe498ce60-70a1-11e0-81a7-5081d0136786%2FmyWaitConditionHandle?Expires=1303976584&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=ik1twT6hpS4cgNAw7wyOoRejVoo%3D"
```

# Amazon CloudFront 範本程式碼片段
<a name="quickref-cloudfront"></a>

在 CloudFormation中將這些範例範本程式碼片段與 Amazon CloudFront 分佈資源搭配使用。如需詳細資訊，請參閱 [Amazon CloudFront 資源類型參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/AWS_CloudFront.html)。

**Topics**
+ [具有 Amazon S3 來源的 Amazon CloudFront 分佈資源](#scenario-cloudfront-s3origin)
+ [Amazon CloudFront 分佈資源與自訂原始伺服器](#scenario-cloudfront-customorigin)
+ [Amazon CloudFront 分佈與多重原始伺服器支援](#scenario-cloudfront-multiorigin)
+ [以 Lambda 函式做為原始伺服器的 Amazon CloudFront 分佈](#scenario-cloudfront-lambda-origin)
+ [另請參閱](#w2aac11c41c27c15)

## 具有 Amazon S3 來源的 Amazon CloudFront 分佈資源
<a name="scenario-cloudfront-s3origin"></a>

以下範例範本顯示使用 [S3Origin](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-cloudfront-distribution-s3originconfig.html) 和[舊版原始存取身分 (OAI) 的 Amazon CloudFront 分佈](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudfront-distribution.html)。如需關於使用原始伺服器存取控制 (OAC) 的詳細資訊，請參閱《*Amazon CloudFront 開發人員指南*》中的[限制對 Amazon Simple Storage Service 原始伺服器的存取](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html)。

### JSON
<a name="quickref-cloudfront-example-1.json"></a>

```
 1. {
 2.     "AWSTemplateFormatVersion" : "2010-09-09",
 3.     "Resources" : {
 4.         "myDistribution" : {
 5.             "Type" : "AWS::CloudFront::Distribution",
 6.             "Properties" : {
 7.                 "DistributionConfig" : {
 8.                     "Origins" : [ {
 9.                         "DomainName" : "amzn-s3-demo-bucket.s3.amazonaws.com",
10.                         "Id" : "myS3Origin",
11.                         "S3OriginConfig" : {
12.                             "OriginAccessIdentity" : "origin-access-identity/cloudfront/E127EXAMPLE51Z"
13.                         }
14.                     }],
15.                     "Enabled" : "true",
16.                     "Comment" : "Some comment",
17.                     "DefaultRootObject" : "index.html",
18.                     "Logging" : {
19.                         "IncludeCookies" : "false",
20.                         "Bucket" : "amzn-s3-demo-logging-bucket.s3.amazonaws.com",
21.                         "Prefix" : "myprefix"
22.                     },
23.                     "Aliases" : [ "mysite.example.com", "yoursite.example.com" ],
24.                     "DefaultCacheBehavior" : {
25.                         "AllowedMethods" : [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ],  
26.                         "TargetOriginId" : "myS3Origin",
27.                         "ForwardedValues" : {
28.                             "QueryString" : "false",
29.                             "Cookies" : { "Forward" : "none" }
30.                         },
31.                         "TrustedSigners" : [ "1234567890EX", "1234567891EX" ],
32.                         "ViewerProtocolPolicy" : "allow-all"
33.                     },
34.                    "PriceClass" : "PriceClass_200",
35.                    "Restrictions" : {
36.                        "GeoRestriction" : {
37.                            "RestrictionType" : "whitelist",
38.                            "Locations" : [ "AQ", "CV" ]
39.                        }
40.                    },
41.                    "ViewerCertificate" : { "CloudFrontDefaultCertificate" : "true" }  
42.                 }
43.             }
44.         }
45.     }
46. }
```

### YAML
<a name="quickref-cloudfront-example-1.yaml"></a>

```
 1. AWSTemplateFormatVersion: '2010-09-09'
 2. Resources:
 3.   myDistribution:
 4.     Type: AWS::CloudFront::Distribution
 5.     Properties:
 6.       DistributionConfig:
 7.         Origins:
 8.         - DomainName: amzn-s3-demo-bucket.s3.amazonaws.com
 9.           Id: myS3Origin
10.           S3OriginConfig:
11.             OriginAccessIdentity: origin-access-identity/cloudfront/E127EXAMPLE51Z
12.         Enabled: 'true'
13.         Comment: Some comment
14.         DefaultRootObject: index.html
15.         Logging:
16.           IncludeCookies: 'false'
17.           Bucket: amzn-s3-demo-logging-bucket.s3.amazonaws.com
18.           Prefix: myprefix
19.         Aliases:
20.         - mysite.example.com
21.         - yoursite.example.com
22.         DefaultCacheBehavior:
23.           AllowedMethods:
24.           - DELETE
25.           - GET
26.           - HEAD
27.           - OPTIONS
28.           - PATCH
29.           - POST
30.           - PUT
31.           TargetOriginId: myS3Origin
32.           ForwardedValues:
33.             QueryString: 'false'
34.             Cookies:
35.               Forward: none
36.           TrustedSigners:
37.           - 1234567890EX
38.           - 1234567891EX
39.           ViewerProtocolPolicy: allow-all
40.         PriceClass: PriceClass_200
41.         Restrictions:
42.           GeoRestriction:
43.             RestrictionType: whitelist
44.             Locations:
45.             - AQ
46.             - CV
47.         ViewerCertificate:
48.           CloudFrontDefaultCertificate: 'true'
```

## Amazon CloudFront 分佈資源與自訂原始伺服器
<a name="scenario-cloudfront-customorigin"></a>

以下範例範本顯示使用 [CustomOrigin](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-cloudfront-distribution-customoriginconfig.html) 的 Amazon CloudFront [分佈](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudfront-distribution.html)。

### JSON
<a name="quickref-cloudfront-example-2.json"></a>

```
 1. {
 2.     "AWSTemplateFormatVersion" : "2010-09-09",
 3.     "Resources" : {
 4.         "myDistribution" : {
 5.             "Type" : "AWS::CloudFront::Distribution",
 6.             "Properties" : {
 7.                 "DistributionConfig" : {
 8.                     "Origins" : [ {
 9.                             "DomainName" : "www.example.com",
10.                             "Id" : "myCustomOrigin",
11.                             "CustomOriginConfig" : {
12.                                 "HTTPPort" : "80",
13.                                 "HTTPSPort" : "443",
14.                                 "OriginProtocolPolicy" : "http-only"
15.                             }
16.                     } ],
17.                     "Enabled" : "true",
18.                     "Comment" : "Somecomment",
19.                     "DefaultRootObject" : "index.html",
20.                     "Logging" : {
21.                         "IncludeCookies" : "true",
22.                         "Bucket" : "amzn-s3-demo-logging-bucket.s3.amazonaws.com",
23.                         "Prefix": "myprefix"
24.                     },
25.                     "Aliases" : [
26.                         "mysite.example.com",
27.                         "*.yoursite.example.com"
28.                     ],
29.                     "DefaultCacheBehavior" : {
30.                         "TargetOriginId" : "myCustomOrigin",
31.                         "SmoothStreaming" : "false",  
32.                         "ForwardedValues" : {
33.                             "QueryString" : "false",
34.                             "Cookies" : { "Forward" : "all" }
35.                         },
36.                         "TrustedSigners" : [
37.                             "1234567890EX",
38.                             "1234567891EX"
39.                         ],
40.                         "ViewerProtocolPolicy" : "allow-all"
41.                     },
42.                     "CustomErrorResponses" : [ {
43.                         "ErrorCode" : "404",
44.                         "ResponsePagePath" : "/error-pages/404.html",
45.                         "ResponseCode" : "200",
46.                         "ErrorCachingMinTTL" : "30"
47.                     } ],
48.                    "PriceClass" : "PriceClass_200",
49.                    "Restrictions" : {
50.                        "GeoRestriction" : {
51.                            "RestrictionType" : "whitelist",
52.                            "Locations" : [ "AQ", "CV" ]
53.                        }
54.                    },
55.                    "ViewerCertificate": { "CloudFrontDefaultCertificate" : "true" }
56.                 }
57.             }
58.         }
59.     }
60. }
```

### YAML
<a name="quickref-cloudfront-example-2.yaml"></a>

```
 1. AWSTemplateFormatVersion: '2010-09-09'
 2. Resources:
 3.   myDistribution:
 4.     Type: AWS::CloudFront::Distribution
 5.     Properties:
 6.       DistributionConfig:
 7.         Origins:
 8.         - DomainName: www.example.com
 9.           Id: myCustomOrigin
10.           CustomOriginConfig:
11.             HTTPPort: '80'
12.             HTTPSPort: '443'
13.             OriginProtocolPolicy: http-only
14.         Enabled: 'true'
15.         Comment: Somecomment
16.         DefaultRootObject: index.html
17.         Logging:
18.           IncludeCookies: 'true'
19.           Bucket: amzn-s3-demo-logging-bucket.s3.amazonaws.com
20.           Prefix: myprefix
21.         Aliases:
22.         - mysite.example.com
23.         - "*.yoursite.example.com"
24.         DefaultCacheBehavior:
25.           TargetOriginId: myCustomOrigin
26.           SmoothStreaming: 'false'
27.           ForwardedValues:
28.             QueryString: 'false'
29.             Cookies:
30.               Forward: all
31.           TrustedSigners:
32.           - 1234567890EX
33.           - 1234567891EX
34.           ViewerProtocolPolicy: allow-all
35.         CustomErrorResponses:
36.         - ErrorCode: '404'
37.           ResponsePagePath: "/error-pages/404.html"
38.           ResponseCode: '200'
39.           ErrorCachingMinTTL: '30'
40.         PriceClass: PriceClass_200
41.         Restrictions:
42.           GeoRestriction:
43.             RestrictionType: whitelist
44.             Locations:
45.             - AQ
46.             - CV
47.         ViewerCertificate:
48.           CloudFrontDefaultCertificate: 'true'
```

## Amazon CloudFront 分佈與多重原始伺服器支援
<a name="scenario-cloudfront-multiorigin"></a>

以下範例範本說明如何宣告具有多重原始伺服器支援的 CloudFront [分佈](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudfront-distribution.html)。在 [DistributionConfig](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-cloudfront-distribution-distributionconfig.html) 中，提供原始伺服器清單，並設定 [DefaultCacheBehavior](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-cloudfront-distribution-defaultcachebehavior.html)。

### JSON
<a name="quickref-cloudfront-example-3.json"></a>

```
{
    "AWSTemplateFormatVersion" : "2010-09-09",
    "Resources" : {
        "myDistribution" : {
            "Type" : "AWS::CloudFront::Distribution",
            "Properties" : {
                "DistributionConfig" : {
                    "Origins" : [ {
                        "Id" : "myS3Origin",
                        "DomainName" : "amzn-s3-demo-bucket.s3.amazonaws.com",
                        "S3OriginConfig" : {
                            "OriginAccessIdentity" : "origin-access-identity/cloudfront/E127EXAMPLE51Z"
                        }
                     }, 
                     {
                         "Id" : "myCustomOrigin",
                         "DomainName" : "www.example.com",
                         "CustomOriginConfig" : {
                             "HTTPPort" : "80",
                             "HTTPSPort" : "443",
                             "OriginProtocolPolicy" : "http-only"
                         }
                     }
                   ],
                   "Enabled" : "true",
                   "Comment" : "Some comment",
                   "DefaultRootObject" : "index.html", 
                   "Logging" : {
                       "IncludeCookies" : "true",
                       "Bucket" : "amzn-s3-demo-logging-bucket.s3.amazonaws.com",
                       "Prefix" : "myprefix"
                   },            
                   "Aliases" : [ "mysite.example.com", "yoursite.example.com" ],
                   "DefaultCacheBehavior" : {
                       "TargetOriginId" : "myS3Origin",
                       "ForwardedValues" : {
                           "QueryString" : "false",
                           "Cookies" : { "Forward" : "all" }
                        },
                       "TrustedSigners" : [ "1234567890EX", "1234567891EX"  ],
                       "ViewerProtocolPolicy" : "allow-all",
                       "MinTTL" : "100",
                       "SmoothStreaming" : "true"
                   },
                   "CacheBehaviors" : [ {
                            "AllowedMethods" : [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ],  
                            "TargetOriginId" : "myS3Origin",
                            "ForwardedValues" : {
                                "QueryString" : "true",
                                "Cookies" : { "Forward" : "none" }
                            },
                            "TrustedSigners" : [ "1234567890EX", "1234567891EX" ],
                            "ViewerProtocolPolicy" : "allow-all",
                            "MinTTL" : "50",
                            "PathPattern" : "images1/*.jpg"
                        }, 
                        {
                            "AllowedMethods" : [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ],  
                            "TargetOriginId" : "myCustomOrigin",
                            "ForwardedValues" : {
                                "QueryString" : "true",
                                "Cookies" : { "Forward" : "none" }
                            },
                            "TrustedSigners" : [ "1234567890EX", "1234567891EX"  ],
                            "ViewerProtocolPolicy" : "allow-all",
                            "MinTTL" : "50",
                            "PathPattern" : "images2/*.jpg"
                        }
                   ],
                   "CustomErrorResponses" : [ {
                       "ErrorCode" : "404",
                       "ResponsePagePath" : "/error-pages/404.html",
                       "ResponseCode" : "200",
                       "ErrorCachingMinTTL" : "30"
                   } ],
                   "PriceClass" : "PriceClass_All",
                   "ViewerCertificate" : { "CloudFrontDefaultCertificate" : "true" }
                }
            }
        }
    }
}
```

### YAML
<a name="quickref-cloudfront-example-3.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  myDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
        - Id: myS3Origin
          DomainName: amzn-s3-demo-bucket.s3.amazonaws.com
          S3OriginConfig:
            OriginAccessIdentity: origin-access-identity/cloudfront/E127EXAMPLE51Z
        - Id: myCustomOrigin
          DomainName: www.example.com
          CustomOriginConfig:
            HTTPPort: '80'
            HTTPSPort: '443'
            OriginProtocolPolicy: http-only
        Enabled: 'true'
        Comment: Some comment
        DefaultRootObject: index.html
        Logging:
          IncludeCookies: 'true'
          Bucket: amzn-s3-demo-logging-bucket.s3.amazonaws.com
          Prefix: myprefix
        Aliases:
        - mysite.example.com
        - yoursite.example.com
        DefaultCacheBehavior:
          TargetOriginId: myS3Origin
          ForwardedValues:
            QueryString: 'false'
            Cookies:
              Forward: all
          TrustedSigners:
          - 1234567890EX
          - 1234567891EX
          ViewerProtocolPolicy: allow-all
          MinTTL: '100'
          SmoothStreaming: 'true'
        CacheBehaviors:
        - AllowedMethods:
          - DELETE
          - GET
          - HEAD
          - OPTIONS
          - PATCH
          - POST
          - PUT
          TargetOriginId: myS3Origin
          ForwardedValues:
            QueryString: 'true'
            Cookies:
              Forward: none
          TrustedSigners:
          - 1234567890EX
          - 1234567891EX
          ViewerProtocolPolicy: allow-all
          MinTTL: '50'
          PathPattern: images1/*.jpg
        - AllowedMethods:
          - DELETE
          - GET
          - HEAD
          - OPTIONS
          - PATCH
          - POST
          - PUT
          TargetOriginId: myCustomOrigin
          ForwardedValues:
            QueryString: 'true'
            Cookies:
              Forward: none
          TrustedSigners:
          - 1234567890EX
          - 1234567891EX
          ViewerProtocolPolicy: allow-all
          MinTTL: '50'
          PathPattern: images2/*.jpg
        CustomErrorResponses:
        - ErrorCode: '404'
          ResponsePagePath: "/error-pages/404.html"
          ResponseCode: '200'
          ErrorCachingMinTTL: '30'
        PriceClass: PriceClass_All
        ViewerCertificate:
          CloudFrontDefaultCertificate: 'true'
```

## 以 Lambda 函式做為原始伺服器的 Amazon CloudFront 分佈
<a name="scenario-cloudfront-lambda-origin"></a>

下列範例建立 CloudFront 分佈，該分佈會面向指定的 Lambda 函式 URL (做為參數提供)，啟用僅限 HTTPS 的存取、快取、壓縮和全域交付。它將 Lambda URL 設定為自訂 HTTPS AWS 原始伺服器，並套用標準快取政策。此分佈已針對效能進行了最佳化，支援 HTTP/2 和 IPv6，並輸出 CloudFront 網域名稱，讓使用者可透過安全的 CDN 支援端點存取 Lambda 函式。如需詳細資訊，請參閱 AWS 部落格上的[搭配使用 Amazon CloudFront AWS Lambda 做為原始伺服器，以加速您的 Web 應用程式](https://aws.amazon.com/blogs/networking-and-content-delivery/using-amazon-cloudfront-with-aws-lambda-as-origin-to-accelerate-your-web-applications/)。

### JSON
<a name="quickref-cloudfront-example-lambda-origin.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "LambdaEndpoint": {
            "Type": "String",
            "Description": "The Lambda function URL endpoint without the 'https://'"
        }
    },
    "Resources": {
        "MyDistribution": {
            "Type": "AWS::CloudFront::Distribution",
            "Properties": {
                "DistributionConfig": {
                    "PriceClass": "PriceClass_All",
                    "HttpVersion": "http2",
                    "IPV6Enabled": true,
                    "Origins": [
                        {
                            "DomainName": {
                                "Ref": "LambdaEndpoint"
                            },
                            "Id": "LambdaOrigin",
                            "CustomOriginConfig": {
                                "HTTPSPort": 443,
                                "OriginProtocolPolicy": "https-only"
                            }
                        }
                    ],
                    "Enabled": "true",
                    "DefaultCacheBehavior": {
                        "TargetOriginId": "LambdaOrigin",
                        "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
                        "ViewerProtocolPolicy": "redirect-to-https",
                        "SmoothStreaming": "false",
                        "Compress": "true"
                    }
                }
            }
        }
    },
    "Outputs": {
        "CloudFrontDomain": {
            "Description": "CloudFront default domain name configured",
            "Value": {
                "Fn::Sub": "https://${MyDistribution.DomainName}/"
            }
        }
    }
}
```

### YAML
<a name="quickref-cloudfront-example-lambda-origin.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  LambdaEndpoint:
    Type: String
    Description: The Lambda function URL endpoint without the 'https://'
Resources:
  MyDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        PriceClass: PriceClass_All
        HttpVersion: http2
        IPV6Enabled: true
        Origins:
        - DomainName: !Ref LambdaEndpoint
          Id: LambdaOrigin
          CustomOriginConfig:
            HTTPSPort: 443
            OriginProtocolPolicy: https-only
        Enabled: 'true'
        DefaultCacheBehavior:
          TargetOriginId: LambdaOrigin
          CachePolicyId: '658327ea-f89d-4fab-a63d-7e88639e58f6'
          ViewerProtocolPolicy: redirect-to-https
          SmoothStreaming: 'false'
          Compress: 'true'
Outputs:
  CloudFrontDomain:
    Description: CloudFront default domain name configured
    Value: !Sub https://${MyDistribution.DomainName}/
```

## 另請參閱
<a name="w2aac11c41c27c15"></a>

若需有關在 Route 53 記錄中新增自訂別名，為 CloudFront 分佈建立易記名稱的範例，請參閱 [CloudFront 分佈的別名資源紀錄集](quickref-route53.md#scenario-user-friendly-url-for-cloudfront-distribution)。

# Amazon CloudWatch 範本程式碼片段
<a name="quickref-cloudwatch"></a>

使用這些範例範本程式碼片段，以協助您在 CloudFormation中描述 Amazon CloudWatch 資源。如需詳細資訊，請參閱 [Amazon CloudWatch 資源類型參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/AWS_CloudWatch.html)。

**Topics**
+ [帳單警示](#cloudwatch-sample-billing-alarm)
+ [CPU 使用率警示](#cloudwatch-sample-cpu-utilization-alarm)
+ [復原 Amazon Elastic Compute Cloud 執行個體](#cloudwatch-sample-recover-instance)
+ [建立基本儀表板](#cloudwatch-sample-dashboard-basic)
+ [建立並排 Widget 的儀表板](#cloudwatch-sample-dashboard-sidebyside)

## 帳單警示
<a name="cloudwatch-sample-billing-alarm"></a>

在下列範例中， AWS 帳戶的費用超過警示閾值時，Amazon CloudWatch 會傳送電子郵件通知。若要取得使用量通知，請啟用帳單提醒。如需詳細資訊，請參閱《*Amazon CloudWatch 使用者指南*》中的[建立帳單警示以監控您的預估 AWS 費用](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html)。>

### JSON
<a name="quickref-cloudwatch-example-1.json"></a>

```
"SpendingAlarm": {
  "Type": "AWS::CloudWatch::Alarm",
  "Properties": {
    "AlarmDescription": { "Fn::Join": ["", [
      "Alarm if AWS spending is over $",
      { "Ref": "AlarmThreshold" }
    ]]},
    "Namespace": "AWS/Billing",
    "MetricName": "EstimatedCharges",
    "Dimensions": [{
      "Name": "Currency",
      "Value" : "USD"
    }],
    "Statistic": "Maximum",
    "Period": "21600",
    "EvaluationPeriods": "1",
    "Threshold": { "Ref": "AlarmThreshold" },
    "ComparisonOperator": "GreaterThanThreshold",
    "AlarmActions": [{
      "Ref": "BillingAlarmNotification"
    }],
    "InsufficientDataActions": [{
      "Ref": "BillingAlarmNotification"
    }]
  }
}
```

### YAML
<a name="quickref-cloudwatch-example-1.yaml"></a>

```
SpendingAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmDescription: 
      'Fn::Join':
        - ''
        - - Alarm if AWS spending is over $
          - !Ref: AlarmThreshold
    Namespace: AWS/Billing
    MetricName: EstimatedCharges
    Dimensions:
    - Name: Currency
      Value: USD
    Statistic: Maximum
    Period: '21600'
    EvaluationPeriods: '1'
    Threshold:
      !Ref: "AlarmThreshold"
    ComparisonOperator: GreaterThanThreshold
    AlarmActions:
    - !Ref: "BillingAlarmNotification"
    InsufficientDataActions:
    - !Ref: "BillingAlarmNotification"
```

## CPU 使用率警示
<a name="cloudwatch-sample-cpu-utilization-alarm"></a>

下列範本程式碼片段會建立警示，在 Amazon EC2 執行個體的平均 CPU 使用率於三段評估期間長達 60 秒以上超過 90% 時，傳送通知。

### JSON
<a name="quickref-cloudwatch-example-2.json"></a>

```
 1. "CPUAlarm" : {
 2.   "Type" : "AWS::CloudWatch::Alarm",
 3.   "Properties" : {
 4.     "AlarmDescription" : "CPU alarm for my instance",
 5.     "AlarmActions" : [ { "Ref" : "logical name of an AWS::SNS::Topic resource" } ],
 6.     "MetricName" : "CPUUtilization",
 7.     "Namespace" : "AWS/EC2",
 8.     "Statistic" : "Average",
 9.     "Period" : "60",
10.     "EvaluationPeriods" : "3",
11.     "Threshold" : "90",
12.     "ComparisonOperator" : "GreaterThanThreshold",
13.     "Dimensions" : [ {
14.       "Name" : "InstanceId",
15.       "Value" : { "Ref" : "logical name of an AWS::EC2::Instance resource" }
16.     } ]
17.   }
18. }
```

### YAML
<a name="quickref-cloudwatch-example-2.yaml"></a>

```
 1. CPUAlarm:
 2.   Type: AWS::CloudWatch::Alarm
 3.   Properties:
 4.     AlarmDescription: CPU alarm for my instance
 5.     AlarmActions:
 6.     - !Ref: "logical name of an AWS::SNS::Topic resource"
 7.     MetricName: CPUUtilization
 8.     Namespace: AWS/EC2
 9.     Statistic: Average
10.     Period: '60'
11.     EvaluationPeriods: '3'
12.     Threshold: '90'
13.     ComparisonOperator: GreaterThanThreshold
14.     Dimensions:
15.     - Name: InstanceId
16.       Value: !Ref: "logical name of an AWS::EC2::Instance resource"
```

## 復原 Amazon Elastic Compute Cloud 執行個體
<a name="cloudwatch-sample-recover-instance"></a>

當 EC2 執行個體的狀態檢查連續 15 分鐘發生故障時，以下 CloudWatch 警示會復原執行個體。如需有關警示動作的詳細資訊，請參閱《*Amazon CloudWatch 使用者指南*》中的[建立警示來停止、終止、重新啟動或復原 EC2 執行個體](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/UsingAlarmActions.html)。

### JSON
<a name="quickref-cloudwatch-example-3.json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters" : {
    "RecoveryInstance" : {
      "Description" : "The EC2 instance ID to associate this alarm with.",
      "Type" : "AWS::EC2::Instance::Id"
    }
  },
  "Resources": {
    "RecoveryTestAlarm": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "AlarmDescription": "Trigger a recovery when instance status check fails for 15 consecutive minutes.",
        "Namespace": "AWS/EC2" ,
        "MetricName": "StatusCheckFailed_System",
        "Statistic": "Minimum",
        "Period": "60",
        "EvaluationPeriods": "15",
        "ComparisonOperator": "GreaterThanThreshold",
        "Threshold": "0",
        "AlarmActions": [ {"Fn::Join" : ["", ["arn:aws:automate:", { "Ref" : "AWS::Region" }, ":ec2:recover" ]]} ],
        "Dimensions": [{"Name": "InstanceId","Value": {"Ref": "RecoveryInstance"}}]
      }
    }
  }
}
```

### YAML
<a name="quickref-cloudwatch-example-3.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  RecoveryInstance:
    Description: The EC2 instance ID to associate this alarm with.
    Type: AWS::EC2::Instance::Id
Resources:
  RecoveryTestAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: Trigger a recovery when instance status check fails for 15
        consecutive minutes.
      Namespace: AWS/EC2
      MetricName: StatusCheckFailed_System
      Statistic: Minimum
      Period: '60'
      EvaluationPeriods: '15'
      ComparisonOperator: GreaterThanThreshold
      Threshold: '0'
      AlarmActions: [ !Sub "arn:aws:automate:${AWS::Region}:ec2:recover" ]
      Dimensions:
      - Name: InstanceId
        Value: !Ref: RecoveryInstance
```

## 建立基本儀表板
<a name="cloudwatch-sample-dashboard-basic"></a>

以下範例會建立一個簡單的 CloudWatch 儀表板，有一個顯示 CPU 使用率的指標 Widget 和一個顯示訊息的文字 Widget。

### JSON
<a name="quickref-cloudwatch-sample-dashboard-basic.json"></a>

```
{
    "BasicDashboard": {
        "Type": "AWS::CloudWatch::Dashboard",
        "Properties": {
            "DashboardName": "Dashboard1",
            "DashboardBody": "{\"widgets\":[{\"type\":\"metric\",\"x\":0,\"y\":0,\"width\":12,\"height\":6,\"properties\":{\"metrics\":[[\"AWS/EC2\",\"CPUUtilization\",\"InstanceId\",\"i-012345\"]],\"period\":300,\"stat\":\"Average\",\"region\":\"us-east-1\",\"title\":\"EC2 Instance CPU\"}},{\"type\":\"text\",\"x\":0,\"y\":7,\"width\":3,\"height\":3,\"properties\":{\"markdown\":\"Hello world\"}}]}"
        }
    }
}
```

### YAML
<a name="quickref-cloudwatch-sample-dashboard-basic.yaml"></a>

```
BasicDashboard:
  Type: AWS::CloudWatch::Dashboard
  Properties:
    DashboardName: Dashboard1
    DashboardBody: '{"widgets":[{"type":"metric","x":0,"y":0,"width":12,"height":6,"properties":{"metrics":[["AWS/EC2","CPUUtilization","InstanceId","i-012345"]],"period":300,"stat":"Average","region":"us-east-1","title":"EC2 Instance CPU"}},{"type":"text","x":0,"y":7,"width":3,"height":3,"properties":{"markdown":"Hello world"}}]}'
```

## 建立並排 Widget 的儀表板
<a name="cloudwatch-sample-dashboard-sidebyside"></a>

以下範例會建立有兩個指標 Widget 並排的儀表板。

### JSON
<a name="quickref-cloudwatch-sample-dashboard-sidebyside.json"></a>

```
{
    "DashboardSideBySide": {
        "Type": "AWS::CloudWatch::Dashboard",
        "Properties": {
            "DashboardName": "Dashboard1",
            "DashboardBody": "{\"widgets\":[{\"type\":\"metric\",\"x\":0,\"y\":0,\"width\":12,\"height\":6,\"properties\":{\"metrics\":[[\"AWS/EC2\",\"CPUUtilization\",\"InstanceId\",\"i-012345\"]],\"period\":300,\"stat\":\"Average\",\"region\":\"us-east-1\",\"title\":\"EC2 Instance CPU\"}},{\"type\":\"metric\",\"x\":12,\"y\":0,\"width\":12,\"height\":6,\"properties\":{\"metrics\":[[\"AWS/S3\",\"BucketSizeBytes\",\"BucketName\",\"amzn-s3-demo-bucket\"]],\"period\":86400,\"stat\":\"Maximum\",\"region\":\"us-east-1\",\"title\":\"amzn-s3-demo-bucket bytes\"}}]}"
        }
    }
}
```

### YAML
<a name="quickref-cloudwatch-sample-dashboard-sidebysidequickref-cloudwatch-sample-dashboard-sidebyside.yaml"></a>

```
DashboardSideBySide:
  Type: AWS::CloudWatch::Dashboard
  Properties:
    DashboardName: Dashboard1
    DashboardBody: '{"widgets":[{"type":"metric","x":0,"y":0,"width":12,"height":6,"properties":{"metrics":[["AWS/EC2","CPUUtilization","InstanceId","i-012345"]],"period":300,"stat":"Average","region":"us-east-1","title":"EC2 Instance CPU"}},{"type":"metric","x":12,"y":0,"width":12,"height":6,"properties":{"metrics":[["AWS/S3","BucketSizeBytes","BucketName","amzn-s3-demo-bucket"]],"period":86400,"stat":"Maximum","region":"us-east-1","title":"amzn-s3-demo-bucket bytes"}}]}'
```

# Amazon CloudWatch Logs 範本程式碼片段
<a name="quickref-cloudwatchlogs"></a>

Amazon CloudWatch Logs 可監控您的系統、應用程式，以及來自 Amazon EC2 執行個體或其他來源的自訂日誌檔案。您可以使用 CloudFormation 來佈建和管理日誌群組和指標篩選條件。如需 Amazon CloudWatch Logs 的詳細資訊，請參閱[《Amazon CloudWatch Logs 使用者指南》](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html)。

**Topics**
+ [從 Linux 執行個體傳送日誌到 CloudWatch Logs](#quickref-cloudwatchlogs-example1)
+ [從 Windows 執行個體傳送日誌到 CloudWatch Logs](#quickref-cloudwatchlogs-example2)
+ [另請參閱](#w2aac11c41c35c11)

## 從 Linux 執行個體傳送日誌到 CloudWatch Logs
<a name="quickref-cloudwatchlogs-example1"></a>

以下範本示範如何透過 CloudWatch Logs 整合，在 Amazon Linux 2023 上設定 Web 伺服器。此範本會執行以下任務：
+ 安裝 Apache 與 PHP。
+ 設定 CloudWatch 代理程式，將 Apache 存取日誌轉送至 CloudWatch Logs。
+ 設定 IAM 角色，允許 CloudWatch 代理程式將日誌資料傳送至 CloudWatch Logs。
+ 建立自訂警示與通知，用於監控 404 錯誤或高頻寬用量。

Web 伺服器的日誌事件會為 CloudWatch 警示提供指標資料。這兩個指標篩選條件描述日誌資訊如何轉換成 CloudWatch 指標。404 指標會計算 404 事件的數量。大小指標會追蹤請求的大小。如果在 2 分鐘內發生兩次以上的 404，或 10 分鐘內的平均請求大小超過 3500 KB，這兩個 CloudWatch 警示會傳送通知。

### JSON
<a name="quickref-cloudwatchlogs-example.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Sample template that sets up and configures CloudWatch Logs on Amazon Linux 2023 instance.",
    "Parameters": {
        "KeyName": {
            "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances",
            "Type": "AWS::EC2::KeyPair::KeyName",
            "ConstraintDescription": "must be the name of an existing EC2 KeyPair."
        },
        "SSHLocation": {
            "Description": "The IP address range that can be used to SSH to the EC2 instances",
            "Type": "String",
            "MinLength": "9",
            "MaxLength": "18",
            "Default": "0.0.0.0/0",
            "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
            "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
        },
        "OperatorEmail": {
            "Description": "Email address to notify when CloudWatch alarms are triggered (404 errors or high bandwidth usage)",
            "Type": "String"
        }
    },
    "Resources": {
        "LogRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "ec2.amazonaws.com"
                                ]
                            },
                            "Action": [
                                "sts:AssumeRole"
                            ]
                        }
                    ]
                },
                "Path": "/",
                "Policies": [
                    {
                        "PolicyName": "LogRolePolicy",
                        "PolicyDocument": {
                            "Version": "2012-10-17",		 	 	 
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "logs:PutLogEvents",
                                        "logs:DescribeLogStreams",
                                        "logs:DescribeLogGroups",
                                        "logs:CreateLogGroup",
                                        "logs:CreateLogStream"
                                    ],
                                    "Resource": "*"
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "LogRoleInstanceProfile": {
            "Type": "AWS::IAM::InstanceProfile",
            "Properties": {
                "Path": "/",
                "Roles": [{"Ref": "LogRole"}]
            }
        },
        "WebServerSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable HTTP access via port 80 and SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 80,
                        "ToPort": 80,
                        "CidrIp": "0.0.0.0/0"
                    },
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 22,
                        "ToPort": 22,
                        "CidrIp": {"Ref": "SSHLocation"}
                    }
                ]
            }
        },
        "WebServerHost": {
            "Type": "AWS::EC2::Instance",
            "Metadata": {
                "Comment": "Install a simple PHP application on Amazon Linux 2023",
                "AWS::CloudFormation::Init": {
                    "config": {
                        "packages": {
                            "dnf": {
                                "httpd": [],
                                "php": [],
                                "php-fpm": []
                            }
                        },
                        "files": {
                            "/etc/amazon-cloudwatch-agent/amazon-cloudwatch-agent.json": {
                                "content": {
                                    "logs": {
                                        "logs_collected": {
                                            "files": {
                                                "collect_list": [{
                                                    "file_path": "/var/log/httpd/access_log",
                                                    "log_group_name": {"Ref": "WebServerLogGroup"},
                                                    "log_stream_name": "{instance_id}/apache.log",
                                                    "timestamp_format": "%d/%b/%Y:%H:%M:%S %z"
                                                }]
                                            }
                                        }
                                    }
                                },
                                "mode": "000644",
                                "owner": "root",
                                "group": "root"
                            },
                            "/var/www/html/index.php": {
                                "content": "<?php\necho '<h1>AWS CloudFormation sample PHP application on Amazon Linux 2023</h1>';\n?>\n",
                                "mode": "000644",
                                "owner": "apache",
                                "group": "apache"
                            },
                            "/etc/cfn/cfn-hup.conf": {
                                "content":  {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "[main]\n",
                                            "stack=",
                                            {"Ref": "AWS::StackId"},
                                            "\n",
                                            "region=",
                                            {"Ref": "AWS::Region"},
                                            "\n"
                                        ]
                                    ]
                                },
                                "mode": "000400",
                                "owner": "root",
                                "group": "root"
                            },
                            "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "[cfn-auto-reloader-hook]\n",
                                            "triggers=post.update\n",
                                            "path=Resources.WebServerHost.Metadata.AWS::CloudFormation::Init\n",
                                            "action=/opt/aws/bin/cfn-init -s ",
                                            {"Ref": "AWS::StackId"},
                                            " -r WebServerHost ",
                                            " --region     ",
                                            {"Ref": "AWS::Region"},
                                            "\n",
                                            "runas=root\n"
                                        ]
                                    ]
                                }
                            }
                        },
                        "services": {
                            "systemd": {
                                "httpd": {
                                    "enabled": "true",
                                    "ensureRunning": "true"
                                },
                                "php-fpm": {
                                    "enabled": "true",
                                    "ensureRunning": "true"
                                }
                            }
                        }
                    }
                }
            },
            "CreationPolicy": {
                "ResourceSignal": {
                    "Timeout": "PT5M"
                }
            },
            "Properties": {
                "ImageId": "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64}}",
                "KeyName": {"Ref": "KeyName"},
                "InstanceType": "t3.micro",
                "SecurityGroupIds": [{"Ref": "WebServerSecurityGroup"}],
                "IamInstanceProfile": {"Ref": "LogRoleInstanceProfile"},
                "UserData": {"Fn::Base64": {"Fn::Join": [ "", [
                    "#!/bin/bash\n",
                    "dnf update -y aws-cfn-bootstrap\n",
                    "dnf install -y amazon-cloudwatch-agent\n",
                    "/opt/aws/bin/cfn-init -v --stack ", {"Ref": "AWS::StackName"}, " --resource WebServerHost --region ", {"Ref": "AWS::Region"}, "\n",
                    "\n",
                    "# Verify Apache log directory exists and create if needed\n",
                    "mkdir -p /var/log/httpd\n",
                    "\n",
                    "# Start CloudWatch agent\n",
                    "/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/etc/amazon-cloudwatch-agent/amazon-cloudwatch-agent.json -s\n",
                    "\n",
                    "# Signal success\n",
                    "/opt/aws/bin/cfn-signal -e $? --stack ", {"Ref": "AWS::StackName"}, " --resource WebServerHost --region ", {"Ref": "AWS::Region"}, "\n"
                ]]}}
            }
        },
        "WebServerLogGroup": {
            "Type": "AWS::Logs::LogGroup",
            "DeletionPolicy": "Retain",
            "UpdateReplacePolicy": "Retain",
            "Properties": {
                "RetentionInDays": 7
            }
        },
        "404MetricFilter": {
            "Type": "AWS::Logs::MetricFilter",
            "Properties": {
                "LogGroupName": {"Ref": "WebServerLogGroup"},
                "FilterPattern": "[ip, identity, user_id, timestamp, request, status_code = 404, size, ...]",
                "MetricTransformations": [
                    {
                        "MetricValue": "1",
                        "MetricNamespace": "test/404s",
                        "MetricName": "test404Count"
                    }
                ]
            }
        },
        "BytesTransferredMetricFilter": {
            "Type": "AWS::Logs::MetricFilter",
            "Properties": {
                "LogGroupName": {"Ref": "WebServerLogGroup"},
                "FilterPattern": "[ip, identity, user_id, timestamp, request, status_code, size, ...]",
                "MetricTransformations": [
                    {
                        "MetricValue": "$size",
                        "MetricNamespace": "test/BytesTransferred",
                        "MetricName": "testBytesTransferred"
                    }
                ]
            }
        },
        "404Alarm": {
            "Type": "AWS::CloudWatch::Alarm",
            "Properties": {
                "AlarmDescription": "The number of 404s is greater than 2 over 2 minutes",
                "MetricName": "test404Count",
                "Namespace": "test/404s",
                "Statistic": "Sum",
                "Period": "60",
                "EvaluationPeriods": "2",
                "Threshold": "2",
                "AlarmActions": [{"Ref": "AlarmNotificationTopic"}],
                "ComparisonOperator": "GreaterThanThreshold"
            }
        },
        "BandwidthAlarm": {
            "Type": "AWS::CloudWatch::Alarm",
            "Properties": {
                "AlarmDescription": "The average volume of traffic is greater 3500 KB over 10 minutes",
                "MetricName": "testBytesTransferred",
                "Namespace": "test/BytesTransferred",
                "Statistic": "Average",
                "Period": "300",
                "EvaluationPeriods": "2",
                "Threshold": "3500",
                "AlarmActions": [{"Ref": "AlarmNotificationTopic"}],
                "ComparisonOperator": "GreaterThanThreshold"
            }
        },
        "AlarmNotificationTopic": {
            "Type": "AWS::SNS::Topic",
            "Properties": {
                "Subscription": [{"Endpoint": {"Ref": "OperatorEmail"}, "Protocol": "email"}]
            }
        }
    },
    "Outputs": {
        "InstanceId": {
            "Description": "The instance ID of the web server",
            "Value": {"Ref": "WebServerHost"}
        },
        "WebsiteURL": {
            "Value": {"Fn::Sub": "http://${WebServerHost.PublicDnsName}"},
            "Description": "URL for the web server"
        },
        "PublicIP": {
            "Description": "Public IP address of the web server",
            "Value": {"Fn::GetAtt": ["WebServerHost","PublicIp"]
            }
        },
        "CloudWatchLogGroupName": {
            "Description": "The name of the CloudWatch log group",
            "Value": {"Ref": "WebServerLogGroup"}
        }
    }
}
```

### YAML
<a name="quickref-cloudwatchlogs-example.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Description: Sample template that sets up and configures CloudWatch Logs on Amazon Linux 2023 instance.
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  OperatorEmail:
    Description: Email address to notify when CloudWatch alarms are triggered (404 errors or high bandwidth usage)
    Type: String
Resources:
  LogRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17		 	 	 
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: LogRolePolicy
          PolicyDocument:
            Version: 2012-10-17		 	 	 
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:PutLogEvents'
                  - 'logs:DescribeLogStreams'
                  - 'logs:DescribeLogGroups'
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                Resource: '*'
  LogRoleInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref LogRole
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80 and SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
  WebServerHost:
    Type: AWS::EC2::Instance
    Metadata:
      Comment: Install a simple PHP application on Amazon Linux 2023
      'AWS::CloudFormation::Init':
        config:
          packages:
            dnf:
              httpd: []
              php: []
              php-fpm: []
          files:
            /etc/amazon-cloudwatch-agent/amazon-cloudwatch-agent.json:
              content: !Sub |
                {
                  "logs": {
                    "logs_collected": {
                      "files": {
                        "collect_list": [
                          {
                            "file_path": "/var/log/httpd/access_log",
                            "log_group_name": "${WebServerLogGroup}",
                            "log_stream_name": "{instance_id}/apache.log",
                            "timestamp_format": "%d/%b/%Y:%H:%M:%S %z"
                          }
                        ]
                      }
                    }
                  }
                }
              mode: '000644'
              owner: root
              group: root
            /var/www/html/index.php:
              content: |
                <?php echo '<h1>AWS CloudFormation sample PHP application on Amazon Linux 2023</h1>';
                ?>
              mode: '000644'
              owner: apache
              group: apache
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.WebServerHost.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -s ${AWS::StackId} -r WebServerHost --region ${AWS::Region}
                runas=root
          services:
            systemd:
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
              php-fpm:
                enabled: 'true'
                ensureRunning: 'true'
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M
    Properties:
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64}}'
      KeyName: !Ref KeyName
      InstanceType: t3.micro
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      IamInstanceProfile: !Ref LogRoleInstanceProfile
      UserData: !Base64
        Fn::Sub: |
          #!/bin/bash
          dnf update -y aws-cfn-bootstrap
          dnf install -y amazon-cloudwatch-agent
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerHost --region ${AWS::Region}
          
          # Verify Apache log directory exists and create if needed
          mkdir -p /var/log/httpd
          
          # Start CloudWatch agent
          /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/etc/amazon-cloudwatch-agent/amazon-cloudwatch-agent.json -s
          
          # Signal success
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerHost --region ${AWS::Region}
          echo "Done"
  WebServerLogGroup:
    Type: AWS::Logs::LogGroup
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      RetentionInDays: 7
  404MetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref WebServerLogGroup
      FilterPattern: >-
        [ip, identity, user_id, timestamp, request, status_code = 404, size, ...]
      MetricTransformations:
        - MetricValue: '1'
          MetricNamespace: test/404s
          MetricName: test404Count
  BytesTransferredMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref WebServerLogGroup
      FilterPattern: '[ip, identity, user_id, timestamp, request, status_code, size, ...]'
      MetricTransformations:
        - MetricValue: $size
          MetricNamespace: test/BytesTransferred
          MetricName: testBytesTransferred
  404Alarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: The number of 404s is greater than 2 over 2 minutes
      MetricName: test404Count
      Namespace: test/404s
      Statistic: Sum
      Period: '60'
      EvaluationPeriods: '2'
      Threshold: '2'
      AlarmActions:
        - !Ref AlarmNotificationTopic
      ComparisonOperator: GreaterThanThreshold
  BandwidthAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: The average volume of traffic is greater 3500 KB over 10 minutes
      MetricName: testBytesTransferred
      Namespace: test/BytesTransferred
      Statistic: Average
      Period: '300'
      EvaluationPeriods: '2'
      Threshold: '3500'
      AlarmActions:
        - !Ref AlarmNotificationTopic
      ComparisonOperator: GreaterThanThreshold
  AlarmNotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref OperatorEmail
          Protocol: email
Outputs:
  InstanceId:
    Description: The instance ID of the web server
    Value: !Ref WebServerHost
  WebsiteURL:
    Value: !Sub 'http://${WebServerHost.PublicDnsName}'
    Description: URL for the web server
  PublicIP:
    Description: Public IP address of the web server
    Value: !GetAtt WebServerHost.PublicIp
  CloudWatchLogGroupName:
    Description: The name of the CloudWatch log group
    Value: !Ref WebServerLogGroup
```

## 從 Windows 執行個體傳送日誌到 CloudWatch Logs
<a name="quickref-cloudwatchlogs-example2"></a>

以下範本會設定 CloudWatch Logs 以適用於 Windows 2012R2 執行個體。

Windows 上的 CloudWatch Logs 代理程式 (Windows 2012R2 和 Windows 2016 AMI 上的 SSM 代理程式) 只會傳送啟動之後的日誌，因此啟動之前產生的任何日誌都不會傳送。若要解決此問題，此範本可協助確保在代理程式啟動之後，才會寫入任何日誌：
+ 將代理程式的設定，設定為 cfn-init `config` 中的第一個 `configSets` 項目。
+ 使用 `waitAfterCompletion` 在啟動代理程式的命令之後插入一個暫停。

### JSON
<a name="quickref-cloudwatchlogs-example2.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Sample template that sets up and configures CloudWatch Logs on Windows 2012R2 instance.",
    "Parameters": {
        "KeyPair": {
            "Description": "Name of an existing EC2 KeyPair to enable RDP access to the instances",
            "Type": "AWS::EC2::KeyPair::KeyName",
            "ConstraintDescription": "must be the name of an existing EC2 KeyPair."
        },
        "RDPLocation": {
            "Description": "The IP address range that can be used to RDP to the EC2 instances",
            "Type": "String",
            "MinLength": "9",
            "MaxLength": "18",
            "Default": "0.0.0.0/0",
            "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
            "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
        },
        "OperatorEmail": {
            "Description": "Email address to notify when CloudWatch alarms are triggered (404 errors)",
            "Type": "String"
        }
    },
    "Resources": {
        "WebServerSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable HTTP access via port 80 and RDP access via port 3389",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "80",
                        "ToPort": "80",
                        "CidrIp": "0.0.0.0/0"
                    },
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "3389",
                        "ToPort": "3389",
                        "CidrIp": {"Ref": "RDPLocation"}
                    }
                ]
            }
        },
        "LogRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "ec2.amazonaws.com"
                                ]
                            },
                            "Action": [
                                "sts:AssumeRole"
                            ]
                        }
                    ]
                },
                "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
                ],
                "Path": "/",
                "Policies": [
                    {
                        "PolicyName": "LogRolePolicy",
                        "PolicyDocument": {
                            "Version": "2012-10-17",		 	 	 
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "logs:Create*",
                                        "logs:PutLogEvents",
                                        "s3:GetObject"
                                    ],
                                    "Resource": [
                                        "arn:aws:logs:*:*:*",
                                        "arn:aws:s3:::*"
                                    ]
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "LogRoleInstanceProfile": {
            "Type": "AWS::IAM::InstanceProfile",
            "Properties": {
                "Path": "/",
                "Roles": [{"Ref": "LogRole"}]
            }
        },
        "WebServerHost": {
            "Type": "AWS::EC2::Instance",
            "CreationPolicy": {
                "ResourceSignal": {
                    "Timeout": "PT15M"
                }
            },
            "Metadata": {
                "AWS::CloudFormation::Init": {
                    "configSets": {
                        "config": [
                            "00-ConfigureCWLogs",
                            "01-InstallWebServer",
                            "02-ConfigureApplication",
                            "03-Finalize"
                        ]
                    },
                    "00-ConfigureCWLogs": {
                        "files": {
                            "C:\\Program Files\\Amazon\\SSM\\Plugins\\awsCloudWatch\\AWS.EC2.Windows.CloudWatch.json": {
                                "content": {
                                    "EngineConfiguration": {
                                        "Components": [
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                                                "Id": "ApplicationEventLog",
                                                "Parameters": {
                                                    "Levels": "7",
                                                    "LogName": "Application"
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                                                "Id": "SystemEventLog",
                                                "Parameters": {
                                                    "Levels": "7",
                                                    "LogName": "System"
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                                                "Id": "SecurityEventLog",
                                                "Parameters": {
                                                    "Levels": "7",
                                                    "LogName": "Security"
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch",
                                                "Id": "EC2ConfigLog",
                                                "Parameters": {
                                                    "CultureName": "en-US",
                                                    "Encoding": "ASCII",
                                                    "Filter": "EC2ConfigLog.txt",
                                                    "LogDirectoryPath": "C:\\Program Files\\Amazon\\Ec2ConfigService\\Logs",
                                                    "TimeZoneKind": "UTC",
                                                    "TimestampFormat": "yyyy-MM-ddTHH:mm:ss.fffZ:"
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch",
                                                "Id": "CfnInitLog",
                                                "Parameters": {
                                                    "CultureName": "en-US",
                                                    "Encoding": "ASCII",
                                                    "Filter": "cfn-init.log",
                                                    "LogDirectoryPath": "C:\\cfn\\log",
                                                    "TimeZoneKind": "Local",
                                                    "TimestampFormat": "yyyy-MM-dd HH:mm:ss,fff"
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch",
                                                "Id": "IISLogs",
                                                "Parameters": {
                                                    "CultureName": "en-US",
                                                    "Encoding": "UTF-8",
                                                    "Filter": "",
                                                    "LineCount": "3",
                                                    "LogDirectoryPath": "C:\\inetpub\\logs\\LogFiles\\W3SVC1",
                                                    "TimeZoneKind": "UTC",
                                                    "TimestampFormat": "yyyy-MM-dd HH:mm:ss"
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                                                "Id": "MemoryPerformanceCounter",
                                                "Parameters": {
                                                    "CategoryName": "Memory",
                                                    "CounterName": "Available MBytes",
                                                    "DimensionName": "",
                                                    "DimensionValue": "",
                                                    "InstanceName": "",
                                                    "MetricName": "Memory",
                                                    "Unit": "Megabytes"
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                                                "Id": "CloudWatchApplicationEventLog",
                                                "Parameters": {
                                                    "AccessKey": "",
                                                    "LogGroup": {"Ref": "LogGroup"},
                                                    "LogStream": "{instance_id}/ApplicationEventLog",
                                                    "Region": {"Ref": "AWS::Region"},
                                                    "SecretKey": ""
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                                                "Id": "CloudWatchSystemEventLog",
                                                "Parameters": {
                                                    "AccessKey": "",
                                                    "LogGroup": {"Ref": "LogGroup"},
                                                    "LogStream": "{instance_id}/SystemEventLog",
                                                    "Region": {"Ref": "AWS::Region"},
                                                    "SecretKey": ""
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                                                "Id": "CloudWatchSecurityEventLog",
                                                "Parameters": {
                                                    "AccessKey": "",
                                                    "LogGroup": {"Ref": "LogGroup"},
                                                    "LogStream": "{instance_id}/SecurityEventLog",
                                                    "Region": {"Ref": "AWS::Region"},
                                                    "SecretKey": ""
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                                                "Id": "CloudWatchEC2ConfigLog",
                                                "Parameters": {
                                                    "AccessKey": "",
                                                    "LogGroup": {"Ref": "LogGroup"},
                                                    "LogStream": "{instance_id}/EC2ConfigLog",
                                                    "Region": {"Ref": "AWS::Region"},
                                                    "SecretKey": ""
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                                                "Id": "CloudWatchCfnInitLog",
                                                "Parameters": {
                                                    "AccessKey": "",
                                                    "LogGroup": {"Ref": "LogGroup"},
                                                    "LogStream": "{instance_id}/CfnInitLog",
                                                    "Region": {"Ref": "AWS::Region"},
                                                    "SecretKey": ""
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                                                "Id": "CloudWatchIISLogs",
                                                "Parameters": {
                                                    "AccessKey": "",
                                                    "LogGroup": {"Ref": "LogGroup"},
                                                    "LogStream": "{instance_id}/IISLogs",
                                                    "Region": {"Ref": "AWS::Region"},
                                                    "SecretKey": ""
                                                }
                                            },
                                            {
                                                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatch.CloudWatchOutputComponent,AWS.EC2.Windows.CloudWatch",
                                                "Id": "CloudWatch",
                                                "Parameters": {
                                                    "AccessKey": "",
                                                    "NameSpace": "Windows/Default",
                                                    "Region": {"Ref": "AWS::Region"},
                                                    "SecretKey": ""
                                                }
                                            }
                                        ],
                                        "Flows": {
                                            "Flows": [
                                                "ApplicationEventLog,CloudWatchApplicationEventLog",
                                                "SystemEventLog,CloudWatchSystemEventLog",
                                                "SecurityEventLog,CloudWatchSecurityEventLog",
                                                "EC2ConfigLog,CloudWatchEC2ConfigLog",
                                                "CfnInitLog,CloudWatchCfnInitLog",
                                                "IISLogs,CloudWatchIISLogs",
                                                "MemoryPerformanceCounter,CloudWatch"
                                            ]
                                        },
                                        "PollInterval": "00:00:05"
                                    },
                                    "IsEnabled": true
                                }
                            }
                        },
                        "commands": {
                            "0-enableSSM": {
                                "command": "powershell.exe -Command \"Set-Service -Name AmazonSSMAgent -StartupType Automatic\" ",
                                "waitAfterCompletion": "0"
                            },
                            "1-restartSSM": {
                                "command": "powershell.exe -Command \"Restart-Service AmazonSSMAgent \"",
                                "waitAfterCompletion": "30"
                            }
                        }
                    },
                    "01-InstallWebServer": {
                        "commands": {
                            "01_install_webserver": {
                                "command": "powershell.exe -Command \"Install-WindowsFeature Web-Server  -IncludeAllSubFeature\"",
                                "waitAfterCompletion": "0"
                            }
                        }
                    },
                    "02-ConfigureApplication": {
                        "files": {
                            "c:\\Inetpub\\wwwroot\\index.htm": {
                                "content": "<html> <head> <title>Test Application Page</title> </head> <body> <h1>Congratulations!! Your IIS server is configured.</h1> </body> </html>"
                            }
                        }
                    },
                    "03-Finalize": {
                        "commands": {
                            "00_signal_success": {
                                "command": {
                                    "Fn::Sub": "cfn-signal.exe -e 0 --resource WebServerHost --stack ${AWS::StackName} --region ${AWS::Region}"
                                },
                                "waitAfterCompletion": "0"
                            }
                        }
                    }
                }
            },
            "Properties": {
                "KeyName": {
                    "Ref": "KeyPair"
                },
                "ImageId": "{{resolve:ssm:/aws/service/ami-windows-latest/Windows_Server-2012-R2_RTM-English-64Bit-Base}}",
                "InstanceType": "t2.xlarge",
                "SecurityGroupIds": [{"Ref": "WebServerSecurityGroup"}],
                "IamInstanceProfile": {"Ref": "LogRoleInstanceProfile"},
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "<script>\n",
                                "wmic product where \"description='Amazon SSM Agent' \" uninstall\n",
                                "wmic product where \"description='aws-cfn-bootstrap' \" uninstall \n",
                                "start /wait c:\\Windows\\system32\\msiexec /passive /qn /i https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-win64-latest.msi\n",
                                "powershell.exe -Command \"iwr https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe  -UseBasicParsing -OutFile C:\\AmazonSSMAgentSetup.exe\"\n",
                                "start /wait C:\\AmazonSSMAgentSetup.exe /install /quiet\n",
                                "cfn-init.exe -v -c config -s ", {"Ref": "AWS::StackName"}, " --resource WebServerHost --region ", {"Ref": "AWS::Region"}, " \n",
                                "</script>\n"
                            ]
                        ]
                    }
                }
            }
        },
        "LogGroup": {
            "Type": "AWS::Logs::LogGroup",
            "Properties": {
                "RetentionInDays": 7
            }
        },
        "404MetricFilter": {
            "Type": "AWS::Logs::MetricFilter",
            "Properties": {
                "LogGroupName": {"Ref": "LogGroup"},
                "FilterPattern": "[timestamps, serverip, method, uri, query, port, dash, clientip, useragent, status_code = 404, ...]",
                "MetricTransformations": [
                    {
                        "MetricValue": "1",
                        "MetricNamespace": "test/404s",
                        "MetricName": "test404Count"
                    }
                ]
            }
        },
        "404Alarm": {
            "Type": "AWS::CloudWatch::Alarm",
            "Properties": {
                "AlarmDescription": "The number of 404s is greater than 2 over 2 minutes",
                "MetricName": "test404Count",
                "Namespace": "test/404s",
                "Statistic": "Sum",
                "Period": "60",
                "EvaluationPeriods": "2",
                "Threshold": "2",
                "AlarmActions": [{"Ref": "AlarmNotificationTopic"}],
                "ComparisonOperator": "GreaterThanThreshold"
            }
        },
        "AlarmNotificationTopic": {
            "Type": "AWS::SNS::Topic",
            "Properties": {
                "Subscription": [{"Endpoint": {"Ref": "OperatorEmail"}, "Protocol": "email"}]
            }
        }
    },
    "Outputs": {
        "InstanceId": {
            "Description": "The instance ID of the web server",
            "Value": {"Ref": "WebServerHost"}
        },
        "WebsiteURL": {
            "Value": {"Fn::Sub": "http://${WebServerHost.PublicDnsName}"},
            "Description": "URL for the web server"
        },
        "PublicIP": {
            "Description": "Public IP address of the web server",
            "Value": {"Fn::GetAtt": ["WebServerHost","PublicIp"]}
        },
        "CloudWatchLogGroupName": {
            "Description": "The name of the CloudWatch log group",
            "Value": {"Ref": "LogGroup"}
        }
    }
}
```

### YAML
<a name="quickref-cloudwatchlogs-example2.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Description: >-
  Sample template that sets up and configures CloudWatch Logs on Windows 2012R2 instance.
Parameters:
  KeyPair:
    Description: Name of an existing EC2 KeyPair to enable RDP access to the instances
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  RDPLocation:
    Description: The IP address range that can be used to RDP to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  OperatorEmail:
    Description: Email address to notify when CloudWatch alarms are triggered (404 errors)
    Type: String
Resources:
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80 and RDP access via port 3389
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '3389'
          ToPort: '3389'
          CidrIp: !Ref RDPLocation
  LogRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17		 	 	 
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'
      Path: /
      Policies:
        - PolicyName: LogRolePolicy
          PolicyDocument:
            Version: 2012-10-17		 	 	 
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:Create*'
                  - 'logs:PutLogEvents'
                  - 's3:GetObject'
                Resource:
                  - 'arn:aws:logs:*:*:*'
                  - 'arn:aws:s3:::*'
  LogRoleInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref LogRole
  WebServerHost:
    Type: AWS::EC2::Instance
    CreationPolicy:
      ResourceSignal:
        Timeout: PT15M
    Metadata:
      'AWS::CloudFormation::Init':
        configSets:
          config:
            - 00-ConfigureCWLogs
            - 01-InstallWebServer
            - 02-ConfigureApplication
            - 03-Finalize
        00-ConfigureCWLogs:
          files:
            'C:\Program Files\Amazon\SSM\Plugins\awsCloudWatch\AWS.EC2.Windows.CloudWatch.json':
              content: !Sub |
                {
                  "EngineConfiguration": {
                      "Components": [
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                              "Id": "ApplicationEventLog",
                              "Parameters": {
                                  "Levels": "7",
                                  "LogName": "Application"
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                              "Id": "SystemEventLog",
                              "Parameters": {
                                  "Levels": "7",
                                  "LogName": "System"
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                              "Id": "SecurityEventLog",
                              "Parameters": {
                                  "Levels": "7",
                                  "LogName": "Security"
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch",
                              "Id": "EC2ConfigLog",
                              "Parameters": {
                                  "CultureName": "en-US",
                                  "Encoding": "ASCII",
                                  "Filter": "EC2ConfigLog.txt",
                                  "LogDirectoryPath": "C:\\Program Files\\Amazon\\Ec2ConfigService\\Logs",
                                  "TimeZoneKind": "UTC",
                                  "TimestampFormat": "yyyy-MM-ddTHH:mm:ss.fffZ:"
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch",
                              "Id": "CfnInitLog",
                              "Parameters": {
                                  "CultureName": "en-US",
                                  "Encoding": "ASCII",
                                  "Filter": "cfn-init.log",
                                  "LogDirectoryPath": "C:\\cfn\\log",
                                  "TimeZoneKind": "Local",
                                  "TimestampFormat": "yyyy-MM-dd HH:mm:ss,fff"
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch",
                              "Id": "IISLogs",
                              "Parameters": {
                                  "CultureName": "en-US",
                                  "Encoding": "UTF-8",
                                  "Filter": "",
                                  "LineCount": "3",
                                  "LogDirectoryPath": "C:\\inetpub\\logs\\LogFiles\\W3SVC1",
                                  "TimeZoneKind": "UTC",
                                  "TimestampFormat": "yyyy-MM-dd HH:mm:ss"
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                              "Id": "MemoryPerformanceCounter",
                              "Parameters": {
                                  "CategoryName": "Memory",
                                  "CounterName": "Available MBytes",
                                  "DimensionName": "",
                                  "DimensionValue": "",
                                  "InstanceName": "",
                                  "MetricName": "Memory",
                                  "Unit": "Megabytes"
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                              "Id": "CloudWatchApplicationEventLog",
                              "Parameters": {
                                  "AccessKey": "",
                                  "LogGroup": "${LogGroup}",
                                  "LogStream": "{instance_id}/ApplicationEventLog",
                                  "Region": "${AWS::Region}",
                                  "SecretKey": ""
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                              "Id": "CloudWatchSystemEventLog",
                              "Parameters": {
                                  "AccessKey": "",
                                  "LogGroup": "${LogGroup}",
                                  "LogStream": "{instance_id}/SystemEventLog",
                                  "Region": "${AWS::Region}",
                                  "SecretKey": ""
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                              "Id": "CloudWatchSecurityEventLog",
                              "Parameters": {
                                  "AccessKey": "",
                                  "LogGroup": "${LogGroup}",
                                  "LogStream": "{instance_id}/SecurityEventLog",
                                  "Region": "${AWS::Region}",
                                  "SecretKey": ""
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                              "Id": "CloudWatchEC2ConfigLog",
                              "Parameters": {
                                  "AccessKey": "",
                                  "LogGroup": "${LogGroup}",
                                  "LogStream": "{instance_id}/EC2ConfigLog",
                                  "Region": "${AWS::Region}",
                                  "SecretKey": ""
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                              "Id": "CloudWatchCfnInitLog",
                              "Parameters": {
                                  "AccessKey": "",
                                  "LogGroup": "${LogGroup}",
                                  "LogStream": "{instance_id}/CfnInitLog",
                                  "Region": "${AWS::Region}",
                                  "SecretKey": ""
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                              "Id": "CloudWatchIISLogs",
                              "Parameters": {
                                  "AccessKey": "",
                                  "LogGroup": "${LogGroup}",
                                  "LogStream": "{instance_id}/IISLogs",
                                  "Region": "${AWS::Region}",
                                  "SecretKey": ""
                              }
                          },
                          {
                              "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatch.CloudWatchOutputComponent,AWS.EC2.Windows.CloudWatch",
                              "Id": "CloudWatch",
                              "Parameters": {
                                  "AccessKey": "",
                                  "NameSpace": "Windows/Default",
                                  "Region": "${AWS::Region}",
                                  "SecretKey": ""
                              }
                          }
                      ],
                      "Flows": {
                          "Flows": [
                              "ApplicationEventLog,CloudWatchApplicationEventLog",
                              "SystemEventLog,CloudWatchSystemEventLog",
                              "SecurityEventLog,CloudWatchSecurityEventLog",
                              "EC2ConfigLog,CloudWatchEC2ConfigLog",
                              "CfnInitLog,CloudWatchCfnInitLog",
                              "IISLogs,CloudWatchIISLogs",
                              "MemoryPerformanceCounter,CloudWatch"
                          ]
                      },
                      "PollInterval": "00:00:05"
                  },
                  "IsEnabled": true
                }
          commands:
            0-enableSSM:
              command: >-
                powershell.exe -Command "Set-Service -Name AmazonSSMAgent
                -StartupType Automatic" 
              waitAfterCompletion: '0'
            1-restartSSM:
              command: powershell.exe -Command "Restart-Service AmazonSSMAgent "
              waitAfterCompletion: '30'
        01-InstallWebServer:
          commands:
            01_install_webserver:
              command: >-
                powershell.exe -Command "Install-WindowsFeature Web-Server 
                -IncludeAllSubFeature"
              waitAfterCompletion: '0'
        02-ConfigureApplication:
          files:
            'c:\Inetpub\wwwroot\index.htm':
              content: >-
                <html> <head> <title>Test Application Page</title> </head>
                <body> <h1>Congratulations !! Your IIS server is
                configured.</h1> </body> </html>
        03-Finalize:
          commands:
            00_signal_success:
              command: !Sub >-
                cfn-signal.exe -e 0 --resource WebServerHost --stack
                ${AWS::StackName} --region ${AWS::Region}
              waitAfterCompletion: '0'
    Properties:
      KeyName: !Ref KeyPair
      ImageId: "{{resolve:ssm:/aws/service/ami-windows-latest/Windows_Server-2012-R2_RTM-English-64Bit-Base}}"
      InstanceType: t2.xlarge
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      IamInstanceProfile: !Ref LogRoleInstanceProfile
      UserData: !Base64 
        'Fn::Sub': >
          <script>

          wmic product where "description='Amazon SSM Agent' " uninstall

          wmic product where "description='aws-cfn-bootstrap' " uninstall 

          start /wait c:\\Windows\\system32\\msiexec /passive /qn /i
          https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-win64-latest.msi

          powershell.exe -Command "iwr
          https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe 
          -UseBasicParsing -OutFile C:\\AmazonSSMAgentSetup.exe"

          start /wait C:\\AmazonSSMAgentSetup.exe /install /quiet

          cfn-init.exe -v -c config -s ${AWS::StackName} --resource
          WebServerHost --region ${AWS::Region} 

          </script>
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      RetentionInDays: 7
  404MetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref LogGroup
      FilterPattern: >-
        [timestamps, serverip, method, uri, query, port, dash, clientip,
        useragent, status_code = 404, ...]
      MetricTransformations:
        - MetricValue: '1'
          MetricNamespace: test/404s
          MetricName: test404Count
  404Alarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: The number of 404s is greater than 2 over 2 minutes
      MetricName: test404Count
      Namespace: test/404s
      Statistic: Sum
      Period: '60'
      EvaluationPeriods: '2'
      Threshold: '2'
      AlarmActions:
        - !Ref AlarmNotificationTopic
      ComparisonOperator: GreaterThanThreshold
  AlarmNotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref OperatorEmail
          Protocol: email
Outputs:
  InstanceId:
    Description: The instance ID of the web server
    Value: !Ref WebServerHost
  WebsiteURL:
    Value: !Sub 'http://${WebServerHost.PublicDnsName}'
    Description: URL for the web server
  PublicIP:
    Description: Public IP address of the web server
    Value: !GetAtt 
      - WebServerHost
      - PublicIp
  CloudWatchLogGroupName:
    Description: The name of the CloudWatch log group
    Value: !Ref LogGroup
```

## 另請參閱
<a name="w2aac11c41c35c11"></a>

如需有關 CloudWatch Logs 資源的詳細資訊，請參閱 [AWS::Logs::LogGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-logs-loggroup.html) 或 [AWS::Logs::MetricFilter](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-logs-metricfilter.html)。

# Amazon DynamoDB 範本程式碼片段
<a name="quickref-dynamodb"></a>

**Topics**
+ [Application Auto Scaling 搭配 Amazon DynamoDB 資料表](#quickref-dynamodb-application-autoscaling)
+ [另請參閱](#w2aac11c41c39b7)

## Application Auto Scaling 搭配 Amazon DynamoDB 資料表
<a name="quickref-dynamodb-application-autoscaling"></a>

此範例會為 `AWS::DynamoDB::Table` 資源設定應用程式 Auto Scaling。範本所定義的 `TargetTrackingScaling` 擴展政策，則可向上擴展資料表的 `WriteCapacityUnits` 傳輸量。

### JSON
<a name="quickref-dynamodb-example.json"></a>

```
{
    "Resources": {
        "DDBTable": {
            "Type": "AWS::DynamoDB::Table",
            "Properties": {
                "AttributeDefinitions": [
                    {
                        "AttributeName": "ArtistId",
                        "AttributeType": "S"
                    },
                    {
                        "AttributeName": "Concert",
                        "AttributeType": "S"
                    },
                    {
                        "AttributeName": "TicketSales",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "ArtistId",
                        "KeyType": "HASH"
                    },
                    {
                        "AttributeName": "Concert",
                        "KeyType": "RANGE"
                    }
                ],
                "GlobalSecondaryIndexes": [
                    {
                        "IndexName": "GSI",
                        "KeySchema": [
                            {
                                "AttributeName": "TicketSales",
                                "KeyType": "HASH"
                            }
                        ],
                        "Projection": {
                            "ProjectionType": "KEYS_ONLY"
                        },
                        "ProvisionedThroughput": {
                            "ReadCapacityUnits": 5,
                            "WriteCapacityUnits": 5
                        }
                    }
                ],
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 5,
                    "WriteCapacityUnits": 5
                }
            }
        },
        "WriteCapacityScalableTarget": {
            "Type": "AWS::ApplicationAutoScaling::ScalableTarget",
            "Properties": {
                "MaxCapacity": 15,
                "MinCapacity": 5,
                "ResourceId": {
                    "Fn::Join": [
                        "/",
                        [
                            "table",
                            {
                                "Ref": "DDBTable"
                            }
                        ]
                    ]
                },
                "RoleARN" : { "Fn::Sub" : "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable" },
                "ScalableDimension": "dynamodb:table:WriteCapacityUnits",
                "ServiceNamespace": "dynamodb"
            }
        },
        "WriteScalingPolicy": {
            "Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
            "Properties": {
                "PolicyName": "WriteAutoScalingPolicy",
                "PolicyType": "TargetTrackingScaling",
                "ScalingTargetId": {
                    "Ref": "WriteCapacityScalableTarget"
                },
                "TargetTrackingScalingPolicyConfiguration": {
                    "TargetValue": 50,
                    "ScaleInCooldown": 60,
                    "ScaleOutCooldown": 60,
                    "PredefinedMetricSpecification": {
                        "PredefinedMetricType": "DynamoDBWriteCapacityUtilization"
                    }
                }
            }
        }
    }
}
```

### YAML
<a name="quickref-dynamodb-example.yaml"></a>

```
Resources:
  DDBTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: "ArtistId"
          AttributeType: "S"
        - AttributeName: "Concert"
          AttributeType: "S"
        - AttributeName: "TicketSales"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "ArtistId"
          KeyType: "HASH"
        - AttributeName: "Concert"
          KeyType: "RANGE"
      GlobalSecondaryIndexes:
        - IndexName: "GSI"
          KeySchema:
            - AttributeName: "TicketSales"
              KeyType: "HASH"
          Projection:
            ProjectionType: "KEYS_ONLY"
          ProvisionedThroughput:
            ReadCapacityUnits: 5
            WriteCapacityUnits: 5
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
  WriteCapacityScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: 15
      MinCapacity: 5
      ResourceId: !Join
        - /
        - - table
          - !Ref DDBTable
      RoleARN:
        Fn::Sub: 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable'
      ScalableDimension: dynamodb:table:WriteCapacityUnits
      ServiceNamespace: dynamodb
  WriteScalingPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: WriteAutoScalingPolicy
      PolicyType: TargetTrackingScaling
      ScalingTargetId: !Ref WriteCapacityScalableTarget
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: 50.0
        ScaleInCooldown: 60
        ScaleOutCooldown: 60
        PredefinedMetricSpecification:
          PredefinedMetricType: DynamoDBWriteCapacityUtilization
```

## 另請參閱
<a name="w2aac11c41c39b7"></a>

如需詳細資訊，請參閱 資料庫部落格上的部落格文章[如何使用 CloudFormation 設定 DynamoDB 資料表和索引的自動擴展](https://aws.amazon.com/blogs/database/how-to-use-aws-cloudformation-to-configure-auto-scaling-for-amazon-dynamodb-tables-and-indexes/) AWS 。

如需有關 DynamoDB 資源的詳細資訊，請參閱 [AWS::DynamoDB::Table](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-dynamodb-table.html)。

# Amazon EC2 CloudFormation 範本程式碼片段
<a name="quickref-ec2"></a>

Amazon EC2 在 AWS 雲端中提供可擴展的運算容量。您可使用 Amazon EC2 按需要啟動任意數量的虛擬伺服器，設定安全性和聯網功能以及管理儲存。這些虛擬伺服器 (稱為執行個體) 可執行各種作業系統和應用程式，並且可進行自訂，以滿足您的特定需求。Amazon EC2 可讓您縱向擴展或縮減，以處理需求變更或用量尖峰。

您可使用 CloudFormation 範本來定義和佈建 Amazon EC2 執行個體，作為基礎設施的一部分。範本可讓您以可重複且一致的方式，輕鬆管理和自動化 Amazon EC2 資源的部署。

下列範例範本程式碼片段描述了 Amazon EC2 的 CloudFormation 資源或元件。這些程式碼片段設計用於整合至範本中，而且並非設計為獨立執行。

**Topics**
+ [設定 EC2 執行個體](quickref-ec2-instance-config.md)
+ [建立啟動範本](quickref-ec2-launch-templates.md)
+ [管理安全群組](quickref-ec2-sg.md)
+ [配置彈性 IP](quickref-ec2-elastic-ip.md)
+ [設定 VPC 資源](quickref-ec2-vpc.md)

# 使用 CloudFormation 設定 Amazon EC2 執行個體
<a name="quickref-ec2-instance-config"></a>

下列程式碼片段示範了如何使用 CloudFormation 設定 Amazon EC2 執行個體。

**Topics**
+ [一般 Amazon EC2 組態](#quickref-ec2-instance-config-general)
+ [指定執行個體的區塊型裝置映射](#scenario-ec2-bdm)

## 一般 Amazon EC2 組態
<a name="quickref-ec2-instance-config-general"></a>

下列程式碼片段示範了使用 CloudFormation 設定 Amazon EC2 執行個體的一般組態。

**Topics**
+ [在指定的可用區域建立 Amazon EC2 執行個體](#scenario-ec2-instance)
+ [使用 EBS 磁碟區和使用者資料設定標記的 Amazon EC2 執行個體](#scenario-ec2-instance-with-vol-and-tags)
+ [在 Amazon EC2 執行個體啟動的使用者資料中定義 DynamoDB 資料表名稱](#scenario-ec2-with-sdb-domain)
+ [使用 `DeletionPolicy` 建立 Amazon EBS 磁碟區](#scenario-ec2-volume)

### 在指定的可用區域建立 Amazon EC2 執行個體
<a name="scenario-ec2-instance"></a>

下列程式碼片段使用 [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源，在指定的可用區域建立 Amazon EC2 執行個體。可用區域的代碼為其區域代碼，後續跟著一個字母識別符。您可在單一可用區域啟動執行個體。

#### JSON
<a name="quickref-ec2-example-6.json"></a>

```
1. "Ec2Instance": {
2.     "Type": "AWS::EC2::Instance",
3.     "Properties": {
4.         "AvailabilityZone": "aa-example-1a",
5.         "ImageId": "ami-1234567890abcdef0"
6.     }
7. }
```

#### YAML
<a name="quickref-ec2-example-6.yaml"></a>

```
1. Ec2Instance:
2.   Type: AWS::EC2::Instance
3.   Properties:
4.     AvailabilityZone: aa-example-1a
5.     ImageId: ami-1234567890abcdef0
```

### 使用 EBS 磁碟區和使用者資料設定標記的 Amazon EC2 執行個體
<a name="scenario-ec2-instance-with-vol-and-tags"></a>

下列程式碼片段會建立具有標籤、EBS 磁碟區和使用者資料的 Amazon EC2 執行個體。它會使用 [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源。在相同的範本中，您必須定義 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源、[AWS::SNS::Topic](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topic.html) 資源和 [AWS::EC2::Volume](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-volume.html) 資源。必須在範本的 `Parameters` 區段中定義 `KeyName`。

標籤可協助您根據您的偏好設定分類 AWS 資源，例如依用途、擁有者或環境。使用者資料允許在啟動期間，將自訂指令碼或資料佈建至執行個體。此資料有助於在初始化期間，對執行個體執行任務自動化、軟體組態設定、套件安裝及其他動作。

如需有關標記您的資源的詳細資訊，請參閱《[Amazon EC2 使用者指南](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html)》中的*標記您的 Amazon EC2 資源*。

如需關於使用者資料的資訊，請參閱《Amazon EC2 使用者指南》**中的[使用執行個體中繼資料管理您的 EC2 執行個體](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)。

#### JSON
<a name="quickref-ec2-example-7.json"></a>

```
 1. "Ec2Instance": {
 2.   "Type": "AWS::EC2::Instance",
 3.   "Properties": {
 4.     "KeyName": { "Ref": "KeyName" },
 5.     "SecurityGroups": [ { "Ref": "Ec2SecurityGroup" } ],
 6.     "UserData": {
 7.       "Fn::Base64": {
 8.         "Fn::Join": [ ":", [
 9.             "PORT=80",
10.             "TOPIC=",
11.             { "Ref": "MySNSTopic" }
12.           ]
13.         ]
14.       }
15.     },
16.     "InstanceType": "aa.size",
17.     "AvailabilityZone": "aa-example-1a",
18.     "ImageId": "ami-1234567890abcdef0",
19.     "Volumes": [
20.       {
21.         "VolumeId": { "Ref": "MyVolumeResource" },
22.         "Device": "/dev/sdk"
23.       }
24.     ],
25.     "Tags": [ { "Key": "Name", "Value": "MyTag" } ]
26.   }
27. }
```

#### YAML
<a name="quickref-ec2-example-7.yaml"></a>

```
 1. Ec2Instance:
 2.   Type: AWS::EC2::Instance
 3.   Properties:
 4.     KeyName: !Ref KeyName
 5.     SecurityGroups:
 6.       - !Ref Ec2SecurityGroup
 7.     UserData:
 8.       Fn::Base64:
 9.         Fn::Join:
10.           - ":"
11.           - - "PORT=80"
12.             - "TOPIC="
13.             - !Ref MySNSTopic
14.     InstanceType: aa.size
15.     AvailabilityZone: aa-example-1a
16.     ImageId: ami-1234567890abcdef0
17.     Volumes:
18.       - VolumeId: !Ref MyVolumeResource
19.         Device: "/dev/sdk"
20.     Tags:
21.       - Key: Name
22.         Value: MyTag
```

### 在 Amazon EC2 執行個體啟動的使用者資料中定義 DynamoDB 資料表名稱
<a name="scenario-ec2-with-sdb-domain"></a>

下列程式碼片段會建立 Amazon EC2 執行個體，並在使用者資料中定義 DynamoDB 資料表名稱，以便在啟動時傳遞至執行個體。它會使用 [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源。您可在使用者資料中定義參數或動態值，以便在啟動時傳遞 EC2 執行個體。

如需關於使用者資料的更多資訊，請參閱*《Amazon EC2 使用者指南》*中的[使用執行個體中繼資料管理您的 EC2 執行個體](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)。

#### JSON
<a name="quickref-ec2-example-8.json"></a>

```
 1. "Ec2Instance": {
 2.     "Type": "AWS::EC2::Instance",
 3.     "Properties": {
 4.         "UserData": {
 5.             "Fn::Base64": {
 6.                 "Fn::Join": [
 7.                     "",
 8.                     [
 9.                         "TableName=",
10.                         {
11.                             "Ref": "DynamoDBTableName"
12.                         }
13.                     ]
14.                 ]
15.             }
16.         },
17.         "AvailabilityZone": "aa-example-1a",
18.         "ImageId": "ami-1234567890abcdef0"
19.     }
20. }
```

#### YAML
<a name="quickref-ec2-example-8.yaml"></a>

```
 1. Ec2Instance:
 2.   Type: AWS::EC2::Instance
 3.   Properties:
 4.     UserData:
 5.       Fn::Base64:
 6.         Fn::Join:
 7.           - ''
 8.           - - 'TableName='
 9.             - Ref: DynamoDBTableName
10.     AvailabilityZone: aa-example-1a
11.     ImageId: ami-1234567890abcdef0
```

### 使用 `DeletionPolicy` 建立 Amazon EBS 磁碟區
<a name="scenario-ec2-volume"></a>

下列程式碼片段使用 Amazon EC2 [AWS::EC2::Volume](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-volume.html) 資源來建立 Amazon EBS 磁碟區。您可使用 `Size` 或 `SnapshotID` 屬性來定義磁碟區，但不能同時使用兩者。`DeletionPolicy` 屬性設定為在刪除堆疊時建立磁碟區快照。

如需有關 `DeletionPolicy` 屬性的詳細資訊，請參閱 [DeletionPolicy 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-deletionpolicy.html)。

如需有關建立 Amazon EBS 磁碟區的詳細資訊，請參閱[建立 Amazon EBS 磁碟區](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-creating-volume.html)。

#### JSON
<a name="quickref-ec2-example-13.json"></a>

此程式碼片段會建立具有指定**大小**的 Amazon EBS 磁碟區。大小設定為 10，但您可視需進行調整。[AWS::EC2::Volume](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-volume.html) 資源允許您指定大小或快照 ID，但不能同時指定兩者。

```
 1. "MyEBSVolume": {
 2.     "Type": "AWS::EC2::Volume",
 3.     "Properties": {
 4.         "Size": "10",
 5.         "AvailabilityZone": {
 6.             "Ref": "AvailabilityZone"
 7.         }
 8.     },
 9.     "DeletionPolicy": "Snapshot"
10. }
```

此程式碼片段使用提供的**快照 ID** 來建立 Amazon EBS 磁碟區。[AWS::EC2::Volume](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-volume.html) 資源允許您指定大小或快照 ID，但不能同時指定兩者。

```
 1. "MyEBSVolume": {
 2.     "Type": "AWS::EC2::Volume",
 3.     "Properties": {
 4.         "SnapshotId" : "snap-1234567890abcdef0",
 5.         "AvailabilityZone": {
 6.             "Ref": "AvailabilityZone"
 7.         }
 8.     },
 9.     "DeletionPolicy": "Snapshot"
10. }
```

#### YAML
<a name="quickref-ec2-example-13.yaml"></a>

此程式碼片段會建立具有指定**大小**的 Amazon EBS 磁碟區。大小設定為 10，但您可視需進行調整。[AWS::EC2::Volume](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-volume.html) 資源允許您指定大小或快照 ID，但不能同時指定兩者。

```
1. MyEBSVolume:
2.   Type: AWS::EC2::Volume
3.   Properties:
4.     Size: 10
5.     AvailabilityZone:
6.       Ref: AvailabilityZone
7.   DeletionPolicy: Snapshot
```

此程式碼片段使用提供的**快照 ID** 來建立 Amazon EBS 磁碟區。[AWS::EC2::Volume](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-volume.html) 資源允許您指定大小或快照 ID，但不能同時指定兩者。

```
1. MyEBSVolume:
2.   Type: AWS::EC2::Volume
3.   Properties:
4.     SnapshotId: snap-1234567890abcdef0
5.     AvailabilityZone:
6.       Ref: AvailabilityZone
7.   DeletionPolicy: Snapshot
```

## 指定執行個體的區塊型裝置映射
<a name="scenario-ec2-bdm"></a>

區塊型裝置映射定義區塊型儲存裝置，其中包括要附接至執行個體的執行個體儲存體磁碟區和 EBS 磁碟區。您可在建立 AMI 時指定區塊型裝置映射，如此從 AMI 啟動的所有執行個體都會使用該映射。或者，也可在啟動執行個體時指定區塊型裝置映射，如此該映射會覆寫啟動執行個體之 AMI 中指定的映射。

您可使用下列範本程式碼片段，以使用 [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源的 `BlockDeviceMappings` 屬性為 EBS 或執行個體儲存體磁碟區指定區塊型裝置映射。

如需區塊型儲存設備映射的詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的 [Amazon EC2 執行個體上磁碟區的區塊型儲存設備映射](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html)。

**Topics**
+ [為兩個 EBS 磁碟區指定區塊型裝置映射](#w2aac11c41c43c13b9c11)
+ [為執行個體儲存體磁碟區指定區塊型裝置映射](#w2aac11c41c43c13b9c13)

### 為兩個 EBS 磁碟區指定區塊型裝置映射
<a name="w2aac11c41c43c13b9c11"></a>

#### JSON
<a name="quickref-ec2-example-1.json"></a>

```
"Ec2Instance": {
    "Type": "AWS::EC2::Instance",
    "Properties": {
      "ImageId": "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
      "KeyName": { "Ref": "KeyName" },
      "InstanceType": { "Ref": "InstanceType" },
      "SecurityGroups": [{ "Ref": "Ec2SecurityGroup" }],
      "BlockDeviceMappings": [
        {
          "DeviceName": "/dev/sda1",
          "Ebs": { "VolumeSize": "50" }
        },
        {
          "DeviceName": "/dev/sdm",
          "Ebs": { "VolumeSize": "100" }
        }
      ]
    }
  }
}
```

#### YAML
<a name="quickref-ec2-example-1.yaml"></a>

```
EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
      KeyName: !Ref KeyName
      InstanceType: !Ref InstanceType
      SecurityGroups:
        - !Ref Ec2SecurityGroup
      BlockDeviceMappings:
        -
          DeviceName: /dev/sda1
          Ebs:
            VolumeSize: 50
        -
          DeviceName: /dev/sdm
          Ebs:
            VolumeSize: 100
```

### 為執行個體儲存體磁碟區指定區塊型裝置映射
<a name="w2aac11c41c43c13b9c13"></a>

#### JSON
<a name="quickref-ec2-example-2.json"></a>

```
"Ec2Instance" : {
  "Type" : "AWS::EC2::Instance", 
  "Properties" : {
    "ImageId" : "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
    "KeyName" : { "Ref" : "KeyName" },
    "InstanceType": { "Ref": "InstanceType" },
    "SecurityGroups" : [{ "Ref" : "Ec2SecurityGroup" }],
    "BlockDeviceMappings" : [
      {
        "DeviceName"  : "/dev/sdc",
        "VirtualName" : "ephemeral0"
      }
    ]
  }
}
```

#### YAML
<a name="quickref-ec2-example-2.yaml"></a>

```
EC2Instance:
  Type: AWS::EC2::Instance
  Properties:
    ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
    KeyName: !Ref KeyName
    InstanceType: !Ref InstanceType
    SecurityGroups:
      - !Ref Ec2SecurityGroup
    BlockDeviceMappings:
      - DeviceName: /dev/sdc
        VirtualName: ephemeral0
```

# 透過 CloudFormation 建立啟動範本
<a name="quickref-ec2-launch-templates"></a>

本節提供一個透過 CloudFormation 建立 Amazon EC2 啟動範本的範例。啟動範本可讓您建立用於在 AWS中設定和佈建 Amazon EC2 執行個體的範本。使用啟動範本，您可以來存放啟動參數，如此您就不需要在每次啟動執行個體時指定參數。如需更多範例，請參閱 `AWS::EC2::LaunchTemplate` 中的[範例](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html#aws-resource-ec2-launchtemplate--examples)區段。

如需有關啟動範本的詳細資訊，請參閱《[Amazon EC2 使用者指南](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html)》中的*在 Amazon EC2 啟動範本中儲存執行個體啟動參數*。

如需有關使用 Auto Scaling 群組建立啟動範本的資訊，請參閱《*Amazon EC2 Auto Scaling 使用者指南*》中的 [Auto Scaling 啟動範本](https://docs.aws.amazon.com/autoscaling/ec2/userguide/launch-templates.html)。

**Topics**
+ [建立指定安全群組、標籤、使用者資料及 IAM 角色的啟動範本](#scenario-as-launch-template)

## 建立指定安全群組、標籤、使用者資料及 IAM 角色的啟動範本
<a name="scenario-as-launch-template"></a>

此程式碼片段顯示 [AWS::EC2::LaunchTemplate](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html) 資源，其中包含啟動執行個體的組態資訊。您可為 `ImageId`、`InstanceType`、`SecurityGroups`、`UserData` 以及 `TagSpecifications` 屬性指定值。`SecurityGroups` 屬性指定現有 EC2 安全群組以及新的安全群組。`Ref` 函數取得在堆疊範本中其他處宣告的 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源 `myNewEC2SecurityGroup` 之 ID。

啟動範本包含自訂使用者資料的區段。您可以在本區段中執行個體啟動時傳入執行的組態任務和指令碼。在此範例中，使用者資料會安裝 AWS Systems Manager 代理程式並啟動 代理程式。

啟動範本還包含 IAM 角色，該角色允許在執行個體上執行的應用程式代表您執行動作。此範例顯示啟動範本的 [AWS::IAM::Role](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-role.html) 資源，此資源使用 `IamInstanceProfile` 屬性指定 IAM 角色。`Ref` 函數取得 [AWS::IAM::InstanceProfile](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-instanceprofile.html) 資源 `myInstanceProfile` 的名稱。若要設定 IAM 角色的許可，請為 `ManagedPolicyArns` 屬性指定值。

### JSON
<a name="quickref-launch-template-example-1.json"></a>

```
 1. {
 2.   "Resources":{
 3.     "myLaunchTemplate":{
 4.       "Type":"AWS::EC2::LaunchTemplate",
 5.       "Properties":{
 6.         "LaunchTemplateName":{ "Fn::Sub": "${AWS::StackName}-launch-template" },
 7.         "LaunchTemplateData":{
 8.           "ImageId":"ami-02354e95b3example",
 9.           "InstanceType":"t3.micro",
10.           "IamInstanceProfile":{
11.             "Name":{
12.               "Ref":"myInstanceProfile"
13.             }
14.           },
15.           "SecurityGroupIds":[
16.             {
17.               "Ref":"myNewEC2SecurityGroup"
18.             },
19.             "sg-083cd3bfb8example"
20.           ],
21.           "UserData":{
22.             "Fn::Base64":{
23.               "Fn::Join": [
24.                 "", [
25.                   "#!/bin/bash\n",
26.                   "cd /tmp\n",
27.                   "yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm\n",
28.                   "systemctl enable amazon-ssm-agent\n",
29.                   "systemctl start amazon-ssm-agent\n"
30.                 ]
31.               ]
32.             }
33.           },
34.           "TagSpecifications":[
35.             {
36.               "ResourceType":"instance",
37.               "Tags":[
38.                 {
39.                   "Key":"environment",
40.                   "Value":"development"
41.                 }
42.               ]
43.             },
44.             {
45.               "ResourceType":"volume",
46.               "Tags":[
47.                 {
48.                   "Key":"environment",
49.                   "Value":"development"
50.                 }
51.               ]
52.             }
53.           ]
54.         }
55.       }
56.     },
57.     "myInstanceRole":{
58.       "Type":"AWS::IAM::Role",
59.       "Properties":{
60.         "RoleName":"InstanceRole",
61.         "AssumeRolePolicyDocument":{
62.           "Version": "2012-10-17",		 	 	 
63.           "Statement":[
64.             {
65.               "Effect":"Allow",
66.               "Principal":{
67.                 "Service":[
68.                   "ec2.amazonaws.com"
69.                 ]
70.               },
71.               "Action":[
72.                 "sts:AssumeRole"
73.               ]
74.             }
75.           ]
76.         },
77.         "ManagedPolicyArns":[
78.           "arn:aws:iam::aws:policy/myCustomerManagedPolicy"
79.         ]
80.       }
81.     },
82.     "myInstanceProfile":{
83.       "Type":"AWS::IAM::InstanceProfile",
84.       "Properties":{
85.         "Path":"/",
86.         "Roles":[
87.           {
88.             "Ref":"myInstanceRole"
89.           }
90.         ]
91.       }
92.     }
93.   }
94. }
```

### YAML
<a name="quickref-launch-template-example-1.yaml"></a>

```
 1. ---
 2. Resources:
 3.   myLaunchTemplate:
 4.     Type: AWS::EC2::LaunchTemplate
 5.     Properties:
 6.       LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
 7.       LaunchTemplateData:
 8.         ImageId: ami-02354e95b3example
 9.         InstanceType: t3.micro
10.         IamInstanceProfile:
11.           Name: !Ref myInstanceProfile
12.         SecurityGroupIds:
13.         - !Ref myNewEC2SecurityGroup
14.         - sg-083cd3bfb8example
15.         UserData:
16.           Fn::Base64: !Sub |
17.             #!/bin/bash
18.             cd /tmp
19.             yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
20.             systemctl enable amazon-ssm-agent
21.             systemctl start amazon-ssm-agent
22.         TagSpecifications:
23.         - ResourceType: instance
24.           Tags:
25.           - Key: environment
26.             Value: development
27.         - ResourceType: volume
28.           Tags:
29.           - Key: environment
30.             Value: development
31.   myInstanceRole:
32.     Type: AWS::IAM::Role
33.     Properties:
34.       RoleName: InstanceRole
35.       AssumeRolePolicyDocument:
36.         Version: '2012-10-17'
37.         Statement:
38.         - Effect: 'Allow'
39.           Principal:
40.             Service:
41.             - 'ec2.amazonaws.com'
42.           Action:
43.           - 'sts:AssumeRole'
44.       ManagedPolicyArns:
45.         - 'arn:aws:iam::aws:policy/myCustomerManagedPolicy'
46.   myInstanceProfile:
47.     Type: AWS::IAM::InstanceProfile
48.     Properties:
49.       Path: '/'
50.       Roles:
51.       - !Ref myInstanceRole
```

# 使用 CloudFormation 管理安全群組
<a name="quickref-ec2-sg"></a>

下列程式碼片段示範如何使用 CloudFormation 管理安全群組和 Amazon EC2 執行個體，以控制對 AWS 資源的存取。

**Topics**
+ [將 Amazon EC2 執行個體與安全群組建立關聯](#quickref-ec2-instances-associate-security-group)
+ [使用傳入規則建立安全群組](#quickref-ec2-instances-ingress)
+ [使用安全群組傳入規則建立 Elastic Load Balancer](#scenario-ec2-security-group-elbingress)

## 將 Amazon EC2 執行個體與安全群組建立關聯
<a name="quickref-ec2-instances-associate-security-group"></a>

下列範例程式碼片段示範了如何使用 CloudFormation，將 Amazon EC2 執行個體與預設 Amazon VPC 安全群組建立關聯。

**Topics**
+ [將 Amazon EC2 執行個體與預設 VPC 安全群組建立關聯](#using-cfn-getatt-default-values)
+ [建立具有附接磁碟區和安全群組的 Amazon EC2 執行個體](#scenario-ec2-volumeattachment)

### 將 Amazon EC2 執行個體與預設 VPC 安全群組建立關聯
<a name="using-cfn-getatt-default-values"></a>

下列程式碼片段會建立 Amazon VPC、VPC 內的子網路以及 Amazon EC2 執行個體。VPC 使用 [AWS::EC2::VPC](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-vpc.html) 資源建立。VPC 的 IP 地址範圍在較大的範本中定義，並且 `MyVPCCIDRRange` 參數會參考該範圍。

子網路在 VPC 內使用 [AWS::EC2:: Subnet](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-subnet.html) 資源。子網路與 VPC 關聯，以 `MyVPC` 做為參考。

EC2 執行個體在 VPC 和子網路內使用 [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源啟動。此資源會指定用於啟動執行個體的 Amazon Machine Image (AMI)、執行執行個體所在的子網路，以及要與執行個體建立關聯的安全群組。`ImageId` 會使用 Systems Manager 參數動態擷取最新的 Amazon Linux 2 AMI。

安全群組 ID 使用 `Fn::GetAtt` 函數取得，該函數會從 `MyVPC` 資源擷取預設安全群組。

執行個體會放置在程式碼片段定義的 `MySubnet` 資源內。

當您使用 CloudFormation 建立 VPC 時， AWS 會自動在 VPC 內建立預設資源，包括預設安全群組。但是，若您在 CloudFormation 範本內定義 VPC，在建立範本時，可能無法存取這些預設資源的 ID。若要存取和使用範本中指定的預設資源，您可以使用內部函數，例如 `Fn::GetAtt`。此函數可讓您使用 CloudFormation 自動建立的預設資源。

#### JSON
<a name="quickref-ec2-example-15.json"></a>

```
"MyVPC": {
    "Type": "AWS::EC2::VPC",
    "Properties": {
        "CidrBlock": {
            "Ref": "MyVPCCIDRRange"
        },
        "EnableDnsSupport": false,
        "EnableDnsHostnames": false,
        "InstanceTenancy": "default"
    }
},
"MySubnet": {
    "Type": "AWS::EC2::Subnet",
    "Properties": {
        "CidrBlock": {
            "Ref": "MyVPCCIDRRange"
        },
        "VpcId": {
            "Ref": "MyVPC"
        }
    }
},
"MyInstance": {
    "Type": "AWS::EC2::Instance",
    "Properties": {
        "ImageId": "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
        "SecurityGroupIds": [
            {
                "Fn::GetAtt": [
                    "MyVPC",
                    "DefaultSecurityGroup"
                ]
            }
        ],
        "SubnetId": {
            "Ref": "MySubnet"
        }
    }
}
```

#### YAML
<a name="quickref-ec2-example-15.yaml"></a>

```
MyVPC:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock:
      Ref: MyVPCCIDRRange
    EnableDnsSupport: false
    EnableDnsHostnames: false
    InstanceTenancy: default
MySubnet:
  Type: AWS::EC2::Subnet
  Properties:
    CidrBlock:
      Ref: MyVPCCIDRRange
    VpcId:
      Ref: MyVPC
MyInstance:
  Type: AWS::EC2::Instance
  Properties:
    ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
    SecurityGroupIds:
      - Fn::GetAtt:
          - MyVPC
          - DefaultSecurityGroup
    SubnetId:
      Ref: MySubnet
```

### 建立具有附接磁碟區和安全群組的 Amazon EC2 執行個體
<a name="scenario-ec2-volumeattachment"></a>

下列程式碼片段會使用 [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源來建立 Amazon EC2 執行個體，該資源從指定的 AMI 啟動。執行個體與安全群組關聯，允許使用 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源，在連接埠 22 上從指定的 IP 地址傳入 SSH 流量。它會使用 [AWS::EC2::Volume](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-volume.html) 資源來建立 100 GB 的 Amazon EBS 磁碟區。磁碟區建立在與執行個體相同的可用區域 (如 `GetAtt` 函數所指定)，並掛接至 `/dev/sdh` 裝置上的執行個體。

如需有關建立 Amazon EBS 磁碟區的詳細資訊，請參閱[建立 Amazon EBS 磁碟區](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-creating-volume.html)。

#### JSON
<a name="quickref-ec2-example-14.json"></a>

```
 1. "Ec2Instance": {
 2.     "Type": "AWS::EC2::Instance",
 3.     "Properties": {
 4.         "SecurityGroups": [
 5.             {
 6.                 "Ref": "InstanceSecurityGroup"
 7.             }
 8.         ],
 9.         "ImageId": "ami-1234567890abcdef0"
10.     }
11. },
12. "InstanceSecurityGroup": {
13.     "Type": "AWS::EC2::SecurityGroup",
14.     "Properties": {
15.         "GroupDescription": "Enable SSH access via port 22",
16.         "SecurityGroupIngress": [
17.             {
18.                 "IpProtocol": "tcp",
19.                 "FromPort": "22",
20.                 "ToPort": "22",
21.                 "CidrIp": "192.0.2.0/24"
22.             }
23.         ]
24.     }
25. },
26. "NewVolume": {
27.     "Type": "AWS::EC2::Volume",
28.     "Properties": {
29.         "Size": "100",
30.         "AvailabilityZone": {
31.             "Fn::GetAtt": [
32.                 "Ec2Instance",
33.                 "AvailabilityZone"
34.             ]
35.         }
36.     }
37. },
38. "MountPoint": {
39.     "Type": "AWS::EC2::VolumeAttachment",
40.     "Properties": {
41.         "InstanceId": {
42.             "Ref": "Ec2Instance"
43.         },
44.         "VolumeId": {
45.             "Ref": "NewVolume"
46.         },
47.         "Device": "/dev/sdh"
48.     }
49. }
```

#### YAML
<a name="quickref-ec2-example-14.yaml"></a>

```
 1. Ec2Instance:
 2.   Type: AWS::EC2::Instance
 3.   Properties:
 4.     SecurityGroups:
 5.       - !Ref InstanceSecurityGroup
 6.     ImageId: ami-1234567890abcdef0
 7. InstanceSecurityGroup:
 8.   Type: AWS::EC2::SecurityGroup
 9.   Properties:
10.     GroupDescription: Enable SSH access via port 22
11.     SecurityGroupIngress:
12.       - IpProtocol: tcp
13.         FromPort: 22
14.         ToPort: 22
15.         CidrIp: 192.0.2.0/24
16. NewVolume:
17.   Type: AWS::EC2::Volume
18.   Properties:
19.     Size: 100
20.     AvailabilityZone: !GetAtt [Ec2Instance, AvailabilityZone]
21. MountPoint:
22.   Type: AWS::EC2::VolumeAttachment
23.   Properties:
24.     InstanceId: !Ref Ec2Instance
25.     VolumeId: !Ref NewVolume
26.     Device: /dev/sdh
```

## 使用傳入規則建立安全群組
<a name="quickref-ec2-instances-ingress"></a>

下列範例程式碼片段示範了如何透過使用 CloudFormation 的特定傳入規則來設定安全群組。

**Topics**
+ [使用傳入規則建立安全群組以進行 SSH 和 HTTP 存取](#scenario-ec2-security-group-rule)
+ [使用傳入規則建立安全群組，以從指定的 CIDR 範圍進行 HTTP 和 SSH 存取](#scenario-ec2-security-group-two-ports)
+ [使用傳入規則建立相互參照的安全群組](#scenario-ec2-security-group-ingress)

### 使用傳入規則建立安全群組以進行 SSH 和 HTTP 存取
<a name="scenario-ec2-security-group-rule"></a>

下列程式碼片段描述了使用 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源的兩個安全群組傳入規則。第一個輸入規則允許 SSH （連接埠 22) 從名為 的現有安全群組進行存取`MyAdminSecurityGroup`，該安全群組由帳號為 AWS 的帳戶所擁有`1111-2222-3333`。第二個傳入規則允許從稱為 `MySecurityGroupCreatedInCFN` 的不同安全群組存取 HTTP (通訊埠 80)，該安全群組在相同範本中建立。`Ref` 函數用於參考在相同範本中建立的安全群組的邏輯名稱。

在第一個傳入規則中，您必須為 `SourceSecurityGroupName` 和 `SourceSecurityGroupOwnerId` 屬性新增值。在第二個傳入規則中，`MySecurityGroupCreatedInCFNTemplate` 會參考在相同範本中建立的不同安全群組。確認邏輯名稱 `MySecurityGroupCreatedInCFNTemplate` 與您在較大範本中指定的安全群組資源的實際邏輯名稱相符。

如需安全群組的詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的 [Amazon EC2 執行個體的 Amazon EC2 安全群組](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)。

#### JSON
<a name="quickref-ec2-example-10.json"></a>

```
 1. "SecurityGroup": {
 2.     "Type": "AWS::EC2::SecurityGroup",
 3.     "Properties": {
 4.         "GroupDescription": "Allow connections from specified source security group",
 5.         "SecurityGroupIngress": [
 6.             {
 7.                 "IpProtocol": "tcp",
 8.                 "FromPort": "22",
 9.                 "ToPort": "22",
10.                 "SourceSecurityGroupName": "MyAdminSecurityGroup",
11.                 "SourceSecurityGroupOwnerId": "1111-2222-3333"
12.             },
13.             {
14.                 "IpProtocol": "tcp",
15.                 "FromPort": "80",
16.                 "ToPort": "80",
17.                 "SourceSecurityGroupName": {
18.                     "Ref": "MySecurityGroupCreatedInCFNTemplate"
19.                 }
20.             }
21.         ]
22.     }
23. }
```

#### YAML
<a name="quickref-ec2-example-10.yaml"></a>

```
 1. SecurityGroup:
 2.   Type: AWS::EC2::SecurityGroup
 3.   Properties:
 4.     GroupDescription: Allow connections from specified source security group
 5.     SecurityGroupIngress:
 6.       - IpProtocol: tcp
 7.         FromPort: '22'
 8.         ToPort: '22'
 9.         SourceSecurityGroupName: MyAdminSecurityGroup
10.         SourceSecurityGroupOwnerId: '1111-2222-3333'
11.       - IpProtocol: tcp
12.         FromPort: '80'
13.         ToPort: '80'
14.         SourceSecurityGroupName:
15.           Ref: MySecurityGroupCreatedInCFNTemplate
```

### 使用傳入規則建立安全群組，以從指定的 CIDR 範圍進行 HTTP 和 SSH 存取
<a name="scenario-ec2-security-group-two-ports"></a>

下列程式碼片段會針對具有兩個傳入規則的 Amazon EC2 執行個體建立安全群組。傳入規則允許從指定 CIDR 範圍的指定連接埠上傳入 TCP 流量。[AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源用於指定規則。您必須針對每項規則指定協定。針對 TCP，您必須指定連接埠或連接埠範圍。如果您未指定來源安全群組或 CIDR 範圍，堆疊會成功啟動，但不會將規則套用至安全群組。

如需安全群組的詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的 [Amazon EC2 執行個體的 Amazon EC2 安全群組](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)。

#### JSON
<a name="quickref-ec2-example-9.json"></a>

```
 1. "ServerSecurityGroup": {
 2.   "Type": "AWS::EC2::SecurityGroup",
 3.   "Properties": {
 4.     "GroupDescription": "Allow connections from specified CIDR ranges",
 5.     "SecurityGroupIngress": [
 6.       {
 7.         "IpProtocol": "tcp",
 8.         "FromPort": "80",
 9.         "ToPort": "80",
10.         "CidrIp": "192.0.2.0/24"
11.       },
12.       {
13.         "IpProtocol": "tcp",
14.         "FromPort": "22",
15.         "ToPort": "22",
16.         "CidrIp": "192.0.2.0/24"
17.       }
18.     ]
19.   }
20. }
```

#### YAML
<a name="quickref-ec2-example-9.yaml"></a>

```
 1. ServerSecurityGroup:
 2.   Type: AWS::EC2::SecurityGroup
 3.   Properties:
 4.     GroupDescription: Allow connections from specified CIDR ranges
 5.     SecurityGroupIngress:
 6.       - IpProtocol: tcp
 7.         FromPort: 80
 8.         ToPort: 80
 9.         CidrIp: 192.0.2.0/24
10.       - IpProtocol: tcp
11.         FromPort: 22
12.         ToPort: 22
13.         CidrIp: 192.0.2.0/24
```

### 使用傳入規則建立相互參照的安全群組
<a name="scenario-ec2-security-group-ingress"></a>

下列程式碼片段使用 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源來建立兩個 Amazon EC2 安全群組 (`SGroup1` 和 `SGroup2`)。允許兩個安全群組之間進行通訊的傳入規則使用 [AWS::EC2::SecurityGroupIngress](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroupingress.html) 資源建立。`SGroup1Ingress` 會建立 `SGroup1` 的傳入規則，以允許來源安全群組 `SGroup2` 連接埠 80 上的傳入 TCP 流量。`SGroup2Ingress` 會建立 `SGroup2` 的傳入規則，以允許來源安全群組 `SGroup1` 連接埠 80 上的傳入 TCP 流量。

#### JSON
<a name="quickref-ec2-example-12.json"></a>

```
 1. "SGroup1": {
 2.     "Type": "AWS::EC2::SecurityGroup",
 3.     "Properties": {
 4.         "GroupDescription": "EC2 instance access"
 5.     }
 6. },
 7. "SGroup2": {
 8.     "Type": "AWS::EC2::SecurityGroup",
 9.     "Properties": {
10.         "GroupDescription": "EC2 instance access"
11.     }
12. },
13. "SGroup1Ingress": {
14.     "Type": "AWS::EC2::SecurityGroupIngress",
15.     "Properties": {
16.         "GroupName": {
17.             "Ref": "SGroup1"
18.         },
19.         "IpProtocol": "tcp",
20.         "ToPort": "80",
21.         "FromPort": "80",
22.         "SourceSecurityGroupName": {
23.             "Ref": "SGroup2"
24.         }
25.     }
26. },
27. "SGroup2Ingress": {
28.     "Type": "AWS::EC2::SecurityGroupIngress",
29.     "Properties": {
30.         "GroupName": {
31.             "Ref": "SGroup2"
32.         },
33.         "IpProtocol": "tcp",
34.         "ToPort": "80",
35.         "FromPort": "80",
36.         "SourceSecurityGroupName": {
37.             "Ref": "SGroup1"
38.         }
39.     }
40. }
```

#### YAML
<a name="quickref-ec2-example-12.yaml"></a>

```
 1. SGroup1:
 2.   Type: AWS::EC2::SecurityGroup
 3.   Properties:
 4.     GroupDescription: EC2 Instance access
 5. SGroup2:
 6.   Type: AWS::EC2::SecurityGroup
 7.   Properties:
 8.     GroupDescription: EC2 Instance access
 9. SGroup1Ingress:
10.   Type: AWS::EC2::SecurityGroupIngress
11.   Properties:
12.     GroupName: !Ref SGroup1
13.     IpProtocol: tcp
14.     ToPort: 80
15.     FromPort: 80
16.     SourceSecurityGroupName: !Ref SGroup2
17. SGroup2Ingress:
18.   Type: AWS::EC2::SecurityGroupIngress
19.   Properties:
20.     GroupName: !Ref SGroup2
21.     IpProtocol: tcp
22.     ToPort: 80
23.     FromPort: 80
24.     SourceSecurityGroupName: !Ref SGroup1
```

## 使用安全群組傳入規則建立 Elastic Load Balancer
<a name="scenario-ec2-security-group-elbingress"></a>

下列範本會在指定的可用區域建立 [AWS::ElasticLoadBalancing::LoadBalancer](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancing-loadbalancer.html) 資源。[AWS::ElasticLoadBalancing::LoadBalancer](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancing-loadbalancer.html) 資源設定為在連接埠 80 上接聽 HTTP 流量，請求也會引導至連接埠 80 上的執行個體。Elastic Load Balancer 負責對執行個體之間的傳入 HTTP 流量進行負載平衡。

 此外，此範本會產生與負載平衡器關聯的 [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 資源。此安全群組使用單一傳入規則建立，描述為 `ELB ingress group`，這會允許連接埠 80 上的傳入 TCP 流量。此傳入規則的來源 `Fn::GetAtt` 函數定義，以從負載平衡器資源擷取屬性。`SourceSecurityGroupOwnerId` 使用 `Fn::GetAtt` 來取得負載平衡器來源安全群組的 `OwnerAlias`。`SourceSecurityGroupName` 使用 `Fn::Getatt` 來取得 ELB 來源安全群組的 `GroupName`。

此設定可確保 ELB 與執行個體之間進行安全通訊。

如需負載平衡的詳細資訊，請參閱 [Elastic Load Balancing 使用者指南](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/)。

### JSON
<a name="quickref-ec2-example-11.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "MyELB": {
            "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
            "Properties": {
                "AvailabilityZones": [
                    "aa-example-1a"
                ],
                "Listeners": [
                    {
                        "LoadBalancerPort": "80",
                        "InstancePort": "80",
                        "Protocol": "HTTP"
                    }
                ]
            }
        },
        "MyELBIngressGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "ELB ingress group",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 80,
                        "ToPort": 80,
                        "SourceSecurityGroupOwnerId": {
                            "Fn::GetAtt": [
                                "MyELB",
                                "SourceSecurityGroup.OwnerAlias"
                            ]
                        },
                        "SourceSecurityGroupName": {
                            "Fn::GetAtt": [
                                "MyELB",
                                "SourceSecurityGroup.GroupName"
                            ]
                        }
                    }
                ]
            }
        }
    }
}
```

### YAML
<a name="quickref-ec2-example-11.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyELB:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties:
      AvailabilityZones:
        - aa-example-1a
      Listeners:
        - LoadBalancerPort: '80'
          InstancePort: '80'
          Protocol: HTTP
  MyELBIngressGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: ELB ingress group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          SourceSecurityGroupOwnerId:
            Fn::GetAtt:
              - MyELB
              - SourceSecurityGroup.OwnerAlias
          SourceSecurityGroupName:
            Fn::GetAtt:
              - MyELB
              - SourceSecurityGroup.GroupName
```

# 配置彈性 IP 位址並與 CloudFormation 產生關聯
<a name="quickref-ec2-elastic-ip"></a>

下列範本程式碼片段是與 Amazon EC2 中的彈性 IP 地址 (EIP) 相關的範例。這些範例涵蓋您的執行個體的 EIP 配置、關聯和管理。

**Topics**
+ [配置彈性 IP 地址並與 Amazon EC2 執行個體建立關聯](#scenario-ec2-eip)
+ [透過指定 IP 地址將彈性 IP 地址與 Amazon EC2 執行個體建立關聯](#scenario-ec2-eip-association)
+ [透過指定 IP 地址的配置 ID 將彈性 IP 地址與 Amazon EC2 執行個體建立關聯](#scenario-ec2-eip-association-vpc)

## 配置彈性 IP 地址並與 Amazon EC2 執行個體建立關聯
<a name="scenario-ec2-eip"></a>

下列程式碼片段配置 Amazon EC2 彈性 IP 地址，並使用 [AWS::EC2::EIP](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-eip.html) 資源將其與 Amazon EC2 執行個體建立關聯。您可以從擁有的地址集區配置 EIP 地址， AWS 或從公有 IPv4 地址範圍建立的地址集區配置 EIP 地址， AWS 以便使用[自有 IP 地址 (BYOIP)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html) 搭配 AWS 資源使用。在此範例中，EIP 是從 擁有的地址集區配置 AWS。

如需有關彈性 IP 地址的詳細資訊，請參閱《Amazon EC2 使用者指南》**中的[彈性 IP 地址](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html)。

### JSON
<a name="quickref-ec2-example-3.json"></a>

```
1. "ElasticIP": {
2.     "Type": "AWS::EC2::EIP",
3.     "Properties": {
4.         "InstanceId": {
5.             "Ref": "Ec2Instance"
6.         }
7.     }
8. }
```

### YAML
<a name="quickref-ec2-example-3.yaml"></a>

```
1. ElasticIP:
2.   Type: AWS::EC2::EIP
3.   Properties:
4.     InstanceId: !Ref EC2Instance
```

## 透過指定 IP 地址將彈性 IP 地址與 Amazon EC2 執行個體建立關聯
<a name="scenario-ec2-eip-association"></a>

下列程式碼片段使用 [AWS::EC2::EIPAssociation](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-eipassociation.html) 資源，將現有的 Amazon EC2 彈性 IP 地址與 EC2 執行個體建立關聯。您必須先配置彈性 IP 地址，才能在帳戶中使用。彈性 IP 地址可與單一執行個體建立關聯。

### JSON
<a name="quickref-ec2-example-4.json"></a>

```
1. "IPAssoc": {
2.   "Type": "AWS::EC2::EIPAssociation",
3.   "Properties": {
4.     "InstanceId": {
5.       "Ref": "Ec2Instance"
6.     },
7.     "EIP": "192.0.2.0"
8.   }
9. }
```

### YAML
<a name="quickref-ec2-example-4.yaml"></a>

```
1. IPAssoc:
2.   Type: AWS::EC2::EIPAssociation
3.   Properties:
4.     InstanceId: !Ref EC2Instance
5.     EIP: 192.0.2.0
```

## 透過指定 IP 地址的配置 ID 將彈性 IP 地址與 Amazon EC2 執行個體建立關聯
<a name="scenario-ec2-eip-association-vpc"></a>

下列程式碼片段使用 [AWS::EC2::EIPAssociation](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-eipassociation.html) 資源，將現有的彈性 IP 地址與 Amazon EC2 執行個體建立關聯。在配置彈性 IP 地址時，配置 ID 會指派給彈性 IP 地址。

### JSON
<a name="quickref-ec2-example-5.json"></a>

```
1. "IPAssoc": {
2.     "Type": "AWS::EC2::EIPAssociation",
3.     "Properties": {
4.         "InstanceId": {
5.             "Ref": "Ec2Instance"
6.         },
7.         "AllocationId": "eipalloc-1234567890abcdef0"
8.     }
9. }
```

### YAML
<a name="quickref-ec2-example-5.yaml"></a>

```
1. IPAssoc:
2.   Type: AWS::EC2::EIPAssociation
3.   Properties:
4.     InstanceId: !Ref EC2Instance
5.     AllocationId: eipalloc-1234567890abcdef0
```

# 使用 CloudFormation 來設定 Amazon VPC 資源
<a name="quickref-ec2-vpc"></a>

本節提供使用 CloudFormation 設定 Amazon VPC 資源的範例。VPC 可讓您在 內建立虛擬網路 AWS，而這些程式碼片段會示範如何設定 VPCs 的各個層面，以符合您的聯網需求。

**Topics**
+ [在 VPC 中啟用僅限 IPv6 傳入網際網路存取](#quickref-ec2-route-egressonlyinternetgateway)
+ [彈性網路介面 (ENI) 範本程式碼片段](#cfn-template-snippets-eni)

## 在 VPC 中啟用僅限 IPv6 傳入網際網路存取
<a name="quickref-ec2-route-egressonlyinternetgateway"></a>

僅限傳入網際網路閘道允許 VPC 內的執行個體存取網際網路，並阻止網際網路上的資源與執行個體通訊。下列程式碼片段會從 VPC 內啟用僅限 IPv6 傳入網際網路存取。它會使用 [AWS::EC2::VPC](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-vpc.html) 資源建立具有 `10.0.0/16` IPv4 地址範圍的 VPC。使用 [AWS::EC2::RouteTable](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-routetable.html) 資源，將路由表與此 VPC 資源建立關聯。路由表會管理 VPC 內執行個體的路由。[AWS::EC2::EgressOnlyInternetGateway](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-egressonlyinternetgateway.html) 用於建立僅限傳入網際網路閘道，以針對 VPC 內執行個體的傳出流量啟用 IPv6 通訊，同時阻止傳入流量。指定 [AWS::EC2::Route](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-route.html) 資源在路由表中建立 IPv6 路由，這會將所有傳出 IPv6 流量 (`::/0`) 引導至僅限傳入網際網路閘道。

如需僅限傳出網際網路閘道的詳細資訊，請參閱 *Amazon VPC 使用者指南*中[使用僅限傳出網際網路閘道啟用傳出 IPv6 流量](https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway.html)。

### JSON
<a name="quickref-ec2-example-16.json"></a>

```
"DefaultIpv6Route": {
    "Type": "AWS::EC2::Route",
    "Properties": {
        "DestinationIpv6CidrBlock": "::/0",
        "EgressOnlyInternetGatewayId": {
            "Ref": "EgressOnlyInternetGateway"
        },
        "RouteTableId": {
            "Ref": "RouteTable"
        }
    }
},
"EgressOnlyInternetGateway": {
    "Type": "AWS::EC2::EgressOnlyInternetGateway",
    "Properties": {
        "VpcId": {
            "Ref": "VPC"
        }
    }
},
"RouteTable": {
    "Type": "AWS::EC2::RouteTable",
    "Properties": {
        "VpcId": {
            "Ref": "VPC"
        }
    }
},
"VPC": {
    "Type": "AWS::EC2::VPC",
    "Properties": {
        "CidrBlock": "10.0.0.0/16"
    }
}
```

### YAML
<a name="quickref-ec2-example-16.yaml"></a>

```
DefaultIpv6Route:
  Type: AWS::EC2::Route
  Properties:
    DestinationIpv6CidrBlock: "::/0"
    EgressOnlyInternetGatewayId:
      Ref: "EgressOnlyInternetGateway"
    RouteTableId:
      Ref: "RouteTable"
EgressOnlyInternetGateway:
  Type: AWS::EC2::EgressOnlyInternetGateway
  Properties:
    VpcId:
      Ref: "VPC"
RouteTable:
  Type: AWS::EC2::RouteTable
  Properties:
    VpcId:
      Ref: "VPC"
VPC:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock: "10.0.0.0/16"
```

## 彈性網路介面 (ENI) 範本程式碼片段
<a name="cfn-template-snippets-eni"></a>

### 使用附接的彈性網絡介面 (ENI) 建立 Amazon EC2 執行個體
<a name="cfn-template-snippets-eni-template"></a>

下列範例程式碼片段會使用 Amazon VPC 和子網路中指定的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 資源建立 Amazon EC2 執行個體。它會將兩個網路介面 (ENI) 附接至執行個體，透過附接的 ENI 將彈性 IP 地址與執行個體建立關聯，以及設定安全群組進行 SSH 和 HTTP 存取。建立執行個體時，會將使用者資料做為啟動組態的一部分提供給執行個體。使用者資料包括以 `base64` 格式編碼的指令碼，以確保將其傳遞至執行個體。啟動執行個體後，指令碼會在引導程序中自動執行。它會安裝 `ec2-net-utils`、設定網路介面，以及啟動 HTTP 服務。

若要根據選取的區域確定適當的 Amazon Machine Image (AMI)，程式碼片段會使用可在 `RegionMap` 映射中查詢值的 `Fn::FindInMap` 函數。此映射必須在較大的範本中定義。使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-networkinterface.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-networkinterface.html) 資源建立兩個網路介面。使用配置給 `vpc` 網域的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-eip.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-eip.html) 資源指定彈性 IP 位址。這些彈性 IP 位址與使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-eipassociation.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-eipassociation.html) 資源的網路介面相關聯。

`Outputs` 區段定義您想要在建立堆疊之後存取的值或資源。在此程式碼片段中，定義的輸出為 `InstancePublicIp`，代表堆疊建立的 EC2 執行個體的公有 IP 地址。您可以在 CloudFormation 主控台的**輸出**索引標籤中擷取此輸出，或使用 [describe-stacks](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) 命令。

如需彈性網路介面的詳細資訊，請參閱[彈性網路介面](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html)。

#### JSON
<a name="cfn-template-snippets-eni-example-1.json"></a>

```
"Resources": {
    "ControlPortAddress": {
        "Type": "AWS::EC2::EIP",
        "Properties": {
            "Domain": "vpc"
        }
    },
    "AssociateControlPort": {
        "Type": "AWS::EC2::EIPAssociation",
        "Properties": {
            "AllocationId": {
                "Fn::GetAtt": [
                    "ControlPortAddress",
                    "AllocationId"
                ]
            },
            "NetworkInterfaceId": {
                "Ref": "controlXface"
            }
        }
    },
    "WebPortAddress": {
        "Type": "AWS::EC2::EIP",
        "Properties": {
            "Domain": "vpc"
        }
    },
    "AssociateWebPort": {
        "Type": "AWS::EC2::EIPAssociation",
        "Properties": {
            "AllocationId": {
                "Fn::GetAtt": [
                    "WebPortAddress",
                    "AllocationId"
                ]
            },
            "NetworkInterfaceId": {
                "Ref": "webXface"
            }
        }
    },
    "SSHSecurityGroup": {
        "Type": "AWS::EC2::SecurityGroup",
        "Properties": {
            "VpcId": {
                "Ref": "VpcId"
            },
            "GroupDescription": "Enable SSH access via port 22",
            "SecurityGroupIngress": [
                {
                    "CidrIp": "0.0.0.0/0",
                    "FromPort": 22,
                    "IpProtocol": "tcp",
                    "ToPort": 22
                }
            ]
        }
    },
    "WebSecurityGroup": {
        "Type": "AWS::EC2::SecurityGroup",
        "Properties": {
            "VpcId": {
                "Ref": "VpcId"
            },
            "GroupDescription": "Enable HTTP access via user-defined port",
            "SecurityGroupIngress": [
                {
                    "CidrIp": "0.0.0.0/0",
                    "FromPort": 80,
                    "IpProtocol": "tcp",
                    "ToPort": 80
                }
            ]
        }
    },
    "controlXface": {
        "Type": "AWS::EC2::NetworkInterface",
        "Properties": {
            "SubnetId": {
                "Ref": "SubnetId"
            },
            "Description": "Interface for controlling traffic such as SSH",
            "GroupSet": [
                {
                    "Fn::GetAtt": [
                        "SSHSecurityGroup",
                        "GroupId"
                    ]
                }
            ],
            "SourceDestCheck": true,
            "Tags": [
                {
                    "Key": "Network",
                    "Value": "Control"
                }
            ]
        }
    },
    "webXface": {
        "Type": "AWS::EC2::NetworkInterface",
        "Properties": {
            "SubnetId": {
                "Ref": "SubnetId"
            },
            "Description": "Interface for web traffic",
            "GroupSet": [
                {
                    "Fn::GetAtt": [
                        "WebSecurityGroup",
                        "GroupId"
                    ]
                }
            ],
            "SourceDestCheck": true,
            "Tags": [
                {
                    "Key": "Network",
                    "Value": "Web"
                }
            ]
        }
    },
    "Ec2Instance": {
        "Type": "AWS::EC2::Instance",
        "Properties": {
            "ImageId": {
                "Fn::FindInMap": [
                    "RegionMap",
                    {
                        "Ref": "AWS::Region"
                    },
                    "AMI"
                ]
            },
            "KeyName": {
                "Ref": "KeyName"
            },
            "NetworkInterfaces": [
                {
                    "NetworkInterfaceId": {
                        "Ref": "controlXface"
                    },
                    "DeviceIndex": "0"
                },
                {
                    "NetworkInterfaceId": {
                        "Ref": "webXface"
                    },
                    "DeviceIndex": "1"
                }
            ],
            "Tags": [
                {
                    "Key": "Role",
                    "Value": "Test Instance"
                }
            ],
            "UserData": {
                "Fn::Base64": {
                    "Fn::Sub": "#!/bin/bash -xe\nyum install ec2-net-utils -y\nec2ifup eth1\nservice httpd start\n"
                }
            }
        }
    }
},
"Outputs": {
    "InstancePublicIp": {
        "Description": "Public IP Address of the EC2 Instance",
        "Value": {
            "Fn::GetAtt": [
                "Ec2Instance",
                "PublicIp"
            ]
        }
    }
}
```

#### YAML
<a name="cfn-template-snippets-eni-example.yaml"></a>

```
Resources:
  ControlPortAddress:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
  AssociateControlPort:
    Type: AWS::EC2::EIPAssociation
    Properties:
      AllocationId:
        Fn::GetAtt:
          - ControlPortAddress
          - AllocationId
      NetworkInterfaceId:
        Ref: controlXface
  WebPortAddress:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
  AssociateWebPort:
    Type: AWS::EC2::EIPAssociation
    Properties:
      AllocationId:
        Fn::GetAtt:
          - WebPortAddress
          - AllocationId
      NetworkInterfaceId:
        Ref: webXface
  SSHSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId:
        Ref: VpcId
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
        - CidrIp: 0.0.0.0/0
          FromPort: 22
          IpProtocol: tcp
          ToPort: 22
  WebSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId:
        Ref: VpcId
      GroupDescription: Enable HTTP access via user-defined port
      SecurityGroupIngress:
        - CidrIp: 0.0.0.0/0
          FromPort: 80
          IpProtocol: tcp
          ToPort: 80
  controlXface:
    Type: AWS::EC2::NetworkInterface
    Properties:
      SubnetId:
        Ref: SubnetId
      Description: Interface for controlling traffic such as SSH
      GroupSet:
        - Fn::GetAtt:
            - SSHSecurityGroup
            - GroupId
      SourceDestCheck: true
      Tags:
        - Key: Network
          Value: Control
  webXface:
    Type: AWS::EC2::NetworkInterface
    Properties:
      SubnetId:
        Ref: SubnetId
      Description: Interface for web traffic
      GroupSet:
        - Fn::GetAtt:
            - WebSecurityGroup
            - GroupId
      SourceDestCheck: true
      Tags:
        - Key: Network
          Value: Web
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId:
        Fn::FindInMap:
          - RegionMap
          - Ref: AWS::Region
          - AMI
      KeyName:
        Ref: KeyName
      NetworkInterfaces:
        - NetworkInterfaceId:
            Ref: controlXface
          DeviceIndex: "0"
        - NetworkInterfaceId:
            Ref: webXface
          DeviceIndex: "1"
      Tags:
        - Key: Role
          Value: Test Instance
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum install ec2-net-utils -y
          ec2ifup eth1
          service httpd start
Outputs:
  InstancePublicIp:
    Description: Public IP Address of the EC2 Instance
    Value:
      Fn::GetAtt:
        - Ec2Instance
        - PublicIp
```

# Amazon Elastic Container Service 範例範本
<a name="quickref-ecs"></a>

Amazon Elastic Container Service (Amazon ECS) 是一種容器管理服務，可以在 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體叢集上輕鬆執行、停止及管理 Docker 容器。

## 建立具有 AL2023 Amazon ECS-Optimized-AMI 的叢集
<a name="create-cluster-al2023"></a>

定義使用在 Amazon EC2 上啟動 AL2023 執行個體的容量提供者的叢集。

**重要**  
如需取得最新的 AMI ID，請參閱《Amazon Elastic Container Service 開發人員指南》中的 [Amazon ECS 最佳化 AMI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html)。

### JSON
<a name="quickref-ecs-example-1.json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "EC2 ECS cluster that starts out empty, with no EC2 instances yet. An ECS capacity provider automatically launches more EC2 instances as required on the fly when you request ECS to launch services or standalone tasks.",
  "Parameters": {
      "InstanceType": {
          "Type": "String",
          "Description": "EC2 instance type",
          "Default": "t2.medium",
          "AllowedValues": [
              "t1.micro",
              "t2.2xlarge",
              "t2.large",
              "t2.medium",
              "t2.micro",
              "t2.nano",
              "t2.small",
              "t2.xlarge",
              "t3.2xlarge",
              "t3.large",
              "t3.medium",
              "t3.micro",
              "t3.nano",
              "t3.small",
              "t3.xlarge"
          ]
      },
      "DesiredCapacity": {
          "Type": "Number",
          "Default": "0",
          "Description": "Number of EC2 instances to launch in your ECS cluster."
      },
      "MaxSize": {
          "Type": "Number",
          "Default": "100",
          "Description": "Maximum number of EC2 instances that can be launched in your ECS cluster."
      },
      "ECSAMI": {
          "Description": "The Amazon Machine Image ID used for the cluster",
          "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
          "Default": "/aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id"
      },
      "VpcId": {
          "Type": "AWS::EC2::VPC::Id",
          "Description": "VPC ID where the ECS cluster is launched",
          "Default": "vpc-1234567890abcdef0"
      },
      "SubnetIds": {
          "Type": "List<AWS::EC2::Subnet::Id>",
          "Description": "List of subnet IDs where the EC2 instances will be launched",
          "Default": "subnet-021345abcdef67890"
      }
  },
  "Resources": {
      "ECSCluster": {
          "Type": "AWS::ECS::Cluster",
          "Properties": {
              "ClusterSettings": [
                  {
                      "Name": "containerInsights",
                      "Value": "enabled"
                  }
              ]
          }
      },
      "ECSAutoScalingGroup": {
          "Type": "AWS::AutoScaling::AutoScalingGroup",
          "DependsOn": [
              "ECSCluster",
              "EC2Role"
          ],
          "Properties": {
              "VPCZoneIdentifier": {
                  "Ref": "SubnetIds"
              },
              "LaunchTemplate": {
                  "LaunchTemplateId": {
                      "Ref": "ContainerInstances"
                  },
                  "Version": {
                      "Fn::GetAtt": [
                          "ContainerInstances",
                          "LatestVersionNumber"
                      ]
                  }
              },
              "MinSize": 0,
              "MaxSize": {
                  "Ref": "MaxSize"
              },
              "DesiredCapacity": {
                  "Ref": "DesiredCapacity"
              },
              "NewInstancesProtectedFromScaleIn": true
          },
          "UpdatePolicy": {
              "AutoScalingReplacingUpdate": {
                  "WillReplace": "true"
              }
          }
      },
      "ContainerInstances": {
          "Type": "AWS::EC2::LaunchTemplate",
          "Properties": {
              "LaunchTemplateName": "asg-launch-template",
              "LaunchTemplateData": {
                  "ImageId": {
                      "Ref": "ECSAMI"
                  },
                  "InstanceType": {
                      "Ref": "InstanceType"
                  },
                  "IamInstanceProfile": {
                      "Name": {
                          "Ref": "EC2InstanceProfile"
                      }
                  },
                  "SecurityGroupIds": [
                      {
                          "Ref": "ContainerHostSecurityGroup"
                      }
                  ],
                  "UserData": {
                      "Fn::Base64": {
                          "Fn::Sub": "#!/bin/bash -xe\n echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config\n yum install -y aws-cfn-bootstrap\n /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource ContainerInstances --configsets full_install --region ${AWS::Region} &\n"
                      }
                  },
                  "MetadataOptions": {
                      "HttpEndpoint": "enabled",
                      "HttpTokens": "required"
                  }
              }
          }
      },
      "EC2InstanceProfile": {
          "Type": "AWS::IAM::InstanceProfile",
          "Properties": {
              "Path": "/",
              "Roles": [
                  {
                      "Ref": "EC2Role"
                  }
              ]
          }
      },
      "CapacityProvider": {
          "Type": "AWS::ECS::CapacityProvider",
          "Properties": {
              "AutoScalingGroupProvider": {
                  "AutoScalingGroupArn": {
                      "Ref": "ECSAutoScalingGroup"
                  },
                  "ManagedScaling": {
                      "InstanceWarmupPeriod": 60,
                      "MinimumScalingStepSize": 1,
                      "MaximumScalingStepSize": 100,
                      "Status": "ENABLED",
                      "TargetCapacity": 100
                  },
                  "ManagedTerminationProtection": "ENABLED"
              }
          }
      },
      "CapacityProviderAssociation": {
          "Type": "AWS::ECS::ClusterCapacityProviderAssociations",
          "Properties": {
              "CapacityProviders": [
                  {
                      "Ref": "CapacityProvider"
                  }
              ],
              "Cluster": {
                  "Ref": "ECSCluster"
              },
              "DefaultCapacityProviderStrategy": [
                  {
                      "Base": 0,
                      "CapacityProvider": {
                          "Ref": "CapacityProvider"
                      },
                      "Weight": 1
                  }
              ]
          }
      },
      "ContainerHostSecurityGroup": {
          "Type": "AWS::EC2::SecurityGroup",
          "Properties": {
              "GroupDescription": "Access to the EC2 hosts that run containers",
              "VpcId": {
                  "Ref": "VpcId"
              }
          }
      },
      "EC2Role": {
          "Type": "AWS::IAM::Role",
          "Properties": {
              "AssumeRolePolicyDocument": {
                  "Statement": [
                      {
                          "Effect": "Allow",
                          "Principal": {
                              "Service": [
                                  "ec2.amazonaws.com"
                              ]
                          },
                          "Action": [
                              "sts:AssumeRole"
                          ]
                      }
                  ]
              },
              "Path": "/",
              "ManagedPolicyArns": [
                  "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role",
                  "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
              ]
          }
      },
      "ECSTaskExecutionRole": {
          "Type": "AWS::IAM::Role",
          "Properties": {
              "AssumeRolePolicyDocument": {
                  "Statement": [
                      {
                          "Effect": "Allow",
                          "Principal": {
                              "Service": [
                                  "ecs-tasks.amazonaws.com"
                              ]
                          },
                          "Action": [
                              "sts:AssumeRole"
                          ],
                          "Condition": {
                              "ArnLike": {
                                  "aws:SourceArn": {
                                      "Fn::Sub": "arn:${AWS::Partition}:ecs:${AWS::Region}:${AWS::AccountId}:*"
                                  }
                              },
                              "StringEquals": {
                                  "aws:SourceAccount": {
                                        "Fn::Sub": "${AWS::AccountId}"
                                    }
                              }
                          }
                      }
                  ]
              },
              "Path": "/",
              "ManagedPolicyArns": [
                  "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
              ]
          }
      }
  },
  "Outputs": {
      "ClusterName": {
          "Description": "The ECS cluster into which to launch resources",
          "Value": "ECSCluster"
      },
      "ECSTaskExecutionRole": {
          "Description": "The role used to start up a task",
          "Value": "ECSTaskExecutionRole"
      },
      "CapacityProvider": {
          "Description": "The cluster capacity provider that the service should use to request capacity when it wants to start up a task",
          "Value": "CapacityProvider"
      }
  }
}
```

### YAML
<a name="quickref-ecs-example-1.yaml"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Description: EC2 ECS cluster that starts out empty, with no EC2 instances yet.
  An ECS capacity provider automatically launches more EC2 instances as required
  on the fly when you request ECS to launch services or standalone tasks.
Parameters:
  InstanceType:
    Type: String
    Description: EC2 instance type
    Default: "t2.medium"
    AllowedValues:
      - t1.micro
      - t2.2xlarge
      - t2.large
      - t2.medium
      - t2.micro
      - t2.nano
      - t2.small
      - t2.xlarge
      - t3.2xlarge
      - t3.large
      - t3.medium
      - t3.micro
      - t3.nano
      - t3.small
      - t3.xlarge
  DesiredCapacity:
    Type: Number
    Default: "0"
    Description: Number of EC2 instances to launch in your ECS cluster.
  MaxSize:
    Type: Number
    Default: "100"
    Description: Maximum number of EC2 instances that can be launched in your ECS cluster.
  ECSAMI:
    Description: The Amazon Machine Image ID used for the cluster
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VPC ID where the ECS cluster is launched
    Default: vpc-1234567890abcdef0
  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: List of subnet IDs where the EC2 instances will be launched
    Default: "subnet-021345abcdef67890"
Resources:
# This is authorizes ECS to manage resources on your
  # account on your behalf. This role is likely already created on your account
  # ECSRole:
  #  Type: AWS::IAM::ServiceLinkedRole
  #  Properties:
  #    AWSServiceName: 'ecs.amazonaws.com'
  
   # ECS Resources
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterSettings:
        - Name: containerInsights
          Value: enabled
  
  # Autoscaling group. This launches the actual EC2 instances that will register
  # themselves as members of the cluster, and run the docker containers.
  ECSAutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    DependsOn:
      # This is to ensure that the ASG gets deleted first before these
    # resources, when it comes to stack teardown.
      - ECSCluster
      - EC2Role
    Properties:
      VPCZoneIdentifier:
        Ref: SubnetIds
      LaunchTemplate:
        LaunchTemplateId: !Ref ContainerInstances
        Version: !GetAtt ContainerInstances.LatestVersionNumber
      MinSize: 0
      MaxSize:
        Ref: MaxSize
      DesiredCapacity:
        Ref: DesiredCapacity
      NewInstancesProtectedFromScaleIn: true
    UpdatePolicy:
      AutoScalingReplacingUpdate:
        WillReplace: "true"
  # The config for each instance that is added to the cluster
  ContainerInstances:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: "asg-launch-template"
      LaunchTemplateData:
        ImageId:
          Ref: ECSAMI
        InstanceType:
          Ref: InstanceType
        IamInstanceProfile:
          Name: !Ref EC2InstanceProfile
        SecurityGroupIds:
          - !Ref ContainerHostSecurityGroup
        # This injected configuration file is how the EC2 instance
      # knows which ECS cluster on your AWS account it should be joining
        UserData:
          Fn::Base64: !Sub |
           #!/bin/bash -xe
            echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config
            yum install -y aws-cfn-bootstrap
            /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource ContainerInstances --configsets full_install --region ${AWS::Region} &
         # Disable IMDSv1, and require IMDSv2
        MetadataOptions:
          HttpEndpoint: enabled
          HttpTokens: required
  EC2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles: 
      - !Ref EC2Role 
  # Create an ECS capacity provider to attach the ASG to the ECS cluster
  # so that it autoscales as we launch more containers
  CapacityProvider:
    Type: AWS::ECS::CapacityProvider
    Properties:
      AutoScalingGroupProvider:
        AutoScalingGroupArn: !Ref ECSAutoScalingGroup
        ManagedScaling:
          InstanceWarmupPeriod: 60
          MinimumScalingStepSize: 1
          MaximumScalingStepSize: 100
          Status: ENABLED
          # Percentage of cluster reservation to try to maintain
          TargetCapacity: 100
        ManagedTerminationProtection: ENABLED
   # Create a cluster capacity provider assocation so that the cluster
  # will use the capacity provider
  CapacityProviderAssociation:
    Type: AWS::ECS::ClusterCapacityProviderAssociations
    Properties:
      CapacityProviders:
        - !Ref CapacityProvider
      Cluster: !Ref ECSCluster
      DefaultCapacityProviderStrategy:
        - Base: 0
          CapacityProvider: !Ref CapacityProvider
          Weight: 1
  # A security group for the EC2 hosts that will run the containers.
  # This can be used to limit incoming traffic to or outgoing traffic
  # from the container's host EC2 instance.
  ContainerHostSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Access to the EC2 hosts that run containers
      VpcId:
        Ref: VpcId
  # Role for the EC2 hosts. This allows the ECS agent on the EC2 hosts
  # to communciate with the ECS control plane, as well as download the docker
  # images from ECR to run on your host.
  EC2Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
      # See reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/security-iam-awsmanpol.html#security-iam-awsmanpol-AmazonEC2ContainerServiceforEC2Role
        - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
      # This managed policy allows us to connect to the instance using SSM
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
  # This is a role which is used within Fargate to allow the Fargate agent
  # to download images, and upload logs.
  ECSTaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ecs-tasks.amazonaws.com
            Action:
              - sts:AssumeRole
            Condition:
              ArnLike:
                aws:SourceArn: !Sub arn:${AWS::Partition}:ecs:${AWS::Region}:${AWS::AccountId}:*
              StringEquals:
                aws:SourceAccount: !Sub ${AWS::AccountId}
      Path: /
      # This role enables all features of ECS. See reference:
    # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/security-iam-awsmanpol.html#security-iam-awsmanpol-AmazonECSTaskExecutionRolePolicy
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Outputs:
  ClusterName:
    Description: The ECS cluster into which to launch resources
    Value: ECSCluster
  ECSTaskExecutionRole:
    Description: The role used to start up a task
    Value: ECSTaskExecutionRole
  CapacityProvider:
    Description: The cluster capacity provider that the service should use to
      request capacity when it wants to start up a task
    Value: CapacityProvider
```

## 部署服務
<a name="create-service"></a>

下列範本定義的服務使用容量提供者來請求 AL2023 容量以供執行。容器會在 AL2023 執行個體上線時啟動到這些執行個體上：

### JSON
<a name="quickref-ecs-example-2.json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "An example service that deploys in AWS VPC networking mode on EC2 capacity. Service uses a capacity provider to request EC2 instances to run on. Service runs with networking in private subnets, but still accessible to the internet via a load balancer hosted in public subnets.",
  "Parameters": {
      "VpcId": {
          "Type": "String",
          "Description": "The VPC that the service is running inside of"
      },
      "PublicSubnetIds": {
          "Type": "List<AWS::EC2::Subnet::Id>",
          "Description": "List of public subnet ID's to put the load balancer in"
      },
      "PrivateSubnetIds": {
          "Type": "List<AWS::EC2::Subnet::Id>",
          "Description": "List of private subnet ID's that the AWS VPC tasks are in"
      },
      "ClusterName": {
          "Type": "String",
          "Description": "The name of the ECS cluster into which to launch capacity."
      },
      "ECSTaskExecutionRole": {
          "Type": "String",
          "Description": "The role used to start up an ECS task"
      },
      "CapacityProvider": {
          "Type": "String",
          "Description": "The cluster capacity provider that the service should use to request capacity when it wants to start up a task"
      },
      "ServiceName": {
          "Type": "String",
          "Default": "web",
          "Description": "A name for the service"
      },
      "ImageUrl": {
          "Type": "String",
          "Default": "public.ecr.aws/docker/library/nginx:latest",
          "Description": "The url of a docker image that contains the application process that will handle the traffic for this service"
      },
      "ContainerCpu": {
          "Type": "Number",
          "Default": 256,
          "Description": "How much CPU to give the container. 1024 is 1 CPU"
      },
      "ContainerMemory": {
          "Type": "Number",
          "Default": 512,
          "Description": "How much memory in megabytes to give the container"
      },
      "ContainerPort": {
          "Type": "Number",
          "Default": 80,
          "Description": "What port that the application expects traffic on"
      },
      "DesiredCount": {
          "Type": "Number",
          "Default": 2,
          "Description": "How many copies of the service task to run"
      }
  },
  "Resources": {
      "TaskDefinition": {
          "Type": "AWS::ECS::TaskDefinition",
          "Properties": {
              "Family": {
                  "Ref": "ServiceName"
              },
              "Cpu": {
                  "Ref": "ContainerCpu"
              },
              "Memory": {
                  "Ref": "ContainerMemory"
              },
              "NetworkMode": "awsvpc",
              "RequiresCompatibilities": [
                  "EC2"
              ],
              "ExecutionRoleArn": {
                  "Ref": "ECSTaskExecutionRole"
              },
              "ContainerDefinitions": [
                  {
                      "Name": {
                          "Ref": "ServiceName"
                      },
                      "Cpu": {
                          "Ref": "ContainerCpu"
                      },
                      "Memory": {
                          "Ref": "ContainerMemory"
                      },
                      "Image": {
                          "Ref": "ImageUrl"
                      },
                      "PortMappings": [
                          {
                              "ContainerPort": {
                                  "Ref": "ContainerPort"
                              },
                              "HostPort": {
                                  "Ref": "ContainerPort"
                              }
                          }
                      ],
                      "LogConfiguration": {
                          "LogDriver": "awslogs",
                          "Options": {
                              "mode": "non-blocking",
                              "max-buffer-size": "25m",
                              "awslogs-group": {
                                  "Ref": "LogGroup"
                              },
                              "awslogs-region": {
                                  "Ref": "AWS::Region"
                              },
                              "awslogs-stream-prefix": {
                                  "Ref": "ServiceName"
                              }
                          }
                      }
                  }
              ]
          }
      },
      "Service": {
          "Type": "AWS::ECS::Service",
          "DependsOn": "PublicLoadBalancerListener",
          "Properties": {
              "ServiceName": {
                  "Ref": "ServiceName"
              },
              "Cluster": {
                  "Ref": "ClusterName"
              },
              "PlacementStrategies": [
                  {
                      "Field": "attribute:ecs.availability-zone",
                      "Type": "spread"
                  },
                  {
                      "Field": "cpu",
                      "Type": "binpack"
                  }
              ],
              "CapacityProviderStrategy": [
                  {
                      "Base": 0,
                      "CapacityProvider": {
                          "Ref": "CapacityProvider"
                      },
                      "Weight": 1
                  }
              ],
              "NetworkConfiguration": {
                  "AwsvpcConfiguration": {
                      "SecurityGroups": [
                          {
                              "Ref": "ServiceSecurityGroup"
                          }
                      ],
                      "Subnets": {
                          "Ref": "PrivateSubnetIds"
                      }
                  }
              },
              "DeploymentConfiguration": {
                  "MaximumPercent": 200,
                  "MinimumHealthyPercent": 75
              },
              "DesiredCount": {
                  "Ref": "DesiredCount"
              },
              "TaskDefinition": {
                  "Ref": "TaskDefinition"
              },
              "LoadBalancers": [
                  {
                      "ContainerName": {
                          "Ref": "ServiceName"
                      },
                      "ContainerPort": {
                          "Ref": "ContainerPort"
                      },
                      "TargetGroupArn": {
                          "Ref": "ServiceTargetGroup"
                      }
                  }
              ]
          }
      },
      "ServiceSecurityGroup": {
          "Type": "AWS::EC2::SecurityGroup",
          "Properties": {
              "GroupDescription": "Security group for service",
              "VpcId": {
                  "Ref": "VpcId"
              }
          }
      },
      "ServiceTargetGroup": {
          "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
          "Properties": {
              "HealthCheckIntervalSeconds": 6,
              "HealthCheckPath": "/",
              "HealthCheckProtocol": "HTTP",
              "HealthCheckTimeoutSeconds": 5,
              "HealthyThresholdCount": 2,
              "TargetType": "ip",
              "Port": {
                  "Ref": "ContainerPort"
              },
              "Protocol": "HTTP",
              "UnhealthyThresholdCount": 10,
              "VpcId": {
                  "Ref": "VpcId"
              },
              "TargetGroupAttributes": [
                  {
                      "Key": "deregistration_delay.timeout_seconds",
                      "Value": 0
                  }
              ]
          }
      },
      "PublicLoadBalancerSG": {
          "Type": "AWS::EC2::SecurityGroup",
          "Properties": {
              "GroupDescription": "Access to the public facing load balancer",
              "VpcId": {
                  "Ref": "VpcId"
              },
              "SecurityGroupIngress": [
                  {
                      "CidrIp": "0.0.0.0/0",
                      "IpProtocol": -1
                  }
              ]
          }
      },
      "PublicLoadBalancer": {
          "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
          "Properties": {
              "Scheme": "internet-facing",
              "LoadBalancerAttributes": [
                  {
                      "Key": "idle_timeout.timeout_seconds",
                      "Value": "30"
                  }
              ],
              "Subnets": {
                  "Ref": "PublicSubnetIds"
              },
              "SecurityGroups": [
                  {
                      "Ref": "PublicLoadBalancerSG"
                  }
              ]
          }
      },
      "PublicLoadBalancerListener": {
          "Type": "AWS::ElasticLoadBalancingV2::Listener",
          "Properties": {
              "DefaultActions": [
                  {
                      "Type": "forward",
                      "ForwardConfig": {
                          "TargetGroups": [
                              {
                                  "TargetGroupArn": {
                                      "Ref": "ServiceTargetGroup"
                                  },
                                  "Weight": 100
                              }
                          ]
                      }
                  }
              ],
              "LoadBalancerArn": {
                  "Ref": "PublicLoadBalancer"
              },
              "Port": 80,
              "Protocol": "HTTP"
          }
      },
      "ServiceIngressfromLoadBalancer": {
          "Type": "AWS::EC2::SecurityGroupIngress",
          "Properties": {
              "Description": "Ingress from the public ALB",
              "GroupId": {
                  "Ref": "ServiceSecurityGroup"
              },
              "IpProtocol": -1,
              "SourceSecurityGroupId": {
                  "Ref": "PublicLoadBalancerSG"
              }
          }
      },
      "LogGroup": {
          "Type": "AWS::Logs::LogGroup"
      }
  }
}
```

### YAML
<a name="quickref-ecs-example-2.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Description: >-
  An example service that deploys in AWS VPC networking mode on EC2 capacity.
  Service uses a capacity provider to request EC2 instances to run on. Service
  runs with networking in private subnets, but still accessible to the internet
  via a load balancer hosted in public subnets.
Parameters:
  VpcId:
    Type: String
    Description: The VPC that the service is running inside of
  PublicSubnetIds:
    Type: 'List<AWS::EC2::Subnet::Id>'
    Description: List of public subnet ID's to put the load balancer in
  PrivateSubnetIds:
    Type: 'List<AWS::EC2::Subnet::Id>'
    Description: List of private subnet ID's that the AWS VPC tasks are in
  ClusterName:
    Type: String
    Description: The name of the ECS cluster into which to launch capacity.
  ECSTaskExecutionRole:
    Type: String
    Description: The role used to start up an ECS task
  CapacityProvider:
    Type: String
    Description: >-
      The cluster capacity provider that the service should use to request
      capacity when it wants to start up a task
  ServiceName:
    Type: String
    Default: web
    Description: A name for the service
  ImageUrl:
    Type: String
    Default: 'public.ecr.aws/docker/library/nginx:latest'
    Description: >-
      The url of a docker image that contains the application process that will
      handle the traffic for this service
  ContainerCpu:
    Type: Number
    Default: 256
    Description: How much CPU to give the container. 1024 is 1 CPU
  ContainerMemory:
    Type: Number
    Default: 512
    Description: How much memory in megabytes to give the container
  ContainerPort:
    Type: Number
    Default: 80
    Description: What port that the application expects traffic on
  DesiredCount:
    Type: Number
    Default: 2
    Description: How many copies of the service task to run
Resources:
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Ref ServiceName
      Cpu: !Ref ContainerCpu
      Memory: !Ref ContainerMemory
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - EC2
      ExecutionRoleArn: !Ref ECSTaskExecutionRole
      ContainerDefinitions:
        - Name: !Ref ServiceName
          Cpu: !Ref ContainerCpu
          Memory: !Ref ContainerMemory
          Image: !Ref ImageUrl
          PortMappings:
            - ContainerPort: !Ref ContainerPort
              HostPort: !Ref ContainerPort
          LogConfiguration:
            LogDriver: awslogs
            Options:
              mode: non-blocking
              max-buffer-size: 25m
              awslogs-group: !Ref LogGroup
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: !Ref ServiceName
  Service:
    Type: AWS::ECS::Service
    DependsOn: PublicLoadBalancerListener
    Properties:
      ServiceName: !Ref ServiceName
      Cluster: !Ref ClusterName
      PlacementStrategies:
        - Field: 'attribute:ecs.availability-zone'
          Type: spread
        - Field: cpu
          Type: binpack
      CapacityProviderStrategy:
        - Base: 0
          CapacityProvider: !Ref CapacityProvider
          Weight: 1
      NetworkConfiguration:
        AwsvpcConfiguration:
          SecurityGroups:
            - !Ref ServiceSecurityGroup
          Subnets: !Ref PrivateSubnetIds
      DeploymentConfiguration:
        MaximumPercent: 200
        MinimumHealthyPercent: 75
      DesiredCount: !Ref DesiredCount
      TaskDefinition: !Ref TaskDefinition
      LoadBalancers:
        - ContainerName: !Ref ServiceName
          ContainerPort: !Ref ContainerPort
          TargetGroupArn: !Ref ServiceTargetGroup
  ServiceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for service
      VpcId: !Ref VpcId
  ServiceTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 6
      HealthCheckPath: /
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      TargetType: ip
      Port: !Ref ContainerPort
      Protocol: HTTP
      UnhealthyThresholdCount: 10
      VpcId: !Ref VpcId
      TargetGroupAttributes:
        - Key: deregistration_delay.timeout_seconds
          Value: 0
  PublicLoadBalancerSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Access to the public facing load balancer
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - CidrIp: 0.0.0.0/0
          IpProtocol: -1
  PublicLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      LoadBalancerAttributes:
        - Key: idle_timeout.timeout_seconds
          Value: '30'
      Subnets: !Ref PublicSubnetIds
      SecurityGroups:
        - !Ref PublicLoadBalancerSG
  PublicLoadBalancerListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          ForwardConfig:
            TargetGroups:
              - TargetGroupArn: !Ref ServiceTargetGroup
                Weight: 100
      LoadBalancerArn: !Ref PublicLoadBalancer
      Port: 80
      Protocol: HTTP
  ServiceIngressfromLoadBalancer:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      Description: Ingress from the public ALB
      GroupId: !Ref ServiceSecurityGroup
      IpProtocol: -1
      SourceSecurityGroupId: !Ref PublicLoadBalancerSG
  LogGroup:
    Type: AWS::Logs::LogGroup
```

# Amazon Elastic File System 範例範本
<a name="quickref-efs"></a>

Amazon Elastic File System (Amazon EFS) 是適用於 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體的檔案儲存服務。透過 Amazon EFS，系統會隨著您新增和移除的檔案自動擴展及縮減儲存容量，讓應用程式可以隨時享有所需的儲存空間。

以下範例範本會部署與 Amazon EFS 檔案系統相關聯的 EC2 執行個體 (在 Auto Scaling 群組中)。為了將執行個體與檔案系統建立關聯，執行個體會執行 cfn-init 協助程式指令碼，進而下載並安裝 `nfs-utils` yum 套件、建立新目錄，接著透過檔案系統的 DNS 名稱在該目錄掛載檔案系統。而系統會在 Amazon EC2 執行個體可用區域中，將該檔案系統的 DNS 名稱解析為掛載目標的 IP 地址。如需有關 DNS 名稱結構的詳細資訊，請參閱 *Amazon Elastic File System User Guide* (《Amazon Elastic File System 使用者指南》) 中的 [Mounting File Systems](https://docs.aws.amazon.com/efs/latest/ug/mounting-fs.html) (掛載檔案系統)。

範本會加入自訂 Amazon CloudWatch 指標，藉此測量網路檔案系統的活動；範本亦會建立 VPC、子網路與安全群組。VPC 必須啟用 DNS，且掛載目標和 EC2 執行個體需位於子網路所指定的相同可用區域 (AZ)，才能讓執行個體與檔案系統互相通訊。

掛載目標的安全群組會啟用 TCP 連接埠 2049 的網路連線，此為 NFSv4 用戶端掛載檔案系統時的必要動作。如需有關 EC2 執行個體和掛載目標之安全群組的詳細資訊，請參閱 [https://docs.aws.amazon.com/efs/latest/ug/](https://docs.aws.amazon.com/efs/latest/ug/) (《Amazon Elastic File System 使用者指南》) 中的 [Security](https://docs.aws.amazon.com/efs/latest/ug/security-considerations.html) (安全性)。

**注意**  
若更新掛載目標導致該目標遭取代，則使用相關檔案系統的執行個體或應用程式可能會中斷，這會造成未遞交的撰寫內容遺失。為了避免中斷，請在更新掛載目標時將所需容量設為零，進而停用執行個體。這項操作能讓執行個體先卸載檔案系統，隨後再刪除掛載目標。掛載更新完成後，請設定所需容量，即可在後續更新作業中啟動執行個體。

## JSON
<a name="quickref-efs-example-1.json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "This template creates an Amazon EFS file system and mount target and associates it with Amazon EC2 instances in an Auto Scaling group. **WARNING** This template creates Amazon EC2 instances and related resources. You will be billed for the AWS resources used if you create a stack from this template.",
  "Parameters": {
    "InstanceType" : {
      "Description" : "WebServer EC2 instance type",
      "Type" : "String",
      "Default" : "t2.small",
      "AllowedValues" : [ 
        "t1.micro", 
        "t2.nano", 
        "t2.micro", 
        "t2.small", 
        "t2.medium", 
        "t2.large", 
        "m1.small", 
        "m1.medium", 
        "m1.large", 
        "m1.xlarge", 
        "m2.xlarge", 
        "m2.2xlarge", 
        "m2.4xlarge", 
        "m3.medium", 
        "m3.large", 
        "m3.xlarge", 
        "m3.2xlarge", 
        "m4.large", 
        "m4.xlarge", 
        "m4.2xlarge", 
        "m4.4xlarge", 
        "m4.10xlarge", 
        "c1.medium", 
        "c1.xlarge", 
        "c3.large", 
        "c3.xlarge", 
        "c3.2xlarge", 
        "c3.4xlarge", 
        "c3.8xlarge", 
        "c4.large", 
        "c4.xlarge", 
        "c4.2xlarge", 
        "c4.4xlarge", 
        "c4.8xlarge", 
        "g2.2xlarge", 
        "g2.8xlarge", 
        "r3.large", 
        "r3.xlarge", 
        "r3.2xlarge", 
        "r3.4xlarge", 
        "r3.8xlarge", 
        "i2.xlarge", 
        "i2.2xlarge", 
        "i2.4xlarge", 
        "i2.8xlarge", 
        "d2.xlarge", 
        "d2.2xlarge", 
        "d2.4xlarge", 
        "d2.8xlarge", 
        "hi1.4xlarge", 
        "hs1.8xlarge", 
        "cr1.8xlarge", 
        "cc2.8xlarge", 
        "cg1.4xlarge"
      ],
      "ConstraintDescription" : "must be a valid EC2 instance type."
    },
    "KeyName": {
      "Type": "AWS::EC2::KeyPair::KeyName",
      "Description": "Name of an existing EC2 key pair to enable SSH access to the EC2 instances"
    },
    "AsgMaxSize": {
      "Type": "Number",
      "Description": "Maximum size and initial desired capacity of Auto Scaling Group",
      "Default": "2"
    },
    "SSHLocation" : {
      "Description" : "The IP address range that can be used to connect to the EC2 instances by using SSH",
      "Type": "String",
      "MinLength": "9",
      "MaxLength": "18",
      "Default": "0.0.0.0/0",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
    },
    "VolumeName" : {
      "Description" : "The name to be used for the EFS volume",
      "Type": "String",
      "MinLength": "1",
      "Default": "myEFSvolume"
    },
    "MountPoint" : {
      "Description" : "The Linux mount point for the EFS volume",
      "Type": "String",
      "MinLength": "1",
      "Default": "myEFSvolume"
    }
  },
  "Mappings" : {
    "AWSInstanceType2Arch" : {
      "t1.micro"    : { "Arch" : "HVM64"  },
      "t2.nano"     : { "Arch" : "HVM64"  },
      "t2.micro"    : { "Arch" : "HVM64"  },
      "t2.small"    : { "Arch" : "HVM64"  },
      "t2.medium"   : { "Arch" : "HVM64"  },
      "t2.large"    : { "Arch" : "HVM64"  },
      "m1.small"    : { "Arch" : "HVM64"  },
      "m1.medium"   : { "Arch" : "HVM64"  },
      "m1.large"    : { "Arch" : "HVM64"  },
      "m1.xlarge"   : { "Arch" : "HVM64"  },
      "m2.xlarge"   : { "Arch" : "HVM64"  },
      "m2.2xlarge"  : { "Arch" : "HVM64"  },
      "m2.4xlarge"  : { "Arch" : "HVM64"  },
      "m3.medium"   : { "Arch" : "HVM64"  },
      "m3.large"    : { "Arch" : "HVM64"  },
      "m3.xlarge"   : { "Arch" : "HVM64"  },
      "m3.2xlarge"  : { "Arch" : "HVM64"  },
      "m4.large"    : { "Arch" : "HVM64"  },
      "m4.xlarge"   : { "Arch" : "HVM64"  },
      "m4.2xlarge"  : { "Arch" : "HVM64"  },
      "m4.4xlarge"  : { "Arch" : "HVM64"  },
      "m4.10xlarge" : { "Arch" : "HVM64"  },
      "c1.medium"   : { "Arch" : "HVM64"  },
      "c1.xlarge"   : { "Arch" : "HVM64"  },
      "c3.large"    : { "Arch" : "HVM64"  },
      "c3.xlarge"   : { "Arch" : "HVM64"  },
      "c3.2xlarge"  : { "Arch" : "HVM64"  },
      "c3.4xlarge"  : { "Arch" : "HVM64"  },
      "c3.8xlarge"  : { "Arch" : "HVM64"  },
      "c4.large"    : { "Arch" : "HVM64"  },
      "c4.xlarge"   : { "Arch" : "HVM64"  },
      "c4.2xlarge"  : { "Arch" : "HVM64"  },
      "c4.4xlarge"  : { "Arch" : "HVM64"  },
      "c4.8xlarge"  : { "Arch" : "HVM64"  },
      "g2.2xlarge"  : { "Arch" : "HVMG2"  },
      "g2.8xlarge"  : { "Arch" : "HVMG2"  },
      "r3.large"    : { "Arch" : "HVM64"  },
      "r3.xlarge"   : { "Arch" : "HVM64"  },
      "r3.2xlarge"  : { "Arch" : "HVM64"  },
      "r3.4xlarge"  : { "Arch" : "HVM64"  },
      "r3.8xlarge"  : { "Arch" : "HVM64"  },
      "i2.xlarge"   : { "Arch" : "HVM64"  },
      "i2.2xlarge"  : { "Arch" : "HVM64"  },
      "i2.4xlarge"  : { "Arch" : "HVM64"  },
      "i2.8xlarge"  : { "Arch" : "HVM64"  },
      "d2.xlarge"   : { "Arch" : "HVM64"  },
      "d2.2xlarge"  : { "Arch" : "HVM64"  },
      "d2.4xlarge"  : { "Arch" : "HVM64"  },
      "d2.8xlarge"  : { "Arch" : "HVM64"  },
      "hi1.4xlarge" : { "Arch" : "HVM64"  },
      "hs1.8xlarge" : { "Arch" : "HVM64"  },
      "cr1.8xlarge" : { "Arch" : "HVM64"  },
      "cc2.8xlarge" : { "Arch" : "HVM64"  }
    },
    "AWSRegionArch2AMI" : {
      "us-east-1"        : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"},
      "us-west-2"        : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"},
      "us-west-1"        : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"},
      "eu-west-1"        : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"},
      "eu-west-2"        : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"},
      "eu-west-3"        : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"},
      "eu-central-1"     : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"},
      "ap-northeast-1"   : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"},
      "ap-northeast-2"   : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"},
      "ap-northeast-3"   : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"},
      "ap-southeast-1"   : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"},
      "ap-southeast-2"   : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"},
      "ap-south-1"       : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"},
      "us-east-2"        : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"},
      "ca-central-1"     : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"},
      "sa-east-1"        : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"},
      "cn-north-1"       : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"},
      "cn-northwest-1"   : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"}
    }
  },
  "Resources": {
    "CloudWatchPutMetricsRole" : {
      "Type"  : "AWS::IAM::Role",
      "Properties" : {
          "AssumeRolePolicyDocument" : {
              "Statement" : [ {
                  "Effect" : "Allow",
                  "Principal" : {
                      "Service" : [ "ec2.amazonaws.com" ]
                  },
                  "Action" : [ "sts:AssumeRole" ]
              } ]
          },
          "Path" : "/"
      }
    },
    "CloudWatchPutMetricsRolePolicy" : {
        "Type" : "AWS::IAM::Policy",
        "Properties" : {
            "PolicyName" : "CloudWatch_PutMetricData",
            "PolicyDocument" : {
              "Version": "2012-10-17",		 	 	 
              "Statement": [
                {
                  "Sid": "CloudWatchPutMetricData",
                  "Effect": "Allow",
                  "Action": ["cloudwatch:PutMetricData"],
                  "Resource": ["*"]
                }
              ]
            },
            "Roles" : [ { "Ref" : "CloudWatchPutMetricsRole" } ]
        }
    },
    "CloudWatchPutMetricsInstanceProfile" : {
      "Type" : "AWS::IAM::InstanceProfile",
      "Properties" : {
        "Path" : "/",
        "Roles" : [ { "Ref" : "CloudWatchPutMetricsRole" } ]
      }
    },
    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "EnableDnsSupport" : "true",
        "EnableDnsHostnames" : "true",
        "CidrBlock": "10.0.0.0/16",
        "Tags": [ {"Key": "Application", "Value": { "Ref": "AWS::StackId"} } ]
      }
    },
    "InternetGateway" : {
      "Type" : "AWS::EC2::InternetGateway",
      "Properties" : {
        "Tags" : [
          { "Key" : "Application", "Value" : { "Ref" : "AWS::StackName" } },
          { "Key" : "Network", "Value" : "Public" }
        ]
      }
    },
    "GatewayToInternet" : {
      "Type" : "AWS::EC2::VPCGatewayAttachment",
      "Properties" : {
        "VpcId" : { "Ref" : "VPC" },
        "InternetGatewayId" : { "Ref" : "InternetGateway" }
      }
    },
    "RouteTable":{
      "Type":"AWS::EC2::RouteTable",
      "Properties":{
        "VpcId": {"Ref":"VPC"}
      }
    },
    "SubnetRouteTableAssoc": {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "RouteTableId" : {"Ref":"RouteTable"},
        "SubnetId" : {"Ref":"Subnet"}
      }
    },
    "InternetGatewayRoute": {
        "Type":"AWS::EC2::Route",
        "Properties":{
            "DestinationCidrBlock":"0.0.0.0/0",
            "RouteTableId":{"Ref":"RouteTable"},
            "GatewayId":{"Ref":"InternetGateway"}
        }
    },
    "Subnet": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "CidrBlock": "10.0.0.0/24",
        "Tags": [ { "Key": "Application", "Value": { "Ref": "AWS::StackId" } } ]
      }
    },    
    "InstanceSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "GroupDescription": "Enable SSH access via port 22",
        "SecurityGroupIngress": [
          { "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": { "Ref": "SSHLocation" } },
          { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" }
         ]
      }
    },
    "MountTargetSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "GroupDescription": "Security group for mount target",
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 2049,
            "ToPort": 2049,
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "FileSystem": {
      "Type": "AWS::EFS::FileSystem",
      "Properties": {
        "PerformanceMode": "generalPurpose",
        "FileSystemTags": [
          {
            "Key": "Name",
            "Value": { "Ref" : "VolumeName" }
          }
        ]
      }
    },
    "MountTarget": {
      "Type": "AWS::EFS::MountTarget",
      "Properties": {
        "FileSystemId": { "Ref": "FileSystem" },
        "SubnetId": { "Ref": "Subnet" },
        "SecurityGroups": [ { "Ref": "MountTargetSecurityGroup" } ]        
      }
    },
    "LaunchConfiguration": {
      "Type": "AWS::AutoScaling::LaunchConfiguration",
      "Metadata" : {
        "AWS::CloudFormation::Init" : {
          "configSets" : {
            "MountConfig" : [ "setup", "mount" ]
          },
          "setup" : {
            "packages" : {
              "yum" : {
                "nfs-utils" : []
              }
            },
            "files" : {
              "/home/ec2-user/post_nfsstat" : {
                "content" : { "Fn::Join" : [ "", [
                      "#!/bin/bash\n",
                      "\n",
                      "INPUT=\"$(cat)\"\n",
                      "CW_JSON_OPEN='{ \"Namespace\": \"EFS\", \"MetricData\": [ '\n",
                      "CW_JSON_CLOSE=' ] }'\n",
                      "CW_JSON_METRIC=''\n",
                      "METRIC_COUNTER=0\n",
                      "\n",
                      "for COL in 1 2 3 4 5 6; do\n",
                      "\n",
                      " COUNTER=0\n",
                      " METRIC_FIELD=$COL\n",
                      " DATA_FIELD=$(($COL+($COL-1)))\n",
                      "\n",
                      " while read line; do\n",
                      "   if [[ COUNTER -gt 0 ]]; then\n",
                      "\n",
                      "     LINE=`echo $line | tr -s ' ' `\n",
                      "     AWS_COMMAND=\"aws cloudwatch put-metric-data --region ", { "Ref": "AWS::Region" }, "\"\n",
                      "     MOD=$(( $COUNTER % 2))\n",
                      "\n",
                      "     if [ $MOD -eq 1 ]; then\n",
                      "       METRIC_NAME=`echo $LINE | cut -d ' ' -f $METRIC_FIELD`\n",
                      "     else\n",
                      "       METRIC_VALUE=`echo $LINE | cut -d ' ' -f $DATA_FIELD`\n",
                      "     fi\n",
                      "\n",
                      "     if [[ -n \"$METRIC_NAME\" && -n \"$METRIC_VALUE\" ]]; then\n",
                      "       INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)\n",
                      "       CW_JSON_METRIC=\"$CW_JSON_METRIC { \\\"MetricName\\\": \\\"$METRIC_NAME\\\", \\\"Dimensions\\\": [{\\\"Name\\\": \\\"InstanceId\\\", \\\"Value\\\": \\\"$INSTANCE_ID\\\"} ], \\\"Value\\\": $METRIC_VALUE },\"\n",
                      "       unset METRIC_NAME\n",
                      "       unset METRIC_VALUE\n",
                      "\n",
                      "       METRIC_COUNTER=$((METRIC_COUNTER+1))\n",
                      "       if [ $METRIC_COUNTER -eq 20 ]; then\n",
                      "         # 20 is max metric collection size, so we have to submit here\n",
                      "         aws cloudwatch put-metric-data --region ", { "Ref": "AWS::Region" }, " --cli-input-json \"`echo $CW_JSON_OPEN ${CW_JSON_METRIC%?} $CW_JSON_CLOSE`\"\n",
                      "\n",
                      "         # reset\n",
                      "         METRIC_COUNTER=0\n",
                      "         CW_JSON_METRIC=''\n",
                      "       fi\n",
                      "     fi  \n",
                      "\n",
                      "\n",
                      "\n",
                      "     COUNTER=$((COUNTER+1))\n",
                      "   fi\n",
                      "\n",
                      "   if [[ \"$line\" == \"Client nfs v4:\" ]]; then\n",
                      "     # the next line is the good stuff \n",
                      "     COUNTER=$((COUNTER+1))\n",
                      "   fi\n",
                      " done <<< \"$INPUT\"\n",
                      "done\n",
                      "\n",
                      "# submit whatever is left\n",
                      "aws cloudwatch put-metric-data --region ", { "Ref": "AWS::Region" }, " --cli-input-json \"`echo $CW_JSON_OPEN ${CW_JSON_METRIC%?} $CW_JSON_CLOSE`\""
                    ] ] },
                "mode": "000755",
                "owner": "ec2-user",
                "group": "ec2-user"
              },
              "/home/ec2-user/crontab" : {
                "content" : { "Fn::Join" : [ "", [
                  "* * * * * /usr/sbin/nfsstat | /home/ec2-user/post_nfsstat\n"
                ] ] },
                "owner": "ec2-user",
                "group": "ec2-user"
              }
            },
            "commands" : {
              "01_createdir" : {
                "command" : {"Fn::Join" : [ "", [ "mkdir /", { "Ref" : "MountPoint" }]]}
              }
            }
          },
          "mount" : {
            "commands" : {
              "01_mount" : {
                "command" : { "Fn::Sub": "sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${FileSystem}.efs.${AWS::Region}.amazonaws.com:/ /${MountPoint}"}
              },
              "02_permissions" : {
                "command" : {"Fn::Join" : [ "", [ "chown ec2-user:ec2-user /", { "Ref" : "MountPoint" }]]}
              }
            }
          }
        }
      },
      "Properties": {
        "AssociatePublicIpAddress" : true,
        "ImageId": {
          "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, {
            "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "InstanceType" }, "Arch" ]
          } ]
        },
        "InstanceType": { "Ref": "InstanceType" },
        "KeyName": { "Ref": "KeyName" },
        "SecurityGroups": [ { "Ref": "InstanceSecurityGroup" } ],
        "IamInstanceProfile" : { "Ref" : "CloudWatchPutMetricsInstanceProfile" },
        "UserData"       : { "Fn::Base64" : { "Fn::Join" : ["", [
             "#!/bin/bash -xe\n",
             "yum install -y aws-cfn-bootstrap\n",

             "/opt/aws/bin/cfn-init -v ",
             "         --stack ", { "Ref" : "AWS::StackName" },
             "         --resource LaunchConfiguration ",
             "         --configsets MountConfig ",
             "         --region ", { "Ref" : "AWS::Region" }, "\n",

             "crontab /home/ec2-user/crontab\n",

             "/opt/aws/bin/cfn-signal -e $? ",
             "         --stack ", { "Ref" : "AWS::StackName" },
             "         --resource AutoScalingGroup ",
             "         --region ", { "Ref" : "AWS::Region" }, "\n"
        ]]}}
      }
    },
    "AutoScalingGroup": {
      "Type": "AWS::AutoScaling::AutoScalingGroup",
      "DependsOn": ["MountTarget", "GatewayToInternet"],
      "CreationPolicy" : {
        "ResourceSignal" : {
          "Timeout" : "PT15M",
          "Count"   : { "Ref": "AsgMaxSize" }
        }
      },
      "Properties": {
        "VPCZoneIdentifier": [ { "Ref": "Subnet" } ],
        "LaunchConfigurationName": { "Ref": "LaunchConfiguration" },
        "MinSize": "1",
        "MaxSize": { "Ref": "AsgMaxSize" },
        "DesiredCapacity": { "Ref": "AsgMaxSize" },
        "Tags": [ {
          "Key": "Name",
          "Value": "EFS FileSystem Mounted Instance",
          "PropagateAtLaunch": "true"
        } ]
      }
    }
  },
  "Outputs" : {
    "MountTargetID" : {
      "Description" : "Mount target ID",
      "Value" :  { "Ref" : "MountTarget" }
    },
    "FileSystemID" : {
      "Description" : "File system ID",
      "Value" :  { "Ref" : "FileSystem" }
    }
  }
}
```

## YAML
<a name="quickref-efs-example-1.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Description: This template creates an Amazon EFS file system and mount target and
  associates it with Amazon EC2 instances in an Auto Scaling group. **WARNING** This
  template creates Amazon EC2 instances and related resources. You will be billed
  for the AWS resources used if you create a stack from this template.
Parameters:
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.small
    AllowedValues:
      - t1.micro
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
      - m1.small
      - m1.medium
      - m1.large
      - m1.xlarge
      - m2.xlarge
      - m2.2xlarge
      - m2.4xlarge
      - m3.medium
      - m3.large
      - m3.xlarge
      - m3.2xlarge
      - m4.large
      - m4.xlarge
      - m4.2xlarge
      - m4.4xlarge
      - m4.10xlarge
      - c1.medium
      - c1.xlarge
      - c3.large
      - c3.xlarge
      - c3.2xlarge
      - c3.4xlarge
      - c3.8xlarge
      - c4.large
      - c4.xlarge
      - c4.2xlarge
      - c4.4xlarge
      - c4.8xlarge
      - g2.2xlarge
      - g2.8xlarge
      - r3.large
      - r3.xlarge
      - r3.2xlarge
      - r3.4xlarge
      - r3.8xlarge
      - i2.xlarge
      - i2.2xlarge
      - i2.4xlarge
      - i2.8xlarge
      - d2.xlarge
      - d2.2xlarge
      - d2.4xlarge
      - d2.8xlarge
      - hi1.4xlarge
      - hs1.8xlarge
      - cr1.8xlarge
      - cc2.8xlarge
      - cg1.4xlarge
    ConstraintDescription: must be a valid EC2 instance type.
  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: Name of an existing EC2 key pair to enable SSH access to the ECS
      instances
  AsgMaxSize:
    Type: Number
    Description: Maximum size and initial desired capacity of Auto Scaling Group
    Default: '2'
  SSHLocation:
    Description: The IP address range that can be used to connect to the EC2 instances
      by using SSH
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  VolumeName:
    Description: The name to be used for the EFS volume
    Type: String
    MinLength: '1'
    Default: myEFSvolume
  MountPoint:
    Description: The Linux mount point for the EFS volume
    Type: String
    MinLength: '1'
    Default: myEFSvolume
Mappings:
  AWSInstanceType2Arch:
    t1.micro:
      Arch: HVM64
    t2.nano:
      Arch: HVM64
    t2.micro:
      Arch: HVM64
    t2.small:
      Arch: HVM64
    t2.medium:
      Arch: HVM64
    t2.large:
      Arch: HVM64
    m1.small:
      Arch: HVM64
    m1.medium:
      Arch: HVM64
    m1.large:
      Arch: HVM64
    m1.xlarge:
      Arch: HVM64
    m2.xlarge:
      Arch: HVM64
    m2.2xlarge:
      Arch: HVM64
    m2.4xlarge:
      Arch: HVM64
    m3.medium:
      Arch: HVM64
    m3.large:
      Arch: HVM64
    m3.xlarge:
      Arch: HVM64
    m3.2xlarge:
      Arch: HVM64
    m4.large:
      Arch: HVM64
    m4.xlarge:
      Arch: HVM64
    m4.2xlarge:
      Arch: HVM64
    m4.4xlarge:
      Arch: HVM64
    m4.10xlarge:
      Arch: HVM64
    c1.medium:
      Arch: HVM64
    c1.xlarge:
      Arch: HVM64
    c3.large:
      Arch: HVM64
    c3.xlarge:
      Arch: HVM64
    c3.2xlarge:
      Arch: HVM64
    c3.4xlarge:
      Arch: HVM64
    c3.8xlarge:
      Arch: HVM64
    c4.large:
      Arch: HVM64
    c4.xlarge:
      Arch: HVM64
    c4.2xlarge:
      Arch: HVM64
    c4.4xlarge:
      Arch: HVM64
    c4.8xlarge:
      Arch: HVM64
    g2.2xlarge:
      Arch: HVMG2
    g2.8xlarge:
      Arch: HVMG2
    r3.large:
      Arch: HVM64
    r3.xlarge:
      Arch: HVM64
    r3.2xlarge:
      Arch: HVM64
    r3.4xlarge:
      Arch: HVM64
    r3.8xlarge:
      Arch: HVM64
    i2.xlarge:
      Arch: HVM64
    i2.2xlarge:
      Arch: HVM64
    i2.4xlarge:
      Arch: HVM64
    i2.8xlarge:
      Arch: HVM64
    d2.xlarge:
      Arch: HVM64
    d2.2xlarge:
      Arch: HVM64
    d2.4xlarge:
      Arch: HVM64
    d2.8xlarge:
      Arch: HVM64
    hi1.4xlarge:
      Arch: HVM64
    hs1.8xlarge:
      Arch: HVM64
    cr1.8xlarge:
      Arch: HVM64
    cc2.8xlarge:
      Arch: HVM64
  AWSRegionArch2AMI:
    us-east-1:
      HVM64: ami-0ff8a91507f77f867
      HVMG2: ami-0a584ac55a7631c0c
    us-west-2:
      HVM64: ami-a0cfeed8
      HVMG2: ami-0e09505bc235aa82d
    us-west-1:
      HVM64: ami-0bdb828fd58c52235
      HVMG2: ami-066ee5fd4a9ef77f1
    eu-west-1:
      HVM64: ami-047bb4163c506cd98
      HVMG2: ami-0a7c483d527806435
    eu-west-2:
      HVM64: ami-f976839e
      HVMG2: NOT_SUPPORTED
    eu-west-3:
      HVM64: ami-0ebc281c20e89ba4b
      HVMG2: NOT_SUPPORTED
    eu-central-1:
      HVM64: ami-0233214e13e500f77
      HVMG2: ami-06223d46a6d0661c7
    ap-northeast-1:
      HVM64: ami-06cd52961ce9f0d85
      HVMG2: ami-053cdd503598e4a9d
    ap-northeast-2:
      HVM64: ami-0a10b2721688ce9d2
      HVMG2: NOT_SUPPORTED
    ap-northeast-3:
      HVM64: ami-0d98120a9fb693f07
      HVMG2: NOT_SUPPORTED
    ap-southeast-1:
      HVM64: ami-08569b978cc4dfa10
      HVMG2: ami-0be9df32ae9f92309
    ap-southeast-2:
      HVM64: ami-09b42976632b27e9b
      HVMG2: ami-0a9ce9fecc3d1daf8
    ap-south-1:
      HVM64: ami-0912f71e06545ad88
      HVMG2: ami-097b15e89dbdcfcf4
    us-east-2:
      HVM64: ami-0b59bfac6be064b78
      HVMG2: NOT_SUPPORTED
    ca-central-1:
      HVM64: ami-0b18956f
      HVMG2: NOT_SUPPORTED
    sa-east-1:
      HVM64: ami-07b14488da8ea02a0
      HVMG2: NOT_SUPPORTED
    cn-north-1:
      HVM64: ami-0a4eaf6c4454eda75
      HVMG2: NOT_SUPPORTED
    cn-northwest-1:
      HVM64: ami-6b6a7d09
      HVMG2: NOT_SUPPORTED
Resources:
  CloudWatchPutMetricsRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - ec2.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
  CloudWatchPutMetricsRolePolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: CloudWatch_PutMetricData
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Sid: CloudWatchPutMetricData
          Effect: Allow
          Action:
          - cloudwatch:PutMetricData
          Resource:
          - "*"
      Roles:
      - Ref: CloudWatchPutMetricsRole
  CloudWatchPutMetricsInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: "/"
      Roles:
      - Ref: CloudWatchPutMetricsRole
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      CidrBlock: 10.0.0.0/16
      Tags:
      - Key: Application
        Value:
          Ref: AWS::StackId
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Application
        Value:
          Ref: AWS::StackName
      - Key: Network
        Value: Public
  GatewayToInternet:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId:
        Ref: VPC
      InternetGatewayId:
        Ref: InternetGateway
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: VPC
  SubnetRouteTableAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId:
        Ref: RouteTable
      SubnetId:
        Ref: Subnet
  InternetGatewayRoute:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      RouteTableId:
        Ref: RouteTable
      GatewayId:
        Ref: InternetGateway
  Subnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      CidrBlock: 10.0.0.0/24
      Tags:
      - Key: Application
        Value:
          Ref: AWS::StackId
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId:
        Ref: VPC
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp:
          Ref: SSHLocation
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
  MountTargetSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId:
        Ref: VPC
      GroupDescription: Security group for mount target
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 2049
        ToPort: 2049
        CidrIp: 0.0.0.0/0
  FileSystem:
    Type: AWS::EFS::FileSystem
    Properties:
      PerformanceMode: generalPurpose
      FileSystemTags:
      - Key: Name
        Value:
          Ref: VolumeName
  MountTarget:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId:
        Ref: FileSystem
      SubnetId:
        Ref: Subnet
      SecurityGroups:
      - Ref: MountTargetSecurityGroup
  LaunchConfiguration:
    Type: AWS::AutoScaling::LaunchConfiguration
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          MountConfig:
          - setup
          - mount
        setup:
          packages:
            yum:
              nfs-utils: []
          files:
            "/home/ec2-user/post_nfsstat":
              content: !Sub |
                #!/bin/bash

                INPUT="$(cat)"
                CW_JSON_OPEN='{ "Namespace": "EFS", "MetricData": [ '
                CW_JSON_CLOSE=' ] }'
                CW_JSON_METRIC=''
                METRIC_COUNTER=0

                for COL in 1 2 3 4 5 6; do

                 COUNTER=0
                 METRIC_FIELD=$COL
                 DATA_FIELD=$(($COL+($COL-1)))

                 while read line; do
                   if [[ COUNTER -gt 0 ]]; then

                     LINE=`echo $line | tr -s ' ' `
                     AWS_COMMAND="aws cloudwatch put-metric-data --region ${AWS::Region}"
                     MOD=$(( $COUNTER % 2))

                     if [ $MOD -eq 1 ]; then
                       METRIC_NAME=`echo $LINE | cut -d ' ' -f $METRIC_FIELD`
                     else
                       METRIC_VALUE=`echo $LINE | cut -d ' ' -f $DATA_FIELD`
                     fi

                     if [[ -n "$METRIC_NAME" && -n "$METRIC_VALUE" ]]; then
                       INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
                       CW_JSON_METRIC="$CW_JSON_METRIC { \"MetricName\": \"$METRIC_NAME\", \"Dimensions\": [{\"Name\": \"InstanceId\", \"Value\": \"$INSTANCE_ID\"} ], \"Value\": $METRIC_VALUE },"
                       unset METRIC_NAME
                       unset METRIC_VALUE

                       METRIC_COUNTER=$((METRIC_COUNTER+1))
                       if [ $METRIC_COUNTER -eq 20 ]; then
                         # 20 is max metric collection size, so we have to submit here
                         aws cloudwatch put-metric-data --region ${AWS::Region} --cli-input-json "`echo $CW_JSON_OPEN ${!CW_JSON_METRIC%?} $CW_JSON_CLOSE`"

                         # reset
                         METRIC_COUNTER=0
                         CW_JSON_METRIC=''
                       fi
                     fi



                     COUNTER=$((COUNTER+1))
                   fi

                   if [[ "$line" == "Client nfs v4:" ]]; then
                     # the next line is the good stuff
                     COUNTER=$((COUNTER+1))
                   fi
                 done <<< "$INPUT"
                done

                # submit whatever is left
                aws cloudwatch put-metric-data --region ${AWS::Region} --cli-input-json "`echo $CW_JSON_OPEN ${!CW_JSON_METRIC%?} $CW_JSON_CLOSE`"
              mode: '000755'
              owner: ec2-user
              group: ec2-user
            "/home/ec2-user/crontab":
              content: "* * * * * /usr/sbin/nfsstat | /home/ec2-user/post_nfsstat\n"
              owner: ec2-user
              group: ec2-user
          commands:
            01_createdir:
              command: !Sub "mkdir /${MountPoint}"
        mount:
          commands:
            01_mount:
              command: !Sub >
                mount -t nfs4 -o nfsvers=4.1 ${FileSystem}.efs.${AWS::Region}.amazonaws.com:/ /${MountPoint}
            02_permissions:
              command: !Sub "chown ec2-user:ec2-user /${MountPoint}"
    Properties:
      AssociatePublicIpAddress: true
      ImageId:
        Fn::FindInMap:
        - AWSRegionArch2AMI
        - Ref: AWS::Region
        - Fn::FindInMap:
          - AWSInstanceType2Arch
          - Ref: InstanceType
          - Arch
      InstanceType:
        Ref: InstanceType
      KeyName:
        Ref: KeyName
      SecurityGroups:
      - Ref: InstanceSecurityGroup
      IamInstanceProfile:
        Ref: CloudWatchPutMetricsInstanceProfile
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfiguration --configsets MountConfig --region ${AWS::Region}
          crontab /home/ec2-user/crontab
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AutoScalingGroup --region ${AWS::Region}
  AutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    DependsOn:
    - MountTarget
    - GatewayToInternet
    CreationPolicy:
      ResourceSignal:
        Timeout: PT15M
        Count:
          Ref: AsgMaxSize
    Properties:
      VPCZoneIdentifier:
      - Ref: Subnet
      LaunchConfigurationName:
        Ref: LaunchConfiguration
      MinSize: '1'
      MaxSize:
        Ref: AsgMaxSize
      DesiredCapacity:
        Ref: AsgMaxSize
      Tags:
      - Key: Name
        Value: EFS FileSystem Mounted Instance
        PropagateAtLaunch: 'true'
Outputs:
  MountTargetID:
    Description: Mount target ID
    Value:
      Ref: MountTarget
  FileSystemID:
    Description: File system ID
    Value:
      Ref: FileSystem
```

# Elastic Beanstalk 範本程式碼片段
<a name="quickref-elasticbeanstalk"></a>

使用 Elastic Beanstalk，您可以在 中快速部署和管理應用程式， AWS 而無需擔心執行這些應用程式的基礎設施。下列範例範本可協助您在 CloudFormation 範本中描述 Elastic Beanstalk 資源。

## Elastic Beanstalk 範例 PHP
<a name="quickref-elasticbeanstalk-sampleenv"></a>

下列範例範本會部署存放在 Amazon S3 儲存貯體的範例 PHP Web 應用程式。此環境也是自動擴展的負載平衡環境，至少有兩個 Amazon EC2 執行個體，最多則有六個。此範例展示的 Elastic Beanstalk 環境使用了舊版啟動組態。有關改用啟動範本的資訊，請參閱《AWS Elastic Beanstalk 開發人員指南**》中的[啟動範本](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-autoscaling-launch-templates.html)。

以解決方案堆疊名稱 (平台版本) 取代 `solution-stack`。如需可用解決方案堆疊的清單，請使用 AWS CLI 命令 **aws elasticbeanstalk list-available-solution-stacks**。

### JSON
<a name="quickref-elasticbeanstalk-example-1.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "sampleApplication": {
            "Type": "AWS::ElasticBeanstalk::Application",
            "Properties": {
                "Description": "AWS Elastic Beanstalk Sample Application"
            }
        },
        "sampleApplicationVersion": {
            "Type": "AWS::ElasticBeanstalk::ApplicationVersion",
            "Properties": {
                "ApplicationName": {
                    "Ref": "sampleApplication"
                },
                "Description": "AWS ElasticBeanstalk Sample Application Version",
                "SourceBundle": {
                    "S3Bucket": {
                        "Fn::Sub": "elasticbeanstalk-samples-${AWS::Region}"
                    },
                    "S3Key": "php-newsample-app.zip"
                }
            }
        },
        "sampleConfigurationTemplate": {
            "Type": "AWS::ElasticBeanstalk::ConfigurationTemplate",
            "Properties": {
                "ApplicationName": {
                    "Ref": "sampleApplication"
                },
                "Description": "AWS ElasticBeanstalk Sample Configuration Template",
                "OptionSettings": [
                    {
                        "Namespace": "aws:autoscaling:asg",
                        "OptionName": "MinSize",
                        "Value": "2"
                    },
                    {
                        "Namespace": "aws:autoscaling:asg",
                        "OptionName": "MaxSize",
                        "Value": "6"
                    },
                    {
                        "Namespace": "aws:elasticbeanstalk:environment",
                        "OptionName": "EnvironmentType",
                        "Value": "LoadBalanced"
                    },
                    {
                        "Namespace": "aws:autoscaling:launchconfiguration",
                        "OptionName": "IamInstanceProfile",
                        "Value": {
                            "Ref": "MyInstanceProfile"
                        }
                    }
                ],
                "SolutionStackName": "solution-stack"
            }
        },
        "sampleEnvironment": {
            "Type": "AWS::ElasticBeanstalk::Environment",
            "Properties": {
                "ApplicationName": {
                    "Ref": "sampleApplication"
                },
                "Description": "AWS ElasticBeanstalk Sample Environment",
                "TemplateName": {
                    "Ref": "sampleConfigurationTemplate"
                },
                "VersionLabel": {
                    "Ref": "sampleApplicationVersion"
                }
            }
        },
        "MyInstanceRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "ec2.amazonaws.com"
                                ]
                            },
                            "Action": [
                                "sts:AssumeRole"
                            ]
                        }
                    ]
                },
                "Description": "Beanstalk EC2 role",
                "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier",
                    "arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker",
                    "arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier"
                ]
            }
        },
        "MyInstanceProfile": {
            "Type": "AWS::IAM::InstanceProfile",
            "Properties": {
                "Roles": [
                    {
                        "Ref": "MyInstanceRole"
                    }
                ]
            }
        }
    }
}
```

### YAML
<a name="quickref-elasticbeanstalk-example-1.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  sampleApplication:
    Type: AWS::ElasticBeanstalk::Application
    Properties:
      Description: AWS Elastic Beanstalk Sample Application
  sampleApplicationVersion:
    Type: AWS::ElasticBeanstalk::ApplicationVersion
    Properties:
      ApplicationName:
        Ref: sampleApplication
      Description: AWS ElasticBeanstalk Sample Application Version
      SourceBundle:
        S3Bucket: !Sub "elasticbeanstalk-samples-${AWS::Region}"
        S3Key: php-newsample-app.zip
  sampleConfigurationTemplate:
    Type: AWS::ElasticBeanstalk::ConfigurationTemplate
    Properties:
      ApplicationName:
        Ref: sampleApplication
      Description: AWS ElasticBeanstalk Sample Configuration Template
      OptionSettings:
      - Namespace: aws:autoscaling:asg
        OptionName: MinSize
        Value: '2'
      - Namespace: aws:autoscaling:asg
        OptionName: MaxSize
        Value: '6'
      - Namespace: aws:elasticbeanstalk:environment
        OptionName: EnvironmentType
        Value: LoadBalanced
      - Namespace: aws:autoscaling:launchconfiguration
        OptionName: IamInstanceProfile
        Value: !Ref MyInstanceProfile        
      SolutionStackName: solution-stack
  sampleEnvironment:
    Type: AWS::ElasticBeanstalk::Environment
    Properties:
      ApplicationName:
        Ref: sampleApplication
      Description: AWS ElasticBeanstalk Sample Environment
      TemplateName:
        Ref: sampleConfigurationTemplate
      VersionLabel:
        Ref: sampleApplicationVersion
  MyInstanceRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Description: Beanstalk EC2 role
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier
        - arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker
        - arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier
  MyInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties: 
      Roles:
        - !Ref MyInstanceRole
```

# Elastic Load Balancing 範本程式碼片段
<a name="quickref-elb"></a>

要建立 Application Load Balancer、Network Load Balancer 或 Gateway Load Balancer，請使用開頭為 `AWS::ElasticLoadBalancingV2` 的 V2 資源類型。要建立 Classic Load Balancer，請使用開頭為 `AWS::ElasticLoadBalancing` 的資源類型。

**Topics**
+ [ELBv2 資源](#scenario-elbv2-load-balancer)
+ [Classic Load Balancer 資源](#scenario-elb-load-balancer)

## ELBv2 資源
<a name="scenario-elbv2-load-balancer"></a>

此範例定義一個 Application Load Balancer，其具備 HTTP 接聽程式和將流量轉送至目標群組的預設動作。此負載平衡器使用預設的運作狀態檢查設定。該目標群組包含兩個已註冊的 EC2 執行個體。

------
#### [ YAML ]

```
Resources:
  myLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: my-alb
      Type: application
      Scheme: internal
      Subnets: 
        - !Ref subnet-AZ1
        - !Ref subnet-AZ2
      SecurityGroups: 
        - !Ref mySecurityGroup

  myHTTPlistener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref myLoadBalancer
      Protocol: HTTP
      Port: 80
      DefaultActions:
        - Type: "forward"
          TargetGroupArn: !Ref myTargetGroup
                        
  myTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: "my-target-group"
      Protocol: HTTP
      Port: 80
      TargetType: instance
      VpcId: !Ref myVPC
      Targets:
        - Id: !GetAtt Instance1.InstanceId
          Port: 80
        - Id: !GetAtt Instance2.InstanceId
          Port: 80
```

------
#### [ JSON ]

```
{
    "Resources": {
        "myLoadBalancer": {
            "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
            "Properties": {
                "Name": "my-alb",
                "Type": "application",
                "Scheme": "internal",
                "Subnets": [
                    {
                        "Ref": "subnet-AZ1"
                    },
                    {
                        "Ref": "subnet-AZ2"
                    }
                ],
                "SecurityGroups": [
                    {
                        "Ref": "mySecurityGroup"
                    }
                ]
            }
        },
        "myHTTPlistener": {
            "Type": "AWS::ElasticLoadBalancingV2::Listener",
            "Properties": {
                "LoadBalancerArn": {
                    "Ref": "myLoadBalancer"
                },
                "Protocol": "HTTP",
                "Port": 80,
                "DefaultActions": [
                    {
                        "Type": "forward",
                        "TargetGroupArn": {
                            "Ref": "myTargetGroup"
                        }
                    }
                ]
            }
        },
        "myTargetGroup": {
            "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
            "Properties": {
                "Name": "my-target-group",
                "Protocol": "HTTP",
                "Port": 80,
                "TargetType": "instance",
                "VpcId": {
                    "Ref": "myVPC"
                },
                "Targets": [
                    {
                        "Id": {
                            "Fn::GetAtt": [
                                "Instance1",
                                "InstanceId"
                            ]
                        },
                        "Port": 80
                    },
                    {
                        "Id": {
                            "Fn::GetAtt": [
                                "Instance2",
                                "InstanceId"
                            ]
                        },
                        "Port": 80
                    }
                ]
            }
        }
    }
}
```

------

## Classic Load Balancer 資源
<a name="scenario-elb-load-balancer"></a>

此範例定義了一個 Classic Load Balancer，其具備 HTTP 接聽程式但沒有已註冊 EC2 執行個體。此負載平衡器使用預設的運作狀態檢查設定。

------
#### [ YAML ]

```
myLoadBalancer:
  Type: AWS::ElasticLoadBalancing::LoadBalancer
  Properties:
    AvailabilityZones:
    - "us-east-1a"
    Listeners:
    - LoadBalancerPort: '80'
      InstancePort: '80'
      Protocol: HTTP
```

------
#### [ JSON ]

```
"myLoadBalancer" : {
    "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
    "Properties" : {
        "AvailabilityZones" : [ "us-east-1a" ],
        "Listeners" : [ {
            "LoadBalancerPort" : "80",
            "InstancePort" : "80",
            "Protocol" : "HTTP"
        } ]
    }
}
```

------

此範例定義了一個 Classic Load Balancer，其具備 HTTP 接聽程式、兩個已註冊 EC2 執行個體和自訂運作狀態檢查設定。

------
#### [ YAML ]

```
myClassicLoadBalancer:
  Type: AWS::ElasticLoadBalancing::LoadBalancer
  Properties:
    AvailabilityZones:
    - "us-east-1a"
    Instances:
    - Ref: Instance1
    - Ref: Instance2
    Listeners:
    - LoadBalancerPort: '80'
      InstancePort: '80'
      Protocol: HTTP
    HealthCheck:
      Target: HTTP:80/
      HealthyThreshold: '3'
      UnhealthyThreshold: '5'
      Interval: '30'
      Timeout: '5'
```

------
#### [ JSON ]

```
"myClassicLoadBalancer" : {
    "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
    "Properties" : {
        "AvailabilityZones" : [ "us-east-1a" ],
        "Instances" : [
            { "Ref" : "Instance1" },
            { "Ref" : "Instance2" }
        ],
        "Listeners" : [ {
            "LoadBalancerPort" : "80",
            "InstancePort" : "80",
            "Protocol" : "HTTP"
        } ],

        "HealthCheck" : {
            "Target" : "HTTP:80/",
            "HealthyThreshold" : "3",
            "UnhealthyThreshold" : "5",
            "Interval" : "30",
            "Timeout" : "5"
        }
    }
}
```

------

# AWS Identity and Access Management 範本程式碼片段
<a name="quickref-iam"></a>

本節包含 AWS Identity and Access Management 範本程式碼片段。

**Topics**
+ [宣告 IAM 使用者資源](#scenario-iam-user)
+ [宣告一個 IAM 存取金鑰資源](#scenario-iam-accesskey)
+ [宣告 IAM 群組資源](#scenario-iam-group)
+ [將使用者新增至群組](#scenario-iam-addusertogroup)
+ [宣告 IAM 政策](#scenario-iam-policy)
+ [宣告 Amazon S3 儲存貯體政策](#scenario-bucket-policy)
+ [宣告 Amazon SNS 主題政策](#scenario-sns-policy)
+ [宣告 Amazon SQS 政策](#scenario-sqs-policy)
+ [IAM 角色範本範例](#scenarios-iamroles)

**重要**  
當使用包含 IAM 資源的範本建立或更新堆疊時，您必須認可使用 IAM 功能。如需詳細資訊，請參閱[認可 CloudFormation 範本中的 IAM 資源](control-access-with-iam.md#using-iam-capabilities)。

## 宣告 IAM 使用者資源
<a name="scenario-iam-user"></a>

此程式碼片段會示範如何宣告 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html) 資源來建立 IAM 使用者。使用者會使用路徑 (`"/"`) 宣告，登入描述檔則會使用密碼 (`myP@ssW0rd`) 宣告。

名為 `giveaccesstoqueueonly` 的政策文件會給予使用者在 Amazon SQS 佇列資源 `myqueue` 上執行所有 Amazon SQS 動作的許可，並拒絕存取所有其他的 Amazon SQS 佇列資源。`Fn::GetAtt` 函數會取得 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sqs-queue.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sqs-queue.html) 資源 `myqueue` 的 Arn 屬性。

名為 `giveaccesstotopiconly` 的政策文件會新增到使用者，給予使用者在 Amazon SNS 主題資源 `mytopic` 上執行所有 Amazon SNS 動作的許可，並拒絕存取所有其他的 Amazon SNS 資源。`Ref` 函數會取得 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topic.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topic.html) 資源 `mytopic` 的 ARN。

### JSON
<a name="quickref-iam-example-1.json"></a>

```
"myuser" : {
   "Type" : "AWS::IAM::User",
   "Properties" : {
      "Path" : "/",
      "LoginProfile" : {
         "Password" : "myP@ssW0rd"
      },
      "Policies" : [ {
         "PolicyName" : "giveaccesstoqueueonly",
         "PolicyDocument" : {
            "Version": "2012-10-17",		 	 	 
            "Statement" : [ {
               "Effect" : "Allow",
               "Action" : [ "sqs:*" ],
               "Resource" : [ {
                  "Fn::GetAtt" : [ "myqueue", "Arn" ]
               } ]
            }, {
               "Effect" : "Deny",
               "Action" : [ "sqs:*" ],
               "NotResource" : [ {
                  "Fn::GetAtt" : [ "myqueue", "Arn" ]
               } ]
            }
         ] }
      }, {
         "PolicyName" : "giveaccesstotopiconly",
         "PolicyDocument" : {
            "Version": "2012-10-17",		 	 	 
            "Statement" : [ {
               "Effect" : "Allow",
               "Action" : [ "sns:*" ],
               "Resource" : [ { "Ref" : "mytopic" } ]
            }, {
               "Effect" : "Deny",
               "Action" : [ "sns:*" ],
               "NotResource" : [ { "Ref" : "mytopic" } ]
            } ]
         }
      } ]
   }
}
```

### YAML
<a name="quickref-iam-example-1.yaml"></a>

```
myuser:
  Type: AWS::IAM::User
  Properties:
    Path: "/"
    LoginProfile:
      Password: myP@ssW0rd
    Policies:
    - PolicyName: giveaccesstoqueueonly
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
          - sqs:*
          Resource:
          - !GetAtt myqueue.Arn
        - Effect: Deny
          Action:
          - sqs:*
          NotResource:
          - !GetAtt myqueue.Arn
    - PolicyName: giveaccesstotopiconly
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
          - sns:*
          Resource:
          - !Ref mytopic
        - Effect: Deny
          Action:
          - sns:*
          NotResource:
          - !Ref mytopic
```

## 宣告一個 IAM 存取金鑰資源
<a name="scenario-iam-accesskey"></a>

### 
<a name="quickref-iam-access-key"></a>

此程式碼片段顯示一個 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-accesskey.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-accesskey.html) 資源。`myaccesskey` 資源會建立存取金鑰，並將其指派給一個已在範本中宣告為 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html) 資源的 IAM 使用者。

#### JSON
<a name="quickref-iam-example-2.json"></a>

```
"myaccesskey" : {
   "Type" : "AWS::IAM::AccessKey",
   "Properties" : {
      "UserName" : { "Ref" : "myuser" }
   }
}
```

#### YAML
<a name="quickref-iam-example-2.yaml"></a>

```
myaccesskey:
  Type: AWS::IAM::AccessKey
  Properties:
    UserName:
      !Ref myuser
```

### 
<a name="quickref-iam-access-key-2"></a>

您可以使用 `AWS::IAM::AccessKey` 函數取得 `Fn::GetAtt` 資源的秘密金鑰。擷取秘密金鑰的其中一個方法，便是將其放入 `Output` 值中。您可以使用 `Ref` 函數取得存取金鑰。以下 `Output` 值宣告會取得 `myaccesskey` 的存取金鑰和秘密金鑰。

#### JSON
<a name="quickref-iam-example-3.json"></a>

```
"AccessKeyformyaccesskey" : {
   "Value" : { "Ref" : "myaccesskey" }
},
"SecretKeyformyaccesskey" : {
   "Value" : {
      "Fn::GetAtt" : [ "myaccesskey", "SecretAccessKey" ]
   }
}
```

#### YAML
<a name="quickref-iam-example-3.yaml"></a>

```
AccessKeyformyaccesskey:
  Value:
    !Ref myaccesskey
SecretKeyformyaccesskey:
  Value: !GetAtt myaccesskey.SecretAccessKey
```

### 
<a name="quickref-iam-access-key-3"></a>

您也可以將 AWS 存取金鑰和私密金鑰傳遞至範本中定義的 Amazon EC2 執行個體或 Auto Scaling 群組。下列 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) 宣告使用 `UserData` 屬性傳遞 `myaccesskey` 資源的存取金鑰和秘密金鑰。

#### JSON
<a name="quickref-iam-example-4.json"></a>

```
"myinstance" : {
   "Type" : "AWS::EC2::Instance",
   "Properties" : {
      "AvailabilityZone" : "us-east-1a",
      "ImageId" : "ami-0ff8a91507f77f867",
      "UserData" : {
         "Fn::Base64" : {
            "Fn::Join" : [
               "", [
                  "ACCESS_KEY=", {
                     "Ref" : "myaccesskey"
                  },
                  "&",
                  "SECRET_KEY=",
                  {
                     "Fn::GetAtt" : [
                        "myaccesskey",
                        "SecretAccessKey"
                     ]
                  }
               ]
            ]
         }
      }
   }
}
```

#### YAML
<a name="quickref-iam-example-4.yaml"></a>

```
myinstance:
  Type: AWS::EC2::Instance
  Properties:
    AvailabilityZone: "us-east-1a"
    ImageId: ami-0ff8a91507f77f867
    UserData:
      Fn::Base64: !Sub "ACCESS_KEY=${myaccesskey}&SECRET_KEY=${myaccesskey.SecretAccessKey}"
```

## 宣告 IAM 群組資源
<a name="scenario-iam-group"></a>

此程式碼片段顯示一個 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-group.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-group.html) 資源。群組具有路徑 (`"/myapplication/"`)。名為 `myapppolicy` 的政策文件會新增到群組，允許群組的使用者在 Amazon SQS 佇列資源 myqueue 上執行所有 Amazon SQS 動作，並拒絕存取除 `myqueue` 之外的所有其他 Amazon SQS 資源。

若要將政策指派給資源，IAM 需要資源的 Amazon Resource Name (ARN)。在程式碼片段中，`Fn::GetAtt` 函數會取得 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sqs-queue.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sqs-queue.html) 資源佇列的 ARN。

### JSON
<a name="quickref-iam-example-5.json"></a>

```
"mygroup" : {
   "Type" : "AWS::IAM::Group",
   "Properties" : {
      "Path" : "/myapplication/",
      "Policies" : [ {
         "PolicyName" : "myapppolicy",
         "PolicyDocument" : {
            "Version": "2012-10-17",		 	 	 
            "Statement" : [ {
               "Effect" : "Allow",
               "Action" : [ "sqs:*" ],
               "Resource" : [ {
                  "Fn::GetAtt" : [ "myqueue", "Arn" ]
               } ]
            },
            {
               "Effect" : "Deny",
               "Action" : [ "sqs:*" ],
               "NotResource" : [ { "Fn::GetAtt" : [ "myqueue", "Arn" ] } ]
            }
         ] }
      } ]
   }
}
```

### YAML
<a name="quickref-iam-example-5.yaml"></a>

```
mygroup:
  Type: AWS::IAM::Group
  Properties:
    Path: "/myapplication/"
    Policies:
    - PolicyName: myapppolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action:
          - sqs:*
          Resource: !GetAtt myqueue.Arn
        - Effect: Deny
          Action:
          - sqs:*
          NotResource: !GetAtt myqueue.Arn
```

## 將使用者新增至群組
<a name="scenario-iam-addusertogroup"></a>

[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-usertogroupaddition.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-usertogroupaddition.html) 資源會將使用者新增至群組。在以下程式碼片段中，`addUserToGroup` 資源會將下列使用者新增到名為 `myexistinggroup2` 的現有群組：現有使用者 `existinguser1` 和在範本中已宣告為 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html) 資源的使用者 `myuser`。

### JSON
<a name="quickref-iam-example-6.json"></a>

```
"addUserToGroup" : {
   "Type" : "AWS::IAM::UserToGroupAddition",
   "Properties" : {
      "GroupName" : "myexistinggroup2",
      "Users" : [ "existinguser1", { "Ref" : "myuser" } ]
   }
}
```

### YAML
<a name="quickref-iam-example-6.yaml"></a>

```
addUserToGroup:
  Type: AWS::IAM::UserToGroupAddition
  Properties:
    GroupName: myexistinggroup2
    Users:
    - existinguser1
    - !Ref myuser
```

## 宣告 IAM 政策
<a name="scenario-iam-policy"></a>

此程式碼片段會示範如何使用名為 `mypolicy` 的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-policy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-policy.html) 資源建立政策，並將其套用到多個群組。`mypolicy` 資源包含 `PolicyDocument` 屬性，允許在由 ARN `GetObject` 代表之 S3 儲存貯體中的物件上執行 `PutObject`、`PutObjectAcl` 和 `arn:aws:s3:::myAWSBucket` 動作。`mypolicy` 資源會將政策套用至名為 `myexistinggroup1` 的現有群組，以及已在範本中宣告為 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-group.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-group.html) 資源的 `mygroup` 群組。此範例會示範如何使用 `Groups` 屬性將政策套用至群組。但是，您也可以改為使用 `Users` 屬性，將政策文件新增至使用者清單。

### JSON
<a name="quickref-iam-example-7.json"></a>

```
"mypolicy" : {
   "Type" : "AWS::IAM::Policy",
   "Properties" : {
      "PolicyName" : "mygrouppolicy",
      "PolicyDocument" : {
         "Version": "2012-10-17",		 	 	 
         "Statement" : [ {
            "Effect" : "Allow",
            "Action" : [
               "s3:GetObject" , "s3:PutObject" , "s3:PutObjectAcl" ],
            "Resource" : "arn:aws:s3:::myAWSBucket/*"
         } ]
      },
      "Groups" : [ "myexistinggroup1", { "Ref" : "mygroup" } ]
   }
}
```

### YAML
<a name="quickref-iam-example-7.yaml"></a>

```
mypolicy:
  Type: AWS::IAM::Policy
  Properties:
    PolicyName: mygrouppolicy
    PolicyDocument:
      Version: '2012-10-17'
      Statement:
      - Effect: Allow
        Action:
        - s3:GetObject
        - s3:PutObject
        - s3:PutObjectAcl
        Resource: arn:aws:s3:::myAWSBucket/*
    Groups:
    - myexistinggroup1
    - !Ref mygroup
```

## 宣告 Amazon S3 儲存貯體政策
<a name="scenario-bucket-policy"></a>

此程式碼片段示範如何使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-s3-bucket.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-s3-bucket.html) 資源建立政策，並將其套用到 Amazon S3 儲存貯體。`mybucketpolicy` 資源會宣告一個政策文件，允許 `user1` IAM 使用者在套用此政策的 S3 儲存貯體中的所有物件上執行 `GetObject` 動作。在程式碼片段中，`Fn::GetAtt` 函數會取得 `user1` 資源的 ARN。`mybucketpolicy` 資源會將政策套用到 `AWS::S3::BucketPolicy` 資源 mybucket。`Ref` 函數會取得 `mybucket` 資源的儲存貯體名稱。

### JSON
<a name="quickref-iam-example-8.json"></a>

```
"mybucketpolicy" : {
   "Type" : "AWS::S3::BucketPolicy",
   "Properties" : {
      "PolicyDocument" : {
         "Id" : "MyPolicy",
         "Version": "2012-10-17",		 	 	 
         "Statement" : [ {
            "Sid" : "ReadAccess",
            "Action" : [ "s3:GetObject" ],
            "Effect" : "Allow",
            "Resource" : { "Fn::Join" : [
                  "", [ "arn:aws:s3:::", { "Ref" : "mybucket" } , "/*" ]
               ] },
            "Principal" : {
               "AWS" : { "Fn::GetAtt" : [ "user1", "Arn" ] }
            }
         } ]
      },
      "Bucket" : { "Ref" : "mybucket" }
   }
}
```

### YAML
<a name="quickref-iam-example-8.yaml"></a>

```
mybucketpolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    PolicyDocument:
      Id: MyPolicy
      Version: '2012-10-17'
      Statement:
      - Sid: ReadAccess
        Action:
        - s3:GetObject
        Effect: Allow
        Resource: !Sub "arn:aws:s3:::${mybucket}/*"
        Principal:
          AWS: !GetAtt user1.Arn
    Bucket: !Ref mybucket
```

## 宣告 Amazon SNS 主題政策
<a name="scenario-sns-policy"></a>

此程式碼片段示範如何使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topicpolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topicpolicy.html) 資源建立政策，並將其套用到 Amazon SNS 主題。`mysnspolicy` 資源包含 `PolicyDocument` 屬性，允許 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html) 資源 `myuser` 在 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topic.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topic.html) 資源 `mytopic` 上執行 `Publish` 動作。在程式碼片段中，`Fn::GetAtt` 函數會取得 `myuser` 資源的 ARN，並且 `Ref` 函數會取得 `mytopic` 資源的 ARN。

### JSON
<a name="quickref-iam-example-9.json"></a>

```
"mysnspolicy" : {
   "Type" : "AWS::SNS::TopicPolicy",
   "Properties" : {
      "PolicyDocument" :  {
         "Id" : "MyTopicPolicy",
         "Version": "2012-10-17",		 	 	 
         "Statement" : [ {
            "Sid" : "My-statement-id",
            "Effect" : "Allow",
            "Principal" : {
               "AWS" : { "Fn::GetAtt" : [ "myuser", "Arn" ] }
            },
            "Action" : "sns:Publish",
            "Resource" : "*"
         } ]
      },
      "Topics" : [ { "Ref" : "mytopic" } ]
   }
}
```

### YAML
<a name="quickref-iam-example-9.yaml"></a>

```
mysnspolicy:
  Type: AWS::SNS::TopicPolicy
  Properties:
    PolicyDocument:
      Id: MyTopicPolicy
      Version: '2012-10-17'
      Statement:
      - Sid: My-statement-id
        Effect: Allow
        Principal:
          AWS: !GetAtt myuser.Arn
        Action: sns:Publish
        Resource: "*"
    Topics:
    - !Ref mytopic
```

## 宣告 Amazon SQS 政策
<a name="scenario-sqs-policy"></a>

此程式碼片段示範如何使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sqs-queuepolicy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sqs-queuepolicy.html) 資源建立政策，並將其套用到 Amazon SQS 佇列。`PolicyDocument` 屬性允許現有的使用者 `myapp` (以其 ARN 指定) 在以其 URL 指定的現有佇列，以及一個 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sqs-queue.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sqs-queue.html) 資源 myqueue 上執行 `SendMessage` 動作。[Ref](resources-section-structure.md#resource-properties-ref) 函數會取得 `myqueue` 資源的 URL。

### JSON
<a name="quickref-iam-example-10.json"></a>

```
"mysqspolicy" : {
   "Type" : "AWS::SQS::QueuePolicy",
   "Properties" : {
      "PolicyDocument" : {
         "Id" : "MyQueuePolicy",
         "Version": "2012-10-17",		 	 	 
         "Statement" : [ {
            "Sid" : "Allow-User-SendMessage",
            "Effect" : "Allow",
            "Principal" : {
               "AWS" : "arn:aws:iam::123456789012:user/myapp"
            },
            "Action" : [ "sqs:SendMessage" ],
            "Resource" : "*"
         } ]
      },
      "Queues" : [
         "https://sqs.us-east-2aws-region.amazonaws.com/123456789012/myexistingqueue",
         { "Ref" : "myqueue" }
      ]
   }
}
```

### YAML
<a name="quickref-iam-example-10.yaml"></a>

```
mysqspolicy:
  Type: AWS::SQS::QueuePolicy
  Properties:
    PolicyDocument:
      Id: MyQueuePolicy
      Version: '2012-10-17'
      Statement:
      - Sid: Allow-User-SendMessage
        Effect: Allow
        Principal:
          AWS: arn:aws:iam::123456789012:user/myapp
        Action:
        - sqs:SendMessage
        Resource: "*"
    Queues:
    - https://sqs.aws-region.amazonaws.com/123456789012/myexistingqueue
    - !Ref myqueue
```

## IAM 角色範本範例
<a name="scenarios-iamroles"></a>

本章節提供 EC2 執行個體 IAM 角色的 CloudFormation 範本範例。

如需詳細資訊，請參閱 *Amazon EC2 User Guide* 中的 [IAM roles for Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)。

### IAM 角色與 EC2
<a name="scenario-iamrole-ec2"></a>

在此範例中，EC2 執行個體的 `IamInstanceProfile` 屬性會參考執行個體設定檔。執行個體政策和角色政策都會參考 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-role.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-role.html)。

#### JSON
<a name="quickref-iam-example-11.json"></a>

```
{
   "AWSTemplateFormatVersion": "2010-09-09",
   "Resources": {
      "myEC2Instance": {
         "Type": "AWS::EC2::Instance",
         "Version": "2009-05-15",
         "Properties": {
            "ImageId": "ami-0ff8a91507f77f867",
            "InstanceType": "m1.small",
            "Monitoring": "true",
            "DisableApiTermination": "false",
            "IamInstanceProfile": {
               "Ref": "RootInstanceProfile"
            }
         }
      },
      "RootRole": {
         "Type": "AWS::IAM::Role",
         "Properties": {
            "AssumeRolePolicyDocument": {
               "Version": "2012-10-17",		 	 	 
               "Statement": [ {
                  "Effect": "Allow",
                  "Principal": {
                     "Service": [ "ec2.amazonaws.com" ]
                  },
                  "Action": [ "sts:AssumeRole" ]
               } ]
            },
            "Path": "/"
         }
      },
      "RolePolicies": {
         "Type": "AWS::IAM::Policy",
         "Properties": {
            "PolicyName": "root",
            "PolicyDocument": {
               "Version": "2012-10-17",		 	 	 
               "Statement": [ {
                  "Effect": "Allow",
                  "Action": "*",
                  "Resource": "*"
               } ]
            },
            "Roles": [ { "Ref": "RootRole" } ]
         }
      },
      "RootInstanceProfile": {
         "Type": "AWS::IAM::InstanceProfile",
         "Properties": {
            "Path": "/",
            "Roles": [ { "Ref": "RootRole" } ]
         }
      }
   }
}
```

#### YAML
<a name="quickref-iam-example-11.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  myEC2Instance:
    Type: AWS::EC2::Instance
    Version: '2009-05-15'
    Properties:
      ImageId: ami-0ff8a91507f77f867
      InstanceType: m1.small
      Monitoring: 'true'
      DisableApiTermination: 'false'
      IamInstanceProfile:
        !Ref RootInstanceProfile
  RootRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - ec2.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
  RolePolicies:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: root
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action: "*"
          Resource: "*"
      Roles:
      - !Ref RootRole
  RootInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: "/"
      Roles:
      - !Ref RootRole
```

### IAM 角色與 Auto Scaling 群組
<a name="scenario-iamrole-asg"></a>

在此範例中，Amazon EC2 Auto Scaling 啟動組態的 `IamInstanceProfile` 屬性會參考執行個體設定檔。

#### JSON
<a name="quickref-iam-example-12.json"></a>

```
{
   "AWSTemplateFormatVersion": "2010-09-09",
   "Resources": {
      "myLCOne": {
         "Type": "AWS::AutoScaling::LaunchConfiguration",
         "Version": "2009-05-15",
         "Properties": {
            "ImageId": "ami-0ff8a91507f77f867",
            "InstanceType": "m1.small",
            "InstanceMonitoring": "true",
            "IamInstanceProfile": { "Ref": "RootInstanceProfile" }
         }
      },
      "myASGrpOne": {
         "Type": "AWS::AutoScaling::AutoScalingGroup",
         "Version": "2009-05-15",
         "Properties": {
            "AvailabilityZones": [ "us-east-1a" ],
            "LaunchConfigurationName": { "Ref": "myLCOne" },
            "MinSize": "0",
            "MaxSize": "0",
            "HealthCheckType": "EC2",
            "HealthCheckGracePeriod": "120"
         }
      },
      "RootRole": {
         "Type": "AWS::IAM::Role",
         "Properties": {
            "AssumeRolePolicyDocument": {
               "Version": "2012-10-17",		 	 	 
               "Statement": [ {
                  "Effect": "Allow",
                  "Principal": {
                     "Service": [ "ec2.amazonaws.com" ]
                  },
                  "Action": [ "sts:AssumeRole" ]
               } ]
            },
            "Path": "/"
         }
      },
      "RolePolicies": {
         "Type": "AWS::IAM::Policy",
         "Properties": {
            "PolicyName": "root",
            "PolicyDocument": {
               "Version": "2012-10-17",		 	 	 
               "Statement": [ {
                  "Effect": "Allow",
                  "Action": "*",
                  "Resource": "*"
               } ]
            },
            "Roles": [ { "Ref": "RootRole" } ]
         }
      },
      "RootInstanceProfile": {
         "Type": "AWS::IAM::InstanceProfile",
         "Properties": {
            "Path": "/",
            "Roles": [ { "Ref": "RootRole" } ]
         }
      }
   }
}
```

#### YAML
<a name="quickref-iam-example-12.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  myLCOne:
    Type: AWS::AutoScaling::LaunchConfiguration
    Version: '2009-05-15'
    Properties:
      ImageId: ami-0ff8a91507f77f867
      InstanceType: m1.small
      InstanceMonitoring: 'true'
      IamInstanceProfile:
        !Ref RootInstanceProfile
  myASGrpOne:
    Type: AWS::AutoScaling::AutoScalingGroup
    Version: '2009-05-15'
    Properties:
      AvailabilityZones:
      - "us-east-1a"
      LaunchConfigurationName:
        !Ref myLCOne
      MinSize: '0'
      MaxSize: '0'
      HealthCheckType: EC2
      HealthCheckGracePeriod: '120'
  RootRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - ec2.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
  RolePolicies:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: root
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action: "*"
          Resource: "*"
      Roles:
      - !Ref RootRole
  RootInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: "/"
      Roles:
      - !Ref RootRole
```

# AWS Lambda 範本
<a name="quickref-lambda"></a>

下列範本使用 AWS Lambda (Lambda) 函數和自訂資源，將新的安全群組附加至現有安全群組的清單。當您想動態建置安全群組清單，使該清單能夠同時包含全新與現有的安全群組時，此函數相當實用。例如，您可以將現有安全群組清單傳遞為參數值，並將新數值附加至該清單，接著在所有數值與 EC2 執行個體之間建立關聯。如需 Lambda 函式資源類型的詳細資訊，請參閱 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html)。

在此範例中，當 CloudFormation 建立 `AllSecurityGroups` 自訂資源時，CloudFormation 即會調用 `AppendItemToListFunction` Lambda 函式。接著，CloudFormation 會將現有安全群組清單與新的安全群組 (`NewSecurityGroup`) 傳遞至該函數，並透過此函數將新的安全群組附加至清單，然後傳回修改後的清單。而修改後的清單則可讓 CloudFormation 將所有安全群組與 `MyEC2Instance` 資源建立關聯。

## JSON
<a name="quickref-lambda-example-1.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "ExistingSecurityGroups": {
            "Type": "List<AWS::EC2::SecurityGroup::Id>"
        },
        "ExistingVPC": {
            "Type": "AWS::EC2::VPC::Id",
            "Description": "The VPC ID that includes the security groups in the ExistingSecurityGroups parameter."
        },
        "InstanceType": {
            "Type": "String",
            "Default": "t2.micro",
            "AllowedValues": [
                "t2.micro",
                "t3.micro"
            ]
        }
    },

    "Resources": {
        "SecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Allow HTTP traffic to the host",
                "VpcId": {
                    "Ref": "ExistingVPC"
                },
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 80,
                        "ToPort": 80,
                        "CidrIp": "0.0.0.0/0"
                    }
                ],
                "SecurityGroupEgress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 80,
                        "ToPort": 80,
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        },
        "AllSecurityGroups": {
            "Type": "Custom::Split",
            "Properties": {
                "ServiceToken": {
                    "Fn::GetAtt": [
                        "AppendItemToListFunction",
                        "Arn"
                    ]
                },
                "List": {
                    "Ref": "ExistingSecurityGroups"
                },
                "AppendedItem": {
                    "Ref": "SecurityGroup"
                }
            }
        },
        "AppendItemToListFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Handler": "index.handler",
                "Role": {
                    "Fn::GetAtt": [
                        "LambdaExecutionRole",
                        "Arn"
                    ]
                },
                "Code": {
                    "ZipFile": {
                        "Fn::Join": [
                            "",
                            [
                                "var response = require('cfn-response');",
                                "exports.handler = function(event, context) {",
                                "   var responseData = {Value: event.ResourceProperties.List};",
                                "   responseData.Value.push(event.ResourceProperties.AppendedItem);",
                                "   response.send(event, context, response.SUCCESS, responseData);",
                                "};"
                            ]
                        ]
                    }
                },
                "Runtime": "nodejs20.x"
            }
        },
        "MyEC2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}",
                "SecurityGroupIds": {
                    "Fn::GetAtt": [
                        "AllSecurityGroups",
                        "Value"
                    ]
                },
                "InstanceType": {
                    "Ref": "InstanceType"
                }
            }
        },
        "LambdaExecutionRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17", 		 	 	 
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "lambda.amazonaws.com"
                                ]
                            },
                            "Action": [
                                "sts:AssumeRole"
                            ]
                        }
                    ]
                },
                "Path": "/",
                "Policies": [
                    {
                        "PolicyName": "root",
                        "PolicyDocument": {
                            "Version": "2012-10-17", 		 	 	 
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "logs:*"
                                    ],
                                    "Resource": "arn:aws:logs:*:*:*"
                                }
                            ]
                        }
                    }
                ]
            }
        }
    },
    "Outputs": {
        "AllSecurityGroups": {
            "Description": "Security Groups that are associated with the EC2 instance",
            "Value": {
                "Fn::Join": [
                    ", ",
                    {
                        "Fn::GetAtt": [
                            "AllSecurityGroups",
                            "Value"
                        ]
                    }
                ]
            }
        }
    }
}
```

## YAML
<a name="quickref-lambda-example-1.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  ExistingSecurityGroups:
    Type: List<AWS::EC2::SecurityGroup::Id>
  ExistingVPC:
    Type: AWS::EC2::VPC::Id
    Description: The VPC ID that includes the security groups in the ExistingSecurityGroups parameter.
  InstanceType:
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - t3.micro
Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTP traffic to the host
      VpcId: !Ref ExistingVPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
  AllSecurityGroups:
    Type: Custom::Split
    Properties:
      ServiceToken: !GetAtt AppendItemToListFunction.Arn
      List: !Ref ExistingSecurityGroups
      AppendedItem: !Ref SecurityGroup
  AppendItemToListFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: !Join
          - ''
          - - var response = require('cfn-response');
            - exports.handler = function(event, context) {
            - '   var responseData = {Value: event.ResourceProperties.List};'
            - '   responseData.Value.push(event.ResourceProperties.AppendedItem);'
            - '   response.send(event, context, response.SUCCESS, responseData);'
            - '};'
      Runtime: nodejs20.x
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2}}'
      SecurityGroupIds: !GetAtt AllSecurityGroups.Value
      InstanceType: !Ref InstanceType
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17' 		 	 	 
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: '2012-10-17' 		 	 	 
            Statement:
              - Effect: Allow
                Action:
                  - logs:*
                Resource: arn:aws:logs:*:*:*
Outputs:
  AllSecurityGroups:
    Description: Security Groups that are associated with the EC2 instance
    Value: !Join
      - ', '
      - !GetAtt AllSecurityGroups.Value
```

# Amazon Redshift 範本程式碼片段
<a name="quickref-redshift"></a>

Amazon Redshift 是一種在雲端中完全受管的 PB 級資料倉儲服務。您可以使用 CloudFormation 來佈建並管理 Amazon Redshift 叢集。

## Amazon Redshift 叢集
<a name="quickref-redshift-samplecluster"></a>

系統建立堆疊時會指定參數值，而以下範例範本會根據該參數值來建立 Amazon Redshift 叢集。另外，與 Amazon Redshift 叢集相關的叢集參數群組則會啟用使用者活動記錄功能。此範本還會在自身定義的 Amazon VPC 中啟動 Amazon Redshift 叢集。該 VPC 將包含網際網路閘道，讓您可以從網際網路存取 Amazon Redshift 叢集。不過，您還是必須要透過路由表項目來啟用叢集和網際網路閘道之間的通訊。

**注意**  
範本會包含 `IsMultiNodeCluster` 條件，因此系統唯有在 `NumberOfNodes` 參數值設為 `ClusterType` 時，才會宣告 `multi-node` 參數。

範例定義的 `MysqlRootPassword` 參數已將其 `NoEcho` 屬性設為 `true`。若您將 `NoEcho` 屬性設為 `true`，CloudFormation 會將任何描述堆疊或堆疊事件呼叫所傳回的參數值以星號 (\$1\$1\$1\$1\$1) 遮罩，但儲存在以下指定位置中的資訊除外。

**重要**  
使用 `NoEcho` 屬性不會遮罩任何儲存在下列資訊中的資訊：  
`Metadata` 範本區段。CloudFormation 不會轉換、修改或標記您在 `Metadata` 區段中包含的任何資訊。若要取得更多資訊，請參閱[中繼資料](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html)。
`Outputs` 範本區段。如需詳細資訊，請參閱[輸出](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)。
資源定義的 `Metadata` 屬性。如需詳細資訊，請參閱 [`Metadata` 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html)。
我們強烈建議您不要使用這些機制來包含敏感資訊，例如密碼或秘密。

**重要**  
我們建議您不要直接在 CloudFormation 範本中嵌入敏感資訊，而是在堆疊範本中使用動態參數來參考在 CloudFormation 外部存放和管理的敏感資訊，例如在 AWS Systems Manager 參數存放區或 中 AWS Secrets Manager。  
如需詳細資訊，請參閱[請勿在範本中內嵌認證](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/security-best-practices.html#creds)的最佳實務。

### JSON
<a name="quickref-redshift-example-1.json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters" : {
    "DatabaseName" : {
      "Description" : "The name of the first database to be created when the cluster is created",
      "Type" : "String",
      "Default" : "dev",
      "AllowedPattern" : "([a-z]|[0-9])+"
    },
    "ClusterType" : {
      "Description" : "The type of cluster",
      "Type" : "String",
      "Default" : "single-node",
      "AllowedValues" : [ "single-node", "multi-node" ]
    },
    "NumberOfNodes" : {
      "Description" : "The number of compute nodes in the cluster. For multi-node clusters, the NumberOfNodes parameter must be greater than 1",
      "Type" : "Number",
      "Default" : "1"
    },
    "NodeType" : {
      "Description" : "The type of node to be provisioned",
      "Type" : "String",
      "Default" : "ds2.xlarge",
      "AllowedValues" : [ "ds2.xlarge", "ds2.8xlarge", "dc1.large", "dc1.8xlarge" ]
    }, 
    "MasterUsername" : {
      "Description" : "The user name that is associated with the master user account for the cluster that is being created",
      "Type" : "String",
      "Default" : "defaultuser",
      "AllowedPattern" : "([a-z])([a-z]|[0-9])*"
    },
    "MasterUserPassword" :  {
      "Description" : "The password that is associated with the master user account for the cluster that is being created.",
      "Type" : "String",
      "NoEcho" : "true"
    },
    "InboundTraffic" : {
      "Description" : "Allow inbound traffic to the cluster from this CIDR range.",
      "Type" : "String",
      "MinLength": "9",
      "MaxLength": "18",
      "Default" : "0.0.0.0/0",
      "AllowedPattern" : "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription" : "must be a valid CIDR range of the form x.x.x.x/x."
    },
    "PortNumber" : {
      "Description" : "The port number on which the cluster accepts incoming connections.",
      "Type" : "Number",
      "Default" : "5439"
    }
  },
  "Conditions" : {
    "IsMultiNodeCluster" : {
      "Fn::Equals" : [{ "Ref" : "ClusterType" }, "multi-node" ]        
    }
  },
  "Resources" : {
    "RedshiftCluster" : {
      "Type" : "AWS::Redshift::Cluster",
      "DependsOn" : "AttachGateway",
      "Properties" : {
        "ClusterType" : { "Ref" : "ClusterType" },
        "NumberOfNodes" : { "Fn::If" : [ "IsMultiNodeCluster",  { "Ref" : "NumberOfNodes" }, { "Ref" : "AWS::NoValue" }]},
        "NodeType" : { "Ref" : "NodeType" },
        "DBName" : { "Ref" : "DatabaseName" },
        "MasterUsername" : { "Ref" : "MasterUsername" },
        "MasterUserPassword" : { "Ref" : "MasterUserPassword" },               
        "ClusterParameterGroupName" : { "Ref" : "RedshiftClusterParameterGroup" },
        "VpcSecurityGroupIds" : [ { "Ref" : "SecurityGroup" } ],
        "ClusterSubnetGroupName" : { "Ref" : "RedshiftClusterSubnetGroup" },
        "PubliclyAccessible" : "true",
        "Port" : { "Ref" : "PortNumber" }
      }
    },
    "RedshiftClusterParameterGroup" : {
      "Type" : "AWS::Redshift::ClusterParameterGroup",
      "Properties" : {
        "Description" : "Cluster parameter group",
        "ParameterGroupFamily" : "redshift-1.0",
        "Parameters" : [{
          "ParameterName" : "enable_user_activity_logging",
          "ParameterValue" : "true"
        }]
      }
    },
    "RedshiftClusterSubnetGroup" : {
      "Type" : "AWS::Redshift::ClusterSubnetGroup",
      "Properties" : {
        "Description" : "Cluster subnet group",
        "SubnetIds" : [ { "Ref" : "PublicSubnet" } ]
      }
    },
    "VPC" : {
      "Type" : "AWS::EC2::VPC",
      "Properties" : {
        "CidrBlock" : "10.0.0.0/16"
      }
    },
    "PublicSubnet" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "CidrBlock" : "10.0.0.0/24",
        "VpcId" : { "Ref" : "VPC" }
      }
    },
    "SecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Security group",
        "SecurityGroupIngress" : [ {
          "CidrIp" : { "Ref": "InboundTraffic" },
          "FromPort" : { "Ref" : "PortNumber" },
          "ToPort" : { "Ref" : "PortNumber" },
          "IpProtocol" : "tcp"
        } ],
        "VpcId" : { "Ref" : "VPC" }
      }
    },
    "myInternetGateway" : {
      "Type" : "AWS::EC2::InternetGateway"
    },
    "AttachGateway" : {
      "Type" : "AWS::EC2::VPCGatewayAttachment",
      "Properties" : {
        "VpcId" : { "Ref" : "VPC" },
        "InternetGatewayId" : { "Ref" : "myInternetGateway" }
      }
    },
    "PublicRouteTable" : {
      "Type" : "AWS::EC2::RouteTable",
      "Properties" : {
        "VpcId" : {
          "Ref" : "VPC"
        }
      }
    },
    "PublicRoute" : {
      "Type" : "AWS::EC2::Route",
      "DependsOn" : "AttachGateway",
      "Properties"  : {
        "RouteTableId" : {
          "Ref" : "PublicRouteTable"
        },
        "DestinationCidrBlock" : "0.0.0.0/0",
        "GatewayId" : {
          "Ref" : "myInternetGateway"
        }
      }
    },
    "PublicSubnetRouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "SubnetId" : {
          "Ref" : "PublicSubnet"
        },
        "RouteTableId" : {
          "Ref" : "PublicRouteTable"
        }
      }
    }
  },
  "Outputs" : {
    "ClusterEndpoint" : {
      "Description" : "Cluster endpoint",
      "Value" : { "Fn::Join" : [ ":", [ { "Fn::GetAtt" : [ "RedshiftCluster", "Endpoint.Address" ] }, { "Fn::GetAtt" : [ "RedshiftCluster", "Endpoint.Port" ] } ] ] }
    },
    "ClusterName" : {
      "Description" : "Name of cluster",
      "Value" : { "Ref" : "RedshiftCluster" }
    },
    "ParameterGroupName" : {
      "Description" : "Name of parameter group",
      "Value" : { "Ref" : "RedshiftClusterParameterGroup" }
    },
    "RedshiftClusterSubnetGroupName" : {
      "Description" : "Name of cluster subnet group",
      "Value" : { "Ref" : "RedshiftClusterSubnetGroup" }
    },
    "RedshiftClusterSecurityGroupName" : {
      "Description" : "Name of cluster security group",
      "Value" : { "Ref" : "SecurityGroup" }
    }
  }
}
```

### YAML
<a name="quickref-redshift-example-1.yaml"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  DatabaseName:
    Description: The name of the first database to be created when the cluster is
      created
    Type: String
    Default: dev
    AllowedPattern: "([a-z]|[0-9])+"
  ClusterType:
    Description: The type of cluster
    Type: String
    Default: single-node
    AllowedValues:
    - single-node
    - multi-node
  NumberOfNodes:
    Description: The number of compute nodes in the cluster. For multi-node clusters,
      the NumberOfNodes parameter must be greater than 1
    Type: Number
    Default: '1'
  NodeType:
    Description: The type of node to be provisioned
    Type: String
    Default: ds2.xlarge
    AllowedValues:
    - ds2.xlarge
    - ds2.8xlarge
    - dc1.large
    - dc1.8xlarge
  MasterUsername:
    Description: The user name that is associated with the master user account for
      the cluster that is being created
    Type: String
    Default: defaultuser
    AllowedPattern: "([a-z])([a-z]|[0-9])*"
  MasterUserPassword:
    Description: The password that is associated with the master user account for
      the cluster that is being created.
    Type: String
    NoEcho: 'true'
  InboundTraffic:
    Description: Allow inbound traffic to the cluster from this CIDR range.
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
    ConstraintDescription: must be a valid CIDR range of the form x.x.x.x/x.
  PortNumber:
    Description: The port number on which the cluster accepts incoming connections.
    Type: Number
    Default: '5439'
Conditions:
  IsMultiNodeCluster:
    Fn::Equals:
    - Ref: ClusterType
    - multi-node
Resources:
  RedshiftCluster:
    Type: AWS::Redshift::Cluster
    DependsOn: AttachGateway
    Properties:
      ClusterType:
        Ref: ClusterType
      NumberOfNodes:
        Fn::If:
        - IsMultiNodeCluster
        - Ref: NumberOfNodes
        - Ref: AWS::NoValue
      NodeType:
        Ref: NodeType
      DBName:
        Ref: DatabaseName
      MasterUsername:
        Ref: MasterUsername
      MasterUserPassword:
        Ref: MasterUserPassword
      ClusterParameterGroupName:
        Ref: RedshiftClusterParameterGroup
      VpcSecurityGroupIds:
      - Ref: SecurityGroup
      ClusterSubnetGroupName:
        Ref: RedshiftClusterSubnetGroup
      PubliclyAccessible: 'true'
      Port:
        Ref: PortNumber
  RedshiftClusterParameterGroup:
    Type: AWS::Redshift::ClusterParameterGroup
    Properties:
      Description: Cluster parameter group
      ParameterGroupFamily: redshift-1.0
      Parameters:
      - ParameterName: enable_user_activity_logging
        ParameterValue: 'true'
  RedshiftClusterSubnetGroup:
    Type: AWS::Redshift::ClusterSubnetGroup
    Properties:
      Description: Cluster subnet group
      SubnetIds:
      - Ref: PublicSubnet
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/24
      VpcId:
        Ref: VPC
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group
      SecurityGroupIngress:
      - CidrIp:
          Ref: InboundTraffic
        FromPort:
          Ref: PortNumber
        ToPort:
          Ref: PortNumber
        IpProtocol: tcp
      VpcId:
        Ref: VPC
  myInternetGateway:
    Type: AWS::EC2::InternetGateway
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId:
        Ref: VPC
      InternetGatewayId:
        Ref: myInternetGateway
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: VPC
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId:
        Ref: PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId:
        Ref: myInternetGateway
  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: PublicSubnet
      RouteTableId:
        Ref: PublicRouteTable
Outputs:
  ClusterEndpoint:
    Description: Cluster endpoint
    Value: !Sub "${RedshiftCluster.Endpoint.Address}:${RedshiftCluster.Endpoint.Port}"
  ClusterName:
    Description: Name of cluster
    Value:
      Ref: RedshiftCluster
  ParameterGroupName:
    Description: Name of parameter group
    Value:
      Ref: RedshiftClusterParameterGroup
  RedshiftClusterSubnetGroupName:
    Description: Name of cluster subnet group
    Value:
      Ref: RedshiftClusterSubnetGroup
  RedshiftClusterSecurityGroupName:
    Description: Name of cluster security group
    Value:
      Ref: SecurityGroup
```

## 另請參閱
<a name="w2aac11c41c72b7"></a>

[AWS::Redshift::Cluster](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-redshift-cluster.html)

# Amazon RDS 範本程式碼片段
<a name="quickref-rds"></a>

**Topics**
+ [Amazon RDS 資料庫執行個體資源](#scenario-rds-instance)
+ [Amazon RDS Oracle Database 資料庫執行個體資源](#scenario-rds-oracleinstance)
+ [適用於 CIDR 範圍的 Amazon RDS DBSecurityGroup 資源](#scenario-rds-security-group-cidr)
+ [具有 Amazon EC2 安全群組的 Amazon RDS DBSecurityGroup](#scenario-rds-security-group-ec2)
+ [多個 VPC 安全群組](#scenario-multiple-vpc-security-groups)
+ [VPC 安全群組中的 Amazon RDS 資料庫執行個體](#w2aac11c41c76c15)

## Amazon RDS 資料庫執行個體資源
<a name="scenario-rds-instance"></a>

此範例顯示具有受管主要使用者密碼的 Amazon RDS 資料庫執行個體資源。如需詳細資訊，請參閱《Amazon RDS 使用者指南》**中的[使用 AWS Secrets Manager進行密碼管理](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-secrets-manager.html)和《Aurora 使用者指南》**中的[使用 AWS Secrets Manager進行密碼管理](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-secrets-manager.html)。由於未指定選用的 `EngineVersion` 屬性，此資料庫執行個體將使用預設的引擎版本。如需有關預設引擎版本和其他預設設定的詳細資訊，請參閱 [CreateDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html)。`DBSecurityGroups` 屬性授權網路輸入至名為 `MyDbSecurityByEC2SecurityGroup` 和 MyDbSecurityByCIDRIPGroup 的 `AWS::RDS::DBSecurityGroup` 資源。如需詳細資訊，請參閱[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html)。資料庫執行個體資源也有設定為 `Snapshot` 的 `DeletionPolicy` 屬性。使用 `Snapshot``DeletionPolicy`集， CloudFormation 會先取得此資料庫執行個體的快照，再於堆疊刪除期間將其刪除。

### JSON
<a name="quickref-rds-example-1.json"></a>

```
 1. "MyDB" : {
 2.  "Type" : "AWS::RDS::DBInstance",
 3.  "Properties" : {
 4.      "DBSecurityGroups" : [
 5.         {"Ref" : "MyDbSecurityByEC2SecurityGroup"}, {"Ref" : "MyDbSecurityByCIDRIPGroup"} ],
 6.      "AllocatedStorage" : "5",
 7.      "DBInstanceClass" : "db.t2.small",
 8.      "Engine" : "MySQL",
 9.      "MasterUsername" : "MyName",
10.      "ManageMasterUserPassword" : true,
11.      "MasterUserSecret" : {
12.         "KmsKeyId" : {"Ref" : "KMSKey"}
13.      }
14.  },
15.  "DeletionPolicy" : "Snapshot"
16. }
```

### YAML
<a name="quickref-rds-example-1.yaml"></a>

```
 1. MyDB:
 2.   Type: AWS::RDS::DBInstance
 3.   Properties:
 4.     DBSecurityGroups:
 5.     - Ref: MyDbSecurityByEC2SecurityGroup
 6.     - Ref: MyDbSecurityByCIDRIPGroup
 7.     AllocatedStorage: '5'
 8.     DBInstanceClass: db.t2.small
 9.     Engine: MySQL
10.     MasterUsername: MyName
11.     ManageMasterUserPassword: true
12.     MasterUserSecret:
13.       KmsKeyId: !Ref KMSKey
14.   DeletionPolicy: Snapshot
```

## Amazon RDS Oracle Database 資料庫執行個體資源
<a name="scenario-rds-oracleinstance"></a>

此範例建立具有受管主要使用者密碼的 Oracle Database 資料庫執行個體資源。如需詳細資訊，請參閱《Amazon RDS 使用者指南》**中的[使用 AWS Secrets Manager進行密碼管理](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-secrets-manager.html)。此範例指定 `Engine` 做為 `oracle-ee` 並使用自有授權的授權模式。如需有關 Oracle Database 資料庫執行個體的詳細資訊，請參閱 [CreateDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html)。DBSecurityGroups 屬性授權網路輸入至名為 MyDbSecurityByEC2SecurityGroup 和 MyDbSecurityByCIDRIPGroup 的 `AWS::RDS::DBSecurityGroup` 資源。如需詳細資訊，請參閱[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html)。資料庫執行個體資源也有設定為 `Snapshot` 的 `DeletionPolicy` 屬性。使用 `Snapshot``DeletionPolicy`集， CloudFormation 會先取得此資料庫執行個體的快照，再於堆疊刪除期間將其刪除。

### JSON
<a name="quickref-rds-example-2.json"></a>

```
 1. "MyDB" : {
 2.  "Type" : "AWS::RDS::DBInstance",
 3.  "Properties" : {
 4.      "DBSecurityGroups" : [
 5.         {"Ref" : "MyDbSecurityByEC2SecurityGroup"}, {"Ref" : "MyDbSecurityByCIDRIPGroup"} ],
 6.      "AllocatedStorage" : "5",
 7.      "DBInstanceClass" : "db.t2.small",
 8.      "Engine" : "oracle-ee",
 9.      "LicenseModel" : "bring-your-own-license",
10.      "MasterUsername" : "master",
11.      "ManageMasterUserPassword" : true,
12.      "MasterUserSecret" : {
13.         "KmsKeyId" : {"Ref" : "KMSKey"}
14.      }
15.  },
16.  "DeletionPolicy" : "Snapshot"
17. }
```

### YAML
<a name="quickref-rds-example-2.yaml"></a>

```
 1. MyDB:
 2.   Type: AWS::RDS::DBInstance
 3.   Properties:
 4.     DBSecurityGroups:
 5.     - Ref: MyDbSecurityByEC2SecurityGroup
 6.     - Ref: MyDbSecurityByCIDRIPGroup
 7.     AllocatedStorage: '5'
 8.     DBInstanceClass: db.t2.small
 9.     Engine: oracle-ee
10.     LicenseModel: bring-your-own-license
11.     MasterUsername: master
12.     ManageMasterUserPassword: true
13.     MasterUserSecret:
14.       KmsKeyId: !Ref KMSKey
15.   DeletionPolicy: Snapshot
```

## 適用於 CIDR 範圍的 Amazon RDS DBSecurityGroup 資源
<a name="scenario-rds-security-group-cidr"></a>

此範例顯示 Amazon RDS `DBSecurityGroup` 資源與具有 `ddd.ddd.ddd.ddd/dd` 格式之指定 CIDR 範圍的輸入授權。如需詳細資訊，請參閱 [AWS::RDS::DBSecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbsecuritygroup.html) 和 [Ingress](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-rds-dbsecuritygroup-ingress.html)。

### JSON
<a name="quickref-rds-example-3.json"></a>

```
1. "MyDbSecurityByCIDRIPGroup" : {
2.  "Type" : "AWS::RDS::DBSecurityGroup",
3.  "Properties" : {
4.      "GroupDescription" : "Ingress for CIDRIP",
5.      "DBSecurityGroupIngress" : {
6.          "CIDRIP" : "192.168.0.0/32"
7.      }
8.  }
9. }
```

### YAML
<a name="quickref-rds-example-3.yaml"></a>

```
1. MyDbSecurityByCIDRIPGroup:
2.   Type: AWS::RDS::DBSecurityGroup
3.   Properties:
4.     GroupDescription: Ingress for CIDRIP
5.     DBSecurityGroupIngress:
6.       CIDRIP: "192.168.0.0/32"
```

## 具有 Amazon EC2 安全群組的 Amazon RDS DBSecurityGroup
<a name="scenario-rds-security-group-ec2"></a>

此範例顯示 [AWS::RDS::DBSecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbsecuritygroup.html) 資源與來自 `MyEc2SecurityGroup` 參考之 Amazon EC2 安全群組的輸入授權。

若要這樣做，請您定義 EC2 安全群組，然後使用內建 `Ref` 函數，以參照您的 `DBSecurityGroup` 內的 EC2 安全群組。

### JSON
<a name="quickref-rds-example-4.json"></a>

```
"DBInstance" : {
   "Type": "AWS::RDS::DBInstance",
   "Properties": {
      "DBName"            : { "Ref" : "DBName" },
      "Engine"            : "MySQL",
      "MasterUsername"    : { "Ref" : "DBUsername" },
      "DBInstanceClass"   : { "Ref" : "DBClass" },
      "DBSecurityGroups"  : [ { "Ref" : "DBSecurityGroup" } ],
      "AllocatedStorage"  : { "Ref" : "DBAllocatedStorage" },
      "MasterUserPassword": { "Ref" : "DBPassword" }
   }
},

"DBSecurityGroup": {
   "Type": "AWS::RDS::DBSecurityGroup",
   "Properties": {
      "DBSecurityGroupIngress": {
         "EC2SecurityGroupName": {
            "Fn::GetAtt": ["WebServerSecurityGroup", "GroupName"]
         }
      },
      "GroupDescription" : "Frontend Access"
   }
},

"WebServerSecurityGroup" : {
   "Type" : "AWS::EC2::SecurityGroup",
   "Properties" : {
      "GroupDescription" : "Enable HTTP access via port 80 and SSH access",
      "SecurityGroupIngress" : [
         {"IpProtocol" : "tcp", "FromPort" : 80, "ToPort" : 80, "CidrIp" : "0.0.0.0/0"},
         {"IpProtocol" : "tcp", "FromPort" : 22, "ToPort" : 22, "CidrIp" : "0.0.0.0/0"}
      ]
   }
}
```

### YAML
<a name="quickref-rds-example-4.yaml"></a>

此範例擷取自以下完整範例：[Drupal\$1Single\$1Instance\$1With\$1RDS.template](https://s3.amazonaws.com/cloudformation-templates-us-east-1/Drupal_Single_Instance_With_RDS.template)

```
DBInstance:
  Type: AWS::RDS::DBInstance
  Properties:
    DBName:
      Ref: DBName
    Engine: MySQL
    MasterUsername:
      Ref: DBUsername
    DBInstanceClass:
      Ref: DBClass
    DBSecurityGroups:
    - Ref: DBSecurityGroup
    AllocatedStorage:
      Ref: DBAllocatedStorage
    MasterUserPassword:
      Ref: DBPassword
DBSecurityGroup:
  Type: AWS::RDS::DBSecurityGroup
  Properties:
    DBSecurityGroupIngress:
      EC2SecurityGroupName:
        Ref: WebServerSecurityGroup
    GroupDescription: Frontend Access
WebServerSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Enable HTTP access via port 80 and SSH access
    SecurityGroupIngress:
    - IpProtocol: tcp
      FromPort: 80
      ToPort: 80
      CidrIp: 0.0.0.0/0
    - IpProtocol: tcp
      FromPort: 22
      ToPort: 22
      CidrIp: 0.0.0.0/0
```

## 多個 VPC 安全群組
<a name="scenario-multiple-vpc-security-groups"></a>

此範例顯示 [AWS::RDS::DBSecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbsecuritygroup.html) 資源與 [AWS::RDS::DBSecurityGroupIngress](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbsecuritygroupingress.html) 中多個 Amazon EC2 VPC 安全群組的輸入授權。

### JSON
<a name="quickref-rds-example-5.json"></a>

```
{
   "Resources" : {
      "DBinstance" : {
         "Type" : "AWS::RDS::DBInstance",
         "Properties" : {
            "AllocatedStorage" : "5",
            "DBInstanceClass" : "db.t2.small",
           "DBName" : {"Ref": "MyDBName" },
            "DBSecurityGroups" : [ { "Ref" : "DbSecurityByEC2SecurityGroup" } ],
            "DBSubnetGroupName" : { "Ref" : "MyDBSubnetGroup" },
            "Engine" : "MySQL",
           "MasterUserPassword": { "Ref" : "MyDBPassword" },
           "MasterUsername"    : { "Ref" : "MyDBUsername" }
        },
         "DeletionPolicy" : "Snapshot"
      },
      "DbSecurityByEC2SecurityGroup" : {
         "Type" : "AWS::RDS::DBSecurityGroup",
         "Properties" : {
            "GroupDescription" : "Ingress for Amazon EC2 security group",
           "EC2VpcId" : { "Ref" : "MyVPC" },
            "DBSecurityGroupIngress" : [ {
               "EC2SecurityGroupId" : "sg-b0ff1111",
               "EC2SecurityGroupOwnerId" : "111122223333"
            }, {
               "EC2SecurityGroupId" : "sg-ffd722222",
               "EC2SecurityGroupOwnerId" : "111122223333"
            } ]
         }
      }
   }
}
```

### YAML
<a name="quickref-rds-example-5.yaml"></a>

```
Resources:
  DBinstance:
    Type: AWS::RDS::DBInstance
    Properties:
      AllocatedStorage: '5'
      DBInstanceClass: db.t2.small
      DBName:
        Ref: MyDBName
      DBSecurityGroups:
      - Ref: DbSecurityByEC2SecurityGroup
      DBSubnetGroupName:
        Ref: MyDBSubnetGroup
      Engine: MySQL
      MasterUserPassword:
        Ref: MyDBPassword
      MasterUsername:
        Ref: MyDBUsername
    DeletionPolicy: Snapshot
  DbSecurityByEC2SecurityGroup:
    Type: AWS::RDS::DBSecurityGroup
    Properties:
      GroupDescription: Ingress for Amazon EC2 security group
      EC2VpcId:
        Ref: MyVPC
      DBSecurityGroupIngress:
      - EC2SecurityGroupId: sg-b0ff1111
        EC2SecurityGroupOwnerId: '111122223333'
      - EC2SecurityGroupId: sg-ffd722222
        EC2SecurityGroupOwnerId: '111122223333'
```

## VPC 安全群組中的 Amazon RDS 資料庫執行個體
<a name="w2aac11c41c76c15"></a>

此範例顯示與 Amazon EC2 VPC 安全群組關聯的 Amazon RDS 資料庫執行個體。

### JSON
<a name="quickref-rds-example-6.json"></a>

```
{
  "DBEC2SecurityGroup": {
    "Type": "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription": "Open database for access",
      "SecurityGroupIngress" : [{
        "IpProtocol" : "tcp",
        "FromPort" : 3306,
        "ToPort" : 3306,
        "SourceSecurityGroupName" : { "Ref" : "WebServerSecurityGroup" }
      }]
    }
  },
  "DBInstance" : {
    "Type": "AWS::RDS::DBInstance",
    "Properties": {
      "DBName"            : { "Ref" : "DBName" },
      "Engine"            : "MySQL",
      "MultiAZ"           : { "Ref": "MultiAZDatabase" },
      "MasterUsername"    : { "Ref" : "DBUser" },
      "DBInstanceClass"   : { "Ref" : "DBClass" },
      "AllocatedStorage"  : { "Ref" : "DBAllocatedStorage" },
      "MasterUserPassword": { "Ref" : "DBPassword" },
      "VPCSecurityGroups" : [ { "Fn::GetAtt": [ "DBEC2SecurityGroup", "GroupId" ] } ]
    }
  }
}
```

### YAML
<a name="quickref-rds-example-6.yaml"></a>

```
DBEC2SecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Open database for access
    SecurityGroupIngress:
    - IpProtocol: tcp
      FromPort: 3306
      ToPort: 3306
      SourceSecurityGroupName:
        Ref: WebServerSecurityGroup
DBInstance:
  Type: AWS::RDS::DBInstance
  Properties:
    DBName:
      Ref: DBName
    Engine: MySQL
    MultiAZ:
      Ref: MultiAZDatabase
    MasterUsername:
      Ref: DBUser
    DBInstanceClass:
      Ref: DBClass
    AllocatedStorage:
      Ref: DBAllocatedStorage
    MasterUserPassword:
      Ref: DBPassword
    VPCSecurityGroups:
    - !GetAtt DBEC2SecurityGroup.GroupId
```

# Route 53 範本程式碼片段
<a name="quickref-route53"></a>

**Topics**
+ [使用託管區域名稱或 ID 的 Amazon Route 53 資源紀錄集](#scenario-route53-recordset-by-host)
+ [使用 RecordSetGroup 設定加權資源紀錄集](#scenario-recordsetgroup-weighted)
+ [使用 RecordSetGroup 設定別名資源紀錄集](#scenario-recordsetgroup-zoneapex)
+ [CloudFront 分佈的別名資源紀錄集](#scenario-user-friendly-url-for-cloudfront-distribution)

## 使用託管區域名稱或 ID 的 Amazon Route 53 資源紀錄集
<a name="scenario-route53-recordset-by-host"></a>

當您建立 Amazon Route 53 資源紀錄集時，您必須指定您希望新增它的託管區域。CloudFormation 提供指定託管區域的兩種方式：
+ 您可以使用 `HostedZoneId` 屬性來明確指定託管區域。
+ 您可以使用 `HostedZoneName` 屬性讓 CloudFormation 尋找託管區域。若您使用 `HostedZoneName` 屬性，而且有多個相同名稱的託管區域，則 CloudFormation 不會建立堆疊。

### 使用 HostedZoneId 新增 RecordSet
<a name="scenario-recordset-using-id"></a>

此範例會新增包含使用 `HostedZoneId` 屬性指定託管區域之網域名稱 `mysite.example.com` `SPF` 記錄的 Amazon Route 53 資源紀錄集，

#### JSON
<a name="quickref-route53-example-1.json"></a>

```
 1. "myDNSRecord" : {
 2.   "Type" : "AWS::Route53::RecordSet",
 3.   "Properties" : 
 4.   {
 5.     "HostedZoneId" : "Z3DG6IL3SJCGPX",
 6.     "Name" : "mysite.example.com.",
 7.     "Type" : "SPF",
 8.     "TTL" : "900",
 9.     "ResourceRecords" : [ "\"v=spf1 ip4:192.168.0.1/16 -all\"" ]
10.   }
11. }
```

#### YAML
<a name="quickref-route53-example-1.yaml"></a>

```
1. myDNSRecord:
2.   Type: AWS::Route53::RecordSet
3.   Properties:
4.     HostedZoneId: Z3DG6IL3SJCGPX
5.     Name: mysite.example.com.
6.     Type: SPF
7.     TTL: '900'
8.     ResourceRecords:
9.     - '"v=spf1 ip4:192.168.0.1/16 -all"'
```

### 使用 HostedZoneName 新增 RecordSet
<a name="scenario-recordset-using-name"></a>

此範例使用 `HostedZoneName` 屬性來指定託管區域，為網域名稱 "mysite.example.com" 新增 Amazon Route 53 資源紀錄集。

#### JSON
<a name="quickref-route53-example-2.json"></a>

```
 1. "myDNSRecord2" : {
 2.             "Type" : "AWS::Route53::RecordSet",
 3.             "Properties" : {
 4.                 "HostedZoneName" : "example.com.",
 5.                 "Name" : "mysite.example.com.",
 6.                 "Type" : "A",
 7.                 "TTL" : "900",
 8.                 "ResourceRecords" : [
 9.                     "192.168.0.1",
10.                     "192.168.0.2"
11.                 ]
12.             }
13.         }
```

#### YAML
<a name="quickref-route53-example-2.yaml"></a>

```
 1. myDNSRecord2:
 2.   Type: AWS::Route53::RecordSet
 3.   Properties:
 4.     HostedZoneName: example.com.
 5.     Name: mysite.example.com.
 6.     Type: A
 7.     TTL: '900'
 8.     ResourceRecords:
 9.     - 192.168.0.1
10.     - 192.168.0.2
```

## 使用 RecordSetGroup 設定加權資源紀錄集
<a name="scenario-recordsetgroup-weighted"></a>

此範例使用 [AWS::Route53::RecordSetGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-route53-recordsetgroup.html) 設定 "example.com" 的兩個 CNAME 記錄。託管區域。`RecordSets` 屬性包含 "mysite.example.com" DNS 名稱的 CNAME 記錄集。每一個記錄集都包含識別碼 (`SetIdentifier`) 和權重 (`Weight`)。路由至資源的網際網路流量比例是根據下列計算：
+ `Frontend One`: `140/(140+60)` = `140/200` = 70%
+ `Frontend Two`: `60/(140+60)` = `60/200` = 30%

如需有關加權資源記錄集的詳細資訊，請參閱《Amazon Route 53 開發人員指南》中的[加權路由](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-weighted.html)。

### JSON
<a name="quickref-route53-example-3.json"></a>

```
 1.         "myDNSOne" : {
 2.             "Type" : "AWS::Route53::RecordSetGroup",
 3.             "Properties" : {
 4.                 "HostedZoneName" : "example.com.",
 5.                 "Comment" : "Weighted RR for my frontends.",
 6.                 "RecordSets" : [
 7.                   {
 8.                     "Name" : "mysite.example.com.",
 9.                     "Type" : "CNAME",
10.                     "TTL" : "900",
11.                     "SetIdentifier" : "Frontend One",
12.                     "Weight" : "140",
13.                     "ResourceRecords" : ["example-ec2.amazonaws.com"]
14.                   },
15.                   {
16.                     "Name" : "mysite.example.com.",
17.                     "Type" : "CNAME",
18.                     "TTL" : "900",
19.                     "SetIdentifier" : "Frontend Two",
20.                     "Weight" : "60",
21.                     "ResourceRecords" : ["example-ec2-larger.amazonaws.com"]
22.                   }
23.                   ]
24.             }
25.         }
```

### YAML
<a name="quickref-route53-example-3.yaml"></a>

```
 1. myDNSOne:
 2.   Type: AWS::Route53::RecordSetGroup
 3.   Properties:
 4.     HostedZoneName: example.com.
 5.     Comment: Weighted RR for my frontends.
 6.     RecordSets:
 7.     - Name: mysite.example.com.
 8.       Type: CNAME
 9.       TTL: '900'
10.       SetIdentifier: Frontend One
11.       Weight: '140'
12.       ResourceRecords:
13.       - example-ec2.amazonaws.com
14.     - Name: mysite.example.com.
15.       Type: CNAME
16.       TTL: '900'
17.       SetIdentifier: Frontend Two
18.       Weight: '60'
19.       ResourceRecords:
20.       - example-ec2-larger.amazonaws.com
```

## 使用 RecordSetGroup 設定別名資源紀錄集
<a name="scenario-recordsetgroup-zoneapex"></a>

下列範例使用 [AWS::Route53::RecordSetGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-route53-recordsetgroup.html) 來設定名為 `example.com` 的別名資源記錄集，以將流量路由至 ELB 第 1 版 負載平衡器 (Classic Load Balancer) 以及第 2 版負載平衡器 (Application Load Balancer 或 Network Load Balancer)。[AliasTarget](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-route53-recordset-aliastarget.html) 屬性使用 `GetAtt` 內建函數，以指定 `myELB` `LoadBalancer` 的託管區域 ID 和 DNS 名稱。`GetAtt` 會擷取 `myELB` 資源的不同屬性，取決於您將流量路由至第 1 版還是第 2 版負載平衡器：
+ 第 1 版負載平衡器：`CanonicalHostedZoneNameID` 和 `DNSName`
+ 第 2 版負載平衡器：`CanonicalHostedZoneID` 和 `DNSName`

如需有關別名資源記錄集的詳細資訊，請參閱《*Route 53 開發人員指南*》中的[選擇別名或非別名記錄](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html)。

### 適用於第 1 版負載平衡器的 JSON
<a name="quickref-route53-example-4.json"></a>

```
 1.       "myELB" : {
 2.         "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
 3.         "Properties" : {
 4.             "AvailabilityZones" : [ "us-east-1a" ],
 5.             "Listeners" : [ {
 6.                 "LoadBalancerPort" : "80",
 7.                 "InstancePort" : "80",
 8.                 "Protocol" : "HTTP"
 9.             } ]
10.         }
11.       },
12.       "myDNS" : {
13.         "Type" : "AWS::Route53::RecordSetGroup",
14.         "Properties" : {
15.           "HostedZoneName" : "example.com.",
16.           "Comment" : "Zone apex alias targeted to myELB LoadBalancer.",
17.           "RecordSets" : [
18.             {
19.               "Name" : "example.com.",
20.               "Type" : "A",
21.               "AliasTarget" : {
22.                   "HostedZoneId" : { "Fn::GetAtt" : ["myELB", "CanonicalHostedZoneNameID"] },
23.                   "DNSName" : { "Fn::GetAtt" : ["myELB","DNSName"] }
24.               }
25.             }
26.           ]
27.         }
28.     }
```

### 適用於第 1 版負載平衡器的 YAML
<a name="quickref-route53-example-4.yaml"></a>

```
 1. myELB:
 2.   Type: AWS::ElasticLoadBalancing::LoadBalancer
 3.   Properties:
 4.     AvailabilityZones:
 5.     - "us-east-1a"
 6.     Listeners:
 7.     - LoadBalancerPort: '80'
 8.       InstancePort: '80'
 9.       Protocol: HTTP
10. myDNS:
11.   Type: AWS::Route53::RecordSetGroup
12.   Properties:
13.     HostedZoneName: example.com.
14.     Comment: Zone apex alias targeted to myELB LoadBalancer.
15.     RecordSets:
16.     - Name: example.com.
17.       Type: A
18.       AliasTarget:
19.         HostedZoneId: !GetAtt 'myELB.CanonicalHostedZoneNameID'
20.         DNSName: !GetAtt 'myELB.DNSName'
```

### 適用於第 2 版負載平衡器的 JSON
<a name="quickref-route53-example-4-v2.json"></a>

```
 1.       "myELB" : {
 2.         "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
 3.         "Properties" : {
 4.             "Subnets" : [ 
 5.                 {"Ref": "SubnetAZ1"}, 
 6.                 {"Ref" : "SubnetAZ2"}
 7.             ]
 8.         }
 9.       },
10.       "myDNS" : {
11.         "Type" : "AWS::Route53::RecordSetGroup",
12.         "Properties" : {
13.           "HostedZoneName" : "example.com.",
14.           "Comment" : "Zone apex alias targeted to myELB LoadBalancer.",
15.           "RecordSets" : [
16.             {
17.               "Name" : "example.com.",
18.               "Type" : "A",
19.               "AliasTarget" : {
20.                   "HostedZoneId" : { "Fn::GetAtt" : ["myELB", "CanonicalHostedZoneID"] },
21.                   "DNSName" : { "Fn::GetAtt" : ["myELB","DNSName"] }
22.               }
23.             }
24.           ]
25.         }
26.     }
```

### 適用於第 2 版負載平衡器的 YAML
<a name="quickref-route53-example-4-v2.yaml"></a>

```
 1. myELB:
 2.   Type: AWS::ElasticLoadBalancingV2::LoadBalancer
 3.   Properties:
 4.     Subnets:
 5.     - Ref: SubnetAZ1
 6.     - Ref: SubnetAZ2
 7. myDNS:
 8.   Type: AWS::Route53::RecordSetGroup
 9.   Properties:
10.     HostedZoneName: example.com.
11.     Comment: Zone apex alias targeted to myELB LoadBalancer.
12.     RecordSets:
13.     - Name: example.com.
14.       Type: A
15.       AliasTarget:
16.         HostedZoneId: !GetAtt 'myELB.CanonicalHostedZoneID'
17.         DNSName: !GetAtt 'myELB.DNSName'
```

## CloudFront 分佈的別名資源紀錄集
<a name="scenario-user-friendly-url-for-cloudfront-distribution"></a>

下列範例建立一個別名 A 記錄，將自訂網域名稱指向現有的 CloudFront 發行版本。`myHostedZoneID` 預設為參考同一範本中實際的 `AWS::Route53::HostedZone` 資源，或為一個參數。`myCloudFrontDistribution` 參考同一範本中的 `AWS::CloudFront::Distribution` 資源。此別名記錄使用標準的 CloudFront 託管區域 ID (`Z2FDTNDATAQYW2`)，並透過 `Fn::GetAtt` 自動解析發行版本的網域名稱。此設定可讓網路流量從自訂網域路由至 CloudFront 發行版本，無需使用 IP 位址。

**注意**  
當您建立別名資源紀錄集時，您必須為 `HostedZoneId` 屬性指定 `Z2FDTNDATAQYW2`。CloudFront 的別名資源紀錄集無法在私有區域中建立。

### JSON
<a name="quickref-route53-example-5.json"></a>

```
 1. {
 2.     "myDNS": {
 3.         "Type": "AWS::Route53::RecordSetGroup",
 4.         "Properties": {
 5.             "HostedZoneId": {
 6.                 "Ref": "myHostedZoneID"
 7.             },
 8.             "RecordSets": [
 9.                 {
10.                     "Name": {
11.                         "Ref": "myRecordSetDomainName"
12.                     },
13.                     "Type": "A",
14.                     "AliasTarget": {
15.                         "HostedZoneId": "Z2FDTNDATAQYW2",
16.                         "DNSName": {
17.                             "Fn::GetAtt": [
18.                                 "myCloudFrontDistribution",
19.                                 "DomainName"
20.                             ]
21.                         },
22.                         "EvaluateTargetHealth": false
23.                     }
24.                 }
25.             ]
26.         }
27.     }
28. }
```

### YAML
<a name="quickref-route53-example-5.yaml"></a>

```
 1. myDNS:
 2.   Type: AWS::Route53::RecordSetGroup
 3.   Properties:
 4.     HostedZoneId: !Ref myHostedZoneID
 5.     RecordSets:
 6.       - Name: !Ref myRecordSetDomainName
 7.         Type: A
 8.         AliasTarget:
 9.           HostedZoneId: Z2FDTNDATAQYW2
10.           DNSName: !GetAtt 
11.             - myCloudFrontDistribution
12.             - DomainName
13.           EvaluateTargetHealth: false
```

# Amazon S3 範本程式碼片段
<a name="quickref-s3"></a>

使用這些 Amazon S3 範例範本，以協助透過 CloudFormation 描述 Amazon S3 儲存貯體。如需更多範例，請參閱 `AWS::S3::Bucket` 中的[範例](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-s3-bucket.html#aws-resource-s3-bucket--examples)區段。

**Topics**
+ [以預設值建立 Amazon S3 儲存貯體](#scenario-s3-bucket)
+ [建立用於網站託管並具有 `DeletionPolicy` 的 Amazon S3 儲存貯體](#scenario-s3-bucket-website)
+ [使用自訂網域建立靜態網站](#scenario-s3-bucket-website-customdomain)

## 以預設值建立 Amazon S3 儲存貯體
<a name="scenario-s3-bucket"></a>

此範例使用 [AWS::S3::Bucket](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-s3-bucket.html) 以預設設定建立儲存貯體。

### JSON
<a name="quickref-s3-example-1.json"></a>

```
1. "myS3Bucket" : {
2.       "Type" : "AWS::S3::Bucket"
3.       }
```

### YAML
<a name="quickref-s3-example-1.yaml"></a>

```
1. MyS3Bucket:
2.     Type: AWS::S3::Bucket
```

## 建立用於網站託管並具有 `DeletionPolicy` 的 Amazon S3 儲存貯體
<a name="scenario-s3-bucket-website"></a>

本範例會建立一個做為網站的儲存貯體，並停用公開存取封鎖功能 (設定用於網站託管的儲存貯體需具備公開讀取許可)。隨後會向該儲存貯體新增公有儲存貯體政策。由於此儲存貯體資源的 `DeletionPolicy` 屬性設為 `Retain`，因此 CloudFormation 在刪除堆疊時不會刪除此儲存貯體。`Output` 區段使用 `Fn::GetAtt` 來擷取 `S3Bucket` 資源的 `WebsiteURL` 屬性和 `DomainName` 屬性。

**注意**  
下列範例假設已在帳戶層級停用 `BlockPublicPolicy` 和 `RestrictPublicBuckets` 封鎖公用存取設定。

### JSON
<a name="quickref-s3-example-2.json"></a>

```
 1. {
 2.     "AWSTemplateFormatVersion": "2010-09-09",
 3.     "Resources": {
 4.         "S3Bucket": {
 5.             "Type": "AWS::S3::Bucket",
 6.             "Properties": {
 7.                 "PublicAccessBlockConfiguration": {
 8.                     "BlockPublicAcls": false,
 9.                     "BlockPublicPolicy": false,
10.                     "IgnorePublicAcls": false,
11.                     "RestrictPublicBuckets": false
12.                 },
13.                 "WebsiteConfiguration": {
14.                     "IndexDocument": "index.html",
15.                     "ErrorDocument": "error.html"
16.                 }
17.             },
18.             "DeletionPolicy": "Retain",
19.             "UpdateReplacePolicy": "Retain"
20.         },
21.         "BucketPolicy": {
22.             "Type": "AWS::S3::BucketPolicy",
23.             "Properties": {
24.                 "PolicyDocument": {
25.                     "Id": "MyPolicy",
26.                     "Version": "2012-10-17", 		 	 	 
27.                     "Statement": [
28.                         {
29.                             "Sid": "PublicReadForGetBucketObjects",
30.                             "Effect": "Allow",
31.                             "Principal": "*",
32.                             "Action": "s3:GetObject",
33.                             "Resource": {
34.                                 "Fn::Join": [
35.                                     "",
36.                                     [
37.                                         "arn:aws:s3:::",
38.                                         {
39.                                             "Ref": "S3Bucket"
40.                                         },
41.                                         "/*"
42.                                     ]
43.                                 ]
44.                             }
45.                         }
46.                     ]
47.                 },
48.                 "Bucket": {
49.                     "Ref": "S3Bucket"
50.                 }
51.             }
52.         }
53.     },
54.     "Outputs": {
55.         "WebsiteURL": {
56.             "Value": {
57.                 "Fn::GetAtt": [
58.                     "S3Bucket",
59.                     "WebsiteURL"
60.                 ]
61.             },
62.             "Description": "URL for website hosted on S3"
63.         },
64.         "S3BucketSecureURL": {
65.             "Value": {
66.                 "Fn::Join": [
67.                     "",
68.                     [
69.                         "https://",
70.                         {
71.                             "Fn::GetAtt": [
72.                                 "S3Bucket",
73.                                 "DomainName"
74.                             ]
75.                         }
76.                     ]
77.                 ]
78.             },
79.             "Description": "Name of S3 bucket to hold website content"
80.         }
81.     }
82. }
```

### YAML
<a name="quickref-s3-example-2.yaml"></a>

```
 1. AWSTemplateFormatVersion: 2010-09-09
 2. Resources:
 3.   S3Bucket:
 4.     Type: AWS::S3::Bucket
 5.     Properties:
 6.       PublicAccessBlockConfiguration:
 7.         BlockPublicAcls: false
 8.         BlockPublicPolicy: false
 9.         IgnorePublicAcls: false
10.         RestrictPublicBuckets: false
11.       WebsiteConfiguration:
12.         IndexDocument: index.html
13.         ErrorDocument: error.html
14.     DeletionPolicy: Retain
15.     UpdateReplacePolicy: Retain
16.   BucketPolicy:
17.     Type: AWS::S3::BucketPolicy
18.     Properties:
19.       PolicyDocument:
20.         Id: MyPolicy
21.         Version: 2012-10-17 		 	 	 
22.         Statement:
23.           - Sid: PublicReadForGetBucketObjects
24.             Effect: Allow
25.             Principal: '*'
26.             Action: 's3:GetObject'
27.             Resource: !Join 
28.               - ''
29.               - - 'arn:aws:s3:::'
30.                 - !Ref S3Bucket
31.                 - /*
32.       Bucket: !Ref S3Bucket
33. Outputs:
34.   WebsiteURL:
35.     Value: !GetAtt 
36.       - S3Bucket
37.       - WebsiteURL
38.     Description: URL for website hosted on S3
39.   S3BucketSecureURL:
40.     Value: !Join 
41.       - ''
42.       - - 'https://'
43.         - !GetAtt 
44.           - S3Bucket
45.           - DomainName
46.     Description: Name of S3 bucket to hold website content
```

## 使用自訂網域建立靜態網站
<a name="scenario-s3-bucket-website-customdomain"></a>

您可以將 Route 53 用於已註冊的網域。下列範例假設您已在 Route 53 中為您的網域建立託管區域。此範例會建立兩個用於網站託管的儲存貯體。根儲存貯體會託管內容，而另一個儲存貯體則會將 `www.domainname.com` 請求重新導向至根儲存貯體。記錄集會將您的網域名稱映射至 Amazon S3 端點。

您也需要新增儲存貯體政策，如上述範例所示。

有關使用自訂網域的詳細資訊，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[教學課程：使用在 Route 53 中註冊的自訂網域設定靜態網站](https://docs.aws.amazon.com/AmazonS3/latest/userguide/website-hosting-custom-domain-walkthrough.html)。

**注意**  
下列範例假設已在帳戶層級停用 `BlockPublicPolicy` 和 `RestrictPublicBuckets` 封鎖公用存取設定。

### JSON
<a name="quickref-s3-example-3.json"></a>

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Mappings" : {
        "RegionMap" : {
            "us-east-1" : { "S3hostedzoneID" : "Z3AQBSTGFYJSTF", "websiteendpoint" : "s3-website-us-east-1.amazonaws.com" },
            "us-west-1" : { "S3hostedzoneID" : "Z2F56UZL2M1ACD", "websiteendpoint" : "s3-website-us-west-1.amazonaws.com" },
            "us-west-2" : { "S3hostedzoneID" : "Z3BJ6K6RIION7M", "websiteendpoint" : "s3-website-us-west-2.amazonaws.com" },            
            "eu-west-1" : { "S3hostedzoneID" : "Z1BKCTXD74EZPE", "websiteendpoint" : "s3-website-eu-west-1.amazonaws.com" },
            "ap-southeast-1" : { "S3hostedzoneID" : "Z3O0J2DXBE1FTB", "websiteendpoint" : "s3-website-ap-southeast-1.amazonaws.com" },
            "ap-southeast-2" : { "S3hostedzoneID" : "Z1WCIGYICN2BYD", "websiteendpoint" : "s3-website-ap-southeast-2.amazonaws.com" },
            "ap-northeast-1" : { "S3hostedzoneID" : "Z2M4EHUR26P7ZW", "websiteendpoint" : "s3-website-ap-northeast-1.amazonaws.com" },
            "sa-east-1" : { "S3hostedzoneID" : "Z31GFT0UA1I2HV", "websiteendpoint" : "s3-website-sa-east-1.amazonaws.com" }
        }
    },
    "Parameters": {
        "RootDomainName": {
            "Description": "Domain name for your website (example.com)",
            "Type": "String"
        }
    },
    "Resources": {
        "RootBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName" : {"Ref":"RootDomainName"},
                "PublicAccessBlockConfiguration": {
                    "BlockPublicAcls": false,
                    "BlockPublicPolicy": false,
                    "IgnorePublicAcls": false,
                    "RestrictPublicBuckets": false
                },
                "WebsiteConfiguration": {
                    "IndexDocument":"index.html",
                    "ErrorDocument":"404.html"
                }
            }
        },
        "WWWBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": {
                    "Fn::Join": ["", ["www.", {"Ref":"RootDomainName"}]]
                },
                "AccessControl": "BucketOwnerFullControl",
                "WebsiteConfiguration": {
                    "RedirectAllRequestsTo": {
                        "HostName": {"Ref": "RootBucket"}
                    }
                }
            }
        },
        "myDNS": {
            "Type": "AWS::Route53::RecordSetGroup",
            "Properties": {
                "HostedZoneName": {
                    "Fn::Join": ["", [{"Ref": "RootDomainName"}, "."]]
                },
                "Comment": "Zone apex alias.",
                "RecordSets": [
                    {
                        "Name": {"Ref": "RootDomainName"},
                        "Type": "A",
                        "AliasTarget": {
                            "HostedZoneId": {"Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "S3hostedzoneID"]},
                            "DNSName": {"Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "websiteendpoint"]}
                        }
                    },
                    {
                        "Name": {
                            "Fn::Join": ["", ["www.", {"Ref":"RootDomainName"}]]
                        },
                        "Type": "CNAME",
                        "TTL" : "900",
                        "ResourceRecords" : [
                            {"Fn::GetAtt":["WWWBucket", "DomainName"]}
                        ]
                    }
                ]
            }
        }
    },
    "Outputs": {
        "WebsiteURL": {
            "Value": {"Fn::GetAtt": ["RootBucket", "WebsiteURL"]},
            "Description": "URL for website hosted on S3"
        }
    }
}
```

### YAML
<a name="quickref-s3-example-3.yaml"></a>

```
Parameters:
  RootDomainName:
    Description: Domain name for your website (example.com)
    Type: String
Mappings:
  RegionMap:
    us-east-1:
      S3hostedzoneID: Z3AQBSTGFYJSTF
      websiteendpoint: s3-website-us-east-1.amazonaws.com
    us-west-1:
      S3hostedzoneID: Z2F56UZL2M1ACD
      websiteendpoint: s3-website-us-west-1.amazonaws.com
    us-west-2:
      S3hostedzoneID: Z3BJ6K6RIION7M
      websiteendpoint: s3-website-us-west-2.amazonaws.com
    eu-west-1:
      S3hostedzoneID: Z1BKCTXD74EZPE
      websiteendpoint: s3-website-eu-west-1.amazonaws.com
    ap-southeast-1:
      S3hostedzoneID: Z3O0J2DXBE1FTB
      websiteendpoint: s3-website-ap-southeast-1.amazonaws.com
    ap-southeast-2:
      S3hostedzoneID: Z1WCIGYICN2BYD
      websiteendpoint: s3-website-ap-southeast-2.amazonaws.com
    ap-northeast-1:
      S3hostedzoneID: Z2M4EHUR26P7ZW
      websiteendpoint: s3-website-ap-northeast-1.amazonaws.com
    sa-east-1:
      S3hostedzoneID: Z31GFT0UA1I2HV
      websiteendpoint: s3-website-sa-east-1.amazonaws.com
Resources:
  RootBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref RootDomainName
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: 404.html
  WWWBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub
        - www.${Domain}
        - Domain: !Ref RootDomainName
      AccessControl: BucketOwnerFullControl
      WebsiteConfiguration:
        RedirectAllRequestsTo:
          HostName: !Ref RootBucket
  myDNS:
    Type: AWS::Route53::RecordSetGroup
    Properties:
      HostedZoneName: !Sub 
        - ${Domain}.
        - Domain: !Ref RootDomainName
      Comment: Zone apex alias.
      RecordSets:
        - Name: !Ref RootDomainName
          Type: A
          AliasTarget:
            HostedZoneId: !FindInMap [ RegionMap, !Ref 'AWS::Region', S3hostedzoneID]
            DNSName: !FindInMap [ RegionMap, !Ref 'AWS::Region', websiteendpoint]
        - Name: !Sub
            - www.${Domain}
            - Domain: !Ref RootDomainName
          Type: CNAME
          TTL: 900
          ResourceRecords:
            - !GetAtt WWWBucket.DomainName
Outputs:
  WebsiteURL:
    Value: !GetAtt RootBucket.WebsiteURL
    Description: URL for website hosted on S3
```

# Amazon SNS 範本程式碼片段
<a name="quickref-sns"></a>

此範例顯示 Amazon SNS 主題資源。它需要一個有效的電子郵件地址。

## JSON
<a name="quickref-sns-example-1.json"></a>

```
1. "MySNSTopic" : {
2.     "Type" : "AWS::SNS::Topic",
3.     "Properties" : {
4.         "Subscription" : [ {
5.             "Endpoint" : "add valid email address",
6.             "Protocol" : "email"
7.         } ]
8.     }
9. }
```

## YAML
<a name="quickref-sns-example-1.yaml"></a>

```
1. MySNSTopic:
2.   Type: AWS::SNS::Topic
3.   Properties:
4.     Subscription:
5.     - Endpoint: "add valid email address"
6.       Protocol: email
```

# Amazon SQS 範本程式碼片段
<a name="scenario-sqs-queue"></a>

此範例顯示 Amazon SQS 佇列。

## JSON
<a name="scenario-sqs-queue-example-1.json"></a>

```
1. "MyQueue" : {
2.     "Type" : "AWS::SQS::Queue",
3.     "Properties" : {
4.         "VisibilityTimeout" : "value"
5.     }
6. }
```

## YAML
<a name="scenario-sqs-queue-example-1.yaml"></a>

```
1. MyQueue:
2.   Type: AWS::SQS::Queue
3.   Properties:
4.     VisibilityTimeout: value
```

# Amazon Timestream 範本程式碼片段
<a name="scenario-timestream-queue"></a>

Amazon Timestream for InfluxDB 可讓應用程式開發人員和 DevOps 團隊輕鬆地在 上執行全受管 InfluxDB 資料庫， AWS 以便使用開放原始碼 APIs 進行即時時間序列應用程式。您可以快速建立能夠處理高要求時間序列工作負載的 InfluxDB 資料庫。只要幾個簡單的 API 呼叫，您就可以 AWS 透過自動化軟體修補、備份和復原，在 上設定、遷移、操作和擴展 InfluxDB 資料庫。您也能在 GitHub 上的 [awslabs/amazon-timestream-tools/tree/mainline/integrations/cloudformation/timestream-influxdb](https://github.com/awslabs/amazon-timestream-tools/tree/mainline/integrations/cloudformation/timestream-influxdb) 找到這些範例。

**Topics**
+ [使用預設值的最小範例](#scenario-timestream-influxdb-example-1)
+ [包含參數的更完整範例](#scenario-timestream-influxdb-example-2)

這些 CloudFormation 範本會建立下列資源，以便成功建立、連線和監控 Amazon Timestream for InfluxDB 執行個體：

**Amazon VPC**
+ `VPC`
+ 一個或多個 `Subnet`
+ `InternetGateway`
+ `RouteTable`
+ `SecurityGroup`

**Amazon S3**
+ `Bucket`

**Amazon Timestream**
+ `InfluxDBInstance`

## 使用預設值的最小範例
<a name="scenario-timestream-influxdb-example-1"></a>

此範例在可能的情況下使用預設值，部署多可用區且可公開存取的執行個體。

### JSON
<a name="scenario-timestream-influxdb-example-1.json"></a>

```
{
  "Metadata": {
    "AWS::CloudFormation::Interface": {
      "ParameterGroups": [
        {
          "Label": {"default": "Amazon Timestream for InfluxDB Configuration"},
          "Parameters": [
            "DbInstanceName",
            "InfluxDBPassword"
          ]
        }
      ],
      "ParameterLabels": {
        "VPCCIDR": {"default": "VPC CIDR"}
      }
    }
  },
  "Parameters": {
    "DbInstanceName": {
      "Description": "The name that uniquely identifies the DB instance when interacting with the Amazon Timestream for InfluxDB API and CLI commands. This name will also be a prefix included in the endpoint. DB instance names must be unique per customer and per Region.",
      "Type": "String",
      "Default": "mydbinstance",
      "MinLength": 3,
      "MaxLength": 40,
      "AllowedPattern": "^[a-zA-z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*$"
    },
    "InfluxDBPassword": {
      "Description": "The password of the initial admin user created in InfluxDB. This password will allow you to access the InfluxDB UI to perform various administrative tasks and also use the InfluxDB CLI to create an operator token. These attributes will be stored in a Secret created in AWS Secrets Manager in your account.",
      "Type": "String",
      "NoEcho": true,
      "MinLength": 8,
      "MaxLength": 64,
      "AllowedPattern": "^[a-zA-Z0-9]+$"
    }
  },
  "Resources": {
    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {"CidrBlock": "10.0.0.0/16"}
    },
    "InternetGateway": {"Type": "AWS::EC2::InternetGateway"},
    "InternetGatewayAttachment": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Properties": {
        "InternetGatewayId": {"Ref": "InternetGateway"},
        "VpcId": {"Ref": "VPC"}
      }
    },
    "Subnet1": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {"Ref": "VPC"},
        "AvailabilityZone": {
          "Fn::Select": [
            0,
            {"Fn::GetAZs": ""}
          ]
        },
        "CidrBlock": {
          "Fn::Select": [
            0,
            {
              "Fn::Cidr": [
                {
                  "Fn::GetAtt": [
                    "VPC",
                    "CidrBlock"
                  ]
                },
                2,
                12
              ]
            }
          ]
        },
        "MapPublicIpOnLaunch": true
      }
    },
    "Subnet2": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {"Ref": "VPC"},
        "AvailabilityZone": {
          "Fn::Select": [
            1,
            {"Fn::GetAZs": ""}
          ]
        },
        "CidrBlock": {
          "Fn::Select": [
            1,
            {
              "Fn::Cidr": [
                {
                  "Fn::GetAtt": [
                    "VPC",
                    "CidrBlock"
                  ]
                },
                2,
                12
              ]
            }
          ]
        },
        "MapPublicIpOnLaunch": true
      }
    },
    "RouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {"Ref": "VPC"}
      }
    },
    "DefaultRoute": {
      "Type": "AWS::EC2::Route",
      "DependsOn": "InternetGatewayAttachment",
      "Properties": {
        "RouteTableId": {"Ref": "RouteTable"},
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": {"Ref": "InternetGateway"}
      }
    },
    "Subnet1RouteTableAssociation": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "RouteTableId": {"Ref": "RouteTable"},
        "SubnetId": {"Ref": "Subnet1"}
      }
    },
    "Subnet2RouteTableAssociation": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "RouteTableId": {"Ref": "RouteTable"},
        "SubnetId": {"Ref": "Subnet2"}
      }
    },
    "InfluxDBSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "influxdb-sg",
        "GroupDescription": "Security group allowing port 8086 ingress for InfluxDB",
        "VpcId": {"Ref": "VPC"}
      }
    },
    "InfluxDBSecurityGroupIngress": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "GroupId": {"Ref": "InfluxDBSecurityGroup"},
        "IpProtocol": "tcp",
        "CidrIp": "0.0.0.0/0",
        "FromPort": 8086,
        "ToPort": 8086
      }
    },
    "InfluxDBLogsS3Bucket": {
      "Type": "AWS::S3::Bucket",
      "DeletionPolicy": "Retain"
    },
    "InfluxDBLogsS3BucketPolicy": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {"Ref": "InfluxDBLogsS3Bucket"},
        "PolicyDocument": {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
            {
              "Action": "s3:PutObject",
              "Effect": "Allow",
              "Resource": {"Fn::Sub": "arn:aws:s3:::${InfluxDBLogsS3Bucket}/InfluxLogs/*"},
              "Principal": {"Service": "timestream-influxdb.amazonaws.com"}
            },
            {
              "Action": "s3:*",
              "Effect": "Deny",
              "Resource": [
                {"Fn::Sub": "arn:aws:s3:::${InfluxDBLogsS3Bucket}/*"},
                {"Fn::Sub": "arn:aws:s3:::${InfluxDBLogsS3Bucket}"}
              ],
              "Principal": "*",
              "Condition": {
                "Bool": {"aws:SecureTransport": false}
              }
            }
          ]
        }
      }
    },
    "DbInstance": {
      "Type": "AWS::Timestream::InfluxDBInstance",
      "DependsOn": "InfluxDBLogsS3BucketPolicy",
      "Properties": {
        "AllocatedStorage": 20,
        "DbInstanceType": "db.influx.medium",
        "Name": {"Ref": "DbInstanceName"},
        "Password": {"Ref": "InfluxDBPassword"},
        "PubliclyAccessible": true,
        "DeploymentType": "WITH_MULTIAZ_STANDBY",
        "VpcSecurityGroupIds": [
          {"Ref": "InfluxDBSecurityGroup"}
        ],
        "VpcSubnetIds": [
          {"Ref": "Subnet1"},
          {"Ref": "Subnet2"}
        ],
        "LogDeliveryConfiguration": {
          "S3Configuration": {
            "BucketName": {"Ref": "InfluxDBLogsS3Bucket"},
            "Enabled": true
          }
        }
      }
    }
  },
  "Outputs": {
    "VPC": {
      "Description": "A reference to the VPC used to create network resources",
      "Value": {"Ref": "VPC"}
    },
    "Subnets": {
      "Description": "A list of the subnets created",
      "Value": {
        "Fn::Join": [
          ",",
          [
            {"Ref": "Subnet1"},
            {"Ref": "Subnet2"}
          ]
        ]
      }
    },
    "Subnet1": {
      "Description": "A reference to the subnet in the 1st Availability Zone",
      "Value": {"Ref": "Subnet1"}
    },
    "Subnet2": {
      "Description": "A reference to the subnet in the 2nd Availability Zone",
      "Value": {"Ref": "Subnet2"}
    },
    "InfluxDBSecurityGroup": {
      "Description": "Security group with port 8086 ingress rule",
      "Value": {"Ref": "InfluxDBSecurityGroup"}
    },
    "InfluxDBLogsS3Bucket": {
      "Description": "S3 Bucket containing InfluxDB logs from the DB instance",
      "Value": {"Ref": "InfluxDBLogsS3Bucket"}
    },
    "DbInstance": {
      "Description": "A reference to the Timestream for InfluxDB DB instance",
      "Value": {"Ref": "DbInstance"}
    },
    "InfluxAuthParametersSecretArn": {
      "Description": "The Amazon Resource Name (ARN) of the AWS Secrets Manager secret containing the initial InfluxDB authorization parameters. The secret value is a JSON formatted key-value pair holding InfluxDB authorization values: organization, bucket, username, and password.",
      "Value": {
        "Fn::GetAtt": [
          "DbInstance",
          "InfluxAuthParametersSecretArn"
        ]
      }
    },
    "Endpoint": {
      "Description": "The endpoint URL to connect to InfluxDB",
      "Value": {
        "Fn::Join": [
          "",
          [
            "https://",
            {
              "Fn::GetAtt": [
                "DbInstance",
                "Endpoint"
              ]
            },
            ":8086"
          ]
        ]
      }
    }
  }
}
```

### YAML
<a name="scenario-timestream-influxdb-example-1.yaml"></a>

```
Metadata: 
  AWS::CloudFormation::Interface:
    ParameterGroups:
      -
        Label:
          default: "Amazon Timestream for InfluxDB Configuration"
        Parameters:
          - DbInstanceName
          - InfluxDBPassword
    ParameterLabels:
      VPCCIDR:
        default: VPC CIDR

Parameters:
  DbInstanceName:
    Description: The name that uniquely identifies the DB instance when interacting with the Amazon Timestream for InfluxDB API and CLI commands. This name will also be a prefix included in the endpoint. DB instance names must be unique per customer and per Region.
    Type: String
    Default: mydbinstance
    MinLength: 3
    MaxLength: 40
    AllowedPattern: ^[a-zA-z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*$
  InfluxDBPassword:
    Description: The password of the initial admin user created in InfluxDB. This password will allow you to access the InfluxDB UI to perform various administrative tasks and also use the InfluxDB CLI to create an operator token. These attributes will be stored in a Secret created in AWS Secrets Manager in your account.
    Type: String
    NoEcho: true
    MinLength: 8
    MaxLength: 64
    AllowedPattern: ^[a-zA-Z0-9]+$

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC
  Subnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: !Select [0, !Cidr [!GetAtt VPC.CidrBlock, 2, 12 ]]
      MapPublicIpOnLaunch: true
  Subnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [1, !GetAZs  '']
      CidrBlock: !Select [1, !Cidr [!GetAtt VPC.CidrBlock, 2, 12 ]]
      MapPublicIpOnLaunch: true
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
  DefaultRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  Subnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable
      SubnetId: !Ref Subnet1
  Subnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable
      SubnetId: !Ref Subnet2
  InfluxDBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: "influxdb-sg"
      GroupDescription: "Security group allowing port 8086 ingress for InfluxDB"
      VpcId: !Ref VPC
  InfluxDBSecurityGroupIngress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref InfluxDBSecurityGroup
      IpProtocol: tcp
      CidrIp: 0.0.0.0/0
      FromPort: 8086
      ToPort: 8086
  InfluxDBLogsS3Bucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
  InfluxDBLogsS3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref InfluxDBLogsS3Bucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Action: "s3:PutObject"
            Effect: Allow
            Resource: !Sub arn:aws:s3:::${InfluxDBLogsS3Bucket}/InfluxLogs/*
            Principal:
              Service: timestream-influxdb.amazonaws.com
          - Action: "s3:*"
            Effect: Deny
            Resource:
              - !Sub arn:aws:s3:::${InfluxDBLogsS3Bucket}/*
              - !Sub arn:aws:s3:::${InfluxDBLogsS3Bucket}
            Principal: "*"
            Condition:
              Bool:
                aws:SecureTransport: false
  DbInstance:
    Type: AWS::Timestream::InfluxDBInstance
    DependsOn: InfluxDBLogsS3BucketPolicy
    Properties:
      AllocatedStorage: 20
      DbInstanceType: db.influx.medium
      Name: !Ref DbInstanceName
      Password: !Ref InfluxDBPassword
      PubliclyAccessible: true
      DeploymentType: WITH_MULTIAZ_STANDBY
      VpcSecurityGroupIds: 
        - !Ref InfluxDBSecurityGroup
      VpcSubnetIds:
        - !Ref Subnet1
        - !Ref Subnet2
      LogDeliveryConfiguration:
        S3Configuration:
          BucketName: !Ref InfluxDBLogsS3Bucket
          Enabled: true

Outputs:
  # Network Resources
  VPC:
    Description: A reference to the VPC used to create network resources
    Value: !Ref VPC
  Subnets:
    Description: A list of the subnets created
    Value: !Join [",", [!Ref Subnet1, !Ref Subnet2]]
  Subnet1:
    Description: A reference to the subnet in the 1st Availability Zone
    Value: !Ref Subnet1
  Subnet2:
    Description: A reference to the subnet in the 2nd Availability Zone
    Value: !Ref Subnet2
  InfluxDBSecurityGroup:
    Description: Security group with port 8086 ingress rule
    Value: !Ref InfluxDBSecurityGroup

  # Timestream for InfluxDB Resources
  InfluxDBLogsS3Bucket:
    Description: S3 Bucket containing InfluxDB logs from the DB instance
    Value: !Ref InfluxDBLogsS3Bucket
  DbInstance:
    Description: A reference to the Timestream for InfluxDB DB instance
    Value: !Ref DbInstance
  InfluxAuthParametersSecretArn:
    Description: "The Amazon Resource Name (ARN) of the AWS Secrets Manager secret containing the initial InfluxDB authorization parameters. The secret value is a JSON formatted key-value pair holding InfluxDB authorization values: organization, bucket, username, and password."
    Value: !GetAtt DbInstance.InfluxAuthParametersSecretArn
  Endpoint:
    Description: The endpoint URL to connect to InfluxDB
    Value: !Join ["", ["https://", !GetAtt DbInstance.Endpoint, ":8086"]]
```

## 包含參數的更完整範例
<a name="scenario-timestream-influxdb-example-2"></a>

此範例範本會根據提供的參數動態調整網路資源。參數包括 `PubliclyAccessible` 與 `DeploymentType`。

### JSON
<a name="scenario-timestream-influxdb-example-2.json"></a>

```
{
  "Metadata": {
    "AWS::CloudFormation::Interface": {
      "ParameterGroups": [
        {
          "Label": {"default": "Network Configuration"},
          "Parameters": ["VPCCIDR"]
        },
        {
          "Label": {"default": "Amazon Timestream for InfluxDB Configuration"},
          "Parameters": [
            "DbInstanceName",
            "InfluxDBUsername",
            "InfluxDBPassword",
            "InfluxDBOrganization",
            "InfluxDBBucket",
            "DbInstanceType",
            "DbStorageType",
            "AllocatedStorage",
            "PubliclyAccessible",
            "DeploymentType"
          ]
        }
      ],
      "ParameterLabels": {
        "VPCCIDR": {"default": "VPC CIDR"}
      }
    }
  },
  "Parameters": {
    "VPCCIDR": {
      "Description": "Please enter the IP range (CIDR notation) for the new VPC",
      "Type": "String",
      "Default": "10.0.0.0/16"
    },
    "DbInstanceName": {
      "Description": "The name that uniquely identifies the DB instance when interacting with the Amazon Timestream for InfluxDB API and CLI commands. This name will also be a prefix included in the endpoint. DB instance names must be unique per customer and per Region.",
      "Type": "String",
      "Default": "mydbinstance",
      "MinLength": 3,
      "MaxLength": 40,
      "AllowedPattern": "^[a-zA-z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*$"
    },
    "InfluxDBUsername": {
      "Description": "The username of the initial admin user created in InfluxDB. Must start with a letter and can't end with a hyphen or contain two consecutive hyphens. For example, my-user1. This username will allow you to access the InfluxDB UI to perform various administrative tasks and also use the InfluxDB CLI to create an operator token. These attributes will be stored in a Secret created in AWS Secrets Manager in your account.",
      "Type": "String",
      "Default": "admin",
      "MinLength": 1,
      "MaxLength": 64
    },
    "InfluxDBPassword": {
      "Description": "The password of the initial admin user created in InfluxDB. This password will allow you to access the InfluxDB UI to perform various administrative tasks and also use the InfluxDB CLI to create an operator token. These attributes will be stored in a Secret created in AWS Secrets Manager in your account.",
      "Type": "String",
      "NoEcho": true,
      "MinLength": 8,
      "MaxLength": 64,
      "AllowedPattern": "^[a-zA-Z0-9]+$"
    },
    "InfluxDBOrganization": {
      "Description": "The name of the initial organization for the initial admin user in InfluxDB. An InfluxDB organization is a workspace for a group of users.",
      "Type": "String",
      "Default": "org",
      "MinLength": 1,
      "MaxLength": 64
    },
    "InfluxDBBucket": {
      "Description": "The name of the initial InfluxDB bucket. All InfluxDB data is stored in a bucket. A bucket combines the concept of a database and a retention period (the duration of time that each data point persists). A bucket belongs to an organization.",
      "Type": "String",
      "Default": "bucket",
      "MinLength": 2,
      "MaxLength": 64,
      "AllowedPattern": "^[^_\\\"][^\\\"]*$"
    },
    "DeploymentType": {
      "Description": "Specifies whether the Timestream for InfluxDB is deployed as Single-AZ or with a MultiAZ Standby for High availability",
      "Type": "String",
      "Default": "WITH_MULTIAZ_STANDBY",
      "AllowedValues": [
        "SINGLE_AZ",
        "WITH_MULTIAZ_STANDBY"
      ]
    },
    "AllocatedStorage": {
      "Description": "The amount of storage to allocate for your DB storage type in GiB (gibibytes).",
      "Type": "Number",
      "Default": 400,
      "MinValue": 20,
      "MaxValue": 16384
    },
    "DbInstanceType": {
      "Description": "The Timestream for InfluxDB DB instance type to run InfluxDB on.",
      "Type": "String",
      "Default": "db.influx.medium",
      "AllowedValues": [
        "db.influx.medium",
        "db.influx.large",
        "db.influx.xlarge",
        "db.influx.2xlarge",
        "db.influx.4xlarge",
        "db.influx.8xlarge",
        "db.influx.12xlarge",
        "db.influx.16xlarge"
      ]
    },
    "DbStorageType": {
      "Description": "The Timestream for InfluxDB DB storage type to read and write InfluxDB data.",
      "Type": "String",
      "Default": "InfluxIOIncludedT1",
      "AllowedValues": [
        "InfluxIOIncludedT1",
        "InfluxIOIncludedT2",
        "InfluxIOIncludedT3"
      ]
    },
    "PubliclyAccessible": {
      "Description": "Configures the DB instance with a public IP to facilitate access.",
      "Type": "String",
      "Default": true,
      "AllowedValues": [
        true,
        false
      ]
    }
  },
  "Conditions": {
    "IsMultiAZ": {
      "Fn::Equals": [
        {"Ref": "DeploymentType"},
        "WITH_MULTIAZ_STANDBY"
      ]
    },
    "IsPublic": {
      "Fn::Equals": [
        {"Ref": "PubliclyAccessible"},
        true
      ]
    }
  },
  "Resources": {
    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": {"Ref": "VPCCIDR"}
      }
    },
    "InternetGateway": {
      "Type": "AWS::EC2::InternetGateway",
      "Condition": "IsPublic"
    },
    "InternetGatewayAttachment": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Condition": "IsPublic",
      "Properties": {
        "InternetGatewayId": {"Ref": "InternetGateway"},
        "VpcId": {"Ref": "VPC"}
      }
    },
    "Subnet1": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {"Ref": "VPC"},
        "AvailabilityZone": {
          "Fn::Select": [
            0,
            {"Fn::GetAZs": ""}
          ]
        },
        "CidrBlock": {
          "Fn::Select": [
            0,
            {
              "Fn::Cidr": [
                {
                  "Fn::GetAtt": [
                    "VPC",
                    "CidrBlock"
                  ]
                },
                2,
                12
              ]
            }
          ]
        },
        "MapPublicIpOnLaunch": {
          "Fn::If": [
            "IsPublic",
            true,
            false
          ]
        }
      }
    },
    "Subnet2": {
      "Type": "AWS::EC2::Subnet",
      "Condition": "IsMultiAZ",
      "Properties": {
        "VpcId": {"Ref": "VPC"},
        "AvailabilityZone": {
          "Fn::Select": [
            1,
            {"Fn::GetAZs": ""}
          ]
        },
        "CidrBlock": {
          "Fn::Select": [
            1,
            {
              "Fn::Cidr": [
                {
                  "Fn::GetAtt": [
                    "VPC",
                    "CidrBlock"
                  ]
                },
                2,
                12
              ]
            }
          ]
        },
        "MapPublicIpOnLaunch": {
          "Fn::If": [
            "IsPublic",
            true,
            false
          ]
        }
      }
    },
    "RouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {"Ref": "VPC"}
      }
    },
    "DefaultRoute": {
      "Type": "AWS::EC2::Route",
      "Condition": "IsPublic",
      "DependsOn": "InternetGatewayAttachment",
      "Properties": {
        "RouteTableId": {"Ref": "RouteTable"},
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": {"Ref": "InternetGateway"}
      }
    },
    "Subnet1RouteTableAssociation": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "RouteTableId": {"Ref": "RouteTable"},
        "SubnetId": {"Ref": "Subnet1"}
      }
    },
    "Subnet2RouteTableAssociation": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Condition": "IsMultiAZ",
      "Properties": {
        "RouteTableId": {"Ref": "RouteTable"},
        "SubnetId": {"Ref": "Subnet2"}
      }
    },
    "InfluxDBSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "influxdb-sg",
        "GroupDescription": "Security group allowing port 8086 ingress for InfluxDB",
        "VpcId": {"Ref": "VPC"}
      }
    },
    "InfluxDBSecurityGroupIngress": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "GroupId": {"Ref": "InfluxDBSecurityGroup"},
        "IpProtocol": "tcp",
        "CidrIp": "0.0.0.0/0",
        "FromPort": 8086,
        "ToPort": 8086
      }
    },
    "InfluxDBLogsS3Bucket": {
      "Type": "AWS::S3::Bucket",
      "DeletionPolicy": "Retain"
    },
    "InfluxDBLogsS3BucketPolicy": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {"Ref": "InfluxDBLogsS3Bucket"},
        "PolicyDocument": {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
            {
              "Action": "s3:PutObject",
              "Effect": "Allow",
              "Resource": {"Fn::Sub": "arn:aws:s3:::${InfluxDBLogsS3Bucket}/InfluxLogs/*"},
              "Principal": {"Service": "timestream-influxdb.amazonaws.com"}
            },
            {
              "Action": "s3:*",
              "Effect": "Deny",
              "Resource": [
                {"Fn::Sub": "arn:aws:s3:::${InfluxDBLogsS3Bucket}/*"},
                {"Fn::Sub": "arn:aws:s3:::${InfluxDBLogsS3Bucket}"}
              ],
              "Principal": "*",
              "Condition": {
                "Bool": {"aws:SecureTransport": false}
              }
            }
          ]
        }
      }
    },
    "DbInstance": {
      "Type": "AWS::Timestream::InfluxDBInstance",
      "DependsOn": "InfluxDBLogsS3BucketPolicy",
      "Properties": {
        "DbStorageType": {"Ref": "DbStorageType"},
        "AllocatedStorage": {"Ref": "AllocatedStorage"},
        "DbInstanceType": {"Ref": "DbInstanceType"},
        "Name": {"Ref": "DbInstanceName"},
        "Username": {"Ref": "InfluxDBUsername"},
        "Password": {"Ref": "InfluxDBPassword"},
        "Organization": {"Ref": "InfluxDBOrganization"},
        "Bucket": {"Ref": "InfluxDBBucket"},
        "PubliclyAccessible": {
          "Fn::If": [
            "IsPublic",
            true,
            false
          ]
        },
        "DeploymentType": {"Ref": "DeploymentType"},
        "VpcSecurityGroupIds": [
          {"Ref": "InfluxDBSecurityGroup"}
        ],
        "VpcSubnetIds": {
          "Fn::If": [
            "IsMultiAZ",
            [
              {"Ref": "Subnet1"},
              {"Ref": "Subnet2"}
            ],
            [
              {"Ref": "Subnet1"}
            ]
          ]
        },
        "LogDeliveryConfiguration": {
          "S3Configuration": {
            "BucketName": {"Ref": "InfluxDBLogsS3Bucket"},
            "Enabled": true
          }
        }
      }
    }
  },
  "Outputs": {
    "VPC": {
      "Description": "A reference to the VPC used to create network resources",
      "Value": {"Ref": "VPC"}
    },
    "Subnets": {
      "Description": "A list of the subnets created",
      "Value": {
        "Fn::If": [
          "IsMultiAZ",
          {
            "Fn::Join": [
              ",",
              [
                {"Ref": "Subnet1"},
                {"Ref": "Subnet2"}
              ]
            ]
          },
          {"Ref": "Subnet1"}
        ]
      }
    },
    "Subnet1": {
      "Description": "A reference to the subnet in the 1st Availability Zone",
      "Value": {"Ref": "Subnet1"}
    },
    "Subnet2": {
      "Condition": "IsMultiAZ",
      "Description": "A reference to the subnet in the 2nd Availability Zone",
      "Value": {"Ref": "Subnet2"}
    },
    "InfluxDBSecurityGroup": {
      "Description": "Security group with port 8086 ingress rule",
      "Value": {"Ref": "InfluxDBSecurityGroup"}
    },
    "InfluxDBLogsS3Bucket": {
      "Description": "S3 Bucket containing InfluxDB logs from the DB instance",
      "Value": {"Ref": "InfluxDBLogsS3Bucket"}
    },
    "DbInstance": {
      "Description": "A reference to the Timestream for InfluxDB DB instance",
      "Value": {"Ref": "DbInstance"}
    },
    "InfluxAuthParametersSecretArn": {
      "Description": "The Amazon Resource Name (ARN) of the AWS Secrets Manager secret containing the initial InfluxDB authorization parameters. The secret value is a JSON formatted key-value pair holding InfluxDB authorization values: organization, bucket, username, and password.",
      "Value": {
        "Fn::GetAtt": [
          "DbInstance",
          "InfluxAuthParametersSecretArn"
        ]
      }
    },
    "Endpoint": {
      "Description": "The endpoint URL to connect to InfluxDB",
      "Value": {
        "Fn::Join": [
          "",
          [
            "https://",
            {
              "Fn::GetAtt": [
                "DbInstance",
                "Endpoint"
              ]
            },
            ":8086"
          ]
        ]
      }
    }
  }
}
```

### YAML
<a name="scenario-timestream-influxdb-example-2.yaml"></a>

```
Metadata: 
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: "Network Configuration"
        Parameters:
          - VPCCIDR
      -
        Label:
          default: "Amazon Timestream for InfluxDB Configuration"
        Parameters:
          - DbInstanceName
          - InfluxDBUsername
          - InfluxDBPassword
          - InfluxDBOrganization
          - InfluxDBBucket
          - DbInstanceType
          - DbStorageType
          - AllocatedStorage
          - PubliclyAccessible
          - DeploymentType
    ParameterLabels:
      VPCCIDR:
        default: VPC CIDR

Parameters:
  # Network Configuration
  VPCCIDR:
    Description: Please enter the IP range (CIDR notation) for the new VPC
    Type: String
    Default: 10.0.0.0/16
  # Timestream for InfluxDB Configuration
  DbInstanceName:
    Description: The name that uniquely identifies the DB instance when interacting with the Amazon Timestream for InfluxDB API and CLI commands. This name will also be a prefix included in the endpoint. DB instance names must be unique per customer and per Region.
    Type: String
    Default: mydbinstance
    MinLength: 3
    MaxLength: 40    
    AllowedPattern: ^[a-zA-z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*$
  # InfluxDB initial user configurations
  InfluxDBUsername:
    Description: The username of the initial admin user created in InfluxDB. Must start with a letter and can't end with a hyphen or contain two consecutive hyphens. For example, my-user1. This username will allow you to access the InfluxDB UI to perform various administrative tasks and also use the InfluxDB CLI to create an operator token. These attributes will be stored in a Secret created in AWS Secrets Manager in your account.
    Type: String
    Default: admin
    MinLength: 1
    MaxLength: 64
  InfluxDBPassword:
    Description: The password of the initial admin user created in InfluxDB. This password will allow you to access the InfluxDB UI to perform various administrative tasks and also use the InfluxDB CLI to create an operator token. These attributes will be stored in a Secret created in AWS in your account.
    Type: String
    NoEcho: true
    MinLength: 8
    MaxLength: 64
    AllowedPattern: ^[a-zA-Z0-9]+$
  InfluxDBOrganization:
    Description: The name of the initial organization for the initial admin user in InfluxDB. An InfluxDB organization is a workspace for a group of users.
    Type: String
    Default: org
    MinLength: 1
    MaxLength: 64
  InfluxDBBucket:
    Description: The name of the initial InfluxDB bucket. All InfluxDB data is stored in a bucket. A bucket combines the concept of a database and a retention period (the duration of time that each data point persists). A bucket belongs to an organization.
    Type: String
    Default: bucket
    MinLength: 2
    MaxLength: 64
    AllowedPattern: ^[^_\"][^\"]*$
  DeploymentType:
    Description: Specifies whether the Timestream for InfluxDB is deployed as Single-AZ or with a MultiAZ Standby for High availability
    Type: String
    Default: WITH_MULTIAZ_STANDBY
    AllowedValues:
      - SINGLE_AZ
      - WITH_MULTIAZ_STANDBY
  AllocatedStorage:
    Description: The amount of storage to allocate for your DB storage type in GiB (gibibytes).
    Type: Number
    Default: 400
    MinValue: 20
    MaxValue: 16384
  DbInstanceType:
    Description: The Timestream for InfluxDB DB instance type to run InfluxDB on.
    Type: String
    Default: db.influx.medium
    AllowedValues:
      - db.influx.medium
      - db.influx.large
      - db.influx.xlarge
      - db.influx.2xlarge
      - db.influx.4xlarge
      - db.influx.8xlarge
      - db.influx.12xlarge
      - db.influx.16xlarge
  DbStorageType:
    Description: The Timestream for InfluxDB DB storage type to read and write InfluxDB data.
    Type: String
    Default: InfluxIOIncludedT1
    AllowedValues:
      - InfluxIOIncludedT1
      - InfluxIOIncludedT2
      - InfluxIOIncludedT3
  PubliclyAccessible:
    Description: Configures the DB instance with a public IP to facilitate access.
    Type: String
    Default: true
    AllowedValues:
      - true
      - false

Conditions:
  IsMultiAZ: !Equals [!Ref DeploymentType, WITH_MULTIAZ_STANDBY]
  IsPublic: !Equals [!Ref PubliclyAccessible, true]

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VPCCIDR
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Condition: IsPublic
  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Condition: IsPublic
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC
  Subnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: !Select [0, !Cidr [!GetAtt VPC.CidrBlock, 2, 12 ]]
      MapPublicIpOnLaunch: !If [IsPublic, true, false]
  Subnet2:
    Type: AWS::EC2::Subnet
    Condition: IsMultiAZ
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [1, !GetAZs  '']
      CidrBlock: !Select [1, !Cidr [!GetAtt VPC.CidrBlock, 2, 12 ]]
      MapPublicIpOnLaunch: !If [IsPublic, true, false]
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
  DefaultRoute:
    Type: AWS::EC2::Route
    Condition: IsPublic
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  Subnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable
      SubnetId: !Ref Subnet1
  Subnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Condition: IsMultiAZ
    Properties:
      RouteTableId: !Ref RouteTable
      SubnetId: !Ref Subnet2
  InfluxDBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: "influxdb-sg"
      GroupDescription: "Security group allowing port 8086 ingress for InfluxDB"
      VpcId: !Ref VPC
  InfluxDBSecurityGroupIngress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref InfluxDBSecurityGroup
      IpProtocol: tcp
      CidrIp: 0.0.0.0/0
      FromPort: 8086
      ToPort: 8086
  InfluxDBLogsS3Bucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
  InfluxDBLogsS3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref InfluxDBLogsS3Bucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Action: "s3:PutObject"
            Effect: Allow
            Resource: !Sub arn:aws:s3:::${InfluxDBLogsS3Bucket}/InfluxLogs/*
            Principal:
              Service: timestream-influxdb.amazonaws.com
          - Action: "s3:*"
            Effect: Deny
            Resource:
              - !Sub arn:aws:s3:::${InfluxDBLogsS3Bucket}/*
              - !Sub arn:aws:s3:::${InfluxDBLogsS3Bucket}
            Principal: "*"
            Condition:
              Bool:
                aws:SecureTransport: false
  DbInstance:
    Type: AWS::Timestream::InfluxDBInstance
    DependsOn: InfluxDBLogsS3BucketPolicy
    Properties:
      DbStorageType: !Ref DbStorageType
      AllocatedStorage: !Ref AllocatedStorage
      DbInstanceType: !Ref DbInstanceType
      Name: !Ref DbInstanceName
      Username: !Ref InfluxDBUsername
      Password: !Ref InfluxDBPassword
      Organization: !Ref InfluxDBOrganization
      Bucket: !Ref InfluxDBBucket
      PubliclyAccessible: !If [IsPublic, true, false]
      DeploymentType: !Ref DeploymentType
      VpcSecurityGroupIds: 
        - !Ref InfluxDBSecurityGroup
      VpcSubnetIds: !If
        - IsMultiAZ
        -
          - !Ref Subnet1
          - !Ref Subnet2
        -
          - !Ref Subnet1
      LogDeliveryConfiguration:
        S3Configuration:
          BucketName: !Ref InfluxDBLogsS3Bucket
          Enabled: true

Outputs:
  # Network Resources
  VPC:
    Description: A reference to the VPC used to create network resources
    Value: !Ref VPC
  Subnets:
    Description: A list of the subnets created
    Value: !If
      - IsMultiAZ
      - !Join [",", [!Ref Subnet1, !Ref Subnet2]]
      - !Ref Subnet1
  Subnet1:
    Description: A reference to the subnet in the 1st Availability Zone
    Value: !Ref Subnet1
  Subnet2:
    Condition: IsMultiAZ
    Description: A reference to the subnet in the 2nd Availability Zone
    Value: !Ref Subnet2
  InfluxDBSecurityGroup:
    Description: Security group with port 8086 ingress rule
    Value: !Ref InfluxDBSecurityGroup

  # Timestream for InfluxDB Resources
  InfluxDBLogsS3Bucket:
    Description: S3 Bucket containing InfluxDB logs from the DB instance
    Value: !Ref InfluxDBLogsS3Bucket
  DbInstance:
    Description: A reference to the Timestream for InfluxDB DB instance
    Value: !Ref DbInstance
  InfluxAuthParametersSecretArn:
    Description: "The Amazon Resource Name (ARN) of the AWS Secrets Manager secret containing the initial InfluxDB authorization parameters. The secret value is a JSON formatted key-value pair holding InfluxDB authorization values: organization, bucket, username, and password."
    Value: !GetAtt DbInstance.InfluxAuthParametersSecretArn
  Endpoint:
    Description: The endpoint URL to connect to InfluxDB
    Value: !Join ["", ["https://", !GetAtt DbInstance.Endpoint, ":8086"]]
```

# 使用 CloudFormation 部署 Windows 型堆疊
<a name="cfn-windows-stacks"></a>

此頁面提供 Windows 型部署中常用 CloudFormation 資源的技術參考文件連結。

CloudFormation 透過 Infrastructure as Code (IaC) 支援部署和管理 Microsoft Windows 堆疊。您可以使用 CloudFormation 來自動佈建 Windows型 EC2 執行個體、Amazon RDS SQL Server和MicrosoftActive Directory透過 Directory Service。

AWS 提供專為Windows平台設計的預先設定 Amazon Machine Image (AMIs)，可協助您在 Amazon EC2 上快速部署應用程式。這些 AMIs包含Microsoft預設設定和 AWS特定自訂。使用 CloudFormation，可以選擇適當的 AMI，啟動執行個體，並使用遠端桌面連線存取它，就像使用任何其他 Windows Server 一樣。AMIs 包含必要的軟體元件，包括 EC2Launch（版本因Windows Server版本而異）、 AWS Tools for PowerShell、 AWS Systems Manager CloudFormation 和各種網路、儲存和圖形驅動程式，以確保最佳的效能和 AWS 與服務的相容性。如需詳細資訊，請參閱 [AWS Windows AMI 參考](https://docs.aws.amazon.com/ec2/latest/windows-ami-reference/windows-amis.html)。

CloudFormation 也支援軟體組態工具，例如 `UserData` 指令碼，可在 EC2 執行個體首次開機時執行 PowerShell 或批次命令。它還提供協助程式指令碼 (`cfn-init`、`cfn-signal`、`cfn-get-metadata` 和 `cfn-hup`)，並支援 `AWS::CloudFormation::Init` 中繼資料，用於管理 Windows 執行個體上的套件、檔案和服務。

對於企業環境，CloudFormation 會啟用網域加入，透過 EC2 Windows授權模型進行授權管理，以及使用 AWS Secrets Manager進行安全憑證處理。CloudFormation 結合版本控制範本和可重複的部署，可協助組織在多個 AWS 區域 和 帳戶中維持一致、安全且可擴展Windows的環境。

如需 Windows 型部署中常用 CloudFormation 資源的詳細資訊，請參閱下列技術參考主題。


| Resource Type (資源類型) | Description | 
| --- | --- | 
|  [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html)  |  用於啟動 Windows EC2 執行個體。  | 
|  [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html)  |  定義 Windows 工作負載的防火牆規則。  | 
|  [AWS::AutoScaling::AutoScalingGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) [AWS::EC2::LaunchTemplate](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html)  |  用於擴展 Windows EC2 執行個體。  | 
|  [AWS::DirectoryService::MicrosoftAD](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-directoryservice-microsoftad.html)  |  用於部署 Microsoft Active Directory。  | 
|  [AWS::FSx::FileSystem](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-fsx-filesystem.html)  |  用於部署 FSx for Windows File Server。  | 
|  [AWS::RDS::DBInstance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-rds-dbinstance.html)  |  用於在 Amazon RDS 上佈建 SQL Server。  | 
|  [AWS::CloudFormation::Init](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-init.html)  |  在 EC2 中繼資料內用於設定執行個體。 如需詳細資訊，請參閱[引導 Windows 型 CloudFormation 堆疊](cfn-windows-stacks-bootstrapping.md)。  | 
|  [AWS::SecretsManager::Secret](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-secretsmanager-secret.html)  |  用於安全管理憑證和 Windows 密碼。  | 
|  [AWS::SSM::Parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ssm-parameter.html)  |  用於安全地存放組態值。  | 
|  [AWS::IAM::InstanceProfile](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-instanceprofile.html) [AWS::IAM::Role](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-role.html)  |  用於為 EC2 執行個體上執行的應用程式授予許可。  | 

# 引導 Windows 型 CloudFormation 堆疊
<a name="cfn-windows-stacks-bootstrapping"></a>

本主題說明如何引導 Windows 堆疊和疑難排解堆疊建立問題。

**Topics**
+ [EC2 執行個體中的使用者資料](#cfn-windows-bootstrapping-user-data)
+ [CloudFormation 協助程式指令碼](#cfn-windows-bootstrapping-helper-scripts)
+ [引導 Windows 堆疊的範例](#cfn-windows-bootstrapping-example)
+ [Windows 檔案路徑中的轉義反斜線](#cfn-windows-stacks-escape-backslashes)
+ [管理 Windows 服務](#cfn-windows-stacks-manage-windows-services)
+ [疑難排解堆疊建立問題](#cfn-windows-stacks-troubleshooting)

## EC2 執行個體中的使用者資料
<a name="cfn-windows-bootstrapping-user-data"></a>

使用者資料是一種 Amazon EC2 功能，可讓您在啟動時將指令碼或組態資訊傳遞給 EC2 執行個體。

對於 Windows EC2 執行個體：
+ 可以使用批次指令碼 (使用 `<script>` 標籤) 或 PowerShell 指令碼 (使用`<powershell>` 標籤)。
+ 由 EC2Launch 處理指令碼執行。

**重要**  
如果要建立自己的 Windows AMI 以搭配 CloudFormation 使用，請確保已正確設定 EC2Launch v2。CloudFormation 引導工具需要 EC2Launch v2，才能在堆疊建立期間正確初始化和設定 Windows 執行個體。如需詳細資訊，請參閱《Amazon EC2 使用者指南》中的[在 EC2 Windows 執行個體啟動期間使用 EC2Launch v2 代理程式來執行任務](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2launch-v2.html)。**  
如需 AMIs的相關資訊 AWS Windows，請參閱 [AWS Windows AMI 參考](https://docs.aws.amazon.com/ec2/latest/windows-ami-reference/windows-amis.html)。

## CloudFormation 協助程式指令碼
<a name="cfn-windows-bootstrapping-helper-scripts"></a>

協助程式指令碼是在引導程序期間設定執行個體的公用程式。與 Amazon EC2 使用者資料搭配使用，其可提供強大的組態選項。

CloudFormation 提供下列 Python 協助程式指令碼，您可以使用這些指令碼在當做堆疊一部分建立的 Amazon EC2 執行個體上安裝軟體及啟動服務：
+  `cfn-init` – 用來擷取及解釋資源中繼資料、安裝套件、建立檔案及啟動服務。
+  `cfn-signal` – 用來透過 `CreationPolicy` 發出訊號，讓您可以在先決條件資源或應用程式就緒時，同步堆疊中的其他資源。
+  `cfn-get-metadata` – 用來擷取資源的中繼資料或特定金鑰的路徑。
+  `cfn-hup` – 用來檢查是否有中繼資料更新，並在偵測到變更時執行自訂勾點。

您可以直接從範本呼叫指令碼。指令碼會搭配同一個範本中定義的資源中繼資料使用。指令碼會在堆疊建立程序期間於 Amazon EC2 執行個體上執行。

如需詳細資訊，請參閱《CloudFormation 範本參考指南》中的 [CloudFormation 協助程式指令碼參考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/cfn-helper-scripts-reference.html)。**

## 引導 Windows 堆疊的範例
<a name="cfn-windows-bootstrapping-example"></a>

讓我們檢查執行下列動作的 Windows Server 範本中的範例程式碼片段：
+ 從 Windows Server 2022 AMI 中啟動名為 `TestInstance` 的 EC2 執行個體。
+ 建立簡單的測試檔案以驗證 `cfn-init` 是否正常運作。
+ 設定 `cfn-hup` 以進行持續的組態管理。
+ 使用 `CreationPolicy` 來確保執行個體發出成功完成的訊號。

`cfn-init` 協助程式指令碼用於根據範本中 `AWS::CloudFormation::Init` 資源中的資訊來執行這些動作中的每個動作。

`AWS::CloudFormation::Init` 區段名為 `TestInstance`，開頭為下列宣告。

```
TestInstance:
  Type: AWS::EC2::Instance
  Metadata:
    AWS::CloudFormation::Init:
      configSets:
        default:
          - create_files
          - start_services
```

在此之後，將宣告 `AWS::CloudFormation::Init` 的 `files` 區段：

```
      create_files:
        files:
          c:\cfn\test.txt:
            content: !Sub |
              Hello from ${AWS::StackName}
          c:\cfn\cfn-hup.conf:
            content: !Sub |
              [main]
              stack=${AWS::StackName}
              region=${AWS::Region}
              interval=2
          c:\cfn\hooks.d\cfn-auto-reloader.conf:
            content: !Sub |
              [cfn-auto-reloader-hook]
              triggers=post.update
              path=Resources.TestInstance.Metadata.AWS::CloudFormation::Init
              action=cfn-init.exe -v -s ${AWS::StackName} -r TestInstance -c default --region ${AWS::Region}
```

在此建立三個檔案，並放在伺服器執行個體的 `C:\cfn` 目錄中：
+ `test.txt`，一種簡單的測試檔案，可驗證 `cfn-init` 是否正常運作，並可建立具有動態內容的檔案。
+ `cfn-hup.conf`，`cfn-hup` 的組態檔案，具有 2 分鐘檢查間隔。
+ `cfn-auto-reloader.conf`，`cfn-hup` 使用的掛接組態檔案，當 `AWS::CloudFormation::Init` 中的中繼資料變更時，用於啟動更新 (呼叫 `cfn-init`)。

接下來是 `start_services` 區段，它可設定 Windows 服務。

```
      start_services:
        services:
          windows:
            cfn-hup:
              enabled: true
              ensureRunning: true
              files:
                - c:\cfn\cfn-hup.conf
                - c:\cfn\hooks.d\cfn-auto-reloader.conf
```

本節可確保 `cfn-hup` 服務已啟動，並在修改組態檔案時自動重新啟動。服務會監控 CloudFormation 中繼資料的變更，並在偵測到更新時重新執行 `cfn-init`。

接下來是 `Properties` 區段。

```
TestInstance:
  Type: AWS::EC2::Instance
  CreationPolicy:
    ResourceSignal:
      Timeout: PT20M
  Metadata:
    AWS::CloudFormation::Init:
      # ... metadata configuration ...
  Properties:
    InstanceType: t2.large
    ImageId: '{{resolve:ssm:/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base}}'
    SecurityGroupIds:
      - !Ref InstanceSecurityGroup
    KeyName: !Ref KeyPairName
    UserData:
      Fn::Base64: !Sub |
        <powershell>
        cfn-init.exe -v -s ${AWS::StackName} -r TestInstance -c default --region ${AWS::Region}
        cfn-signal.exe -e $lastexitcode --stack ${AWS::StackName} --resource TestInstance --region ${AWS::Region}
        </powershell>
```

在此區段中，`UserData` 屬性包含 EC2Launch 將執行的 PowerShell 指令碼，被包圍在 `<powershell>` 標籤中。指令碼使用 `default` configSet 來執行 `cfn-init`，然後使用 `cfn-signal` 向 CloudFormation 回報結束碼。`CreationPolicy` 用於確保在堆疊建立視為完成之前正確設定執行個體。

`ImageId` 屬性會使用 Systems Manager Parameter Store 公有參數自動擷取最新的 Windows Server 2022 AMI ID。此方法不需要區域特定的 AMI 映射，並確保您始終取得最新的 AMI。針對 AMI ID 使用 Systems Manager 參數是維護目前 AMI 參考的最佳實務。如果打算連線到執行個體，請確保 `SecurityGroupIds` 屬性可參考允許 RDP 存取的安全群組。

`CreationPolicy` 會宣告為資源屬性的一部分，並指定逾時期間。執行個體組態完成時，使用者資料中的 `cfn-signal` 命令會發出訊號：

```
TestInstance:
  Type: AWS::EC2::Instance
  CreationPolicy:
    ResourceSignal:
      Timeout: PT20M
  Properties:
    # ... other properties ...
```

由於引導程序很小，而且只會建立檔案並啟動服務，因此 `CreationPolicy` 會在逾時前等待 20 分鐘 (PT20M)。使用 ISO 8601 持續時間格式來指定逾時。請注意，Windows 執行個體啟動所需的時間通常比 Linux 執行個體長，因此請進行徹底測試，以確定滿足您需求的最佳逾時值。

如果一切順利，`CreationPolicy` 會成功完成，而且您可以使用執行個體的公有 IP 位址來存取 Windows Server 執行個體。堆疊建立完成後，執行個體 ID 和公有 IP 位址將顯示在 CloudFormation 主控台的**輸出**標籤中。

```
Outputs:
  InstanceId:
    Value: !Ref TestInstance
    Description: Instance ID of the Windows Server
  PublicIP:
    Value: !GetAtt TestInstance.PublicIp
    Description: Public IP address of the Windows Server
```

也可以手動驗證引導是否正常運作，方法是透過 RDP 連線至執行個體，並檢查檔案 `C:\cfn\test.txt` 是否存在並包含預期的內容。如需有關連線至 Windows 執行個體的詳細資訊，請參閱《Amazon EC2 使用者指南》中的[使用 RDP 連線至 Windows 執行個體](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connecting_to_windows_instance.html)。**

## Windows 檔案路徑中的轉義反斜線
<a name="cfn-windows-stacks-escape-backslashes"></a>

在 CloudFormation 範本中參考 Windows 路徑時，請務必記得根據您使用的範本格式正確轉義反斜線 (`\`)。
+ 對於 JSON 範本，必須在 Windows 檔案路徑中使用雙反斜線，因為 JSON 會將反斜線視為轉義字元。第一個反斜線會轉義第二個斜線，導致解譯單一常值反斜線。

  ```
  "commands" : {
    "1-extract" : {
      "command" : "C:\\SharePoint\\SharePointFoundation2010.exe /extract:C:\\SharePoint\\SPF2010 /quiet /log:C:\\SharePoint\\SharePointFoundation2010-extract.log"
    }
  }
  ```
+ 對於 YAML 範本，單一反斜線通常就足夠。

  ```
  commands:
    1-extract:
      command: C:\SharePoint\SharePointFoundation2010.exe /extract:C:\SharePoint\SPF2010 /quiet /log:C:\SharePoint\SharePointFoundation2010-extract.log
  ```

## 管理 Windows 服務
<a name="cfn-windows-stacks-manage-windows-services"></a>

您管理 Windows 服務的方式與管理 Linux 服務的方式相同，但使用的是 `windows` 鍵而非 `sysvinit`。下列範例會啟動 `cfn-hup` 服務，並將其設為「自動」，如果 `cfn-init` 修改 `c:\cfn\cfn-hup.conf` 或 `c:\cfn\hooks.d\cfn-auto-reloader.conf` 組態檔案，則會重新啟動服務。

```
        services:
          windows:
            cfn-hup:
              enabled: true
              ensureRunning: true
              files:
                - c:\cfn\cfn-hup.conf
                - c:\cfn\hooks.d\cfn-auto-reloader.conf
```

可以使用該名稱而非顯示名稱來參考服務，以相同的方式管理其他 Windows 服務。

## 疑難排解堆疊建立問題
<a name="cfn-windows-stacks-troubleshooting"></a>

如果堆疊在建立期間失敗，預設行為是復原故障。雖然這樣的預設行為一般而言是好的，因其可避免不必要的額外費用，但卻會對堆疊建立失敗原因進行除錯時造成困難。

若要在使用 CloudFormation 主控台建立或更新堆疊時關閉此行為，請選擇**堆疊失敗選項**下的**保留成功佈建的資源**選項。如需詳細資訊，請參閱[選擇佈建資源時的失敗處理方式](stack-failure-options.md)。這可讓您登入執行個體並檢視日誌檔案，以找出執行啟動指令碼時發生的問題。

要查看的重要日誌如下：
+ EC2 組態日誌，位於 `%ProgramData%\Amazon\EC2Launch\log\agent.log`
+ `C:\cfn\log\cfn-init.log` 中的 **cfn-init** 日誌 (檢查特定故障點的結束代碼和錯誤訊息)

如需更多日誌，請參閱《Amazon EC2 使用者指南》**中的下列主題：
+ [EC2Launch 目錄結構](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2config-service.html#UsingConfigXML_WinAMI)
+ [EC2Launch v2 目錄結構](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2launch-v2.html#ec2launch-v2-directory)

如需有關對引導問題進行疑難排解的詳細資訊，請參閱[如何使用 Windows 執行個體對 CloudFormation 堆疊中不會引導的協助程式指令碼進行疑難排解？](https://repost.aws/knowledge-center/cloudformation-helper-scripts-windows)。

# 使用 CloudFormation 提供的資源類型來擴展範本的功能
<a name="cloudformation-supplied-resource-types"></a>

CloudFormation 提供數種可在堆疊範本中使用的資源類型來擴展其功能，從而超越簡單的堆疊範本功能。

這些資源類型包括：


| Resource Type (資源類型) | Description | 文件 | 
| --- | --- | --- | 
|  自訂資源  |  `AWS::CloudFormation::CustomResource` 資源類型可讓您建立自訂資源，以執行特定佈建任務，或包含無法作為 CloudFormation 資源類型使用的資源。  |  [自訂資源](template-custom-resources.md) | 
|  巨集  |  `AWS::CloudFormation::Macro` 資源類型會定義可重複使用的程式碼片段，可在 CloudFormation 範本上執行自訂處理。巨集可以在堆疊建立或更新期間修改範本、產生其他資源或執行其他自訂操作。  | [範本巨集](template-macros.md) | 
|  巢狀堆疊  |  `AWS::CloudFormation::Stack` 資源類型可讓您在 CloudFormation 範本內建立巢狀堆疊，以取得更加模組化且可重複使用的堆疊架構。  | [巢狀堆疊](using-cfn-nested-stacks.md) | 
|  StackSet  |  `AWS::CloudFormation::StackSet` 資源類型會建立或更新 CloudFormation StackSet，這是堆疊的容器，可跨多個 AWS 帳戶 和 區域部署。  | [透過 StackSets 管理堆疊](what-is-cfnstacksets.md) | 
|  等待條件  |  `AWS::CloudFormation::WaitCondition` 資源類型會暫停堆疊建立或更新，直到符合特定條件為止，例如成功完成長時間執行的程序或外部資源的可用性。  | [等待條件](using-cfn-waitcondition.md) | 
|  等待條件控點  |  `AWS::CloudFormation::WaitConditionHandle` 資源類型可與 `AWS::CloudFormation::WaitCondition` 資源類型搭配使用。它提供預先簽章的 URL，用於傳送訊號，指出已滿足特定條件。這些訊號可讓堆疊建立或更新程序繼續進行。  | [等待條件](using-cfn-waitcondition.md) | 

# 使用自訂資源建立自訂佈建邏輯
<a name="template-custom-resources"></a>

自訂資源可讓您能在 CloudFormation 範本中撰寫自訂佈建邏輯，讓 CloudFormation 可在您建立、更新 (若您變更自訂資源) 或刪除堆疊時隨時執行。當您的佈建需求涉及無法以 CloudFormation 內建資源類型表示的複雜邏輯或工作流程時，這會很實用。

例如，您可能會希望包含無法做為 CloudFormation 資源類型使用的資源。您可以使用自訂資源包含那些資源。以此方式，您仍然可以在單一堆疊中管理所有相關資源。

在 CloudFormation 範本中，您可以使用 `AWS::CloudFormation::CustomResource` 或 `Custom::MyCustomResourceTypeName` 資源類型來定義自訂資源。自訂資源需要一個屬性：服務字符，指定 CloudFormation 傳送請求的目的地，例如 Amazon SNS 主題或 Lambda 函式。

下列主題提供有關如何使用自訂資源的資訊：

**Topics**
+ [自訂資源的運作方式](#how-custom-resources-work)
+ [回應逾時](#response-timeout)
+ [CloudFormation 自訂資源請求和回應參考](crpg-ref.md)
+ [Amazon SNS 支援的自訂資源](template-custom-resources-sns.md)
+ [Lambda 後端自訂資源](template-custom-resources-lambda.md)

**注意**  
CloudFormation 登錄檔與自訂資源各有其優點。自訂資源提供下列優點：  
您無需註冊資源。
您可在範本中包含整個資源，而無需註冊。
支援 `Create`、`Update` 和 `Delete` 操作
登錄檔型資源所提供的優點包括如下：  
支援建模、佈建和管理第三方應用程式資源
支援 `Create`、`Read`、`Update` `Delete`、和 `List` (`CRUDL`) 操作
支援私有和第三方資源類型的偏移偵測
與自訂資源不同，以登錄為基礎的資源不需要關聯 Amazon SNS 主題或 Lambda 函數來執行 `CRUDL` 操作。如需詳細資訊，請參閱[使用 CloudFormation 登錄檔管理擴充功能](registry.md)。

## 自訂資源的運作方式
<a name="how-custom-resources-work"></a>

設定新自訂資源的一般程序包括下列步驟。這些步驟涉及兩個角色：擁有自訂資源的*自訂資源提供者*，以及建立包含自訂資源類型範本的*開發人員*。這可以是同一個人，但若不是，自訂資源提供者應與範本開發人員協作。

1. 自訂資源提供者會撰寫邏輯，用於決定如何處理來自 CloudFormation 的請求，以及對自訂資源執行相應操作。

1. 自訂資源提供者會建立 Amazon SNS 主題或 Lambda 函式，供 CloudFormation 傳送請求。Amazon SNS 主題或 Lambda 函式必須位於即將建立堆疊的同一區域。

1. 自訂資源提供者會將 Amazon SNS 主題 ARN 或 Lambda 函式 ARN 提供給範本開發人員。

1. 範本開發人員在 CloudFormation 範本中定義自訂資源。其中包含服務字符和任何輸入資料參數。輸入資料的服務字符和結構由自訂資源提供者定義。服務字符會指定 Amazon SNS 主題 ARN 或 Lambda 函式 ARN，且為必要項目，但輸入資料是否需要則取決於自訂資源。

現在，每當任何人使用範本來建立、更新或刪除自訂資源時，CloudFormation 都會向指定的服務字符傳送請求，並等待回應後再繼續執行堆疊操作。

以下是從範本建立堆疊的流程總結：

1. CloudFormation 向指定的服務字符傳送請求。請求包含請求類型和預先簽章的 Amazon S3 儲存貯體 URL 等資訊，自訂資源會將回應傳送到其中。如需請求中包含項目的詳細資訊，請參閱 [CloudFormation 自訂資源請求和回應參考](crpg-ref.md)。

   以下範例資料顯示 CloudFormation 在 `Create` 請求中包含的項目：在此範例中，`ResourceProperties` 可讓 CloudFormation 建立自訂承載，以傳送至 Lambda 函式。

   ```
   {
      "RequestType" : "Create",
      "RequestId" : "unique id for this create request",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::TestResource",
      "LogicalResourceId" : "MyTestResource",
      "ResourceProperties" : {
         "Name" : "Value",
         "List" : [ "1", "2", "3" ]
      }
   }
   ```

1. 自訂資源提供者會處理 CloudFormation 請求，並將 `SUCCESS` 或 `FAILED` 的回應傳送至預先簽章的 URL。custom resource provider 會以 JSON 格式檔案提供回應，並上傳至預先簽章的 S3 URL。如需詳細資訊，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[使用預先簽章的 URL 上傳物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html)。

   在回應中，自訂資源提供者也可包含範本開發人員可存取的名稱值對。例如，若請求成功，回應可包含輸出資料，或是若請求失敗，則包含錯誤訊息。如需回應的詳細資訊，請參閱 [CloudFormation 自訂資源請求和回應參考](crpg-ref.md)。
**重要**  
如果名稱值對包含敏感資訊，您應該使用 `NoEcho` 欄位來遮罩自訂資源的輸出。否則，這些值可透過表示屬性值 (例如 `DescribeStackEvents`) 的 API 可見。  
如需使用 `NoEcho` 遮罩敏感資訊的詳細資訊，請參閱 [請勿在您的範本中內嵌憑證](security-best-practices.md#creds) 最佳實務。

   custom resource provider 負責接聽和回應請求。例如，針對 Amazon SNS 通知，自訂資源提供者必須接聽和回應傳送到特定主題 ARN 的通知。CloudFormation 會在預先簽章的 URL 位置等待並接聽回應。

   以下範例資料顯示回應中可能包含的自訂資源：

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique id for this create request",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MyTestResource",
      "PhysicalResourceId" : "TestResource1",
      "Data" : {
         "OutputName1" : "Value1",
         "OutputName2" : "Value2",
      }
   }
   ```

1. 在取得 `SUCCESS` 回應後，CloudFormation 便會繼續堆疊操作。若傳回 `FAILED` 回應或沒有任何回應，則操作便會失敗。任何來自自訂資源的輸出資料都會存放在預先簽章的 URL 位置。範本開發人員可使用 [Fn::GetAtt](resources-section-structure.md#resource-properties-getatt) 函數擷取該資料。

**注意**  
如果您使用 AWS PrivateLink，VPC 中的自訂資源必須能夠存取 CloudFormation 特定的 S3 儲存貯體。自訂資源必須傳送回應至預先簽章的 Amazon S3 URL。若無法將回應傳送至 Amazon S3，CloudFormation 便不會收到回應，而堆疊操作則會失敗。如需詳細資訊，請參閱[CloudFormation 使用界面端點存取 (AWS PrivateLink)](vpc-interface-endpoints.md)。

## 回應逾時
<a name="response-timeout"></a>

自訂資源的預設逾時為 3600 秒 (1 小時)。如果在這段時間內沒有收到任何回應，堆疊操作就會失敗。

您可根據預期自訂資源傳回回應的時間，調整逾時數值。例如，若佈建的自訂資源會調用預期在五分鐘內回應的 Lambda 函式，您可在堆疊範本中透過指定 `ServiceTimeout` 屬性，將逾時時間設定為五分鐘。如需詳細資訊，請參閱[CloudFormation 自訂資源請求和回應參考](crpg-ref.md)。如此一來，若 Lambda 函式發生錯誤導致卡住，CloudFormation 會在五分鐘後使堆疊操作失敗，而非等待完整的一小時。

但請注意，勿將逾時數值設定過低。為避免非預期的逾時，請確保您的自訂資源有足夠時間執行必要動作並傳回回應。

# CloudFormation 自訂資源請求和回應參考
<a name="crpg-ref"></a>

CloudFormation 透過與您的自訂資源提供者通訊的請求回應通訊協定來管理自訂資源。每個請求都包含請求類型 (`Create`、 或 `Delete`)`Update`，並遵循此高階工作流程：

1. 範本開發人員在範本`ServiceTimeout`中定義具有 `ServiceToken`和 的自訂資源，並啟動堆疊操作。

1. CloudFormation 透過 SNS 或 Lambda 將 JSON 請求傳送至自訂資源提供者。

1. 自訂資源提供者會處理請求，並在逾時期間到期之前，將 JSON 回應傳回預先簽章的 Amazon S3 儲存貯體 URL。

1. CloudFormation 會讀取回應並繼續堆疊操作。如果在逾時期間結束前未收到任何回應，請求會被視為失敗，且堆疊操作會失敗。

如需詳細資訊，請參閱[自訂資源的運作方式](template-custom-resources.md#how-custom-resources-work)。

本節說明每個請求類型的結構、參數和預期回應。

**注意**  
回應內文的總大小不能超過 4096 個位元組。

## 範本設定
<a name="crpg-ref-template-setup"></a>

在範本中定義自訂資源時，範本開發人員會使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html)搭配下列屬性：

`ServiceToken`  
Amazon SNS 主題 ARN 或 Lambda 函數 ARN，來自與堆疊相同的區域。  
*必要*：是  
*類型：*字串

`ServiceTimeout`  
自訂資源操作逾時之前的時間上限，以秒為單位。它必須是介於 1 到 3600 之間的值。預設：3600 秒 (1 小時）。  
*必要*：否  
*類型：*字串

支援其他資源屬性。資源屬性將做為 包含在請求`ResourceProperties`中。自訂資源提供者必須判斷哪些屬性有效及其可接受的值。

## 請求物件
<a name="crpg-ref-requesttypes"></a>

------
#### [ Create ]

當範本開發人員建立包含自訂資源的堆疊時，CloudFormation 會傳送將 `RequestType` 設定為 的請求`Create`。

建立包含以下欄位的請求：

`RequestType`  
`Create`.  
*必要*：是  
*類型：*字串

`RequestId`  
請求的唯一 ID。  
結合 `StackId` 與 `RequestId` 形成值，該值可用於唯一識別特定自訂資源上的請求。  
*必要*：是  
*類型：*字串

`StackId`  
識別包含自訂資源之堆疊的 Amazon Resource Name (ARN)。  
結合 `StackId` 與 `RequestId` 形成值，該值可用於唯一識別特定自訂資源上的請求。  
*必要*：是  
*類型：*字串

`ResponseURL`  
回應 URL 會識別預先簽章的 S3 儲存貯體，該儲存貯體會從自訂資源提供者接收對 CloudFormation 的回應。  
*必要*：是  
*類型：*字串

`ResourceType`  
CloudFormation 範本內由範本開發人員選擇之自訂資源的資源類型。自訂資源類型名稱的長度上限為 60 個字元，且可包含英數字元及以下字元：`_@-`。  
*必要*：是  
*類型：*字串

`LogicalResourceId`  
CloudFormation 範本中自訂資源的範本開發人員選擇名稱 （邏輯 ID)。  
*必要*：是  
*類型：*字串

`ResourceProperties`  
此欄位包含由範本開發人員傳送的 `Properties` 物件內容。其內容由自訂資源提供者定義。  
*必要*：否  
*類型*：JSON 物件

*範例*

```
{
   "RequestType" : "Create",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-create-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "ResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------
#### [ Update ]

當範本開發人員變更範本中自訂資源的屬性並更新堆疊時，CloudFormation 會將請求傳送至自訂資源提供者，並將 `RequestType` 設定為 `Update`。這表示您的自訂資源程式碼不需要偵測資源的變更，因為它知道其屬性在請求類型為 `Update` 時已變更。

更新包含以下欄位的請求：

`RequestType`  
`Update`.  
*必要*：是  
*類型：*字串

`RequestId`  
請求的唯一 ID。  
結合 `StackId` 與 `RequestId` 形成值，該值可用於唯一識別特定自訂資源上的請求。  
*必要*：是  
*類型：*字串

`StackId`  
識別包含自訂資源之堆疊的 Amazon Resource Name (ARN)。  
結合 `StackId` 與 `RequestId` 形成值，該值可用於唯一識別特定自訂資源上的請求。  
*必要*：是  
*類型：*字串

`ResponseURL`  
回應 URL 會識別預先簽章的 S3 儲存貯體，該儲存貯體會從自訂資源提供者接收對 CloudFormation 的回應。  
*必要*：是  
*類型：*字串

`ResourceType`  
CloudFormation 範本內由範本開發人員選擇之自訂資源的資源類型。自訂資源類型名稱的長度上限為 60 個字元，且可包含英數字元及以下字元：`_@-`。您無法於更新期間變更類型。  
*必要*：是  
*類型：*字串

`LogicalResourceId`  
CloudFormation 範本中自訂資源的範本開發人員選擇名稱 （邏輯 ID)。  
*必要*：是  
*類型：*字串

`PhysicalResourceId`  
自訂資源提供者定義的實體 ID，對於該提供者是唯一的。  
*必要*：是  
*類型：*字串

`ResourceProperties`  
此欄位包含由範本開發人員傳送的 `Properties` 物件內容。其內容由自訂資源提供者定義。  
*必要*：否  
*類型*：JSON 物件

`OldResourceProperties`  
僅用於 `Update` 請求。範本開發人員之前在 CloudFormation 範本中宣告的資源屬性值。  
*必要*：是  
*類型*：JSON 物件

*範例*

```
{
   "RequestType" : "Update",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-update-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "PhysicalResourceId" : "provider-defined-physical-id",
   "ResourceProperties" : {
      "key1" : "new-string",
      "key2" : [ "new-list" ],
      "key3" : { "key4" : "new-map" }
   },
   "OldResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------
#### [ Delete ]

當範本開發人員刪除堆疊或從範本中移除自訂資源，然後更新堆疊時，CloudFormation 會傳送將 `RequestType` 設定為 的請求`Delete`。

刪除包含以下欄位的請求：

`RequestType`  
`Delete`.  
*必要*：是  
*類型：*字串

`RequestId`  
請求的唯一 ID。  
*必要*：是  
*類型：*字串

`StackId`  
識別包含自訂資源之堆疊的 Amazon Resource Name (ARN)。  
*必要*：是  
*類型：*字串

`ResponseURL`  
回應 URL 會識別預先簽章的 S3 儲存貯體，該儲存貯體會從自訂資源提供者接收對 CloudFormation 的回應。  
*必要*：是  
*類型：*字串

`ResourceType`  
CloudFormation 範本內由範本開發人員選擇之自訂資源的資源類型。自訂資源類型名稱的長度上限為 60 個字元，且可包含英數字元及以下字元：`_@-`。  
*必要*：是  
*類型：*字串

`LogicalResourceId`  
CloudFormation 範本中自訂資源的範本開發人員選擇名稱 （邏輯 ID)。  
*必要*：是  
*類型：*字串

`PhysicalResourceId`  
自訂資源提供者定義的實體 ID，對於該提供者是唯一的。  
*必要*：是  
*類型：*字串

`ResourceProperties`  
此欄位包含由範本開發人員傳送的 `Properties` 物件內容。其內容由自訂資源提供者定義。  
*必要*：否  
*類型*：JSON 物件

*範例*

```
{
   "RequestType" : "Delete",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-delete-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "PhysicalResourceId" : "provider-defined-physical-id",
   "ResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------

## 回應物件
<a name="crpg-ref-responses"></a>

自訂資源提供者會將回應傳送至所有請求類型的預先簽章 URL。如果自訂資源提供者未傳送回應，CloudFormation 會等到操作逾時。

回應必須是具有下列欄位的 JSON 物件：

`Status`  
必須為 `SUCCESS` 或 `FAILED`。  
*必要*：是  
*類型：*字串

`RequestId`  
請求的唯一 ID。複製此值與請求中顯示的完全相同。  
*必要*：是  
*類型：*字串

`StackId`  
識別包含自訂資源之堆疊的 Amazon Resource Name (ARN)。複製此值與請求中顯示的完全相同。  
*必要*：是  
*類型：*字串

`LogicalResourceId`  
CloudFormation 範本中自訂資源的範本開發人員選擇名稱 （邏輯 ID)。複製此值與請求中顯示的完全相同。  
*必要*：是  
*類型：*字串

`PhysicalResourceId`  
此值應為自訂資源廠商的唯一識別碼，且大小上限為 1 KB。此值必須是非空白字串，並且對於相同資源的所有回應必須完全相同。  
更新自訂資源時， 傳回的值會`PhysicalResourceId`決定更新行為。如果值保持不變，CloudFormation 會將其視為正常更新。如果值變更，CloudFormation 會將更新解譯為取代，並將刪除請求傳送至舊資源。如需詳細資訊，請參閱[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html)。  
*必要*：是  
*類型：*字串

`Reason`  
描述失敗回應的原因。  
在 `Status` 為 `FAILED` 時需要。否則為選用。  
*必要*：有條件  
*類型：*字串

`NoEcho`  
指示使用 `Fn::GetAtt` 函數擷取自訂資源時是否要遮罩其輸出。如果設定為 `true`，則所有傳回的值都會以星號 (\$1\$1\$1\$1\$1) 遮罩，*但儲存在範本 `Metadata` 區段中的值除外*。CloudFormation 不會轉換、修改或標記您在 `Metadata` 區段中包含的任何資訊。預設值為 `false`。  
如需使用 `NoEcho` 遮罩敏感資訊的詳細資訊，請參閱 [請勿在您的範本中內嵌憑證](security-best-practices.md#creds) 最佳實務。  
僅適用於 `Create`和 `Update`回應。不支援`Delete`回應。  
*必要*：否  
*類型*：布林值

`Data`  
要與回應一起傳送的自訂資源提供者定義之名稱值對。您可以在模板中透過 `Fn::GetAtt` 依名稱存取此處提供的值。  
僅適用於 `Create`和 `Update`回應。不支援`Delete`回應。  
如果名稱值對包含敏感資訊，您應該使用 `NoEcho` 欄位來遮罩自訂資源的輸出。否則，這些值可透過表示屬性值 (例如 `DescribeStackEvents`) 的 API 可見。
*必要*：否  
*類型*：JSON 物件

### 成功回應範例
<a name="crpg-ref-success-response-examples"></a>

#### `Create` 和 `Update` 回應
<a name="crpg-ref-success-response-example-1"></a>

```
{
   "Status": "SUCCESS",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id", 
   "PhysicalResourceId": "provider-defined-physical-id",
   "NoEcho": true,
   "Data": {
      "key1": "value1",
      "key2": "value2"
   }
}
```

#### `Delete` 回應
<a name="crpg-ref-success-response-example-2"></a>

```
{
   "Status": "SUCCESS",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id", 
   "PhysicalResourceId": "provider-defined-physical-id"
}
```

### 失敗的回應範例
<a name="crpg-ref-failed-response-example"></a>

```
{
   "Status": "FAILED",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id",
   "PhysicalResourceId": "provider-defined-physical-id",
   "Reason": "Required failure reason string"
}
```

# Amazon SNS 支援的自訂資源
<a name="template-custom-resources-sns"></a>

本主題說明如何為自訂資源設定服務字符，該服務字符會指定 CloudFormation 傳送請求的 Amazon SNS 主題。您也會了解自訂資源堆疊建立、更新和刪除所產生的事件順序，以及傳送和接收的訊息。

您可以使用自訂資源和 Amazon SNS 來啟用案例，例如將新資源新增至堆疊，並將動態資料插入堆疊。例如，當您建立堆疊時，CloudFormation 可以將 `Create` 請求傳送到應用程式 (執行於 Amazon EC2 執行個體上) 監控的主題。Amazon SNS 通知會觸發應用程式執行額外的佈建任務，例如擷取列入允許清單的彈性 IP 地址集區。完成之後，應用程式會傳送回應 (以及任何輸出資料)，以通知 CloudFormation 繼續堆疊操作。

若您指定 Amazon SNS 主題作為自訂資源的目標，CloudFormation 會在涉及該自訂資源的堆疊操作期間，向指定的 SNS 主題傳送訊息。若要處理這些訊息並執行必要的操作，您必須有支援的端點訂閱該 SNS 主題。

有關自訂資源的簡介及其運作方式，請參閱 [自訂資源的運作方式](template-custom-resources.md#how-custom-resources-work)。如需 Amazon SNS 及其運作方式的資訊，請參閱 [Amazon Simple Notification Service 開發人員指南](https://docs.aws.amazon.com/sns/latest/dg/)。

## 使用 Amazon SNS 建立自訂資源
<a name="walkthrough-custom-resources-sns-adding-nonaws-resource"></a>

**Topics**
+ [步驟 1：建立堆疊](#crpg-walkthrough-stack-creation)
+ [步驟 2：更新堆疊](#crpg-walkthrough-stack-updates)
+ [步驟 3：刪除堆疊](#crpg-walkthrough-stack-deletion)

### 步驟 1：建立堆疊
<a name="crpg-walkthrough-stack-creation"></a>

1. <a name="crpg-walkthrough-stack-creation-customer-template"></a>範本開發人員會建立包含自訂資源的 CloudFormation 堆疊。

   下列範例範本中，我們為邏輯 ID 為 `MySeleniumTest` 的自訂資源使用自訂資源類型名稱 `Custom::SeleniumTester`。自訂資源類型名稱必須是英數字元，長度上限為 60 個字元。

   自訂資源類型的宣告是使用服務字符、選用的提供者特定屬性，以及選用的 [Fn::GetAtt](resources-section-structure.md#resource-properties-getatt) 屬性 (由自訂資源提供者定義)。這些屬性可用來將資訊從範本開發人員傳遞到自訂資源提供者 (反之亦然)。服務字符會指定資源提供者已設定的 Amazon SNS 主題。

   ```
   {
      "AWSTemplateFormatVersion" : "2010-09-09",
      "Resources" : {
         "MySeleniumTest" : {
            "Type": "Custom::SeleniumTester",
            "Version" : "1.0",
            "Properties" : {
               "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest",
               "seleniumTester" : "SeleniumTest()",
               "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
               "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
            }
         }
      },
      "Outputs" : {
         "topItem" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
         },
         "numRespondents" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
         }
      }
   }
   ```
**注意**  
在提供者回應 CloudFormation 期間，自訂資源提供者會傳回以 `Fn::GetAtt` 存取的資料名稱和值。如果custom resource provider是第三方，則範本開發人員必須從自訂資源提供者取得這些傳回值的名稱。

1. <a name="crpg-walkthrough-stack-creation-provider-request"></a>CloudFormation 會使用 `"RequestType" : "Create"` 將 Amazon SNS 通知傳送給資源提供者，其中包含堆疊的相關資訊、堆疊範本的自訂資源屬性，以及回應的 S3 URL。

   `ServiceToken` 屬性中的範本內嵌了用來傳送通知的 SNS 主題。為避免使用硬式編碼的值，範本開發人員可以使用範本參數，在啟動堆疊時輸入值。

   以下範例顯示自訂資源 `Create` 請求，其中包括使用 `Custom::SeleniumTester` 的 `LogicalResourceId` 所建立的自訂資源類型名稱 `MySeleniumTester`：

   ```
   {
      "RequestType" : "Create",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
      }
   }
   ```

   如需 `Create` 請求之請求物件的詳細資訊，請參閱 [請求和回應參考](crpg-ref.md)主題。

1. <a name="crpg-walkthrough-stack-creation-provider-response"></a>自訂資源提供者會處理範本開發人員傳送的資料，並判斷 `Create` 請求是否成功。接著，資源提供者會使用 CloudFormation 傳送的 S3 URL 來傳送 `SUCCESS` 或 `FAILED` 的回應。

   CloudFormation 預期的回應欄位根據回應類型而異。如需特定請求類型的回應欄位資訊，請參閱 [請求和回應參考](crpg-ref.md) 區段中該請求類型的文件。

   在回應建立或更新請求時，自訂資源提供者可傳回回應 `Data` 欄位中的資料元素。這些是名稱值對；*名稱*對應至 `Fn::GetAtt` 屬性，其與堆疊範本中的自訂資源搭配使用。*值*是範本開發人員以屬性名稱在資源上呼叫 `Fn::GetAtt` 時傳回的資料。

   以下為自訂資源回應的範例：

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "Data" : {
         "resultsPage" : "http://www.myexampledomain/test-results/guid",
         "lastUpdate" : "2012-11-14T03:30Z"
      }
   }
   ```

   如需 `Create` 請求之回應物件的詳細資訊，請參閱 [請求和回應參考](crpg-ref.md)主題。

   `StackId`、`RequestId` 以及 `LogicalResourceId` 欄位必須從請求逐字複製。

1. <a name="crpg-walkthrough-stack-creation-stack-status"></a> CloudFormation 會將堆疊狀態宣告為 `CREATE_COMPLETE` 或 `CREATE_FAILED`。如果已成功建立堆疊，範本開發人員可透過 [Fn::GetAtt](resources-section-structure.md#resource-properties-getatt) 來存取利用所建立自訂資源的輸出值。

   例如，示範的自訂資源範本會使用 `Fn::GetAtt` 將資源輸出複製到堆疊輸出中：

   ```
   "Outputs" : {
      "topItem" : {
         "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
      },
      "numRespondents" : {
         "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
      }
   }
   ```

### 步驟 2：更新堆疊
<a name="crpg-walkthrough-stack-updates"></a>

若要更新現有堆疊，您必須提交範本以指定堆疊中的資源屬性更新，如以下範例所示。CloudFormation 只會更新含範本中指定變更的資源。如需詳細資訊，請參閱[了解更新堆疊資源的行為](using-cfn-updating-stacks-update-behaviors.md)。

您可以更新需要替換基礎實體資源的自訂資源。當您更新 CloudFormation 範本中的自訂資源時，CloudFormation 會將更新請求傳送給該自訂資源。若需替換自訂資源，新的自訂資源必須以新的實體 ID 傳送回應。CloudFormation 接收回應時，會比較新舊自訂資源的 `PhysicalResourceId`。如果不同，CloudFormation 會將更新視為取代，並將刪除請求傳送到舊資源，如[步驟 3：刪除堆疊](#crpg-walkthrough-stack-deletion)所示。

**注意**  
如果您未變更自訂資源，CloudFormation 就不會在堆疊更新期間傳送請求給自訂資源。

1. <a name="crpg-walkthrough-stack-updates-customer-template"></a>範本開發人員可啟動包含自訂資源的堆疊更新。在更新期間，範本開發人員可以指定堆疊範本中的新 Properties (屬性)。

   以下是使用自訂資源類型的堆疊範本 `Update` 範例：

   ```
   {
      "AWSTemplateFormatVersion" : "2010-09-09",
      "Resources" : {
         "MySeleniumTest" : {
            "Type": "Custom::SeleniumTester",
            "Version" : "1.0",
            "Properties" : {
               "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest",
               "seleniumTester" : "SeleniumTest()",
               "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
                  "http://mynewsite.com" ],
               "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
            }
         }
      },
      "Outputs" : {
         "topItem" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
         },
         "numRespondents" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
         }
      }
   }
   ```

1. <a name="crpg-walkthrough-stack-updates-provider-request"></a>CloudFormation 會使用 `"RequestType" : "Update"` 將 Amazon SNS 通知傳送給資源提供者，其中包含類似於 `Create` 呼叫的資訊，差別在於 `OldResourceProperties` 欄位包含舊資源屬性，而 ResourceProperties 包含更新的資源屬性 (如果有)。

   以下是 `Update` 請求範例：

   ```
   {
      "RequestType" : "Update",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
            "http://mynewsite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
      },
      "OldResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
      }
   }
   ```

   如需 `Update` 請求之請求物件的詳細資訊，請參閱 [請求和回應參考](crpg-ref.md)主題。

1. <a name="crpg-walkthrough-stack-updates-provider-response"></a>自訂資源提供者會處理 CloudFormation 傳送的資料。自訂資源會執行更新並傳送 `SUCCESS` 或 `FAILED` 的回應給 S3 URL。然後，CloudFormation 會比較新舊自訂資源的 `PhysicalResourceIDs`。若其不同，CloudFormation 會將該更新視為需要替換，並傳送刪除請求給舊資源。以下範例示範custom resource provider對 `Update` 請求的回應。

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester2"
   }
   ```

   如需 `Update` 請求之回應物件的詳細資訊，請參閱 [請求和回應參考](crpg-ref.md)主題。

   `StackId`、`RequestId` 以及 `LogicalResourceId` 欄位必須從請求逐字複製。

1. <a name="crpg-walkthrough-stack-updates-stack-status"></a>CloudFormation 會將堆疊狀態宣告為 `UPDATE_COMPLETE` 或 `UPDATE_FAILED`。如果更新失敗，即會復原堆疊。如果已成功更新堆疊，範本開發人員即可使用 `Fn::GetAtt` 來存取已建立之自訂資源的任何新輸出值。

### 步驟 3：刪除堆疊
<a name="crpg-walkthrough-stack-deletion"></a>

1. <a name="crpg-walkthrough-stack-deletion-customer-template"></a>範本開發人員可刪除包含自訂資源的堆疊。CloudFormation 可取得堆疊範本中指定的目前屬性與 SNS 主題，並準備向自訂資源提供者發出請求。

1. <a name="crpg-walkthrough-stack-deletion-provider-request"></a>CloudFormation 會使用 `"RequestType" : "Delete"` 將 Amazon SNS 通知傳送給資源提供者，其中包含堆疊的目前資訊、堆疊範本的自訂資源屬性，以及回應的 S3 URL。

   每當您刪除堆疊，或更新堆疊以移除或取代自訂資源時，CloudFormation 會比較新舊自訂資源的 `PhysicalResourceId`。如果不同，CloudFormation 會將更新視為取代，並針對舊資源 (`OldPhysicalResource`) 傳送刪除請求，如下列 `Delete` 請求範例所示。

   ```
   {
      "RequestType" : "Delete",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
            "http://mynewsite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
      }
   }
   ```

   如需 `Delete` 請求之請求物件的詳細資訊，請參閱 [請求和回應參考](crpg-ref.md)主題。

   `DescribeStackResource`、`DescribeStackResources` 以及 `ListStackResources` 會顯示使用者定義的名稱 (如有指定)。

1. <a name="crpg-walkthrough-stack-deletion-provider-response"></a>自訂資源提供者會處理 CloudFormation 傳送的資料，並判斷 `Delete` 請求是否成功。接著，資源提供者會使用 CloudFormation 傳送的 S3 URL 來傳送 `SUCCESS` 或 `FAILED` 的回應。若要成功刪除含自訂資源的堆疊，custom resource provider 必須成功回應刪除請求。

   以下為 custom resource provider對 `Delete` 請求的回應範例：

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1"
   }
   ```

   如需 `Delete` 請求之回應物件的詳細資訊，請參閱 [請求和回應參考](crpg-ref.md)主題。

   `StackId`、`RequestId` 以及 `LogicalResourceId` 欄位必須從請求逐字複製。

1. <a name="crpg-walkthrough-stack-updates-stack-status-delete"></a>CloudFormation 會將堆疊狀態宣告為 `DELETE_COMPLETE` 或 `DELETE_FAILED`。

# Lambda 後端自訂資源
<a name="template-custom-resources-lambda"></a>

當您將 Lambda 函式與自訂資源建立關聯時，便會在建立、更新或刪除自訂資源時調用函數。CloudFormation 會呼叫 Lambda API 以調用函數，並將所有請求資料 (例如請求類型和資源屬性) 傳遞給函數。Lambda 函式與 CloudFormation 結合使用所帶來的功能和自訂性，可帶來各種使用案例，例如在堆疊建立時動態尋找 AMI ID，或是實作及使用公用程式函數 (例如字串反轉函數)。

有關自訂資源的簡介及其運作方式，請參閱 [自訂資源的運作方式](template-custom-resources.md#how-custom-resources-work)。

**Topics**
+ [逐步解說：使用 Lambda 支援的自訂資源建立延遲機制](walkthrough-lambda-backed-custom-resources.md)
+ [`cfn-response` 模組](cfn-lambda-function-code-cfnresponsemodule.md)

# 逐步解說：使用 Lambda 支援的自訂資源建立延遲機制
<a name="walkthrough-lambda-backed-custom-resources"></a>

此逐步解說展示如何使用範例 CloudFormation 範本來設定和啟動 Lambda 支援的自訂資源。此範本會建立延遲機制，可暫停堆疊部署一段指定時間。當您需要在資源佈建期間刻意加入延遲時，例如等待資源穩定後再建立相依資源，這項功能相當實用。

**注意**  
雖然先前建議 Lambda 後端自訂資源用於擷取 AMI IDs，但現在建議使用 AWS Systems Manager 參數。此方法可讓您的範本更具可重複使用性，且更易於維護。如需詳細資訊，請參閱[從 Systems Manager Parameter Store 取得純文字值](dynamic-references-ssm.md)。

**Topics**
+ [概觀](#walkthrough-lambda-backed-custom-resources-overview)
+ [範例範本](#walkthrough-lambda-backed-custom-resources-sample-template)
+ [範例範本逐步解說](#walkthrough-lambda-backed-custom-resources-sample-template-walkthrough)
+ [先決條件](#walkthrough-lambda-backed-custom-resources-prerequisites)
+ [啟動堆疊](#walkthrough-lambda-backed-custom-resources-createfunction-createstack)
+ [清除資源](#walkthrough-lambda-backed-custom-resources-createfunction-cleanup)
+ [相關資訊](#w2aac11c45b9c24b9c23)

## 概觀
<a name="walkthrough-lambda-backed-custom-resources-overview"></a>

本操作指南使用的堆疊範例範本，會建立一個 Lambda 支援的自訂資源。此自訂資源會在堆疊建立期間加入可設定的延遲 (預設為 60 秒)。僅當自訂資源的屬性被修改時，堆疊更新期間才會發生延遲。

此範本會佈建以下資源：
+ 自訂資源，
+ Lambda 函式，以及
+ 讓 Lambda 將日誌寫入 CloudWatch 的 IAM 角色。

它還定義了兩個輸出：
+ 函數實際等待的時間。
+ 每次執行 Lambda 函式時產生的唯一識別碼。



**注意**  
CloudFormation 是免費服務，但 Lambda 會根據您函數的請求次數和程式碼執行時間收費。如需 Lambda 定價的詳細資訊，請參閱 [AWS Lambda 定價](https://aws.amazon.com/lambda/pricing/)。

## 範例範本
<a name="walkthrough-lambda-backed-custom-resources-sample-template"></a>

以下是具備延遲機制的 Lambda 支援自訂資源範例範本：

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "LambdaExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": { "Service": ["lambda.amazonaws.com"] },
            "Action": ["sts:AssumeRole"]
          }]
        },
        "Path": "/",
        "Policies": [{
          "PolicyName": "AllowLogs",
          "PolicyDocument": {
            "Statement": [{
              "Effect": "Allow",
              "Action": ["logs:*"],
              "Resource": "*"
            }]
          }
        }]
      }
    },
    "CFNWaiter": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Handler": "index.handler",
        "Runtime": "python3.9",
        "Timeout": 900,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] },
        "Code": {
          "ZipFile": { "Fn::Join": ["\n", [
            "from time import sleep",
            "import json",
            "import cfnresponse",
            "import uuid",
            "",
            "def handler(event, context):",
            "  wait_seconds = 0",
            "  id = str(uuid.uuid1())",
            "  if event[\"RequestType\"] in [\"Create\", \"Update\"]:",
            "    wait_seconds = int(event[\"ResourceProperties\"].get(\"ServiceTimeout\", 0))",
            "    sleep(wait_seconds)",
            "  response = {",
            "    \"TimeWaited\": wait_seconds,",
            "    \"Id\": id ",
            "  }",
            "  cfnresponse.send(event, context, cfnresponse.SUCCESS, response, \"Waiter-\"+id)"
          ]]}
        }
      }
    },
    "CFNWaiterCustomResource": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": { "Fn::GetAtt": ["CFNWaiter", "Arn"] },
        "ServiceTimeout": 60
      }
    }
  },
  "Outputs": {
    "TimeWaited": {
      "Value": { "Fn::GetAtt": ["CFNWaiterCustomResource", "TimeWaited"] },
      "Export": { "Name": "TimeWaited" }
    },
    "WaiterId": {
      "Value": { "Fn::GetAtt": ["CFNWaiterCustomResource", "Id"] },
      "Export": { "Name": "WaiterId" }
    }
  }
}
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-yaml"></a>

```
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      Policies:
        - PolicyName: "AllowLogs"
          PolicyDocument:
            Statement:
              - Effect: "Allow"
                Action:
                  - "logs:*"
                Resource: "*"
  CFNWaiter:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Runtime: python3.9 
      Timeout: 900
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile:
          !Sub |
          from time import sleep
          import json
          import cfnresponse
          import uuid
​
          def handler(event, context):
            wait_seconds = 0
            id = str(uuid.uuid1())
            if event["RequestType"] in ["Create", "Update"]:
              wait_seconds = int(event["ResourceProperties"].get("ServiceTimeout", 0))
              sleep(wait_seconds)
            response = {
              "TimeWaited": wait_seconds,
              "Id": id 
            }
            cfnresponse.send(event, context, cfnresponse.SUCCESS, response, "Waiter-"+id)
  CFNWaiterCustomResource:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !GetAtt CFNWaiter.Arn
      ServiceTimeout: 60
Outputs:
  TimeWaited:
    Value: !GetAtt CFNWaiterCustomResource.TimeWaited
    Export:
      Name: TimeWaited
  WaiterId:
    Value: !GetAtt CFNWaiterCustomResource.Id
    Export:
      Name: WaiterId
```

## 範例範本逐步解說
<a name="walkthrough-lambda-backed-custom-resources-sample-template-walkthrough"></a>

以下程式碼片段將說明範例範本的相關部分，協助您了解 Lambda 函式如何與自訂資源相關聯，並了解其輸出。

[AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) 資源 `CFNWaiter`  
`AWS::Lambda::Function` 資源會指定函式的原始程式碼、處理常式名稱、執行時期環境，以及執行角色的 Amazon Resource Name (ARN)。  
由於使用 Python 原始程式碼，因此 `Handler` 屬性設定為 `index.handler`。如需有關使用內嵌函數原始程式碼時可接受處理常式識別碼的詳細資訊，請參閱 [ AWS::Lambda::Function Code](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html#cfn-lambda-function-code-zipfile)。  
由於原始檔是 Python 程式碼，`Runtime` 指定為 `python3.9`。  
`Timeout` 設定為 900 秒。  
`Role` 屬性會使用 `Fn::GetAtt` 函數來擷取範本中 `AWS::IAM::Role` 資源所宣告的 `LambdaExecutionRole` 執行角色 ARN。  
`Code` 屬性會使用 Python 函數來內嵌定義函數程式碼。範例範本中的 Python 函式會執行下列動作：  
+ 使用 UUID 建立唯一 ID
+ 檢查請求是建立請求還是更新請求
+ 在 `Create` 或 `Update` 請求期間為 `ServiceTimeout` 指定的持續時間休眠
+ 傳回等待時間及唯一 ID

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-lambda-resource-json"></a>

```
...
    "CFNWaiter": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Handler": "index.handler",
        "Runtime": "python3.9",
        "Timeout": 900,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] },
        "Code": {
          "ZipFile": { "Fn::Join": ["\n", [
            "from time import sleep",
            "import json",
            "import cfnresponse",
            "import uuid",
            "",
            "def handler(event, context):",
            "  wait_seconds = 0",
            "  id = str(uuid.uuid1())",
            "  if event[\"RequestType\"] in [\"Create\", \"Update\"]:",
            "    wait_seconds = int(event[\"ResourceProperties\"].get(\"ServiceTimeout\", 0))",
            "    sleep(wait_seconds)",
            "  response = {",
            "    \"TimeWaited\": wait_seconds,",
            "    \"Id\": id ",
            "  }",
            "  cfnresponse.send(event, context, cfnresponse.SUCCESS, response, \"Waiter-\"+id)"
          ]]}
        }
      }
    },
...
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-lambda-resource-yaml"></a>

```
...
  CFNWaiter:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Runtime: python3.9 
      Timeout: 900
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile:
          !Sub |
          from time import sleep
          import json
          import cfnresponse
          import uuid
​
          def handler(event, context):
            wait_seconds = 0
            id = str(uuid.uuid1())
            if event["RequestType"] in ["Create", "Update"]:
              wait_seconds = int(event["ResourceProperties"].get("ServiceTimeout", 0))
              sleep(wait_seconds)
            response = {
              "TimeWaited": wait_seconds,
              "Id": id 
            }
            cfnresponse.send(event, context, cfnresponse.SUCCESS, response, "Waiter-"+id)
...
```

[AWS::IAM::Role](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-role.html) 資源 `LambdaExecutionRole`  
`AWS::IAM:Role` 資源會為 Lambda 函式建立執行角色，其中包含允許 Lambda 使用該角色的擔任角色政策。此外，它還包含一個允許存取 CloudWatch Logs 的政策。

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-iam-role-json"></a>

```
...
    "LambdaExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": { "Service": ["lambda.amazonaws.com"] },
            "Action": ["sts:AssumeRole"]
          }]
        },
        "Path": "/",
        "Policies": [{
          "PolicyName": "AllowLogs",
          "PolicyDocument": {
            "Statement": [{
              "Effect": "Allow",
              "Action": ["logs:*"],
              "Resource": "*"
            }]
          }
        }]
      }
    },
...
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-iam-role-yaml"></a>

```
...
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      Policies:
        - PolicyName: "AllowLogs"
          PolicyDocument:
            Statement:
              - Effect: "Allow"
                Action:
                  - "logs:*"
                Resource: "*"
...
```

[AWS::CloudFormation::CustomResource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html) 資源 `CFNWaiterCustomResource`  
自訂資源會透過 `!GetAtt CFNWaiter.Arn`，使用 Lambda 函式的 ARN 與其建立關聯。根據 `ServiceTimeout` 中的設定，它會為建立和更新操作實作 60 秒的等待時間。僅當屬性被修改時，才會在更新操作中調用此資源。

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-custom-resource-json"></a>

```
...
    "CFNWaiterCustomResource": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": { "Fn::GetAtt": ["CFNWaiter", "Arn"] },
        "ServiceTimeout": 60
      }
    }
  },
...
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-custom-resource-yaml"></a>

```
...
  CFNWaiterCustomResource:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !GetAtt CFNWaiter.Arn
      ServiceTimeout: 60
...
```

`Outputs`  
此範本的 `Outputs` 為 `TimeWaited` 和 `WaiterId`。`TimeWaited` 數值會使用 `Fn::GetAtt` 函數，提供等待程式資源實際等待的時間。`WaiterId` 會使用 `Fn::GetAtt` 函數來提供產生並與執行相關聯的唯一 ID。

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-output-json"></a>

```
...
  "Outputs": {
    "TimeWaited": {
      "Value": { "Fn::GetAtt": ["CFNWaiterCustomResource", "TimeWaited"] },
      "Export": { "Name": "TimeWaited" }
    },
    "WaiterId": {
      "Value": { "Fn::GetAtt": ["CFNWaiterCustomResource", "Id"] },
      "Export": { "Name": "WaiterId" }
    }
  }
}
...
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-output-yaml"></a>

```
...
Outputs:
  TimeWaited:
    Value: !GetAtt CFNWaiterCustomResource.TimeWaited
    Export:
      Name: TimeWaited
  WaiterId:
    Value: !GetAtt CFNWaiterCustomResource.Id
    Export:
      Name: WaiterId
...
```

## 先決條件
<a name="walkthrough-lambda-backed-custom-resources-prerequisites"></a>

您必須具備使用所有對應服務 (如 Lambda 和 CloudFormation) 的 IAM 許可。

## 啟動堆疊
<a name="walkthrough-lambda-backed-custom-resources-createfunction-createstack"></a>

**建立堆疊**

1. 從 [範例範本](#walkthrough-lambda-backed-custom-resources-sample-template) 區段尋找您偏好設定的範本 (YAML 或 JSON)，並將其儲存到名為 `samplelambdabackedcustomresource.template` 的機器。

1. 開啟位在 [https://console.aws.amazon.com/cloudformation/](https://console.aws.amazon.com/cloudformation/) 的 CloudFormation​ 主控台。

1. 從**堆疊**頁面的右上角，選擇**建立堆疊**，並選擇**使用新資源 (標準)**。

1. 對於**先決條件 - 準備範本**，選取**選擇現有範本**。

1. 對於**指定範本**下，選擇**上傳範本檔案**，然後選擇**選擇檔案**。

1. 選取您先前儲存的 `samplelambdabackedcustomresource.template` 範本檔案。

1. 選擇**下一步**。

1. 對於**秘密名稱**，輸入 **SampleCustomResourceStack**，然後選擇**下一步**。

1. 在此逐步解說中，您不需要新增標籤或指定進階設定，因此請選擇 **Next (下一步)**。

1. 確定堆疊名稱正確，然後選擇**更新**。

CloudFormation 可能需要幾分鐘的時間來建立您的堆疊。若要監控進度，請檢視堆疊事件。如需詳細資訊，請參閱[在 CloudFormation 主控台中檢視堆疊資訊](cfn-console-view-stack-data-resources.md)。

若堆疊建立成功，則系統會一併建立堆疊中所有資源 (如 Lambda 函式和自訂資源)。您已成功使用 Lambda 函式和自訂資源。

若 Lambda 函式回傳錯誤訊息，則可以在 CloudWatch Logs 的[主控台](https://console.aws.amazon.com/cloudwatch/home#logs:)檢視該函數的日誌。日誌串流名稱即為自訂資源的實體 ID，您能夠檢視堆疊資源以查詢該名稱。如需詳細資訊，請參閱《*Amazon CloudWatch 使用者指南*》中的[檢視日誌資料](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#ViewingLogData)。

## 清除資源
<a name="walkthrough-lambda-backed-custom-resources-createfunction-cleanup"></a>

您可以刪除堆疊以清除建立的所有堆疊資源，便無需為不必要的資源支付費用。

**刪除堆疊**

1. 從 CloudFormation 主控台選擇 **SampleCustomResourceStack** 堆疊。

1. 選擇 **Actions (動作)**，然後選擇 **Delete Stack (刪除堆疊)**。

1. 在確認訊息中，選擇 **Yes, Delete (是，刪除)**。

系統將刪除您建立的所有資源。

現在，您已經了解如何建立並使用 Lambda 支援的自訂資源，即可善用本逐步說明的範例範本和程式碼來建置其他堆疊及函數。

## 相關資訊
<a name="w2aac11c45b9c24b9c23"></a>
+ [CloudFormation 自訂資源參考](crpg-ref.md)
+ [AWS::CloudFormation::CustomResource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html)

# `cfn-response` 模組
<a name="cfn-lambda-function-code-cfnresponsemodule"></a>

在 CloudFormation 範本中，您可以將 Lambda 函式指定為自訂資源的目標。使用 `ZipFile` 屬性來指定[函數的](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html)原始程式碼時，可以載入 `cfn-response` 模組，以將回應從 Lambda 函式傳送至自訂資源。`cfn-response` 模組是一個程式庫，可簡化將回應傳送至調用 Lambda 函式的自訂資源。此模組具有 `send` 方法，它可透過 Amazon S3 預先簽章的 URL (`ResponseURL`) 將[回應物件](crpg-ref.md#crpg-ref-responses)傳送給自訂資源。

只有在您使用 `cfn-response` 屬性撰寫來源碼時，才能使用 `ZipFile` 模組。這不適用於 Amazon S3 儲存貯體中所存放的來源碼。針對儲存貯體中的程式碼，您必須撰寫自己的函數來傳送回應。

**注意**  
執行 `send` 方法之後，Lambda 函數即會終止，因此會忽略您在該方法之後撰寫的任何內容。

## 載入 `cfn-response` 模組
<a name="cfn-lambda-function-code-cfnresponsemodule-loading"></a>

對於 Node.js 函數，使用 `require()` 函數來載入 `cfn-response` 模組。例如，下列程式碼範例會建立名稱為 `cfn-response` 的 `response` 物件：

```
var response = require('cfn-response');
```

對於 Python，使用 `import` 陳述式載入 `cfnresponse` 模組，如下列範例所示：

**注意**  
使用此確切 import 陳述式。如果您使用 import 陳述式的其他變體，則 CloudFormation 不會包括回應模組。

```
import cfnresponse
```

## `send` 方法參數
<a name="cfn-lambda-function-code-cfnresponsemodule-send-parameters"></a>

您可以搭配使用下列參數與 `send` 方法。

`event`  
[自訂資源請求](crpg-ref.md#crpg-ref-requesttypes)中的欄位。

`context`  
Lambda 函數特有的物件，可用來指定函數和任何回呼完成執行的時機，或存取 Lambda 執行環境內的資訊。如需詳細資訊，請參閱《AWS Lambda 開發人員指南》**中的[使用 Node.js 建立 Lambda 函式](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html)。

`responseStatus`  
函數是否成功完成。使用 `cfnresponse` 模組常數指定狀態：`SUCCESS` 表示執行成功，而 `FAILED` 表示執行失敗。

`responseData`  
自訂資源[回應物件](crpg-ref.md#crpg-ref-responses)的 `Data` 欄位。資料是名稱/值組清單。

`physicalResourceId`  
選用。已呼叫函數之自訂資源的唯一識別碼。根據預設，模組會使用與 Lambda 函數建立關聯之 Amazon CloudWatch Logs 日誌串流的名稱。  
傳回的 `PhysicalResourceId` 值可以變更自訂資源更新操作。如果傳回的值相同，則視為正常更新。若傳回的值不同，CloudFormation 會將該更新視為取代，並傳送刪除請求給舊資源。如需詳細資訊，請參閱[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html)。

`noEcho`  
選用。指示在使用 `Fn::GetAtt` 函數擷取自訂資源時是否要遮蔽其輸出。如果設定為 `true`，則所有傳回的值都會以星號 (\$1\$1\$1\$1\$1) 遮罩，但儲存在下列指定位置的資訊除外。根據預設，此值為 `false`。  
使用 `NoEcho` 屬性不會遮罩任何儲存在下列資訊中的資訊：  
+ `Metadata` 範本區段。CloudFormation 不會轉換、修改或標記您在 `Metadata` 區段中包含的任何資訊。若要取得更多資訊，請參閱[中繼資料](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html)。
+ `Outputs` 範本區段。如需詳細資訊，請參閱[輸出](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)。
+ 資源定義的 `Metadata` 屬性。如需詳細資訊，請參閱 [`Metadata` 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html)。
我們強烈建議您不要使用這些機制來包含敏感資訊，例如密碼或秘密。
如需使用 `NoEcho` 遮罩敏感資訊的詳細資訊，請參閱 [請勿在您的範本中內嵌憑證](security-best-practices.md#creds) 最佳實務。

## 範例
<a name="cfn-lambda-function-code-cfnresponsemodule-examples"></a>

### Node.js
<a name="cfn-lambda-function-code-zipfile-examplenodejs"></a>

在下列 Node.js 範例中，內嵌 Lambda 函數採用輸入值，並將它乘以 5。內嵌函數特別適用於較小的函數，因為它們可讓您直接在範本中指定來源碼，而不是建立套件並將它上傳至 Amazon S3 儲存貯體。此函數使用 `cfn-response` `send` 方法，將結果送回給呼叫它的自訂資源。

#### JSON
<a name="cfn-lambda-function-code-zipfile-examplenodejs.json"></a>

```
"ZipFile": { "Fn::Join": ["", [
  "var response = require('cfn-response');",
  "exports.handler = function(event, context) {",
  "  var input = parseInt(event.ResourceProperties.Input);",
  "  var responseData = {Value: input * 5};",
  "  response.send(event, context, response.SUCCESS, responseData);",
  "};"
]]}
```

#### YAML
<a name="cfn-lambda-function-code-zipfile-examplenodejs-yaml"></a>

```
ZipFile: >
  var response = require('cfn-response');
  exports.handler = function(event, context) {
    var input = parseInt(event.ResourceProperties.Input);
    var responseData = {Value: input * 5};
    response.send(event, context, response.SUCCESS, responseData);
  };
```

### Python
<a name="cfn-lambda-function-code-zipfile-examplepython"></a>

在下列 Python 範例中，內嵌 Lambda 函數採用整數值，並將它乘以 5。

#### JSON
<a name="cfn-lambda-function-code-zipfile-examplepython.json"></a>

```
"ZipFile" : { "Fn::Join" : ["\n", [
  "import json",
  "import cfnresponse",
  "def handler(event, context):",
  "   responseValue = int(event['ResourceProperties']['Input']) * 5",
  "   responseData = {}",
  "   responseData['Data'] = responseValue",
  "   cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, \"CustomResourcePhysicalID\")"
]]}
```

#### YAML
<a name="cfn-lambda-function-code-zipfile-examplepython.yaml"></a>

```
ZipFile: |
  import json
  import cfnresponse
  def handler(event, context):
    responseValue = int(event['ResourceProperties']['Input']) * 5
    responseData = {}
    responseData['Data'] = responseValue
    cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
```

## 模組來源碼
<a name="cfn-lambda-function-code-cfnresponsemodule-source"></a>

**Topics**
+ [非同步 Node.js 原始程式碼](#cfn-lambda-function-code-cfnresponsemodule-source-nodejs-async)
+ [Node.js 原始程式碼](#cfn-lambda-function-code-cfnresponsemodule-source-nodejs)
+ [Python 原始碼](#cfn-lambda-function-code-cfnresponsemodule-source-python)

### 非同步 Node.js 原始程式碼
<a name="cfn-lambda-function-code-cfnresponsemodule-source-nodejs-async"></a>

如果處理常式為異步，以下是 Node.js 函數的回應模組原始程式碼。請檢閱它以了解模組功能，並協助您實作您自己的回應函數。

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0

exports.SUCCESS = "SUCCESS";
exports.FAILED = "FAILED";

exports.send = function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {

    return new Promise((resolve, reject) => {
        var responseBody = JSON.stringify({
            Status: responseStatus,
            Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
            PhysicalResourceId: physicalResourceId || context.logStreamName,
            StackId: event.StackId,
            RequestId: event.RequestId,
            LogicalResourceId: event.LogicalResourceId,
            NoEcho: noEcho || false,
            Data: responseData
        });

        console.log("Response body:\n", responseBody);

        var https = require("https");
        var url = require("url");

        var parsedUrl = url.parse(event.ResponseURL);
        var options = {
            hostname: parsedUrl.hostname,
            port: 443,
            path: parsedUrl.path,
            method: "PUT",
            headers: {
                "content-type": "",
                "content-length": responseBody.length
            }
        };

        var request = https.request(options, function(response) {
            console.log("Status code: " + parseInt(response.statusCode));
            resolve(context.done());
        });

        request.on("error", function(error) {
            console.log("send(..) failed executing https.request(..): " + maskCredentialsAndSignature(error));
            reject(context.done(error));
        });

        request.write(responseBody);
        request.end();
    })
}
 
function maskCredentialsAndSignature(message) {
    return message.replace(/X-Amz-Credential=[^&\s]+/i, 'X-Amz-Credential=*****')
        .replace(/X-Amz-Signature=[^&\s]+/i, 'X-Amz-Signature=*****');
}
```

### Node.js 原始程式碼
<a name="cfn-lambda-function-code-cfnresponsemodule-source-nodejs"></a>

如果處理常式不是異步，以下是 Node.js 函數的回應模組原始程式碼。請檢閱它以了解模組功能，並協助您實作您自己的回應函數。

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0
 
exports.SUCCESS = "SUCCESS";
exports.FAILED = "FAILED";

exports.send = function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {

    var responseBody = JSON.stringify({
        Status: responseStatus,
        Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
        PhysicalResourceId: physicalResourceId || context.logStreamName,
        StackId: event.StackId,
        RequestId: event.RequestId,
        LogicalResourceId: event.LogicalResourceId,
        NoEcho: noEcho || false,
        Data: responseData
    });

    console.log("Response body:\n", responseBody);

    var https = require("https");
    var url = require("url");

    var parsedUrl = url.parse(event.ResponseURL);
    var options = {
        hostname: parsedUrl.hostname,
        port: 443,
        path: parsedUrl.path,
        method: "PUT",
        headers: {
            "content-type": "",
            "content-length": responseBody.length
        }
    };

    var request = https.request(options, function(response) {
        console.log("Status code: " + parseInt(response.statusCode));
        context.done();
    });

    request.on("error", function(error) {
        console.log("send(..) failed executing https.request(..): " + maskCredentialsAndSignature(error));
        context.done();
    });

    request.write(responseBody);
    request.end();
}
```

### Python 原始碼
<a name="cfn-lambda-function-code-cfnresponsemodule-source-python"></a>

以下是 Python 函數的回應模組來源程式碼：

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
 
from __future__ import print_function
import urllib3
import json
import re

SUCCESS = "SUCCESS"
FAILED = "FAILED"

http = urllib3.PoolManager()


def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False, reason=None):
    responseUrl = event['ResponseURL']

    responseBody = {
        'Status' : responseStatus,
        'Reason' : reason or "See the details in CloudWatch Log Stream: {}".format(context.log_stream_name),
        'PhysicalResourceId' : physicalResourceId or context.log_stream_name,
        'StackId' : event['StackId'],
        'RequestId' : event['RequestId'],
        'LogicalResourceId' : event['LogicalResourceId'],
        'NoEcho' : noEcho,
        'Data' : responseData
    }

    json_responseBody = json.dumps(responseBody)

    print("Response body:")
    print(json_responseBody)

    headers = {
        'content-type' : '',
        'content-length' : str(len(json_responseBody))
    }

    try:
        response = http.request('PUT', responseUrl, headers=headers, body=json_responseBody)
        print("Status code:", response.status)


    except Exception as e:

        print("send(..) failed executing http.request(..):", mask_credentials_and_signature(e))
 
 
def mask_credentials_and_signature(message):
    message = re.sub(r'X-Amz-Credential=[^&\s]+', 'X-Amz-Credential=*****', message, flags=re.IGNORECASE)
    return re.sub(r'X-Amz-Signature=[^&\s]+', 'X-Amz-Signature=*****', message, flags=re.IGNORECASE)
```

# 使用範本巨集在 CloudFormation 範本上執行自訂處理
<a name="template-macros"></a>

透過巨集，讓可您在範本上執行自訂處理，例如尋找和取代操作這種簡單動作，乃至於全部範本的大規模轉換。

若要了解可能性的廣度，請考慮使用 `AWS::Include` 和 `AWS::Serverless` 轉換 (由 CloudFormation 託管的巨集)：
+ [AWS::Include 轉換](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-include.html)可讓您將樣板式範本程式碼片段插入範本中。
+ [AWS::Serverless 轉換](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-serverless.html)採用以無 AWS 伺服器應用程式模型 (AWS SAM) 語法編寫的整個範本，並將其轉換並擴展為合規的 CloudFormation 範本。如需無伺服器應用程式的詳細資訊 AWS SAM，請參閱 [AWS Serverless Application Model 開發人員指南](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)。

**Topics**
+ [帳單](#template-macros-billing)
+ [巨集範例](#template-macros-examples-list)
+ [相關資源](#template-macros-related-resources)
+ [CloudFormation 巨集概觀](template-macros-overview.md)
+ [建立 CloudFormation 巨集定義](template-macros-author.md)
+ [簡單字串取代巨集範](macros-example.md)
+ [疑難排解處理過的範本](template-macros-troubleshoot-processed-template.md)

## 帳單
<a name="template-macros-billing"></a>

當巨集執行時，Lambda 函數的擁有者需要支付執行該函數的任何相關費用。

`AWS::Include` 和 `AWS::Serverless` 轉換是由 CloudFormation 託管的巨集。可免費使用它們。

## 巨集範例
<a name="template-macros-examples-list"></a>

除了本區段中的此範例外，您還可以在我們的 [GitHub 程式碼庫](https://github.com/aws-cloudformation/aws-cloudformation-templates/tree/main/CloudFormation/MacrosExamples)中找到包含原始程式碼和範本的巨集範例。這些範例「按現狀」提供作為教學用途。

## 相關資源
<a name="template-macros-related-resources"></a>
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-macro.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-macro.html)
+ [CloudFormation 範本 Transform 區段](transform-section-structure.md)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-transform.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference-transform.html)
+ [AWS::Serverless 轉換](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-serverless.html)
+ [AWS::Include 轉換](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-include.html)

# CloudFormation 巨集概觀
<a name="template-macros-overview"></a>

使用巨集處理範本有兩個主要步驟：建立巨集本身，然後使用巨集在您的範本上執行處理。

若要建立巨集定義，您必須建立下列項目：
+ 用來執行範本處理的 Lambda 函式。此 Lambda 函數接受程式碼片段或整個範本，以及您定義的任何其他參數。它會傳回已處理的範本程式碼片段或整個範本作為回應。
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-macro.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-macro.html) 類型的資源，可讓使用者從 CloudFormation 範本內呼叫 Lambda 函式。此資源指定針對此巨集叫用的 Lambda 函數的 ARN，以及可協助除錯的其他選用屬性。若要在帳戶中建立此資源，請撰寫包含`AWS::CloudFormation::Macro`資源的範本，然後從範本建立具有自我管理許可的堆疊或堆疊集。 CloudFormation StackSets 目前不支援從參考巨集的範本建立或更新具有服務管理許可的堆疊集。

若要使用巨集，請在範本中參考巨集：
+ 若要處理範本的區段或部分，請在 `Fn::Transform` 函數 (位置相對於您想要轉換的範本內容) 中參考巨集。當您使用 `Fn::Transform` 時，您也可以傳遞它需要的任何指定參數。
+ 若要處理整個範本，請在範本的 [Transform](transform-section-structure.md) 區段中參考巨集。

接著，您通常會建立變更集，然後加以執行。(處理巨集可能會新增您不了解的多項資源。為了確保您知道巨集所產生的所有變更，我們強烈建議您使用變更集。) CloudFormation 會將指定的範本內容以及任何額外的指定參數，傳遞到巨集資源中指定的 Lambda 函式。Lambda 函數會傳回已處理的範本內容，不論是程式碼片段或整個範本。

所有巨集之後，CloudFormation 會產生已稱為在範本中變更設定，包含處理範本的內容。檢閱變更集之後，請執行它來套用變更。

![\[使用 Fn::Transform 內建函數或範本的 Transform 區段，將範本內容和相關參數傳遞到巨集的基礎 Lambda 函式，而此函數會傳回已處理的範本內容。\]](http://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/images/template-macro-use.png)


## 如何直接建立堆疊
<a name="template-macros-change-sets"></a>

若要使用參考巨集的範本來建立或更新堆疊，您通常會建立變更集，然後執行它。變更集說明 CloudFormation 將根據處理過的範本所採取的動作。處理巨集可能會新增您不了解的多個資源。為了確保您知道巨集所產生的所有變更，我們強烈建議您使用變更集。檢閱變更集之後，您可以執行它來確實套用變更。

巨集可以將 IAM 資源新增至您的範本。針對這些資源，CloudFormation 會要求您[確認其功能](control-access-with-iam.md#using-iam-capabilities)。因為 CloudFormation 無法知道在處理範本之前新增哪些資源，所以您建立變更集時可能需要確認 IAM 功能 (視參考的巨集是否包含 IAM 資源而定)。因此，當您執行變更集時，CloudFormation 具有必要功能來建立 IAM 資源。

要透過處理範本建立或更新堆疊，無需先在變更集中審核建議的變更，可在 `CreateStack` 或 `UpdateStack` 請求期間指定 `CAPABILITY_AUTO_EXPAND` 功能。如果您知道巨集執行哪些處理，您應只直接透過包含巨集的堆疊範本來建立堆疊。您不能將變更集與堆疊集巨集一起使用；您必須直接更新堆疊集。

如需詳細資訊，請參閱《AWS CloudFormation API 參考》**中的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html) 或 [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_UpdateStack.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_UpdateStack.html)。

**重要**  
如果您的堆疊集範本參考了一或多個巨集，您必須直接從處理的範本建立堆疊集，而不必先檢視變更集中產生的變更。處理巨集可能會新增您不了解的多個資源。從直接參考巨集的範本建立或更新堆疊集之前，請確定您知道巨集會執行哪些處理操作。

若要減少從參考巨集的範本啟動堆疊的步驟數目，您可以使用 `package`和 `deploy` AWS CLI 命令。如需詳細資訊，請參閱[使用 將本機成品上傳至 S3 儲存貯體 AWS CLI](using-cfn-cli-package.md)及[建立包含轉換的堆疊](service_code_examples.md#deploy-sdk)。

## 考量事項
<a name="template-macros-considerations"></a>

配合使用巨集時，請記住下列考量事項和限制：
+ 只有提供 Lambda AWS 區域 的 才支援巨集。如需可使用 Lambda 的區域清單，請參閱 [AWS Lambda 端點與配額](https://docs.aws.amazon.com/general/latest/gr/lambda-service.html)。
+ 任何處理的範本程式碼片段都必須是有效的 JSON。
+ 任何處理的範本程式碼片段都必須通過建立堆疊、更新堆疊、建立堆疊集或更新堆疊集操作的驗證檢查。
+ CloudFormation 會先解析巨集，再處理範本。產生的範本必須是有效的 JSON，且不能超過範本大小上限。
+ 由於 CloudFormation 處理範本中元素的順序，巨集無法將模組包含在傳回至 CloudFormation 的處理範本內容中。如需詳細資訊，請參閱[巨集評估順序](template-macros-author.md#template-macros-order)。
+ CloudFormation 會採用原始範本的副本來執行更新復原功能。即使加入的程式碼片段有所變更，它也會復原至原始範本。
+ 在巨集內包含巨集沒有作用，因為我們不會處理以遞迴方式處理巨集。
+ 巨集內目前不支援 `Fn::ImportValue` 內部函數。
+ 範本包含的內部函數是在任何巨集之後評估。因此，巨集傳回的已處理範本內容可能包含內部函數的呼叫，一樣照常評估。
+ StackSets 目前不支援從參考 CloudFormation 巨集的範本建立或更新具有服務受管許可的 StackSets。

## 巨集帳戶範圍和許可
<a name="template-macros-permissions"></a>

巨集只能在它們已建立為資源的帳戶中使用。巨集的名稱在給定帳戶內必須是唯一的。不過，您可以在基礎 Lambda 函數上啟用跨帳戶存取，然後建立巨集定義在多個帳戶中參考該函數，就能讓多個帳戶使用相同的功能。在下列範例中，三個帳戶包含巨集定義，各指向相同的 Lambda 函數。

![\[允許 Lambda 函數上的跨帳戶存取， AWS 可讓您在參考該函數的多個帳戶中建立巨集。\]](http://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/images/template-macro-accounts.png)


為了建立巨集定義，使用者必須有許可，才能在指定的帳戶內建立堆疊或堆疊集。

為了讓 CloudFormation 成功執行範本中包含的巨集，使用者必須有基礎 Lambda 函式的 `Invoke` 許可。為避免潛在提升許可，CloudFormation 會在執行巨集時模擬使用者。

如需詳細資訊，請參閱《AWS Lambda 開發人員指南**》中的[在 AWS Lambda中管理許可](https://docs.aws.amazon.com/lambda/latest/dg/lambda-permissions.html)，以及《服務授權參考**》中的 [AWS Lambda的動作、資源和條件索引鍵](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awslambda.html)。

# 建立 CloudFormation 巨集定義
<a name="template-macros-author"></a>

當您建立巨集定義時，巨集定義會在指定的帳戶中提供基礎 Lambda 函式，供 CloudFormation 調用以處理範本。

## 事件映射
<a name="template-macros-event-mapping"></a>

當 CloudFormation 調用巨集的 Lambda 函式時，會傳送 JSON 格式的請求，其結構如下：

```
{
    "region" : "us-east-1",
    "accountId" : "$ACCOUNT_ID",
    "fragment" : { ... },
    "transformId" : "$TRANSFORM_ID",
    "params" : { ... },
    "requestId" : "$REQUEST_ID",
    "templateParameterValues" : { ... }
}
```
+ `region`

  巨集所在的區域。
+ `accountId`

  供巨集用來叫用 Lambda 函數的帳戶的帳戶 ID。
+ `fragment`

  可供自訂處理的範本內容 (JSON 格式)。
  + 對於 `Transform` 範本區段包含的巨集，這是整個範本 (`Transform` 區段除外)。
  + 對於 `Fn::Transform` 內部函數呼叫包含的巨集，這包括以內部函數 (`Fn::Transform` 函數除外) 在範本內的位置為基礎的所有同級節點 (及其子系)。如需詳細資訊，請參閱[巨集的範本範圍](#template-macros-scope)。
+ `transformId`

  叫用此函數的巨集的名稱。
+ `params`

  若為 `Fn::Transform` 函數呼叫，則為該函數指定的任何參數。CloudFormation 不會在將這些參數傳遞至 函數之前對其進行評估。

  對於 `Transform` 範本區段包含的巨集，這個區段是空的。
+ `requestId`

  叫用此函數的請求的 ID。
+ `templateParameterValues`

  範本 [Parameters](parameters-section-structure.md) 區段中指定的任何參數。CloudFormation 會在將這些參數傳遞至函數之前對其進行評估。

## 回應格式
<a name="template-macros-response-format"></a>

CloudFormation 期望 Lambda 函式傳回的回應是下列 JSON 格式：

```
{
    "requestId" : "$REQUEST_ID",
    "status" : "$STATUS",
    "fragment" : { ... },
    "errorMessage": "optional error message for failures"
}
```
+ `requestId`

  叫用此函數的請求的 ID。這必須符合 CloudFormation 在調用函數時提供的請求 ID。
+ `status`

  請求的狀態 (不區分大小寫)。應設為 `success`。CloudFormation 會將任何其他回應視為失敗。
+ `fragment`

  供 CloudFormation 納入處理後範本的已處理範本內容，含同級項目。CloudFormation 會將傳遞給 Lambda 函式的範本內容取代為在 Lambda 回應中收到的範本片段。

  處理過的範本內容必須是有效的 JSON，而納入所處理的範本中之後必須形成有效的範本。

  如果您的函數不實際變更 CloudFormation 傳來的範本內容，但您仍然需要將該內容納入所處理的範本中，則函數必須在其回應中將該範本內容傳回給 CloudFormation。
+ `errorMessage`

  說明轉換失敗原因的錯誤訊息。CloudFormation 會在堆疊 **Stack details** (堆疊詳細資訊) 頁面的 **Events** (事件) 窗格中顯示此錯誤訊息。

  例如：

  ```
  Error creating change set: Transform
                              AWS 帳戶 account
                              number::macro name failed with:
                              error message string.
  ```

## 建立巨集定義
<a name="create-a-macro-definition"></a>

**建立 CloudFormation 巨集定義**

1. [建置 Lambda 函式](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html)，用於處理範本內容的處理。它可以處理範本的任何部分，甚至整個範本。

1. 建立包含 `AWS::CloudFormation::Macro` 資源類型的 CloudFormation 範本，並指定 `Name` 和 `FunctionName` 屬性。`FunctionName` 屬性必須包含當 CloudFormation 執行巨集時調用的 Lambda 函式的 ARN。

1. (選用) 為了協助除錯，當您為巨集建立 `AWS::CloudFormation::Macro` 資源類型時，您也可以指定 `LogGroupName` 和 `LogRoleArn` 屬性。這些屬性可讓您指定 CloudWatch Logs 日誌群組，供 CloudFormation 在調用巨集的基礎 Lambda 函式時傳送錯誤日誌記錄資訊，也可指定 CloudFormation 將日誌項目傳送到這些日誌時應該擔任的角色。

1. 在您要使用它的帳戶中，使用具有巨集的範本[建立堆疊](cfn-console-create-stack.md)。或者，在管理員帳戶中使用包含該巨集的範本，[建立具有自我管理許可的堆疊集](stacksets-getting-started-create-self-managed.md)，然後在目標帳戶中建立堆疊執行個體。

1. 當 CloudFormation 成功建立包含巨集定義的堆疊之後，即可在這些帳戶內使用巨集。在範本中，請在您要處理的範本內容的相對適當位置上參考巨集，以此來使用巨集。

## 巨集的範本範圍
<a name="template-macros-scope"></a>

範本的 `Transform` 區段中參考的巨集可以處理該範本的整個內容。

`Fn::Transform` 函數中參考的巨集可以處理該 `Fn::Transform` 函數在範本中的任何同級元素 (包括子系) 的內容。

例如，在以下範本範例中，`AWS::Include` 可以根據其所在 `Fn::Transform` 函數的位置，而處理所有 `MyBucket` 屬性。`MyMacro` 可以處理整個範本的內容，因為它已納入 `Transform` 區段中。

```
# Start of processable content for MyMacro
AWSTemplateFormatVersion: 2010-09-09 
 Transform: [MyMacro]
 Resources:
    WaitCondition:
      Type: AWS::CloudFormation::WaitCondition
    MyBucket:
      Type: AWS::S3::Bucket
      # Start of processable content for AWS::Include
      Properties:
        BucketName: amzn-s3-demo-bucket1
        Tags: [{"key":"value"}] 
        'Fn::Transform':
          - Name: 'AWS::Include'
              Parameters:
                Location: s3://amzn-s3-demo-bucket2/MyFileName.yaml
        CorsConfiguration: []
        # End of processable content for AWS::Include
    MyEc2Instance:
      Type: AWS::EC2::Instance
      Properties:
        ImageID: ami-1234567890abcdef0
# End of processable content for MyMacro
```

## 巨集評估順序
<a name="template-macros-order"></a>

您可以在給定的範本中參考多個巨集，包括由 CloudFormation 託管的轉換，例如 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-include.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-include.html) 和 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-serverless.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-serverless.html)。

巨集是根據在範本中的位置而依序評估，從最深巢狀往外到最通用。範本中同一位置的巨集是根據它們所列順序而按順序評估。

在動作順序和範圍方面，轉換 (例如 `AWS::Include` 和 `AWS::Transform`) 與任何其他巨集視為相同。

例如，在以下範本範例中，CloudFormation 會先評估 `PolicyAdder` 巨集，因為它是範本中最深層巢狀的巨集。然後，CloudFormation 會評估 `MyMacro`，再評估 `AWS::Serverless`，因為它在 `Transform` 區段中列在 `AWS::Serverless` 前面。

```
AWSTemplateFormatVersion: 2010-09-09
 Transform: [MyMacro, AWS::Serverless]
 Resources:
    WaitCondition:
      Type: AWS::CloudFormation::WaitCondition
    MyBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: amzn-s3-demo-bucket
        Tags: [{"key":"value"}]
        'Fn::Transform':
          - Name: PolicyAdder
        CorsConfiguration: []
    MyEc2Instance:
      Type: AWS::EC2::Instance
      Properties:
        ImageID: ami-1234567890abcdef0
```

# 簡單字串取代巨集範
<a name="macros-example"></a>

以下範例逐步介紹如何使用巨集，包括在範本中定義巨集、為巨集建立 Lambda 函式，然後在範本中使用巨集。

在這個範例中，我們會建立簡單巨集，在處理的範本中插入指定的字串，以取代指定的目標內容。然後，我們會使用它在處理的範本中的指定位置插入空白 `WaitHandleCondition`。

## 建立巨集
<a name="macros-example-definiton"></a>

使用巨集之前，我們必須先做兩件事：建立 Lambda 函數來執行所需的範本處理，然後建立巨集定義，讓該 Lambda 函數可供 CloudFormation 使用。

以下範例範本包含範例巨集的定義。若要讓巨集可在特定 中使用 AWS 帳戶，請從範本建立堆疊。巨集定義會指定巨集名稱、簡短描述，並於範本中使用此巨集時參考 CloudFormation 叫用的 Lambda 函數的 ARN。(我們未包含用於錯誤記錄的 `LogGroupName` 或 `LogRoleARN` 屬性。) 

在這個範例中，假設從這個範本建立的堆疊名為 `JavaMacroFunc`。由於巨集 `Name` 屬性設為堆疊名稱，產生的巨集也名為 `JavaMacroFunc`。

```
AWSTemplateFormatVersion: 2010-09-09
  Resources:
    Macro:
      Type: AWS::CloudFormation::Macro
      Properties:
        Name: !Sub '${AWS::StackName}'
        Description: Adds a blank WaitConditionHandle named WaitHandle
        FunctionName: 'arn:aws:lambda:us-east-1:012345678910:function:JavaMacroFunc'
```

## 使用巨集
<a name="macros-example-usage"></a>

為了使用我們的巨集，我們將使用 `Fn::Transform` 內建函數將它納入範本中。

當我們使用以下範本建立堆疊時，CloudFormation 會呼叫我們的範例巨集。基礎 Lambda 函數會將一個指定的字串替換成另一個指定的字串。在此案例中，結果是在所處理的範本中插入空白 `AWS::CloudFormation::WaitConditionHandle`。

```
Parameters:
  ExampleParameter:
    Type: String
    Default: 'SampleMacro'

Resources:
  2a:
    Fn::Transform:
      Name: "JavaMacroFunc"
      Parameters:
        replacement: 'AWS::CloudFormation::WaitConditionHandle'
        target: '$$REPLACEMENT$$'
    Type: '$$REPLACEMENT$$'
```
+ 要調用的巨集指定為 `JavaMacroFunc`，這是來自上一個巨集定義範例。
+ 有兩個參數傳遞給巨集：`target` 和 `replacement`，代表目標字串及其所需的替換值。
+ 巨集可以處理 `Type` 節點的內容，因為 `Type` 是參考巨集的 `Fn::Transform` 函數的同級項目。
+ 產生的 `AWS::CloudFormation::WaitConditionHandle` 名為 `2a`。
+ 範本還包含巨集也可存取的範本參數：`ExampleParameter` (但在這個案例中未使用)。

## Lambda 輸入資料
<a name="macros-example-request"></a>

當 CloudFormation 在堆疊建立期間處理我們的範例範本時，它會將下列事件映射傳遞到 `JavaMacroFunc` 巨集定義中參考的 Lambda 函式。
+ `region` : `us-east-1`
+ `accountId` : `012345678910`
+ `fragment` :

  ```
  {
    "Type": "$$REPLACEMENT$$"
  }
  ```
+ `transformId` : `012345678910::JavaMacroFunc`
+ `params` : 

  ```
  {
      "replacement": "AWS::CloudFormation::WaitConditionHandle",
      "target": "$$REPLACEMENT$$"
  }
  ```
+ `requestId` : `5dba79b5-f117-4de0-9ce4-d40363bfb6ab`
+ `templateParameterValues` :

  ```
  {
      "ExampleParameter": "SampleMacro"
  }
  ```

請注意，`fragment` 包含的 JSON 代表巨集可處理的範本片段。此片段由 `Fn::Transform` 函數呼叫的同級項目組成，而不是函數呼叫本身。此外，`params` 包含代表巨集參數的 JSON。在此案例中是 replacement 和 target。同樣地，`templateParameterValues` 包含的 JSON 代表針對整個範本指定的參數。

## Lambda 函式程式碼
<a name="macros-example-function"></a>

以下是 `JavaMacroFunc` 範例巨集的基礎 Lambda 函式的實際程式碼。它會逐一查看回應 (不論是字串、清單或映射格式) 包含的範本片段，尋找指定的目標字串。如果找到指定的目標字串，Lambda 函數會以指定的替換字串取代目標字串。如果找不到，該函數會將範本片段保持不變。然後，該函數會將預期屬性的映射 (以下詳細討論) 傳回給 CloudFormation。

```
package com.macroexample.lambda.demo;

import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class LambdaFunctionHandler implements RequestHandler<Map<String, Object>, Map<String, Object>> {

	private static final String REPLACEMENT = "replacement";
	private static final String TARGET = "target";
	private static final String PARAMS = "params";
	private static final String FRAGMENT = "fragment";
	private static final String REQUESTID = "requestId";
	private static final String STATUS = "status";
	private static final String SUCCESS = "SUCCESS";
	private static final String FAILURE = "FAILURE";
    @Override
    public Map<String, Object> handleRequest(Map<String, Object> event, Context context) {
        // TODO: implement your handler
    	final Map<String, Object> responseMap = new HashMap<String, Object>();
        responseMap.put(REQUESTID, event.get(REQUESTID));
        responseMap.put(STATUS, FAILURE);
    	try {
	        if (!event.containsKey(PARAMS)) {
	        	throw new RuntimeException("Params are required");
	        }
	    	
	        final Map<String, Object> params = (Map<String, Object>) event.get(PARAMS);
	        if (!params.containsKey(REPLACEMENT) || !params.containsKey(TARGET)) {
	        	throw new RuntimeException("replacement or target under Params are required");
	        }
	    	
	    	final String replacement = (String) params.get(REPLACEMENT);
	    	final String target = (String) params.get(TARGET);
	    	final Object fragment = event.getOrDefault(FRAGMENT, new HashMap<String, Object>());
	    	final Object retFragment;
	    	if (fragment instanceof String) {
	    		retFragment = iterateAndReplace(replacement, target, (String) fragment);
	    	} else if (fragment instanceof List) {
	    		retFragment = iterateAndReplace(replacement, target, (List<Object>) fragment);
	    	} else if (fragment instanceof Map) {
	    		retFragment = iterateAndReplace(replacement, target, (Map<String, Object>) fragment);
	    	} else {
	    		retFragment = fragment;
	    	}
	        responseMap.put(STATUS, SUCCESS);
	        responseMap.put(FRAGMENT, retFragment);
	        return responseMap;
    	} catch (Exception e) {
    		e.printStackTrace();
    		context.getLogger().log(e.getMessage());
    		return responseMap;
    	}
    }
    
    private Map<String, Object> iterateAndReplace(final String replacement, final String target, final Map<String, Object> fragment) {
    	final Map<String, Object> retFragment = new HashMap<String, Object>();
    	final List<String> replacementKeys = new ArrayList<>();
    	fragment.forEach((k, v) -> {
    		if (v instanceof String) {
    			retFragment.put(k, iterateAndReplace(replacement, target, (String)v));
    		} else if (v instanceof List) {
    			retFragment.put(k, iterateAndReplace(replacement, target, (List<Object>)v));
    		} else if (v instanceof Map ) {
    			retFragment.put(k, iterateAndReplace(replacement, target, (Map<String, Object>) v));
    		} else {
    			retFragment.put(k, v);
    		}
    	});
    	return retFragment;
    }

    private List<Object> iterateAndReplace(final String replacement, final String target, final List<Object> fragment) {
    	final List<Object> retFragment = new ArrayList<>();
    	fragment.forEach(o -> {
    		if (o instanceof String) {
    			retFragment.add(iterateAndReplace(replacement, target, (String) o));
    		} else if (o instanceof List) {
    			retFragment.add(iterateAndReplace(replacement, target, (List<Object>) o));
    		} else if (o instanceof Map) {
    			retFragment.add(iterateAndReplace(replacement, target, (Map<String, Object>) o));
    		} else {
    			retFragment.add(o);
    		}
    	});
    	return retFragment;
    }
    
    private String iterateAndReplace(final String replacement, final String target, final String fragment) {
    	System.out.println(replacement + " == " + target + " == " + fragment );
    	if (fragment != null AND_AND fragment.equals(target))
    		return replacement;
    	return fragment;
    }
}
```

## Lambda 函式回應
<a name="macros-example-response"></a>

以下是 Lambda 函式傳回給 CloudFormation 來處理的映射。
+ `requestId` : `5dba79b5-f117-4de0-9ce4-d40363bfb6ab`
+ `status` : `SUCCESS`
+ `fragment` :

  ```
  {
    "Type": "AWS::CloudFormation::WaitConditionHandle"
  }
  ```

`requestId` 符合 CloudFormation 傳來的值，而 `status` 值 `SUCCESS` 表示 Lambda 函數成功處理請求中包含的範本片段。在這個回應中，`fragment` 包含的 JSON 代表在所處理的範本中插入的內容，用以取代原始範本程式碼片段。

## 產生的已處理範本
<a name="macros-example-processed"></a>

CloudFormation 收到 Lambda 函數的成功回應之後，就會將傳回的範本片段插入所處理的範本中。

以下是我們的範例產生的處理過範本。已不包含參考 `JavaMacroFunc` 巨集的 `Fn::Transform` 內建函數呼叫。Lambda 函數傳回的範本片段會納入適當的位置中，結果是內容 `"Type": "$$REPLACEMENT$$"` 已替換成 `"Type": "AWS::CloudFormation::WaitConditionHandle"`。

```
{
    "Parameters": {
        "ExampleParameter": {
            "Default": "SampleMacro",
            "Type": "String"
        }
    },
    "Resources": {
        "2a": {
            "Type": "AWS::CloudFormation::WaitConditionHandle"
        }
    }
}
```

# 疑難排解處理過的範本
<a name="template-macros-troubleshoot-processed-template"></a>

使用巨集時，可在 CloudFormation 主控台中找到處理過的範本。

範本的階段會標示其處理狀態：
+ `Original`：使用者最初提交以建立或更新堆疊或堆疊集的範本。
+ `Processed`：由 CloudFormation 在處理任何參考的巨集後用來建立或更新堆疊或堆疊集的範本。即使原始範本是 YAML 格式，處理過的範本會變成 JSON 格式。

疑難排解時，請使用處理過的範本。如果範本未參考巨集，則原始範本和處理過的範本會相同。

如需詳細資訊，請參閱[在 CloudFormation 主控台中檢視堆疊資訊](cfn-console-view-stack-data-resources.md)。

若要使用 AWS CLI 取得已處理的範本，請使用 [get-template](service_code_examples.md#get-template-sdk)命令。

## 大小限制
<a name="template-macros-size-limitation"></a>

已處理堆疊範本直接傳遞到 `CreateStack`、`UpdateStack` 或 `ValidateTemplate` 請求時的大小上限是 51,200 位元組，當使用 Amazon S3 範本的 URL 作為 S3 物件傳遞時的大小上限是 1 MB。不過，CloudFormation 在處理期間會更新範本的臨時狀態，因為它會按順序處理範本中包含的巨集。因此，處理期間的範本大小可能暫時超過完全處理範本允許的大小。CloudFormation 允許為這些處理中範本提供一些緩衝區。不過，您在設計範本和巨集時應謹記處理堆疊範本的允許大小上限。

如果 CloudFormation 傳回 `Transformation data limit exceeded` 錯誤，同時處理您的範本，則範本超過 CloudFormation 在處理期間允許的範本大小上限。

若要解決這個問題，請考量下列解決方案：
+ 將範本重建為多個範本，以避免超過處理中範本的大小上限。例如：
  + 使用巢狀堆疊範本，來封裝部分範本。如需詳細資訊，請參閱[運用巢狀堆疊，將範本分割成可重複使用的部分](using-cfn-nested-stacks.md)。
  + 建立多個堆疊，並使用跨堆疊參考來在這些堆疊之間交換資訊。如需詳細資訊，請參閱[參考在另一個 CloudFormation 堆疊中的資源輸出](walkthrough-crossstackref.md)。
+ 減少特定巨集傳回的範本片段大小。CloudFormation 不會竄改巨集傳回的片段內容。

# 運用巢狀堆疊，將範本分割成可重複使用的部分
<a name="using-cfn-nested-stacks"></a>

隨著基礎設施擴充，您可能會在多個範本中重複建立相同的資源組態。為避免這種重複性，您可以將這些通用組態拆分至專用範本中。然後，在其他範本中使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-stack.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-stack.html) 資源參考這些專用範本，建立巢狀堆疊。

例如，假設您有一個用於您大多數堆疊的負載平衡器組態。相較於複製相同的組態並在您的範本中貼上，您可以為負載平衡器建立專用的範本。之後，任何需要相同負載平衡器組態的其他範本，都可以參考此範本。

巢狀堆疊本身也能包含其他巢狀堆疊，形成堆疊的階層，如下圖所示。*根堆疊*為最上層的堆疊，即為所有巢狀堆疊最終所屬的堆疊。每一個巢狀堆疊都有一個立即的「父系堆疊」。針對第一層巢狀堆疊，根堆疊也是其父系堆疊。
+ 堆疊 A 是所有其他、巢狀、階層中堆疊的根堆疊。
+ 針對堆疊 B，堆疊 A 同時是其父系堆疊及根堆疊。
+ 針對堆疊 D，堆疊 C 是父系堆疊；針對堆疊 C，堆疊 B 為其父系堆疊。

![\[巢狀堆疊，即做為另一個堆疊的部分建立的堆疊，具有立即的父系堆疊，以及最上層的根堆疊。\]](http://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/images/cfn-console-nested-stacks.png)


**Topics**
+ [範本拆分的前後範例](#create-nested-stack-template)
+ [巢狀堆疊架構範例](#nested-stack-examples)
+ [對巢狀堆疊執行堆疊操作](#perform-stack-operations-on-nested-stacks)
+ [相關資訊](#nested-stacks-related-information)

## 範本拆分的前後範例
<a name="create-nested-stack-template"></a>

本範例展示如何將單一大型 CloudFormation 範本，透過巢狀範本，重組為更具結構化且可重複使用的設計。一開始，「巢狀堆疊前」的範本將所有資源定義在同一個檔案中。隨著資源數量增加，這種方式會變得雜亂且難以管理。「巢狀堆疊後」的範本將資源拆分至多個較小的獨立範本中。每個巢狀堆疊負責處理一組特定的相關資源，使整體結構更具條理且易於維護。


| 巢狀堆疊前 | 巢狀堆疊後 | 
| --- | --- | 
| <pre>AWSTemplateFormatVersion: 2010-09-09<br />Parameters:<br />  InstanceType:<br />    Type: String<br />    Default: t2.micro<br />    Description: The EC2 instance type<br />  <br />  Environment:<br />    Type: String<br />    Default: Production<br />    Description: The deployment environment<br /><br />Resources:<br />  MyEC2Instance:<br />    Type: AWS::EC2::Instance<br />    Properties:<br />      ImageId: ami-1234567890abcdef0<br />      InstanceType: !Ref InstanceType<br /><br />  MyS3Bucket:<br />    Type: AWS::S3::Bucket</pre> | <pre>AWSTemplateFormatVersion: 2010-09-09<br />Resources:<br />  MyFirstNestedStack:<br />    Type: AWS::CloudFormation::Stack<br />    Properties:<br />      TemplateURL: https://s3.amazonaws.com/amzn-s3-demo-bucket/first-nested-stack.yaml<br />      Parameters:<br />        # Pass parameters to the nested stack if needed<br />        InstanceType: t3.micro<br /><br />  MySecondNestedStack:<br />    Type: AWS::CloudFormation::Stack<br />    Properties:<br />      TemplateURL: https://s3.amazonaws.com/amzn-s3-demo-bucket/second-nested-stack.yaml<br />      Parameters:<br />        # Pass parameters to the nested stack if needed<br />        Environment: Testing<br />    DependsOn: MyFirstNestedStack</pre> | 

## 巢狀堆疊架構範例
<a name="nested-stack-examples"></a>

本節展示一個巢狀堆疊架構，包含一個參考巢狀堆疊的最上層堆疊。該巢狀堆疊會部署 Node.js Lambda 函式，從最上層堆疊接收參數數值，並傳回透過最上層堆疊公開的輸出。

**Topics**
+ [步驟 1：在本機系統建立巢狀堆疊的範本](#create-a-nested-stack-template)
+ [步驟 2：在本機系統建立最上層堆疊的範本](#create-a-nested-stack-parent-template)
+ [步驟 3：封裝並部署範本](#create-a-nested-stack-parent-template)

### 步驟 1：在本機系統建立巢狀堆疊的範本
<a name="create-a-nested-stack-template"></a>

下列範例示範巢狀堆疊範本的格式。

#### YAML
<a name="nested-stack-child-example.yaml"></a>

```
 1. AWSTemplateFormatVersion: 2010-09-09
 2. Description: Nested stack template for Lambda function deployment
 3. Parameters:
 4.   MemorySize:
 5.     Type: Number
 6.     Default: 128
 7.     MinValue: 128
 8.     MaxValue: 10240
 9.     Description: Lambda function memory allocation (128-10240 MB)
10. Resources:
11.   LambdaFunction:
12.     Type: AWS::Lambda::Function
13.     Properties:
14.       FunctionName: !Sub "${AWS::StackName}-Function"
15.       Runtime: nodejs18.x
16.       Handler: index.handler
17.       Role: !GetAtt LambdaExecutionRole.Arn
18.       Code:
19.         ZipFile: |
20.           exports.handler = async (event) => {
21.             return {
22.               statusCode: 200,
23.               body: JSON.stringify('Hello from Lambda!')
24.             };
25.           };
26.       MemorySize: !Ref MemorySize
27.   LambdaExecutionRole:
28.     Type: AWS::IAM::Role
29.     Properties:
30.       AssumeRolePolicyDocument:
31.         Version: '2012-10-17'
32.         Statement:
33.           - Effect: Allow
34.             Principal:
35.               Service: lambda.amazonaws.com
36.             Action: sts:AssumeRole
37.       ManagedPolicyArns:
38.         - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
39. Outputs:
40.   LambdaArn:
41.     Description: ARN of the created Lambda function
42.     Value: !GetAtt LambdaFunction.Arn
```

### 步驟 2：在本機系統建立最上層堆疊的範本
<a name="create-a-nested-stack-parent-template"></a>

下列範例展示最上層堆疊範本的格式，以及參考您在上一步建立之堆疊的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-stack.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-stack.html) 資源。

#### YAML
<a name="nested-stack-parent-example.yaml"></a>

```
 1. AWSTemplateFormatVersion: 2010-09-09
 2. Description: Top-level stack template that deploys a nested stack
 3. Resources:
 4.   NestedStack:
 5.     Type: AWS::CloudFormation::Stack
 6.     Properties:
 7.       TemplateURL: /path_to_template/nested-template.yaml
 8.       Parameters:
 9.         MemorySize: 256
10. Outputs:
11.   NestedStackLambdaArn:
12.     Description: ARN of the Lambda function from nested stack
13.     Value: !GetAtt NestedStack.Outputs.LambdaArn
```

### 步驟 3：封裝並部署範本
<a name="create-a-nested-stack-parent-template"></a>

**注意**  
在本機使用範本時， AWS CLI **package**命令可協助您準備部署的範本。它會自動處理本機成品上傳至 Amazon S3 (包括 `TemplateURL`)，並產生新的範本檔案，其中包含這些 S3 位置的更新參考。如需詳細資訊，請參閱[使用 將本機成品上傳至 S3 儲存貯體 AWS CLI](using-cfn-cli-package.md)。

接著，您可以使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html) 命令將巢狀範本上傳至 Amazon S3 儲存貯體。

```
aws cloudformation package \
  --s3-bucket amzn-s3-demo-bucket \
  --template /path_to_template/top-level-template.yaml \
  --output-template-file packaged-template.yaml \
  --output json
```

命令會在 `--output-template-file` 指定的路徑上產生新的範本。如下所示，它會將 `TemplateURL` 參考取代為 Amazon S3 位置。

**產生範本**

```
AWSTemplateFormatVersion: 2010-09-09
Description: Top-level stack template that deploys a nested stack
Resources:
  NestedStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.us-west-2.amazonaws.com/amzn-s3-demo-bucket/8b3bb7aa7abfc6e37e2d06b869484bed.template
      Parameters:
        MemorySize: 256
Outputs:
  NestedStackLambdaArn:
    Description: ARN of the Lambda function from nested stack
    Value:
      Fn::GetAtt:
      - NestedStack
      - Outputs.LambdaArn
```

執行 **package** 命令後，您可以使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/) 命令部署已處理的範本。對於包含 IAM 資源巢狀堆疊的 IAM 功能，您必須透過包含 `--capabilities` 選項確認 IAM 功能。

```
aws cloudformation deploy \
  --template-file packaged-template.yaml \
  --stack-name stack-name \
  --capabilities CAPABILITY_NAMED_IAM
```

## 對巢狀堆疊執行堆疊操作
<a name="perform-stack-operations-on-nested-stacks"></a>

處理巢狀堆疊時，執行操作時需謹慎對待。某些堆疊操作 (例如堆疊更新) 應從根堆疊啟動，而非直接在巢狀堆疊上執行。更新根堆疊時，僅有範本發生變更的巢狀堆疊會被更新。

此外，巢狀堆疊的存在可能會影響對根堆疊的操作。例如，若某個巢狀堆疊卡在 `UPDATE_ROLLBACK_IN_PROGRESS` 狀態，根堆疊會等待該巢狀堆疊完成復原後再繼續。執行更新操作前，請確保您具備取消堆疊更新的 IAM 許可，以防其復原。如需詳細資訊，請參閱[使用 控制 CloudFormation 存取 AWS Identity and Access Management](control-access-with-iam.md)。

透過下列步驟尋找根堆疊和巢狀堆疊。

**檢視巢狀堆疊的根堆疊**

1. 登入 AWS 管理主控台 並在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 在**堆疊**頁面上，選擇要檢視根堆疊的巢狀堆疊名稱。

   巢狀堆疊會在其堆疊名稱上方顯示**巢狀**。

1. 在**堆疊資訊**索引標籤的**概觀**區段中，選擇列為**根堆疊**的堆疊名稱。

**檢視屬於根堆疊的巢狀堆疊**

1. 從您要檢視其巢狀堆疊的根堆疊，選擇**資源**索引標籤。

1. 在**類型**欄中，尋找 **AWS::CloudFormation::Stack** 類型的資源。

## 相關資訊
<a name="nested-stacks-related-information"></a>
+ [巢狀現有堆疊](resource-import-nested-stacks.md)
+ [了解更新堆疊資源的行為](using-cfn-updating-stacks-update-behaviors.md)
+ [從失敗的巢狀堆疊更新中繼續復原](using-cfn-updating-stacks-continueupdaterollback.md#nested-stacks)
+ [巢狀堆疊復原失敗](troubleshooting.md#troubleshooting-errors-nested-stacks-are-stuck)

# 在 CloudFormation 範本中建立等待條件
<a name="using-cfn-waitcondition"></a>

此主題解釋了如何在範本中建立等待條件可協調堆疊資源的建立，或追蹤組態程序的進度。例如，您可以在應用程式組態完成一部分後，開始建立另一個資源，或是在安裝和組態程序期間傳送訊號來追蹤其進度。

在 CloudFormation 建立包含等待條件的堆疊時：
+ 它像任何其他資源一樣建立等待條件，並將等待條件的狀態設定為 `CREATE_IN_PROGRESS`。
+ CloudFormation 會等待，直到收到所需數量的成功訊號，或等待條件的逾時時間到期。
+ 若在逾時時間到期前收到所需數量的成功訊號：
  + 等待條件狀態變更為 `CREATE_COMPLETE`
  + 堆疊建立繼續
+ 如果逾時過期，或收到失敗訊號：
  + 等待條件狀態變更為 `CREATE_FAILED`
  + 堆疊復原

**重要**  
針對 Amazon EC2 和 Auto Scaling 資源，我們建議您使用 CreationPolicy 屬性，而非等待條件。請將 CreationPolicy 屬性新增至這類資源，並使用 cfn-signal 的 helper 指令碼在執行個體建立流程成功完成後發出訊號。  
如需詳細資訊，請參閱 [CreationPolicy 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-creationpolicy.html)。

**注意**  
如果您使用 AWS PrivateLink，VPC 中回應等待條件的資源必須能夠存取 CloudFormation 特定的 Amazon Simple Storage Service (Amazon S3) 儲存貯體。資源必須傳送等待條件回應至預先簽章的 Amazon S3 URL。若無法將回應傳送至 Amazon S3，CloudFormation 便不會收到回應，而堆疊操作則會失敗。如需詳細資訊，請參閱 [CloudFormation 使用界面端點存取 (AWS PrivateLink)](vpc-interface-endpoints.md) 和[使用儲存貯體政策控制 VPC 端點的存取](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies-vpc-endpoint.html)。

**Topics**
+ [在您的範本中建立等待條件](#creating-wait-condition)
+ [等待條件訊號語法](#wait-condition-signal-syntax)
+ [存取訊號資料](#wait-condition-access-signal-data)

## 在您的範本中建立等待條件
<a name="creating-wait-condition"></a>

**1. 等待條件控點**  
首先在堆疊的範本中定義 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-waitconditionhandle.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-waitconditionhandle.html) 資源。此資源會產生傳送訊號所需的預先簽章 URL。這可讓您傳送訊號，無需提供您的 AWS 憑證。例如：

```
Resources:
  MyWaitHandle:
    Type: AWS::CloudFormation::WaitConditionHandle
```

**2. 等待條件**  
接下來，您可在堆疊的範本中定義 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-waitcondition.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-waitcondition.html) 資源。`AWS::CloudFormation::WaitCondition` 的基本結構如下所示：

```
  MyWaitCondition:
    Type: AWS::CloudFormation::WaitCondition
    Properties:
      Handle: String
      Timeout: String
      Count: Integer
```

`AWS::CloudFormation::WaitCondition` 資源有兩個必要屬性和一個選用屬性。
+ `Handle` (必要) – 範本中所宣告 `WaitConditionHandle` 的參考。
+ `Timeout` (必要) – CloudFormation 等待收到必要訊號數的秒數。`Timeout` 是最小限制屬性，表示逾時不會早於您指定的時間，但會在之後不久發生。您可以指定的時間上限是 43200 秒 (12 小時)。
+ `Count` (選用) – CloudFormation 在將等待條件的狀態設定為 `CREATE_COMPLETE` 之前，必須接收的成功訊號數量，並繼續建立堆疊。如果未指定，預設值為 1。

通常，您會希望等待條件在特定資源建立完成後立即開始。您可以將 `DependsOn` 屬性新增至等待條件來執行此操作。向等待條件新增 `DependsOn` 屬性後，CloudFormation 會先建立 `DependsOn` 屬性中指定的資源，再建立等待條件。如需詳細資訊，請參閱 [DependsOn 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-dependson.html)。

下列範例示範的等待條件如下：
+ 在成功建立 `MyEC2Instance` 資源後開始
+ 將 `MyWaitHandle` 資源用作 `WaitConditionHandle`
+ 逾時時間為 4500 秒
+ 預設 `Count` 為 1 (因為未指定 `Count` 屬性)

```
  MyWaitCondition:
    Type: AWS::CloudFormation::WaitCondition
    DependsOn: MyEC2Instance
    Properties:
      Handle: !Ref MyWaitHandle
      Timeout: '4500'
```

**3. 傳送訊號**  
若要向 CloudFormation 傳出成功或失敗訊號，您通常會執行一些程式碼或指令碼。例如，在 EC2 執行個體上執行的應用程式可能會執行一些額外的組態工作，然後向 CloudFormation 傳送訊號以表示完成。

訊號必須傳送至等待條件控制代碼產生的預先簽章 URL。使用預先簽章的 URL 傳送成功或失敗訊號。

**傳送訊號**

1. 要擷取範本中的預先簽章 URL，請使用 `Ref` 內建函數搭配等待條件控點的邏輯名稱。

   如以下範例所示，您的範本可以宣告 Amazon EC2 執行個體，並透過 Amazon EC2 `UserData` 屬性將預先簽章的 URL 傳遞至 Amazon EC2 執行個體。這讓在這些執行個體上執行的指令碼或應用程式能向 CloudFormation 傳送成功或失敗訊號。

   ```
     MyEC2Instance:
       Type: AWS::EC2::Instance
       Properties:
       InstanceType: t2.micro  # Example instance type
       ImageId: ami-055e3d4f0bbeb5878  # Change this as needed (Amazon Linux 2023 in us-west-2)
       UserData:
         Fn::Base64: 
           Fn::Join: 
             - ""
             - - "SignalURL="
               - { "Ref": "MyWaitHandle" }
   ```

   這導致 `UserData` 輸出結果類似以下內容：

   ```
   SignalURL=https://amzn-s3-demo-bucket.s3.amazonaws.com/....
   ```

   注意：在 AWS 管理主控台 和命令列工具中，預先簽章的 URL 會顯示為等待條件處理資源的實體 ID。

1. (選用) 若要偵測堆疊何時進入等待條件，您可以使用下列其中一種方法：
   + 如果您建立堆疊並啟用通知，CloudFormation 會針對每個堆疊事件發佈通知到指定的主題。如果您或您的應用程式訂閱該主題，您可以監控等待條件控點建立事件的通知，並從通知訊息擷取預先簽章的 URL。
   + 您也可以使用 AWS 管理主控台、 AWS CLI或 SDK 來監控堆疊的事件。

1. 若要傳送訊號，您可以使用預先簽章的 URL 傳送 HTTP 請求訊息。請求方法必須是 `PUT`，而且 `Content-Type` 標頭必須是空白字串或予以省略。請求訊息必須是 [等待條件訊號語法](#wait-condition-signal-syntax) 中指定格式的 JSON 結構。

   您必須傳送 `Count` 屬性指定的成功訊號數目，CloudFormation 才能繼續建立堆疊。如果您的 `Count` 大於 1，在傳送至特定等待條件的所有訊號之間，每個訊號的 `UniqueId` 值必須都是不重複的。`UniqueId` 是任意英數字串。

   `curl` 命令是傳送訊號的一種方式。下列範例示範將成功訊號傳送至等待條件的 `curl` 命令列。

   ```
   $ curl -T /tmp/a \
     "https://amzn-s3-demo-bucket.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3A034017226601%3Astack%2Fstack-gosar-20110427004224-test-stack-with-WaitCondition--VEYW%2Fe498ce60-70a1-11e0-81a7-5081d0136786%2FmyWaitConditionHandle?Expires=1303976584&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=ik1twT6hpS4cgNAw7wyOoRejVoo%3D"
   ```

   其中 *`/tmp/a`* 檔案包含下列 JSON 結構：

   ```
   {
      "Status" : "SUCCESS",
      "Reason" : "Configuration Complete",
      "UniqueId" : "ID1234",
      "Data" : "Application has completed configuration."
   }
   ```

   此範例示範傳送同一個成功訊號的 `curl` 命令列，差別在於在命令列中以參數的形式傳送 JSON 結構。

   ```
   $ curl -X PUT \
     -H 'Content-Type:' --data-binary '{"Status" : "SUCCESS","Reason" : "Configuration Complete","UniqueId" : "ID1234","Data" : "Application has completed configuration."}' \
     "https://amzn-s3-demo-bucket.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3A034017226601%3Astack%2Fstack-gosar-20110427004224-test-stack-with-WaitCondition--VEYW%2Fe498ce60-70a1-11e0-81a7-5081d0136786%2FmyWaitConditionHandle?Expires=1303976584&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=ik1twT6hpS4cgNAw7wyOoRejVoo%3D"
   ```

## 等待條件訊號語法
<a name="wait-condition-signal-syntax"></a>

當您向等候條件控點所產生的 URL 傳送訊號時，您必須使用下列 JSON 格式：

```
{
  "Status" : "StatusValue",
  "UniqueId" : "Some UniqueId",
  "Data" : "Some Data",
  "Reason" : "Some Reason"
}
```

### Properties
<a name="wait-condition-signal-properties"></a>

`Status` 欄位可以是以下其中一個值：
+ `SUCCESS`
+ `FAILURE`

`UniqueId` 欄位用於識別 CloudFormation 的訊號。如果等待條件的 `Count` 屬性大於 1，`UniqueId` 值在傳送給特定等待條件的所有訊號之間必須是唯一的；否則，CloudFormation 會認為是使用先前傳送過 `UniqueId` 相同之訊號重新傳輸的訊號，而忽略該訊號。

`Data` 欄位可包含您想要隨訊號傳回的任何資訊。在範本內使用 [Fn::GetAtt](resources-section-structure.md#resource-properties-getatt) 函數就可存取 `Data` 值。

`Reason` 欄位是字串，內容除了需要符合 JSON 規定以外，沒有其他限制。

## 存取訊號資料
<a name="wait-condition-access-signal-data"></a>

要存取有效訊號傳送的資料，您可在 CloudFormation 範本中建立等待條件的輸出值。例如：

```
Outputs:
  WaitConditionData:
    Description: The data passed back as part of signalling the WaitCondition
    Value: !GetAtt MyWaitCondition.Data
```

然後，您可使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) 命令或 CloudFormation 主控台的**輸出**索引標籤來檢視此資料。

`Fn::GetAtt` 函數會在 JSON 結構內以名稱/值對的形式傳回 `UniqueId` 和 `Data`。例如：

```
{"Signal1":"Application has completed configuration."}
```

# 透過 CloudFormation 模組建立可跨範本納入的可重複使用資源組態
<a name="modules"></a>

*模組*可讓您以透明、易於管理且可重複的方式，來封裝可包含在堆疊範本之間的資源組態。模組可透過可自訂的模組化建置區塊形式，來封裝通用服務組態和最佳實務，以便您將其納入堆疊範本中。模組可讓您納入資源組態，這些資源組態會將最佳實務、專業領域知識和公認指導方針 (適用於安全性、合規性、控管和產業法規等領域) 納入範本，無須深入了解資源實作的複雜細節。

例如，聯網的領域專家可以建立模組，其中包含內建安全性群組和遵守安全性指導方針的輸入/輸出規則。然後，您可以將該模組納入範本中，以便在堆疊中佈建安全的聯網基礎設施，而不需花時間了解 VPC、子網路、安全性群組和閘道的運作方式。由於模組是由版本控制的，如果安全性指導方針會隨著時間而改變，則模組作者可以建立新版的模組，以納入那些變更。

在範本中使用模組的特性包括：
+ **可預測性** – 模組必須遵守它在 CloudFormation 登錄中註冊的結構描述，以便讓您了解在將模組包含在範本時，該模組可以解析哪些資源。
+ **可重複使用性** - 您可以跨多個範本和帳戶使用相同的模組。
+ **可追蹤性** – CloudFormation 會保留堆疊中哪些資源是透過模組佈建而得的知識，讓您輕鬆了解資源變更的來源。
+ **可管理性** – 在您註冊模組後，就可以透過 CloudFormation 登錄管理模組，包括版本控制、帳戶和區域可用性。

模組可以包含：
+ 要透過模組佈建的一或多個資源，以及輸出或條件等任何相關資料。
+ 任何模組參數，可讓您在使用模組時指定自訂值。

如需開發模組的資訊，請參閱《*CloudFormation CLI 使用者指南*》中的[開發模組](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/modules.html)。

**Topics**
+ [使用模組時的考量](#module-considerations)
+ [了解模組版本控制](module-versioning.md)
+ [使用 CloudFormation 私有登錄檔的模組](modules-using.md)
+ [使用參數來指定模組值](module-using-params.md)
+ [在 CloudFormation 範本中參考模組資源](module-ref-resources.md)

## 使用模組時的考量
<a name="module-considerations"></a>
+ 使用模組無需額外收費。您只需為那些模組在堆疊中解析的資源付費。
+ CloudFormation 配額 (例如堆疊中允許的資源數目上限或範本內文的大小上限) 適用於已處理的範本，無論該範本中包含的資源是否來自模組。如需詳細資訊，請參閱[了解 CloudFormation 配額](cloudformation-limits.md)。
+ 您在堆疊層級指定的標籤會指派給自模組衍生的個別資源。
+ CloudFormation 處理範本時，在模組層級指定的協助程式指令碼不會傳播到模組中包含的個別資源。
+ 模組中指定的輸出會傳播到範本層級的輸出。

  每個輸出將分配到一個邏輯 ID，此 ID 是模組邏輯名稱和在模組中定義之輸出名稱的串連。如需詳細資訊，請參閱[從部署的 CloudFormation 堆疊取得匯出的輸出](using-cfn-stack-exports.md)。
+ 模組中指定的參數不會傳播到範本層級的參數。

  不過，您可以建立參考模組層級參數的範本層級參數。如需詳細資訊，請參閱[使用參數來指定模組值](module-using-params.md)。

# 了解模組版本控制
<a name="module-versioning"></a>

CloudFormation 登錄檔做為儲存庫，您可以在其中註冊和管理模組，以便在 AWS 帳戶 和 區域中使用。您可以在您的帳戶和區域中註冊來自各種來源的模組 AWS，包括第三方發佈者和您自己的自訂擴充功能。如需詳細資訊，請參閱[使用 CloudFormation 登錄檔管理擴充功能](registry.md)。

模組可以有不同版本，因此您可以指定要使用的模組版本。當您需要更新或修改模組而不中斷依賴它的現有堆疊時，此版本控制功能特別實用。

使用多個版本的模組時，請注意以下考量事項：
+ 在堆疊操作期間，CloudFormation 會使用目前註冊為執行堆疊操作之 AWS 帳戶 和 區域中預設版本的任何模組版本。這包括在其他模組中巢狀堆疊的模組。

  因此，請注意，如果您在不同帳戶或區域中將相同模組的不同版本註冊為預設版本，則使用相同的範本可能會產生不同的結果。
+ 在堆疊操作期間，CloudFormation 會使用目前註冊為執行堆疊操作之 AWS 帳戶 和 區域中預設版本的任何資源版本。其中包括內含模組所產生的資源。
+ 變更模組的預設版本不會起始任何堆疊更新操作。不過，在您下次使用任何包含該模組的範本 (例如堆疊更新) 執行堆疊操作時，CloudFormation 將在操作中使用新的預設版本。

  如下所述，唯一的例外是，使用指定的 **use previous template (使用先前範本)** 選項執行堆疊更新時。
+ 對於堆疊更新操作，如果您指定 **use previous template (使用先前範本)** 選項，CloudFormation 會使用先前處理的範本進行堆疊更新，而且不會針對您可能對其所做的任何變更重新處理模組。
+ 為了保證結果一致，如果您將模組包含在堆疊範本中以供堆疊集使用，則應確保在您計劃部署堆疊執行個體的所有帳戶和區域中，將相同的模組版本設定為預設版本。這包括在其他模組巢狀堆疊中的模組。如需詳細資訊，請參閱[透過 StackSets 跨帳戶和區域管理堆疊](what-is-cfnstacksets.md)。

## 啟用第三方公有模組的需求
<a name="requirements-for-modules"></a>

若要成功啟用帳戶和區域中的第三方公有模組，模組中包含的每個第三方公有擴充功能 (資源或模組) 必須符合下列條件：
+ **擴充功能啟用** – 擴充功能必須在您要使用它的帳戶及區域中啟用。如需詳細資訊，請參閱[從 CloudFormation 登錄檔使用第三方公有擴充功能](registry-public.md)。
+ **別名註冊** - 如果模組中的擴充功能使用類型名稱別名，則必須使用相同類型名稱別名在帳戶和區域中註冊擴充功能。如需詳細資訊，請參閱[使用別名來稱呼擴充功能](registry-public.md#registry-public-enable-alias)。
+ **版本相容性** - 目前已啟用擴充功能版本必須是模組中指定之該擴充功能的主要支援版本之一。

如果您沒有啟用正確的第三方公有擴充功能和擴充功能版本，CloudFormation 將導致操作失敗並顯示錯誤，此錯誤會列出成功啟用模組之前需要啟用的擴充功能和版本。

# 使用 CloudFormation 私有登錄檔的模組
<a name="modules-using"></a>

本主題說明了如何在 CloudFormation 範本中使用模組。可將模組視為預先製作的資源套件，您可以將其新增至範本中。

使用模組的步驟如下：
+ **註冊模組** – 您可以在 CloudFormation 登錄檔中將模組註冊為私有延伸項目。請確定它已在您正在使用的 AWS 帳戶 和 區域中註冊。如需詳細資訊，請參閱[CloudFormation 登錄檔概念](registry-concepts.md)。
+ **將其包含在範本中** – 如同處理其他資源一般，將模組新增至 CloudFormation 範本的 [Resources](resources-section-structure.md) 區段。您還需提供該模組所需的所有必要屬性。
+ **建立或更新堆疊** – 當您起始堆疊操作時，CloudFormation 會產生處理過的範本，將任何包含的模組解析為適當的資源。
+ **預覽變更** – 進行變更前，您可使用變更集查看即將新增或變更的資源。如需詳細資訊，請參閱[透過變更集更新 CloudFormation 堆疊](using-cfn-updating-stacks-changesets.md)。

請考量下面的範例：你擁有同時內含資源和模組的範本。該範本包含一個個別的資源 `ResourceA`，以及模組 `ModuleParent`。該模組包含兩個資源 `ResourceB` 與 `ResourceC`，以及一個巢狀模組 `ModuleChild`，而 `ModuleChild` 包含單一資源 `ResourceD`。如果您透過此範本建立堆疊，CloudFormation 會處理此範本，並將模組解析為適當的資源。最終的堆疊包含四個資源：`ResourceA`、`ResourceB`、`ResourceC` 和 `ResourceD`。

![\[在堆疊操作期間，CloudFormation 會將堆疊範本中包含的兩個模組解析為適當的四個資源。\]](http://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/images/modules-resource-inclusion.png)


CloudFormation 會追蹤堆疊中的哪些資源是透過模組而建立。您可以在指定堆疊的 **Events** (事件)、**Resources** (資源) 和 **Drifts** (漂移) 索引標籤上檢視此資訊，變更集預覽中也會包含此資訊。

模組與範本中的資源有所不同，因為它們遵循的是以下四段命名慣例，而不是資源使用的典型三段慣例：

```
organization::service::use-case::MODULE
```

# 使用參數來指定模組值
<a name="module-using-params"></a>

在 CloudFormation 中，可以透過在堆疊建立或更新期間提供輸入值，使用範本參數來自訂堆疊。這些參數可讓您根據需求變更堆疊的某些層面。如需定義範本參數的詳細資訊，請參閱 [CloudFormation 範本 Parameters 語法](parameters-section-structure.md)。

同樣地，模組也可擁有參數。這些模組參數可讓您從使用它的範本 (或其他模組) 將自訂值輸入模組。然後，此模組可以使用這些自訂值，來設定其包含的屬性值。

您還可以定義範本參數，進而設定模組屬性，以便您可以輸入在堆疊操作時傳遞給模組的值。

如果模組包含的巢狀模組擁有自己的模組參數，您可以選擇以下任一方式：
+ 直接在父模組中指定巢狀模組參數的值。
+ 在父模組中定義對應的模組參數，使包含父模組的範本 (或模組) 可設定巢狀模組的參數。

## 使用範本參數指定模組參數值
<a name="module-using-params-example-1"></a>

下列範例顯示如何定義將值傳遞給模組的範本參數。

包含 `My::S3::SampleBucket::MODULE` 的範本會定義範本參數 `BucketName`，該參數可讓使用者在堆疊操作過程中指定 S3 儲存貯體名稱。

```
# Template containing My::S3::SampleBucket::MODULE
Parameters:
  BucketName:
    Description: Name for your sample bucket
    Type: String
Resources:
  MyBucket:
    Type: 'My::S3::SampleBucket::MODULE'
    Properties:
      BucketName: !Ref BucketName
```

## 透過父模組在子模組中指定資源的屬性
<a name="module-using-params-example-2"></a>

下列範例說明如何在另一個模組中巢狀堆疊的模組中指定參數值。

第一個模組 `My::S3::SampleBucketPrivate::MODULE` 將是子模組。其定義了兩個參數：`BucketName` 和 `AccessControl`。為這些參數指定的值會用來指定此模組包含之 `AWS::S3::Bucket` 資源的 `BucketName` 和 `AccessControl` 屬性。以下是 `My::S3::SampleBucketPrivate::MODULE` 的範本片段。

```
# My::S3::SampleBucketPrivate::MODULE
AWSTemplateFormatVersion: 2010-09-09
Description: A sample S3 Bucket with Versioning and DeletionPolicy.
Parameters:
  BucketName:
    Description: Name for the bucket
    Type: String
  AccessControl:
    Description: AccessControl for the bucket
    Type: String
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      AccessControl: !Ref AccessControl
      DeletionPolicy: Retain
      VersioningConfiguration:
        Status: Enabled
```

接下來，前一個模組會在父模組 `My::S3::SampleBucket::MODULE` 中巢狀堆疊。此父模組 `My::S3::SampleBucket::MODULE` 會以下列方式設定子模組參數：
+ 它會將 `My::S3::SampleBucketPrivate::MODULE` 的 `AccessControl` 參數設定為 `Private`。
+ 若是 `BucketName`，則會定義模組參數，此參數將允許在包含 `My::S3::SampleBucket::MODULE` 的範本 (或模組) 中指定儲存貯體名稱。

```
# My::S3::SampleBucket::MODULE
AWSTemplateFormatVersion: 2010-09-09
Description: A sample S3 Bucket. With Private AccessControl.
Parameters:
  BucketName:
    Description: Name for your sample bucket
    Type: String
Resources:
  MyBucket:
    Type: 'My::S3::SampleBucketPrivate::MODULE'
    Properties:
      BucketName: !Ref BucketName
      AccessControl: Private
```

## 指定模組參數的限制條件
<a name="modules-using-parameters-constraints"></a>

模組參數不支援限制條件強制實施。若要對模組參數執行限制條件檢查，請建立具有所需限制條件的範本參數。然後，在您的模組參數中參考該範本參數。如需定義範本參數的詳細資訊，請參閱 [CloudFormation 範本 Parameters 語法](parameters-section-structure.md)。

# 在 CloudFormation 範本中參考模組資源
<a name="module-ref-resources"></a>

在 CloudFormation 範本中，您通常需要根據另一個資源的名稱或屬性，設定某個資源的屬性。如需詳細資訊，請參閱[參考資源](resources-section-structure.md#using-cross-resource-references)。

若要在 CloudFormation 範本中參考模組內含的資源，您必須合併兩個邏輯名稱：
+ 當您將其引入範本時，為模組本身設定的邏輯名稱。
+ 該模組內特定資源的邏輯名稱。

您可以在這兩個邏輯名稱之間加點 (.) 或不加點，合併形成完整名稱。例如，若模組的邏輯名稱是 `MyModule`，而資源的邏輯名稱是 `MyBucket`，您可將該資源稱為 `MyModule.MyBucket` 或 `MyModuleMyBucket`。

若要查詢模組內資源的邏輯名稱，可以參閱模組的結構描述，該結構描述可在 CloudFormation 登錄檔或使用 [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeType.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeType.html) 操作取得。該結構描述會列出屬於模組的所有資源及其邏輯名稱。

取得完整的邏輯名稱後，您可以使用 `GetAtt` 和 `Ref` 等 CloudFormation 函數，存取模組資源上的屬性值。

例如，您有一個 `My::S3::SampleBucket::MODULE` 模組，其中包含邏輯名稱為 `S3Bucket` 的 `AWS::S3::Bucket` 資源。要使用 `Ref` 函數參考此儲存貯體的名稱，可以將範本 (`MyBucket`) 中的模組名稱與模組 (`S3Bucket`) 中的資源邏輯名稱合併。完整邏輯名稱可為 `MyBucket.S3Bucket` 或 `MyBucketS3Bucket`。

**範例 範本**  
下列範例範本會使用 `My::S3::SampleBucket::MODULE` 模組建立一個 S3 儲存貯體。它還會建立 Amazon SQS 佇列，並將其名稱設定為與模組中的儲存貯體名稱相同。此外，該範本會輸出建立的 S3 儲存貯體的 Amazon Resource Name (ARN)。

```
# Template that uses My::S3::SampleBucket::MODULE
Parameters:
  BucketName:
    Description: Name for your sample bucket
    Type: String
Resources:
  MyBucket:
    Type: My::S3::SampleBucket::MODULE
    Properties:
      BucketName: !Ref BucketName
  exampleQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: !Ref MyBucket.S3Bucket
Outputs:
  BucketArn:
    Value: !GetAtt MyBucket.S3Bucket.Arn
```