Help us learn about your current experience with the documentation. Take the survey.

从 GitLab CI/CD 部署到 AWS

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

GitLab 提供了包含部署到 AWS 所需库和工具的 Docker 镜像。 您可以在 CI/CD 管道中引用这些镜像。

如果您使用 GitLab.com 并部署到 Amazon Elastic Container Service (ECS), 请阅读有关 部署到 ECS 的文档。

如果您自己配置部署没有问题,只需要获取 AWS 凭证, 可以考虑使用 ID 令牌和 OpenID Connect。 ID 令牌比将凭证存储在 CI/CD 变量中更安全,但不适用于本页面的指导。

让 GitLab 与 AWS 认证

要使用 GitLab CI/CD 连接到 AWS,您必须进行认证。 设置认证后,您可以配置 CI/CD 进行部署。

  1. 登录您的 AWS 账户。

  2. 创建 一个 IAM 用户

  3. 选择您的用户以访问其详细信息。转到 Security credentials > Create a new access key

  4. 记下 Access key IDSecret access key

  5. 在您的 GitLab 项目中,转到 Settings > CI/CD。设置以下 CI/CD 变量

    环境变量名称
    AWS_ACCESS_KEY_ID 您的访问密钥 ID。
    AWS_SECRET_ACCESS_KEY 您的秘密访问密钥。
    AWS_DEFAULT_REGION 您的区域代码。您可能需要确认您打算使用的 AWS 服务在所选区域可用
  6. 变量默认受保护。 要将 GitLab CI/CD 与未受保护的分支或标签一起使用, 请取消勾选 Protect variable 复选框。

使用镜像运行 AWS 命令

如果镜像包含 AWS Command Line Interface, 您可以在项目的 .gitlab-ci.yml 文件中引用该镜像。然后您可以在 CI/CD 作业中运行 aws 命令。

例如:

deploy:
  stage: deploy
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  script:
    - aws s3 ...
    - aws create-deployment ...
  environment: production

GitLab 提供了一个包含 AWS CLI 的 Docker 镜像:

  • 镜像托管在 GitLab 容器注册表中。最新镜像是 registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  • 镜像存储在 GitLab 仓库中

或者,您可以使用 Amazon Elastic Container Registry (ECR) 镜像。 了解如何将镜像推送到您的 ECR 仓库

您也可以使用来自任何第三方注册表的镜像。

将您的应用程序部署到 ECS

您可以将应用程序的部署自动化到您的 Amazon ECS 集群。

先决条件:

  • 让 AWS 与 GitLab 认证
  • 在 Amazon ECS 上创建一个集群。
  • 创建相关组件,如 ECS 服务或 Amazon RDS 上的数据库。
  • 创建一个 ECS 任务定义,其中 containerDefinitions[].name 属性的值 与您目标 ECS 服务中定义的 Container name 相同。任务定义可以是:
    • ECS 中现有的任务定义。
    • 您 GitLab 项目中的 JSON 文件。使用 AWS 文档中的模板 并将文件保存在您的项目中。例如 <project-root>/ci/aws/task-definition.json

要部署到您的 ECS 集群:

  1. 在您的 GitLab 项目中,转到 Settings > CI/CD。设置以下 CI/CD 变量。您可以通过 在您的 Amazon ECS 控制台 上选择目标集群来找到这些名称。

    环境变量名称
    CI_AWS_ECS_CLUSTER 您要部署到的 AWS ECS 集群的名称。
    CI_AWS_ECS_SERVICE 与您的 AWS ECS 集群关联的目标服务的名称。确保此变量范围适当的环境(productionstagingreview/*)。
    CI_AWS_ECS_TASK_DEFINITION 如果任务定义在 ECS 中,则与服务关联的任务定义的名称。
    CI_AWS_ECS_TASK_DEFINITION_FILE 如果任务定义是 GitLab 中的 JSON 文件,则文件名,包括路径。例如,ci/aws/my_task_definition.json。如果您的 JSON 文件中的任务定义名称与 ECS 中现有任务定义的名称相同,则 CI/CD 运行时会创建一个新版本。否则,将创建一个全新的任务定义,从版本 1 开始。

    如果同时定义了 CI_AWS_ECS_TASK_DEFINITION_FILECI_AWS_ECS_TASK_DEFINITIONCI_AWS_ECS_TASK_DEFINITION_FILE 优先。

  2. .gitlab-ci.yml 中包含此模板:

    include:
      - template: AWS/Deploy-ECS.gitlab-ci.yml

    AWS/Deploy-ECS 模板随 GitLab 一起提供,并且可在 GitLab.com 上获取。

  3. 将更新后的 .gitlab-ci.yml 提交并推送到您的项目仓库。

您的应用程序 Docker 镜像将被重新构建并推送到 GitLab 容器注册表。 如果您的镜像位于私有注册表中,请确保您的任务定义 配置了 repositoryCredentials 属性

目标任务定义将更新为新 Docker 镜像的位置, 并在 ECS 中创建一个新版本作为结果。

最后,您的 AWS ECS 服务将使用任务定义的新版本更新, 使集群拉取您应用程序的最新版本。

ECS 部署作业会等待部署完成后再退出。要禁用此行为, 将 CI_AWS_ECS_WAIT_FOR_ROLLOUT_COMPLETE_DISABLED 设置为非空值。

AWS/Deploy-ECS.gitlab-ci.yml 模板包含两个模板:Jobs/Build.gitlab-ci.ymlJobs/Deploy/ECS.gitlab-ci.yml。不要单独包含这些模板。只包含 AWS/Deploy-ECS.gitlab-ci.yml 模板。这些其他模板设计为 仅与主模板一起使用。它们可能会意外移动或更改。此外,这些模板中的 作业名称可能会更改。不要在自己的管道中覆盖这些作业名称, 因为当名称更改时,覆盖将停止工作。

将您的应用程序部署到 EC2

GitLab 提供了一个名为 AWS/CF-Provision-and-Deploy-EC2 的模板, 帮助您部署到 Amazon EC2。

当您配置相关的 JSON 对象并使用该模板时,管道会:

  1. 创建堆栈:使用 AWS CloudFormation API 预配您的基础设施。
  2. 推送到 S3 存储桶:当您的构建运行时,它会创建一个工件。 该工件被推送到 AWS S3 存储桶。
  3. 部署到 EC2:内容被部署到 AWS EC2 实例上, 如下图所示:

显示 CF-Provision-and-Deploy-EC2 管道,包括预配基础架构、将工件推送到 S3 和部署到 EC2 的步骤。

配置模板和 JSON

要部署到 EC2,请完成以下步骤。

  1. 为您的堆栈创建 JSON。使用 AWS 模板

  2. 创建要推送到 S3 的 JSON。包含以下详细信息。

    {
      "applicationName": "string",
      "source": "string",
      "s3Location": "s3://your/bucket/project_built_file...]"
    }

    sourcebuild 作业构建您的应用程序的位置。 构建保存到 artifacts:paths

  3. 创建要部署到 EC2 的 JSON。使用 AWS 模板

  4. 使 JSON 对象对您的管道可访问:

    • 如果您希望将这些 JSON 对象保存在您的仓库中,请将对象保存为三个 单独的文件。

      在您的 .gitlab-ci.yml 文件中,添加 CI/CD 变量 指向相对于项目根目录的文件路径。例如, 如果您的 JSON 文件在 <project_root>/aws 文件夹中:

      variables:
        CI_AWS_CF_CREATE_STACK_FILE: 'aws/cf_create_stack.json'
        CI_AWS_S3_PUSH_FILE: 'aws/s3_push.json'
        CI_AWS_EC2_DEPLOYMENT_FILE: 'aws/create_deployment.json'
    • 如果您不希望将这些 JSON 对象保存在您的仓库中,请将每个对象 作为单独的 文件类型 CI/CD 变量 添加到项目设置中。使用相同的先前变量名称。

  5. 在您的 .gitlab-ci.yml 文件中,为堆栈名称创建一个 CI/CD 变量。例如:

    variables:
      CI_AWS_CF_STACK_NAME: 'YourStackName'
  6. 在您的 .gitlab-ci.yml 文件中,添加 CI 模板:

    include:
      - template: AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml
  7. 运行管道。

    • 您的 AWS CloudFormation 堆栈基于您 CI_AWS_CF_CREATE_STACK_FILE 变量的内容创建。 如果您的堆栈已存在,则跳过此步骤,但它所属的 provision 作业仍会运行。
    • 您构建的应用程序被推送到您的 S3 存储桶,然后基于 相关 JSON 对象的内容部署到您的 EC2 实例。当部署到 EC2 完成或失败时,部署作业结束。

故障排除

错误:‘ascii’ codec can’t encode character ‘\uxxxx’

当 Cloud Deploy 使用的 aws-cli 工具的响应包含 Unicode 字符时,可能会发生此错误。我们提供的 Cloud Deploy 镜像没有定义区域设置,默认使用 ASCII。要解决此错误,请添加以下 CI/CD 变量:

variables:
  LANG: "UTF-8"