

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

# 透過 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
```