用无服务器应用模型部署无服务器应用

阅读数:111 2019 年 11 月 11 日 08:00

用无服务器应用模型部署无服务器应用
_ 作者:薛峰 _
复制代码
上一篇文章中我们介绍了 AWS 无服务器应用模型和 SAM 模板的基本功能和特性,并带领大家用一个实例体验了通过 CloudFormation 部署 SAM 模板。在这一篇中,我们仍然结合实例讲解,为大家继续介绍使用 AWS CodeBuild 构建 Lambda 函数以及使用 AWS CodePipeline 实现自动化持续集成。
### 部署配置 AWS CodeBuild
如果我们的 Lambda 函数使用了依赖库时,我们可以通过 AWS CodeBuild 来把依赖库编译进 Lambda 函数的部署包里。
AWS CodeBuild 是一个完全托管的构建服务,可用于编写源代码、运行测试并生成可立即部署的软件包。CodeBuild 基于 AWS 管理的容器,从而实现用户无需配置、管理和扩展自己的构建服务器。CodeBuild 可持续缩放和并行处理多个生成任务,因此构建任务不必在队列中等待。使用 CodeBuild,我们只需要按构建时使用计算资源的分钟数付费,从而无需为预置的构建服务器的空闲时间付费。
除了常见的 Java 之类的程序源码的构建,CodeBuild 还可用于 Lambda 函数部署前的构建。下面我们用一个例子来具体说明。
请先从以下 git 库下载源码。
https://github.com/xfsnow/serverless/tree/master/sam/codebuild
这个例子中的 Lambda 函数需要 Node.js 依赖库 time,我们使用 CodeBuild 在构建时安装这个这个 time 库,把它加入到 Lambda 函数的包中。
index.js 文件中以下这行,表示需要依赖库 time。
Java
复制代码
var time = require('time');
复制代码
buildspec.yml
Java
复制代码
install:
commands:
- npm install time
复制代码
表示在构建的安装步骤把 time 库安装进来。
Java
复制代码
build:
commands:
- aws cloudformation package --template-file codebuild.yaml --s3-bucket <bucket-name> --output-template-file output_codebuild.yaml
复制代码
这段其实就是使用在上一章节我们介绍过的 aws cloudformation package 打包。
#### 上传源文件
把 buildspec.yml 文件中的 <bucket-name> 等变量值替换成你的具体的值。
在当前目录下除了 md 文件的其它文件打包成 codebuild.zip,然后把这个 zip 文件上传你自己的 S3 桶中。
#### 配置 CodeBuild 项目
打开 CodeBuild 控制台
点击 Create project。
在 Configure your project 页
Project name 输入 serverlessCodebuild
Source provider 选择 Amazon S3
Bucket 栏选择我们的刚才上传 zip 文件的 S3 桶名称
S3 object key 输入 codebuild.zip。
Environment image 保持选择 Use an image managed by AWS CodeBuild
Operating system 选择 Ubuntu
Runtime 选 Node.js
Version 选择 aws/codebuild/nodejs:4.3.2
Artifacts type 选 Amazon S3
Bucket name 还选择我们的刚才上传 zip 文件的 S3 桶名称
确认 Create a service role in your account 已选中
Role name 输入 serverlessCodebuild
点击右下角 Continue 按钮
在 Review 页点击右下方的 Save and build 按钮。
创建成功后前进到 Build projects 列表页,此时刚刚新建的项目应该是选中的状态。点击左上角 Start build 按钮。
在 Start new build 页,直接点击右下角 Start build 按钮。
在 Build 页可以查看构建进行的进度信息。注意看 Phase details 下面的输出内容。 构建成功完成以后,可以到我们的 S3 桶中查看结果,可以看到创建出一个 serverlessCodebuild 目录,里面就是构建的成果—— output_codebuild.yaml 文件。我们把它下载到本地,就可以用它再执行 CloudFormation 部署。
#### 使用 CloudFormation 部署
执行以下命令
Java
复制代码
aws cloudformation deploy \
--template-file output_codebuild.yaml \
--stack-name serverlessCodebuild \
--capabilities CAPABILITY_IAM
复制代码
顺利地话,会看到逐渐输出的返回结果
`Waiting for changeset to be created.. `
Java
复制代码
Waiting for stack create/update to complete
Successfully created/updated stack - serverlessCodebuild
复制代码
这时到 CloudFormation 的控制台已经创建出一个 serverlessCodebuild ,整个过程大约持续 1 到 2 分钟。
然后到 API Gateway 控制台,可以看到创建出的 serverlessCodebuild 的 API,点击其 Stages 下的 Prod 链接,可以看到形如下面的调用 URL: Invoke URL: https://xxxxxxxxx.execute-api.my-region.amazonaws.com/Prod
点击它,打开一个新窗口,显示
“The time in Los Angeles is Mon Aug 07 2017 03:32:42 GMT-0700 (PDT)”
表示已经部署成功。
### 部署配置 AWS CodePipeline
每次都要手工执行 aws cloudformation deploy 命令来部署仍然有些繁琐,而且手工部署难免会有人工的失误。下面我们使用 AWS CodePipeline 来最终实现完全自动化的部署。
AWS CodePipeline 是一个托管的持续集成与持续交付服务,可以实现快速而可靠的应用程序和基础设施更新。每次更改代码时,CodePipeline 都会根据我们定义的发布流程模型构建、测试和部署代码,就像管道一样逐个步骤的执行流程中的每一步操作,还支持可选的人工审核步骤。和 CodeBuild 一样, CodePipeline 也是只按实际使用量付费,同样无需为预置的资源空闲付费。
我们下面这个例子,Lambda 函数还是使用了 time 依赖库,仍然使用 CodeBuild 安装依赖库、CloudFormation 进行部署,这次我们配置 CodePipeline 来完成构建和部署的全部流程,实现持续集成。
总的操作流程主要是以下几步:
1. 在 github 上创建一个库存放源文件。
2. 创建一个 CodeBuild 项目,用于构建无服务器应用。
3. 创建一个 IAM 角色,用于 CloudFormation 部署无服务器应用。
4. 创建一个 CodePipeline 项目,把上述若干步骤和资源组建成管道。
在 github 上创建一个库存放源文件
请在你自己的 github 新建一个存储库,名为 serverlessCodepipepline。
从以下 git 库下载源码。
https://github.com/xfsnow/serverless/blob/master/sam/codepipeline
放在我们自已的 serverlessCodepipepline 库的根目录下。
把 buildspec.yml 中的 <bucket> 更新成自己的桶名称,再 commit 到 git 库中。
#### 配置 CodeBuild 项目
* 打开 CodeBuild 控制台,点击 Create project
> 在 Configure your project
>
> Project name 输入 serverlessCodepipeline
>
> Source provider 选择 Github
>
> Repository 选择 Use a repository in my account
>
> Repository URL 输入我们自己的库的路径,比如 https://github.com/xfsnow/serverlessCodepipepline
* Environment image 保持选择 Use an image managed by AWS CodeBuild
> Operating system 选择 Ubuntu
>
> Runtime 选 Node.js
>
> Version 选择 aws/codebuild/nodejs:4.3.2
>
> Build specification 保持选中 Use the buildspec.yml in the source code root directory
>
> Artifacts type 选 Amazon S3
>
> Bucket name 还选择我们在 buildspec.yml 中指定的 S3 桶名称
>
> 确认 Create a service role in your account 已选中
>
> Role name 输入 serverlessCodebuild,点击右下角 Continue 按钮。
* 在 Review 页点击右下方的 Save and build 按钮。
> 创建成功后前进到 Build projects 列表页,此时刚刚新建的项目应该是选中的状态。点击左上角 Start build 按钮。
>
> 在 Start new build 页,直接点击右下角 Start build 按钮。
* 在 Build 页可以查看构建进行的进度信息。注意看 Phase details 下面的输出内容。
> 构建成功完成以后,可以到我们的 S3 桶中查看结果,可以看到创建出一个 serverlessCodepipeline 目录,里面就是构建的成果—— output-codepipeline.yaml 文件。
>
> 我们可以把它下载到本地看一下,后续我们继续配置 CodePipeline 就是用它来做无服务器资源的部署。
#### 配置 IAM 角色
登录 AWS 管理控制台。点击左侧导航链接中的 Roles,点击 Create new role 按钮。
* 在 Select role type 页选择 AWS Service Role,找到 AWS Cloudformation Role 点击其右边的 Select 按钮。
* 在 Attach Policy 页,选择 AWSLambdaExecute。点击 Next Step 按钮。
* 在 Set role name and review 页, Role name 输入 cloudformation-lambda-execution,然后点击 Create role 按钮。
* 打开刚才创建的角色,在 Permissions 选项卡下,点击 Inline Policies 展开之,然后选择 click here 链接。
选择 Custom Policy,然后选择 Select
Policy Name 中,输入 cloudformation-deploy-lambda ,然后将以下内容中的 **region** 和 **account_id** 替换成你自己的值,粘贴到 Policy Document 字段中:
Java
复制代码
{
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketVersioning"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::codepipeline*"
],
"Effect": "Allow"
},
{
"Action": [
"lambda:*"
],
"Resource": [
"arn:aws:lambda:region:account-id:function:*"
],
"Effect": "Allow"
},
{
"Action": [
"apigateway:*"
],
"Resource": [
"arn:aws:apigateway:region::*"
],
"Effect": "Allow"
},
{
"Action": [
"iam:GetRole",
"iam:CreateRole",
"iam:DeleteRole"
],
"Resource": [
"arn:aws:iam::account-id:role/*"
],
"Effect": "Allow"
},
{
"Action": [
"iam:AttachRolePolicy",
"iam:DetachRolePolicy"
],
"Resource": [
"arn:aws:iam::account-id:role/*"
],
"Effect": "Allow"
},
{
"Action": [
"iam:PassRole"
],
"Resource": [
"*"
],
"Effect": "Allow"
},
{
"Action": [
"cloudformation:CreateChangeSet"
],
"Resource": [
"arn:aws:cloudformation:region:aws:transform/Serverless-2016-10-31"
],
"Effect": "Allow"
}
],
"Version": "2012-10-17"
}
复制代码
点击 Validate Policy,然后点击 Apply Policy。
配置 CodePipeline 项目
打开 CodePipeline 控制台,点击 Create project
* 在 Step 1: Name
> Project name 输入 serverlessCodepipeline,点击“Next Step” 按钮。
* 在 Step 2: Source
> Source provider 选择 Github,然后点击 Connect to GitHub 按钮,关联 GitHub 账号。按提示完成关联操作。
>
> 回到 AWS 页面后,Repository 选择前述我们自己创建的存储库。
>
> Branch 选择 master ,点击“Next Step” 按钮。
* 在 Step 3: Build
> Build provider 选择 AWS CodeBuild
>
> Configure your project 保持选中 Select an existing build project
>
> Project name 在下拉列表中选择我们前面创建的 serverlessCodepipeline 项目。
* 在 Step 4: Deploy 页
> Deployment provider 选择 AWS CloudFormation。
>
> Action mode 选择 Create or replace a change set
>
> Stack name 输入 serverlessCodepipeline。
>
> Change set name 输入 serverlessCodepipelineChangeSet。
>
> Template file 输入 buildspec.yml 中指定的构建结果文件名 output-codepipeline.yaml。
>
> Capabilities 选择 CAPABILITY_IAM。
>
> Role name 选择我们前面创建的 IAM 角色 cloudformation-lambda-execution。 点击 Next Step 按钮。
* 在 Step 5: Service Role
> 点击 Create Role 按钮,在弹出的 IAM AWS CodePipeline is requesting permission to use resources in your account 页面,直接点击右下角 Allow 按钮,返回后点击 Next Step 按钮。
* 在 Step 6: Review 页面,直接点击右下角 点击右下角的 Create Pipeline 按钮。最后来到 serverlessCodepipeline 项目详情页。
* 增加测试部署阶段 在 serverlessCodepipeline 详情页点击 Edit 按钮。
> 在 Staging 阶段下面点击 +Stage 链接。
>
> 在 Stage name 栏输入 Beta,然后点击其下面的 +Action 按钮。
>
> 在 Action category 中,选择 Deploy。
>
> 在 Action name 中,输入 executeChangeSet。
>
> 在 Deployment provider 中,选择 AWS CloudFormation。
>
> 在 Action mode: 中,选择 execute a changeset。前一步我们已经创建了 ChangeSet,将 SAM 模板转换为完整的 AWS CloudFormation 格式,现在我们要使用 deployChangeSet 部署 AWS CloudFormation 模板了。
>
> 在 Stack name:中,输入 serverlessCodepipeline。
>
> 在 Change set name:中,输入 serverlessCodepipelineChangeSet。
>
> 选择 Add Action
>
> 回到页面顶部点击 Save pipeline changes。
>
> 选择 Save and continue。
#### 查看结果
我们在 serverlessCodepipeline 项目详情页稍等 10 秒左右,Pipeline 会自动开始第一次部署。可以随时查看到各个步骤的执行情况,比如:
Source
GitHub
Succeeded 2 min ago
d24ff81
最后等到 Beta 步骤也完成,这时到 CloudFormation 的控制台查看已经创建出一个 serverlessCodepipeline ,整个过程大约持续 35 分钟。
然后到 API Gateway 控制台,可以看到创建出的 serverlessCodepipeline 的 API,点击其 Stages 下的 Prod 链接,可以看到形如下面的调用 URL: Invoke URL: https://xxxxxxxxx.execute-api.my-region.amazonaws.com/Prod
复制此 URL,打开一个新窗口,粘贴进地址栏,然后在后面再输入 /time,组成形如
https://xxxxxxxxx.execute-api.my-region.amazonaws.com/Prod/time
的链接再访问之,显示
“The time in Los Angeles is Mon Aug 07 2017 03:31:39 GMT-0700 (PDT)”
表示已经部署成功。
然后我们模拟代码更新,把你自己的 github 存储库中的 README.md 文件编辑一下,然后 git commit 到 github 上去。 然后再回到 serverlessCodepipeline 详情页,稍等一会我们会看到从 Source 开始整个管道会再次执行一遍。
执行到每一步时,我们都可以点击 Detail 链接到相关服务的详情页查看具体进度。比如 CloudFormation 会创建出一个新的 serverlessCodepipelineChangeSet 来执行变更。
最后到 API Gateway 的 serverlessCodepipeline API,选择一个 Stage ,再点选 Deployment History 可以看到 Deployment date 时间更新了。
### 小结
今天我们继续结合实例,为大家讲解了使用 AWS CodeBuild 构建 Lambda 函数以及使用 AWS CodePipeline 实现自动化持续集成。这些也是基于 AWS 无服务器应用模型和 SAM 模板,再与其它 AWS 运维的服务集成,共同实现无服务器应用的自动化运维。
相关资源链接
Serverless Application Model (SAM):
无服务器服务官网:
运维相关的服务:
CodeBuild: https://aws.amaz.com/codebuild
** 作者介绍:**
![](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/09/04/Xue-Feng.jpg)
薛峰,亚马逊 AWS 解决方案架构师,AWS 的云计算方案架构的咨询和设计,同时致力于 AWS 云服务在国内和全球的应用和推广,在大规模并发应用架构、移动应用以及无服务器架构等方面有丰富的实践经验。在加入 AWS 之前曾长期从事互联网应用开发,先后在新浪、唯品会等公司担任架构师、技术总监等职位。对跨平台多终端的互联网应用架构和方案有深入的研究。

本文转载自 AWS 技术博客。

原文链接:
https://amazonaws-china.com/cn/blogs/china/continuous-integration-using-a-server-free-application-model/

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布