在 Amazon ECS 上部署容器 Web 應用程式

入門指南

單元 2:建立基礎設施及部署應用程式

在本單元中,您將建立 ECS 叢集,並以 CDK 部署應用程式

簡介

在本單元中,您將建立 AWS CDK 應用程式,以建立設定 ECS 叢集、並在上部署範例容器所需的全部基礎設施。

您將學到的內容

  • 建立簡單的 CDK 應用程式
  • 建立 ECS 叢集,並有 Fargate 以處理容量
  • 建立任務定義與服務,以部署我們的應用程式

 完成時間

15 分鐘

 單元先決條件

  • 有管理員等級存取權限的 AWS 帳戶**
  • 建議的瀏覽器:最新版的 Chrome 或 Firefox

[**]過去 24 小時內建立的帳戶可能尚未有權存取本教學課程所需的服務。

實作

建立 CDK 應用程式

首先,確保您已安裝 CDK。如果您沒有安裝它,請按照 AWS CDK 入門進行操作:

cdk --version

我們現在將使用 TypeScript 作為所選擇的語言來建立框架 CDK 應用程式。在終端機中執行以下命令:

mkdir cdk-ecs-infra
cd cdk-ecs-infra
cdk init app --language typescript

這將輸出如下內容:

Applying project template app for typescript
# Welcome to your CDK TypeScript project!

This is a blank project for TypeScript development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands

 * `npm run build`   compile typescript to js
 * `npm run watch`   watch for changes and compile
 * `npm run test`    perform the jest unit tests
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk synth`       emits the synthesized CloudFormation template

Executing npm install...
✅ All done!

建立資源堆疊的程式碼

前往檔案 /lib/cdk-ecs-infra-stack.ts,您將在此為您要建立的資源堆疊撰寫程式碼。

資源堆疊是一組將佈建至特定帳戶中的雲端基礎設施資源 (在特定案例中,將全都是 AWS 資源)。佈建這些資源的帳戶/區域可以在堆疊中設定 (如 AWS CDK 入門指南所述)。

在此資源堆疊中,您將建立下列資源:

  • IAM 角色:此角色將分配給容器以允許它叫用其他 AWS 服務。
  • ECS 任務定義:啟動容器時使用的特定參數。
  • ECS Pattern for Fargate 負載平衡服務:可抽離建立叢集、負載平衡器、服務,及設定一切以共同運作所需全部元件的繁雜。

建立 ECS 叢集

要開始建立 ECS 叢集,您首先需要匯入正確的模組:

npm i @aws-cdk/aws-s3-assets

然後,在您的 lib/cdk-eb-infra-stack.ts 檔案中,將相依性新增至檔案的最上方。

npm i @aws-cdk/aws-ec2 @aws-cdk/aws-ecs @aws-cdk/aws-ecs-patterns @aws-cdk/aws-iam 

然後,您將編輯 lib/cdk-eb-infra-stack.ts 檔案,將相依項新增至檔案頂部:

import ecs = require('@aws-cdk/aws-ecs'); // Allows working with ECS resources
import ec2 = require('@aws-cdk/aws-ec2'); // Allows working with EC2 and VPC resources
import iam = require('@aws-cdk/aws-iam'); // Allows working with IAM resources
import ecsPatterns = require('@aws-cdk/aws-ecs-patterns') // Helper to create ECS services with loadbalancers, and configure them

這些模組提供對部署 Web 應用程式所需的所有元件的存取。第一個步驟是新增以下程式碼來查找您帳戶中現有的預設 VPC:

// Look up the default VPC
const vpc = ec2.Vpc.fromLookup(this, "VPC", {
   isDefault: true
});

接下來,您需要定義使用的容器,以及應當如何設定。其作法是建立任務定義,以提供容器連接埠、其所需的 CPU 和記憶體數量,以及使用的容器映像。針對此指南,我們將建置 SampleApp 資料夾中範例應用程式隨附的容器映像,並以 CDK 代為容器的管理、建置、上傳及部署。我們也將建立空白 IAM 角色以連接至任務定義,供日後的指南使用。 

若要建立任務定義和 IAM 角色,請新增以下程式碼:

const taskIamRole = new iam.Role(this, "AppRole", {
    roleName: "AppRole",
    assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});

const taskDefinition = new ecs.FargateTaskDefinition(this, 'Task', {
    taskRole: taskIamRole,
});

taskDefinition.addContainer('MyContainer', {
    image: ecs.ContainerImage.fromAsset('../SampleApp'),
    portMappings: [{ containerPort: 80 }],
    memoryReservationMiB: 256,
     cpu : 256,
});

在上方的程式碼中,可以看見您藉由 FargateTaskDefintion 以及藉由 ContainerImage.fromAsset,指定了部署至 Fargate 的任務定義類型。CDK 會使用 SampleApp 目錄中的 Dockerfile 建置容器映像。

接下來,您需要設定 ECS 叢集、定義服務、建立負載平衡器、將它設定為連線至服務,並且設定所需的安全群組規則。ECS 中有一項服務用來指定您要的份數、部署策略及其他組態,以啟動任務定義。為此範例,我們只啟動 1 份容器。安全群組為您的執行個體擔任虛擬防火牆,以控制傳入與傳出流量,但您無需設定,因為您所使用的 ECS Pattern 會代勞。 

請在您的專案中,任務定義的下方新增以下程式碼:

new ecsPatterns.ApplicationLoadBalancedFargateService(this, "MyApp", {
    vpc: vpc,
    taskDefinition: taskDefinition,
    desiredCount: 1,
    serviceName: 'MyWebApp',
    assignPublicIp: true,
    publicLoadBalancer: true,
})

這會傳遞入您先前查詢的 VPC 物件,以指定建立所有資源的位置,並連同任務定義,其定義所部署的容器映像。desiredCount 指出您想要的份數、serviceName 指出您想為服務取的名稱,publicLoadBalancer 設為 True,以便您能透過網際網路加以存取。 此範例中,將 assignPublicIp 設定為 True 的字行相當重要,因為我們要使用並無私有子網路的預設 VPC。最佳實務建議在私有子網路中啟動服務,但這超出本指南的範圍。

現在您已就緒可部署 Web 應用程式,但首先必須在所要部署至的帳戶上設定 CDK。 

編輯 bin/cdk-ecs-infra.ts 檔案,並取消注釋第 14 列:

env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

這將使用 AWS CLI 中設定的帳戶 ID 和區域。在您可以使用 CDK 之前,它需要進行 Bootstrap - 這將建立 CDK 的必要基礎設施,以在您的帳戶中管理基礎設施。若要 Bootstrap CDK,請執行 cdk bootstrap。您應該會看到如下的輸出:

cdk bootstrap

#output
⏳  Bootstrapping environment aws://0123456789012/<region>...
✅  Environment aws://0123456789012/<region> bootstrapped

如此可建立讓 CDK 管理您帳戶內之基礎設施所需的基礎設施 - 若您對於設定 CDK 應用程式並不熟悉,我們建議逐步使用 AWS CDK 入門指南。

一旦自舉完成,請執行 cdk deploy 以部署所需的容器、叢集和其餘基礎設施。您應該會看到如下的輸出:

CDK 將在建立基礎設施之前提示您,因為它正要建立的基礎設施會變更安全組態 - 在您的案例中,方法是建立 IAM 角色和安全群組。按下 y,然後按 enter 來部署。CDK 現在將設定您定義的所有基礎設施,完成時間需要幾分鐘。 

執行中時,會顯示如下的更新:

一旦完成,您即可看見如下輸出,並附帶公有 URL 的連結,以用來存取您的服務:

完整程式碼範例

import * as cdk from '@aws-cdk/core';
import ecs = require('@aws-cdk/aws-ecs');
import ec2 = require('@aws-cdk/aws-ec2');
import iam = require('@aws-cdk/aws-iam');
import ecsPatterns = require('@aws-cdk/aws-ecs-patterns')

export class CdkEcsInfraStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

      // Look up the default VPC
      const vpc = ec2.Vpc.fromLookup(this, "VPC", {
        isDefault: true
      });

      const taskIamRole = new iam.Role(this, "AppRole", {
        roleName: "AppRole",
        assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
      });

      const taskDefinition = new ecs.FargateTaskDefinition(this, 'Task', {
        taskRole: taskIamRole,
      });

      taskDefinition.addContainer('MyContainer', {
        image: ecs.ContainerImage.fromAsset('../SampleApp'),
        portMappings: [{ containerPort: 80 }],
        memoryReservationMiB: 256,
        cpu : 256,
      });

      new ecsPatterns.ApplicationLoadBalancedFargateService(this, "MyApp", {
        vpc: vpc,
        taskDefinition: taskDefinition,
        desiredCount: 1,
        serviceName: 'MyWebApp',
        assignPublicIp: true,
        publicLoadBalancer: true,
      })

  }
}

結語

在此單元中,您已了解如何建立 ECS 叢集,及使用 CDK 提供的 ECS Pattern,以負載平衡器供應流量至 Fargate 上執行的容器。在下一個單元中,您將清理本指南中建立的所有資源。

下一步:清理資源

讓我們知道我們表現如何。