

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

# 在 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)。