概述 本文演示了如何利用 AWS 服务开发无服务器 API,并在 AWS 环境中建立持续集成/持续部署 (CICD) 管道。 探索如何创建 Lambda 函数来处理来自 API 网关的请求并使用无服务器应用程序模型将数据保留在 DynamoDB 中。 第 1 部分: 详细介绍在 AWS 中配置 CodeCommit 存储库并设置 CICD 管道的必要步骤,该管道在向存储库提交新更改后自动启动构建过程。 第 2 部分: 先决条件 对于此项目,您需要一个 AWS 账户(免费套餐就足够了)。将使用以下 AWS 组件: AWS API网关 AWS Lambda AWS 动态数据库 AWS 代码提交 AWS 代码构建 AWS 代码管道 AWS S3 其他 - CloudWatch、IAM 等 确保您的本地开发环境设置如下: :按照 指南安装 AWS 命令行界面。 安装 AWS CLI 此处的 :按照 说明安装 SAM CLI。 安装 AWS SAM(无服务器应用程序模型) 此处的 :使用IntelliJ或类似的IDE进行开发。我更喜欢IntelliJ 选择IDE :确保您已安装 Maven 以打包您的应用程序。 用于打包的 Maven (如果您需要在本地测试 Lambda 函数):如果您计划在本地测试 Lambda 函数,请安装 Docker。 可选:Docker 这些工具和组件将构成该项目的基础。 第 1 部分:开发 在本节中,我们将看到使用 AWS SAM 创建入门项目的过程,包括完成处理程序类、构建、部署到 AWS 以及使用 Postman 进行测试 环境设置 : AWS 设置 转至 AWS 控制台 ,使用您的管理员用户凭证登录。 https://aws.amazon.com/console/ : 在 IAM 中创建用户 在 IAM 中,创建一个专用于本地开发和 CLI/SAM 使用的用户。 : 创建 DynamoDB 表 名称:“users”,主键:“id”(类型:字符串) : 在本地计算机上配置 AWS CLI 打开终端并运行 $ aws configure 提供之前创建的 IAM 用户的访问密钥和其他默认值 : 使用 AWS 无服务器应用程序模型 (SAM) 初始化项目 打开终端并运行 $ sam init 选择 AWS 快速入门模板。 选择“Hello World”示例。 选择Java 11或17,包类型为zip,并使用Maven作为依赖管理器。 使用 CloudWatch 和 XRay 启用日志记录和监控。 :将项目重命名为您喜欢的名称。 重命名项目 :启动 IntelliJ,然后打开项目。 在 IntelliJ 中打开项目 : 将依赖项添加到 pom.xml 将必要的依赖项添加到 文件中。您只需添加 DynamoDB,因为 SAM 将自动包含其他依赖项。 pom.xml <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.11.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-dynamodb</artifactId> <version>1.12.573</version> </dependency> </dependencies> 编写处理程序类 对于lambda函数,编辑sam自动生成的处理程序类,并添加以下代码;这是一个简单的代码,对于实际项目,您可能需要使用更模块化的代码。 public class UserRequestHandler implements RequestHandler<Map<String,String>, Map<String,String>> { private AmazonDynamoDB amazonDynamoDB; private String DYNAMODB_TABLE_NAME = "users"; private Regions REGION = Regions.US_EAST_1; @Override public Map<String,String> handleRequest(Map<String,String> input, Context context) { this.initDynamoDbClient(); LambdaLogger logger = context.getLogger(); logger.log("Input payload:" + input.toString()); String userId = UUID.randomUUID().toString(); String firstName= input.get("firstName"); String lastName= input.get("lastName"); Map<String, AttributeValue> attributesMap = new HashMap<>(); attributesMap.put("id", new AttributeValue(userId)); attributesMap.put("firstName", new AttributeValue(firstName)); attributesMap.put("lastName", new AttributeValue(lastName)); logger.log(attributesMap.toString()); amazonDynamoDB.putItem(DYNAMODB_TABLE_NAME, attributesMap); Map<String, String> response = new HashMap<>(); response.put("id", userId); response.put("firstName", firstName); response.put("lastName", lastName); return response; } private void initDynamoDbClient() { this.amazonDynamoDB = AmazonDynamoDBClientBuilder.standard() .withRegion(REGION) .build(); } } 更新 SAM 模板文件 SAM 模板文件在构建和部署 AWS 更改方面发挥着关键作用。更新项目的文件。该文件中需要关注的关键元素是 Lambda 函数名称和 API 网关端点。它们是无服务器应用程序功能的核心。 AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > pc-aws-user-api Sample SAM Template for pc-aws-user-api # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 20 MemorySize: 128 Tracing: Active Api: TracingEnabled: true Resources: UserRequestHandlerLambdaFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: PcAwsUsersApi Handler: com.pc.aws.users.UserRequestHandler::handleRequest Runtime: java11 Architectures: - x86_64 MemorySize: 512 Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: PARAM1: VALUE JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1 # More info about tiered compilation https://aws.amazon.com/blogs/compute/optimizing-aws-lambda-function-performance-for-java/ Events: PcUsers: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /users Method: post ApplicationResourceGroup: Type: AWS::ResourceGroups::Group Properties: Name: Fn::Sub: ApplicationInsights-SAM-${AWS::StackName} ResourceQuery: Type: CLOUDFORMATION_STACK_1_0 ApplicationInsightsMonitoring: Type: AWS::ApplicationInsights::Application Properties: ResourceGroupName: Ref: ApplicationResourceGroup AutoConfigurationEnabled: 'true' Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api PcAwsUsersApi: Description: API Gateway endpoint URL for Prod stage Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/users/" UserRequestHandlerLambdaFunction: Description: Lambda Function ARN Value: !GetAtt UserRequestHandlerLambdaFunction.Arn UserRequestHandlerLambdaFunctionIamRole: Description: Implicit IAM Role created Value: !GetAtt UserRequestHandlerLambdaFunctionRole.Arn 使用 SAM 构建和部署代码 在 IntelliJ 中,打开终端,然后执行以下命令: $ sam build $ sam deploy –guided 出现提示时,提供堆栈名称“PcAwsUsersApi”,然后选择默认选项。 输出将展示已创建的 CloudFormation 堆栈,还将提供 API 网关端点。 测试API 在测试 API 之前,请授予 DynamoDB 对 SAM 创建的 Lambda 角色的访问权限。 在 AWS 控制台中打开 Lambda 函数。 导航到“权限”,然后找到角色名称。 向此角色添加“DynamoDBFullAccess”权限。 此步骤确保 Lambda 函数具有与 DynamoDB 交互所需的权限。 导航到 API Gateway,然后按照以下步骤获取您的服务的 URL: 转到 AWS 控制台中的 API 网关。 选择您的 API。 在左侧边栏中,单击“阶段”。 在“阶段”下,选择“Prod”阶段。 在阶段编辑器部分中,您将找到“调用 URL”。复制此网址。 启动邮递员应用程序。 创建 POST 请求:使用以下详细信息设置新请求: 方法:邮寄 URL:粘贴之前获取的 API 网关端点 URL。 设置标头:添加任何必要的标头(例如 )。 Content-Type: application/json 添加请求正文:创建一个 JSON 对象,表示要在请求中发送的用户数据。这将是您希望存储在 DynamoDB 中的数据。 第二部分 实施 CICD 管道 在本部分中,我们将演示如何使用 AWS CodeCommit、CodeBuild 和 CodePipeline 构建 CICD 管道。该管道将启动一个构建过程,从存储库中获取代码,使用构建文件进行构建,并触发 CloudFormation 创建堆栈。 创建 CodeCommit 存储库 登录 AWS,然后搜索 CodeCommit 服务。 在 AWS CodeCommit 中创建新存储库来存储项目的源代码。 将代码提交到存储库 在 IntelliJ 中,打开终端并输入以下命令以提交在步骤 I 中创建的代码 $ git init → This initialize local git $ git add . → This will stage files $ git commit -m "commit to CodeCommit" 将更改推送到远程存储库 从 aws 控制台复制 CodeCommit 存储库 URL。 $ git remote add origin <repo URL> $ git push --set-upstream origin master --> This will prompt for user/password 创建 AWS CodeBuild 项目 设置一个 CodeBuild 项目来指定如何构建应用程序。这包括定义构建环境、构建命令和依赖项。 创建一个 S3 存储桶来存储构建文件。 搜索 AWS Code Build,创建一个新项目,并提供 CodeCommit 作为代码源和 S3 用于工件存储 要设置 CodeBuild,您需要在项目目录中创建一个名为 的构建规范文件。该文件将包含 CodeBuild 的构建命令和说明。 buildspec.yml 您可以参考 官方文档,了解有关创建 文件的详细说明。 此处的 buildspec.yml version: 0.2 phases: install: runtime-versions: java: corretto11 pre_build: commands: - echo Nothing to do in the pre_build phase... build: commands: - echo Build started on `date` - sam build - sam package --output-template-file pcoutputtemplate.yaml --s3-bucket com-appsdev-pc-001 post_build: commands: - echo Build completed on `date` artifacts: files: - pcoutputtemplate.yaml 将新文件从本地推送到存储库。 之后,您可以构建项目以查看代码是否从 Repo 中提取并构建了工件。 创建代码管道 在 AWS CodePipeline 中创建新管道。 将管道连接到您的 CodeCommit 存储库作为源。 配置管道以使用 CodeBuild 作为构建阶段。 添加部署阶段以使用您创建的模板触发 CloudFormation。 管道将根据 git 提交自动构建和部署代码。 测试管道 在 IntelliJ 中打开您的项目。 对其中一个文件进行一些小的更改,例如添加另一个记录器行。 将更改提交到本地 Git 存储库。 将提交推送到 CodeCommit 存储库。 $ git branch CR01 $ git checkout CR01 $ git add . $ git commit -m “CR01” $ git push --set-upstream origin CR01 You cand also create a pull request in aws code commit, just for simplicity I am merging from local $ git checkout master $ git merge --ff-only CR01 $ git push 转到 AWS CodePipeline 控制台。 您应该看到管道自动启动。它将从存储库中提取最新代码,使用 CodeBuild 构建项目,并使用 CloudFormation 进行部署。 在 CodePipeline 仪表板中监控进度。 这将模拟对代码进行更改、将其推送到存储库以及让 CICD 管道自动触发和部署更新的代码的过程。 通过利用 AWS API Gateway、Lambda、DynamoDB、CodeCommit、CodeBuild 和 CodePipeline,本文演示了如何构建弹性且自动化的部署流程。 感谢您的阅读。祝您的无服务器努力取得成功和创新!