AWS Lambda和持续交付pipeline

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2016/11/19/aws-lambda-ci-pipeline/

为了让更多的事情自动化,并且能够持续的交付和发布新的功能,一个顺手的Pipeline是必要的。

如果是自己维护的持续交付pipeline,那么大部分都是Jenkins。如果是不自己维护的,那选择就太多了,从Travis CI, Circle CI 到Snap CI选择丰富,而且很多也提供了收费服务。

我们以一个Spring Boot的Web项目为例,一般情况下这个pipeline需要以下几个必要的步骤:

pipeline

其中发布到各种环境的操作大体为以下几个步骤:

  1. 停止运行原有jar文件
  2. 拷贝新的jar文件和必要的其他文件到运行环境
  3. 重新运行jar文件
  4. 测试是否正常启动

如果同样一个项目采用无服务器架构,即serverless模式,那么多半使用的使用AWS Lambda。

对于这种情况再对比我们的pipeline,其实很明显,需要改变的只有最后两个步骤lambda-pipeline

发布步骤如下:

  1. 准备必要的zip包(这一步可以再编译项目环境就完成)
  2. 上传zip包到aws lambda
  3. 执行lambda并测试结果

所以我们的问题叫变成了

  1. 如果在pipeline中更新AWS Lambda function的代码
  2. 如何调用lambda并测试结果

更新AWS Lambda function代码

由于AWS Lambda function并不能直接触发,而是需要一个触发器来执行,这里的触发器是API Gateway,通过API Gateway将所有Lambda function暴露出去。

那么更新代码就涉及到一个问题,如果添加一个新的Endpoint(假定我们要实现一个新的功能,这个功能之前没有),那么API Gateway中就需要新增一个对应的配置,这个配置是手动的,还是自动的。

只更新代码不涉及触发器

如果是手动的,那么我们就可以假定所有发布实质上只是代码包的更新,这种情况下我们可以直接简单的调用AWS API即可,没有必要使用第三方的库或者工具了。

PUT /2015-03-31/functions/FunctionName/code HTTP/1.1
Content-type: application/json

{
   "Publish": boolean,
   "S3Bucket": "string",
   "S3Key": "string",
   "S3ObjectVersion": "string",
   "ZipFile": blob
}

这个API调用只能针对已经存在的function,当然也有创建新的function的API

POST /2015-03-31/functions HTTP/1.1
Content-type: application/json

{
   "Code": { 
      "S3Bucket": "string",
      "S3Key": "string",
      "S3ObjectVersion": "string",
      "ZipFile": blob
   },
   "Description": "string",
   "Environment": { 
      "Variables": { 
         "string" : "string" 
      }
   },
   "FunctionName": "string",
   "Handler": "string",
   "KMSKeyArn": "string",
   "MemorySize": number,
   "Publish": boolean,
   "Role": "string",
   "Runtime": "string",
   "Timeout": number,
   "VpcConfig": { 
      "SecurityGroupIds": [ "string" ],
      "SubnetIds": [ "string" ]
   }
}

Jenkins中可以找一个AWS Lambda的插件,它可以更新代码,当function不存在的时候也会自动创建。

aws-jenkins-plugin

 

更新代码且需要维护触发器

这种情况稍微麻烦一些,但是也是我觉得最理想的情况。手动维护触发器很繁琐,出错与否先不论,如果不能自动化,还需要在不同的测试环境之间同步配置,实在闹心。

对于这种情况,AWS API当然能够做到,而且还有aws cli工具呢。

aws apigateway put-method --rest-api-id 1234123412 --resource-id a1b2c3 --http-method PUT --authorization-type "NONE" --no-api-key-required --request-parameters "method.request.header.custom-header=false" --region us-west-2

这里推荐使用Serverless framework (https://serverless.com/)

serverless

它有专门的机制管理了event的维护,这是一个实例配置,它的触发器是api gateway

# 'functions' in serverless.yml
functions:
  createUser: # Function name
    handler: handler.createUser # Reference to file handler.js & exported function 'createUser'
    events: # All events associated with this function
      - http:
          path: users/create
          method: post

当然还有多个event的情况,它也支持

# 'functions' in serverless.yml
functions:
  createUser: # Function name
    handler: handler.users # Reference to file handler.js & exported function 'users'
    events: # All events associated with this function
      - http:
          path: users/create
          method: post
      - http:
          path: users/update
          method: put
      - http:
          path: users/delete
          method: delete

这样的好处在于触发器的配置可以包含在代码库中,而相关的维护由工具完成。

执行lambda并测试结果

这里指定lambda的原因和之前的原因可能不大意义。

因为pipeline有一个build number的概念,合理的时候可以帮助我们判断当前测试环境的代码版本便于管理和回滚。而AWS Lambda中对于版本的管理是采用Versioning的方式,我们默认更新的是$LATEST版本,所以执行lambda的作用更多的是在于判断是否能够成功触发。

还有一个好处是AWS Lambda虽然是无状态的,会随时销毁的,但是依然有重用机制,执行一次之后会有一个容器方便下次使用,可以带来一定的性能提升。

具体的执行办法就比较多了,上面提到的Jenkins AWS Lambda Plugin和Serverless framework都可以实现。

当然因为这里的例子是一个Web项目,直接请求API Gateway也是可以的。、

结论

所以对于运行于AWS Lambda的项目而言,其Pipeline并不会有太多变化,主要集中在发布上,而发布这个问题上AWS自身提供了完整功能的API,所以即便没有任何工具和插件,也是可以使用简单脚本实现的。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2016/11/19/aws-lambda-ci-pipeline/

发表评论