如何部署到 AWS ECS

我们将部署相同的代码到 AWS —— 这一次,我们将通过 Docker 容器部署到 ECS。ECS 是一个高度可扩展的容器管理服务,允许您在集群中运行、停止和管理容器。您可以在以下链接找到逐步指导: GitHub Step-by-Step Guide

部署 AWS 资源

我找不到一个简单的脚本来部署所有资源到 AWS,同时又没有一些复杂的 JSON 文件。这就是为什么我使用手动步骤的原因,参考了动手实验的步骤。

首先,您需要创建一个 Elastic Container Registry(ECR)仓库,用于部署容器。我们用来部署的凭证叫做 Access Keys,它们包含两个值:Access Key IDSecret Access Key

第一次部署后,容器会存储在注册表中,您可以使用它并通过向导设置您的 ECS 资源。

您需要提取任务定义,并将其保存到 aws-task-definition.json 文件中。在第二次运行工作流时,容器就能成功地部署到 ECS。

使用 GitHub Actions 部署容器

我还将工作流分为两个阶段:构建阶段部署阶段。这样,您可以轻松地添加环境和更多阶段。为了使其工作,您必须将构建阶段的镜像名称传递给部署阶段。您可以使用工作输出实现这一点:

jobs:
  Build:
    runs-on: ubuntu-latest
    outputs:
      image: ${{ steps.build-image.outputs.image }}

为了配置身份验证,我们使用 configure-aws-credentials 操作,并提供 Access Key IDSecret Access Key 值。

需要注意的是,GitHub 会屏蔽部分镜像名称,且不会将其传递给下一个作业。为避免这种情况,您必须禁止 configure-aws-credentials 操作屏蔽您的账户 ID:

- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: ${{ env.AWS_REGION }}
    mask-aws-account-id: no

登录到 ECR 后,您将获得注册表的名称,并在后续步骤中使用:

- name: Login to Amazon ECR
  id: login-ecr
  uses: aws-actions/amazon-ecr-login@v1

接下来,您将构建镜像并将其推送到 ECR,并设置输出供下一个阶段使用:

- name: Build, tag, and push image to Amazon ECR
  id: build-image
  env:
    ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
    IMAGE_TAG: ${{ github.sha }}
  working-directory: ch9_release/src/Tailwind.Traders.Web
  run: |
    imagename=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
    echo "Build and push $imagename"
    docker build -t $imagename .
    docker push $imagename
    echo "::set-output name=image::$imagename"

下一个作业依赖于构建阶段,并在生产环境中运行:

Deploy:
  runs-on: ubuntu-latest
  environment: prod
  needs: Build

此外,部署阶段还需要配置 AWS 凭证,然后通过传递给作业的镜像名称,配置 aws-taskdefinition.json 文件:

- name: Fill in the new image ID in the ECS task definition
  id: task-def
  uses: aws-actions/amazon-ecs-render-task-definition@v1
  with:
    task-definition: ${{ env.ECS_TASK_DEFINITION }}
    container-name: ${{ env.CONTAINER_NAME }}
    image: ${{ needs.Build.outputs.image }}

最后一步是使用前一步输出的任务定义部署容器:

- name: Deploy Amazon ECS task definition
  uses: aws-actions/amazon-ecs-deploy-task-definition@v1
  with:
    task-definition: ${{ steps.task-def.outputs.task-definition }}
    service: ${{ env.ECS_SERVICE }}
    cluster: ${{ env.ECS_CLUSTER }}
    wait-for-service-stability: true

如果您按照逐步指南操作,您将有一个阶段化的工作流,可以将容器部署到 ECS。您可以根据需要添加更多阶段,或者在不同的服务中运行不同版本的容器。