happyr/bref-hook-handler

处理 Bref Lambda 钩子的简单方法

资助包维护!
Nyholm

0.2.6 2020-11-27 09:57 UTC

This package is auto-updated.

Last update: 2024-08-28 19:13:50 UTC


README

Latest Version Software License Total Downloads

这个小型库可以帮助你确保在将流量引入之前,你的 lambda 应用程序的新版本确实可以工作。它使运行“预流量钩子”变得简单。

安装

composer require happyr/bref-hook-handler

我们还需要来自 davidgfserverless-plugin-canary-deployments

npm i --save-dev serverless-plugin-canary-deployments

配置

想法是创建一个新的 lambda 函数,可以验证一切是否正常工作。当我们确信一切正常时,我们将向 CodeDeploy 发出信号,允许真实流量。

示例 serverless.yml

service: canary-example
frameworkVersion: ">=1.69.0 <2.0.0"

# Bref and canary plugins
plugins:
  - ./vendor/bref/bref
  - serverless-plugin-canary-deployments

provider:
  name: aws
  region: eu-north-1
  runtime: provided
  memorySize: 1792
  environment:
    # Optional add the name of our main lambda function as env var
    HOOK_VERIFY_FUNCTION_NAME: ${self:service}-${opt:stage, "dev"}-website

  # Add IAM roles to use CodeDeploy and to be able to invoke our lambda function.
  iamRoleStatements:
    - Effect: Allow
      Action:
        - codedeploy:*
      Resource:
        - "*"
    - Effect: Allow
      Action:
        - lambda:InvokeFunction
      Resource:
        - arn:aws:lambda:${self:provider.region}:99999999:function:${self:service}-${opt:stage, "dev"}-website

functions:
  website:
    handler: public/index.php
    description: ''
    timeout: 8
    layers:
      - ${bref:layer.php-74-fpm}
    events:
      - http: 'ANY /'
      - http: 'ANY /{proxy+}'

    # Add deployment settings. This says: Deploy all at once if "preHook" says it is okey
    deploymentSettings:
      type: AllAtOnce
      alias: Live
      preTrafficHook: preHook

  # Define a PHP script to run to verify deployment.
  preHook:
    handler: prehook.php
    description: 'To verify deployment before allowing traffic'
    timeout: 10
    layers:
      - ${bref:layer.php-74}

示例 prehook.php

预钩子脚本是你启动应用程序内核、测试写入数据库、在队列上分发消息等的地方。如果你使用 HookHandler,它将自动与 CodeDeploy 进行通信。

当然,可以添加所需的多或少逻辑。

<?php

require dirname(__DIR__).'/vendor/autoload.php';

use Happyr\BrefHookHandler\ApiGatewayFaker;
use Happyr\BrefHookHandler\HookHandler;

return new class extends HookHandler {

    protected function validateDeployment(): bool
    {
        $apiGateway = new ApiGatewayFaker(\getenv('HOOK_VERIFY_FUNCTION_NAME'));
        $response = $apiGateway->request('GET', '/');
        $response->assertStatusCode(200);
        $response->assertBodyContains('Welcome to our site');

        $kernel = new \App\Kernel('prod', false);
        $kernel->boot();
        $kernel->getContainer()->get(CacheAccessChecker::class)->verify();

        // If no exceptions were thrown and we return true, then we will
        // signal CodeDeploy to allow traffic
        return true;
    }
};

发送 HTTP 请求

在上面的例子中,我们向我们的主页发送 HTTP 请求。我们不能使用 API Gateway,因为它不会将流量路由到新的 Lambda 版本。因此,我们直接使用看起来像来自 ApiGateway 的参数调用 lambda 版本。 ApiGatewayFaker 帮助我们做到这一点。

这就是为什么我们需要在 IAM 角色中配置 lambda:InvokeFunction 的唯一原因。

注意

如果 prehook.php 没有向 CodeDeploy 发出请求,则部署将卡在“检查堆栈更新进度”状态。这是一个好事。这确保了预钩子脚本总是报告“成功”。

如果发生这种情况,请检查 CloudWatch 日志。

太好了,让我们进行金丝雀部署!

可能会很诱人将 deploymentSettings.type 改为“全部同时”以外的其他值,以便首先将新版本暴露给 10% 的请求... 但这可能不是最佳选择。在更改之前,请先阅读这篇文章: https://lumigo.io/blog/canary-deployment-for-aws-lambda/