

# 适用于 Amazon ECS 服务部署的生命周期挂钩
<a name="deployment-lifecycle-hooks"></a>

部署开始时，它会经历生命周期的各个阶段。每个阶段都可以处于 `IN_PROGRESS` 或 `SUCCEEDED` 等状态。您可以使用生命周期挂钩，这是 Amazon ECS 在指定的生命周期阶段代表您运行的 Lambda 函数。每次调用都包含一个 JSON 有效载荷，其中包含有关部署当前状态的信息。

## 生命周期钩子
<a name="lifecycle-hook-status"></a>

生命周期挂钩是 Amazon ECS 在部署的特定阶段调用的 Lambda 函数。您可以使用钩子来运行验证测试、强制执行治理策略，或在部署之前实施手动审批步骤。

当 Amazon ECS 调用钩子时，函数必须返回一个包含 `hookStatus` 字段的 JSON 对象。您可以选择包含 `callBackDelay` 来控制重试时间，以及包含 `hookDetails` 来在调用之间传递数据。如果函数未返回有效的 `hookStatus` 或失败，则 Amazon ECS 会回滚部署。

### hookStatus 值
<a name="hook-status-values"></a>

以下是有效的 `hookStatus` 值：
+ `SUCCEEDED`：部署将持续到下一个生命周期阶段。
+ `FAILED`：Amazon ECS 将部署回滚到上一个成功的服务修订。
+ `IN_PROGRESS`：Amazon ECS 在延迟一段时间后再次调用函数。默认延迟时间为 30 秒。您可以同时返回 `callBackDelay` 和 `hookStatus` 来自定义此值。

以下示例演示了如何返回带有自定义回调延迟的 `hookStatus`。在此示例中，Amazon ECS 会在 60 秒（不是默认 30 秒）后重试钩子：

```
{
    "hookStatus": "IN_PROGRESS",
    "callBackDelay": 60
}
```

### 通过 hookDetails 传递状态
<a name="hook-details"></a>

`hookDetails` 字段是一个字典，您可以使用它将数据传递给生命周期挂钩函数。有两种方法可以填充 `hookDetails`：
+ **在创建或更新服务时**：在服务定义的生命周期挂钩配置中定义 `hookDetails`。Amazon ECS 在每次调用时都会将此数据传递给您的函数。使用此方法可通过传入特定于服务的配置来使钩子可在多个服务中重复使用。
+ **在运行时通过 IN\_PROGRESS 响应**：返回 `hookDetails` 和 `IN_PROGRESS` 钩子状态。Amazon ECS 在下次调用时会将此数据传递回您的函数。使用此方法可在没有外部存储的情况下维护两次调用之间的状态。

以下示例展示了服务定义中的生命周期挂钩配置，该配置将 S3 存储桶名称传递给函数：

```
{
    "hookTargetArn": "arn:aws:lambda:us-west-2:123456789012:function:my-approval-hook",
    "roleArn": "arn:aws:iam::123456789012:role/ecs-lambda-invoke-role",
    "lifecycleStages": [
        "POST_TEST_TRAFFIC_SHIFT"
    ],
    "hookDetails": {
        "S3_BUCKET_NAME": "my-approval-bucket"
    }
}
```

当函数返回 `IN_PROGRESS` 时，您也可以在响应中包含 `hookDetails`。Amazon ECS 会将这些数据合并，并在下次调用时将其传递回去。常见使用案例包括在两次调用之间传递外部资源的指标计数器或 ARN。

```
{
    "hookStatus": "IN_PROGRESS",
    "callBackDelay": 30,
    "hookDetails": {
        "approvalChecked": true,
        "S3_BUCKET_NAME": "my-approval-bucket"
    }
}
```

下次调用时，Amazon ECS 会将 `hookDetails` 与 `executionDetails` 一起包含在事件有效载荷中：

```
{
  "executionId": "e8d5a28f-eb01-4f3c-9454-a30ba6dc54bc",
  "lifecycleStage": "POST_TEST_TRAFFIC_SHIFT",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {},
    "productionTrafficWeights": {}
  },
  "hookDetails": {
    "approvalChecked": true,
    "S3_BUCKET_NAME": "my-approval-bucket"
  }
}
```

函数可以读取 `event["hookDetails"]` 来访问先前调用中的配置和状态。

**注意**  
运行时添加到 `hookDetails` 的数据仅在单个部署中调用同一钩子时才会保留。数据不会在同一部署中的不同钩子之间传递，也不会在不同部署中的同一钩子之间传递。

## 生命周期阶段类别
<a name="lifecycle-stage-categories"></a>

生命周期阶段分为两类：

1. **单次调用阶段**：Amazon ECS 在服务部署期间只会调用这些阶段一次：
   + `RECONCILE_SERVICE`
   + `PRE_SCALE_UP`
   + `POST_SCALE_UP`
   + `POST_TEST_TRAFFIC_SHIFT`
   + `POST_PRODUCTION_TRAFFIC_SHIFT`

1. **重复调用阶段**：Amazon ECS 可以在服务部署期间多次调用这些阶段，包括在回滚期间：
   + `TEST_TRAFFIC_SHIFT`
   + `PRODUCTION_TRAFFIC_SHIFT`

## 生命周期有效载荷
<a name="service-deployment-lifecycle-payloads"></a>

### 常用有效载荷结构
<a name="common-payload-structure"></a>

当 Amazon ECS 调用生命周期挂钩 Lambda 函数时，事件有效载荷包含以下顶级字段：
+ `executionId`：此钩子执行的唯一标识符。
+ `lifecycleStage`：当前生命周期阶段（例如 `PRODUCTION_TRAFFIC_SHIFT`）。
+ `resourceArn`：与部署关联的资源的 ARN。
+ `executionDetails`：包含以下列表中描述的部署特定信息的对象。

`executionDetails` 对象包含以下字段：
+  `serviceArn`：服务的 Amazon 资源名称（ARN）。
+  `targetServiceRevisionArn`：正在部署的目标服务修订的 ARN。
+  `testTrafficWeights`：服务修订 ARN 与相应测试流量权重百分比的映射。
+  `productionTrafficWeights`：服务修订 ARN 与相应生产流量权重百分比的映射。

以下示例展示了 Lambda 函数接收的完整事件结构：

```
{
  "executionId": "f4fcae0f-9bec-41c6-ba87-0eaa0cef8af5",
  "lifecycleStage": "PRODUCTION_TRAFFIC_SHIFT",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {},
    "productionTrafficWeights": {
      "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900": 100,
      "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/1920498462936580504": 0
    }
  }
}
```

### 生命周期阶段有效载荷
<a name="lifecycle-stage-payloads"></a>

以下各节展示了每个生命周期阶段的示例有效载荷。在这些示例中，绿色服务修订（`9313423515462893900`）是正在部署的新修订，而蓝色服务修订（`1920498462936580504`）是现有的生产修订。

#### PRE\_SCALE\_UP
<a name="pre-scale-up"></a>

此阶段发生在 Amazon ECS 启动绿色服务修订任务之前。绿色服务修订尚未开始，也没有流量路由到该修订。

```
{
  "executionId": "e8d5a28f-eb01-4f3c-9454-a30ba6dc54bc",
  "lifecycleStage": "PRE_SCALE_UP",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {},
    "productionTrafficWeights": {}
  }
}
```

#### POST\_SCALE\_UP
<a name="post-scale-up"></a>

此阶段发生在 Amazon ECS 启动绿色服务修订任务且这些任务运行正常之后。绿色任务正在运行，但尚未接收到任何流量。

```
{
  "executionId": "8b095b05-7bb0-4c56-a223-a3f61f4f9295",
  "lifecycleStage": "POST_SCALE_UP",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {},
    "productionTrafficWeights": {}
  }
}
```

#### TEST\_TRAFFIC\_SHIFT
<a name="test-traffic-shift"></a>

此阶段发生在 Amazon ECS 将测试流量转移到绿色服务修订时。`testTrafficWeights` 显示绿色修订接收 100% 的测试流量，而蓝色修订接收 0% 的流量。生产流量继续流向蓝色修订。

```
{
  "executionId": "779085de-ab47-42bc-84ad-41f9914a8643",
  "lifecycleStage": "TEST_TRAFFIC_SHIFT",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {
      "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900": 100,
      "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/1920498462936580504": 0
    },
    "productionTrafficWeights": {}
  }
}
```

#### POST\_TEST\_TRAFFIC\_SHIFT
<a name="post-test-traffic-shift"></a>

此阶段发生在 Amazon ECS 完成测试流量转移之后。绿色服务修订正在处理 100% 的测试流量。

```
{
  "executionId": "3a0345ba-b029-404b-890d-7da2a4b266aa",
  "lifecycleStage": "POST_TEST_TRAFFIC_SHIFT",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {},
    "productionTrafficWeights": {}
  }
}
```

#### PRODUCTION\_TRAFFIC\_SHIFT
<a name="production-traffic-shift"></a>

此阶段发生在 Amazon ECS 将生产流量转移到绿色服务修订时。`productionTrafficWeights` 显示绿色修订接收 100% 的生产流量，而蓝色修订接收 0% 的流量。

```
{
  "executionId": "f4fcae0f-9bec-41c6-ba87-0eaa0cef8af5",
  "lifecycleStage": "PRODUCTION_TRAFFIC_SHIFT",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {},
    "productionTrafficWeights": {
      "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900": 100,
      "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/1920498462936580504": 0
    }
  }
}
```

#### POST\_PRODUCTION\_TRAFFIC\_SHIFT
<a name="post-production-traffic-shift"></a>

此阶段发生在 Amazon ECS 完成生产流量转移之后。绿色服务修订现在处理所有生产流量。

```
{
  "executionId": "5f40ed04-7e54-437d-b95d-98bc872fec49",
  "lifecycleStage": "POST_PRODUCTION_TRAFFIC_SHIFT",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {},
    "productionTrafficWeights": {}
  }
}
```

## 回滚期间的生命周期挂钩
<a name="lifecycle-hooks-during-rollback"></a>

没有专门的 `ROLLBACK` 生命周期阶段。发生回滚时，Amazon ECS 会重新调用在 `PRODUCTION_TRAFFIC_SHIFT` 和 `TEST_TRAFFIC_SHIFT` 阶段（重复调用阶段）注册的钩子。回滚期间，有效载荷中的 `productionTrafficWeights` 显示流量正在转移回蓝色修订。

`targetServiceRevisionArn` 仍然是绿色修订 ARN，因为它仍然是原始部署的目标，尽管流量正在偏离它。

以下示例显示了回滚期间的 `PRODUCTION_TRAFFIC_SHIFT` 有效载荷。请注意，蓝色修订（`1920498462936580504`）现在接收 100% 的生产流量，而绿色修订（`9313423515462893900`）接收 0% 的流量：

```
{
  "executionId": "70073435-cb99-457f-b900-6ee1dcad05ec",
  "lifecycleStage": "PRODUCTION_TRAFFIC_SHIFT",
  "resourceArn": "arn:aws:ecs:us-west-2:123456789012:service-deployment/my-cluster/my-service/EZe5RNVLH6PPzHXINuP28",
  "executionDetails": {
    "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/my-cluster/my-service",
    "targetServiceRevisionArn": "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900",
    "testTrafficWeights": {},
    "productionTrafficWeights": {
      "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/9313423515462893900": 0,
      "arn:aws:ecs:us-west-2:123456789012:service-revision/my-cluster/my-service/1920498462936580504": 100
    }
  }
}
```

要确定回滚期间是否调用了钩子，请检查 `productionTrafficWeights`。如果 `targetServiceRevisionArn`（绿色修订）的权重为 0%，而另一个修订的权重为 100%，则部署正在回滚。