将 Lambda 与基础设施即代码(IaC)结合使用 - AWS Lambda

将 Lambda 与基础设施即代码(IaC)结合使用

Lambda 函数很少单独运行。相反,它们通常与数据库、队列和存储等其他资源一起都是无服务器应用程序的组成部分。借助基础设施即代码(IaC),可以自动执行部署流程,从而快速、可重复地部署和更新整个无服务器应用程序,涵盖许多独立的 AWS 资源。这种方法可以加快开发周期,简化配置管理,并确保每次都以相同的方式部署资源。

适用于 Lambda 的 IaC 工具

AWS CloudFormation

CloudFormation 是来自 AWS 的基础 IaC 服务。可以使用 YAML 或 JSON 模板,对整个 AWS 基础设施(包括 Lambda 函数)进行建模和预置。CloudFormation 可以处理创建、更新和删除 AWS 资源的复杂工作。

AWS Serverless Application Model (AWS SAM)

AWS SAM 是一个开源框架,构建在 CloudFormation 之上。它提供了用于定义无服务器应用程序的简化语法。使用 AWS SAM 模板,只需几行 YAML 即可快速预置 Lambda 函数、API、数据库和事件源。

AWS Cloud Development Kit (AWS CDK)

CDK 是 IaC 的代码优先方法。可以使用 TypeScript、JavaScript、Python、Java、C#/Net 或 Go 来定义基于 Lambda 的架构。选择首选语言,并使用参数、条件、循环、组合和继承等编程元素来定义基础设施的预期结果。然后,CDK 会生成底层 CloudFormation 模板用于部署。有关如何配合使用 Lambda 和 CDK 的示例,请参阅 使用 AWS CDK 部署 Lambda 函数

该示意图显示了 AWS SAM 和 AWS CDK 如何使用 AWS CloudFormation 部署 AWS 资源和代码

AWS 还提供了一项名为 AWS 基础设施编辑器 的服务,可使用简单图形界面开发 IaC 模板。凭借基础设施编辑器,可以通过在可视画布中拖动、分组和连接 AWS 服务来设计应用程序架构。然后,基础设施编辑器会根据您的设计创建 AWS SAM 模板或 AWS CloudFormation 模板,供您用于部署应用程序。

在以下 IaC for Lambda 入门 部分中,您将使用基础设施编辑器,根据现有 Lambda 函数为无服务器应用程序开发模板。

IaC for Lambda 入门

在本教程中,您可以通过使用现有 Lambda 函数创建 AWS SAM 模板,然后通过添加其他 AWS 资源在基础设施编辑器中构建无服务器应用程序,从而开始将 IaC 与 Lambda 结合使用。

在学习本教程时,您将学习一些基本概念,例如如何在 AWS SAM 中指定 AWS 资源。您还将了解如何使用基础设施编辑器来构建可使用 AWS SAM 或 AWS CloudFormation 部署的无服务器应用程序。

要完成本教程,请执行以下步骤:

  • 创建示例 Lambda 函数

  • 使用 Lambda 控制台查看函数的 AWS SAM 模板

  • 将函数的配置导出到 AWS 基础设施编辑器 并根据函数的配置设计一个简单的无服务器应用程序

  • 保存更新后的 AWS SAM 模板,可作为部署无服务器应用程序的基础

先决条件

在本教程中,您将使用基础设施编辑器的本地同步功能,将模板和代码文件保存到本地生成计算机。要使用此功能,您需要一个支持文件系统访问 API 的浏览器,它允许 Web 应用程序在本地文件系统中读取、写入和保存文件。我们建议使用 Google Chrome 或 Microsoft Edge。有关文件系统访问 API 的更多信息,请参阅 What is the File System Access API?

创建 Lambda 函数

在第一步中,您会创建 Lambda 函数以用于完成本教程的其余部分。为了简单起见,您可以使用 Lambda 控制台通过 Python 3.11 运行时系统创建基本的“Hello world”函数。

使用控制台创建“Hello world”Lambda 函数
  1. 打开 Lambda 控制台

  2. 选择 Create function(创建函数)。

  3. 选择从头开始创作,然后在基本信息中输入 LambdaIaCDemo 作为函数名称

  4. 对于运行时系统,选择 Python 3.11

  5. 选择 Create function (创建函数)

查看函数的 AWS SAM 模板

在将函数配置导出到基础设施编辑器之前,请使用 Lambda 控制台将函数的当前配置作为 AWS SAM 模板查看。按照本节中的步骤操作,您将了解 AWS SAM 模板的剖析以及如何定义诸如 Lambda 函数之类的资源以开始指定无服务器应用程序。

查看函数的 AWS SAM 模板
  1. 打开 Lamba 控制台的函数页面

  2. 选择您刚刚创建的函数(LambdaIaCDemo)。

  3. 函数概述窗格中,选择模板

    您将看到的不是表示函数配置的图表,而是函数的 AWS SAM 模板。该模板应该如下所示。

    # This AWS SAM template has been generated from your function's # configuration. If your function has one or more triggers, note # that the AWS resources associated with these triggers aren't fully # specified in this template and include placeholder values.Open this template # in AWS Application Composer or your favorite IDE and modify # it to specify a serverless application with other AWS resources. AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: An AWS Serverless Specification template describing your function. Resources: LambdaIaCDemo: Type: AWS::Serverless::Function Properties: CodeUri: . Description: '' MemorySize: 128 Timeout: 3 Handler: lambda_function.lambda_handler Runtime: python3.11 Architectures: - x86_64 EventInvokeConfig: MaximumEventAgeInSeconds: 21600 MaximumRetryAttempts: 2 EphemeralStorage: Size: 512 RuntimeManagementConfig: UpdateRuntimeOn: Auto SnapStart: ApplyOn: None PackageType: Zip Policies: Statement: - Effect: Allow Action: - logs:CreateLogGroup Resource: arn:aws:logs:us-east-1:123456789012:* - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: - >- arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/LambdaIaCDemo:*

我们需要花些时间查看函数的 YAML 模板并理解一些关键概念。

模板以声明 Transform: AWS::Serverless-2016-10-31 开头。此声明是必需的,因为 AWS SAM 模板在幕后要通过 AWS CloudFormation 部署。使用 Transform 语句将模板标识为 AWS SAM 模板文件。

Transform 声明之后是 Resources 部分。在这里可以定义要使用 AWS SAM 模板部署的 AWS 资源。AWS SAM 模板可以包含 AWS SAM 资源和 AWS CloudFormation 资源的组合。这是因为在部署过程中,AWS SAM 模板会扩展为 AWS CloudFormation 模板,因此任何有效的 AWS CloudFormation 语法都可以添加到 AWS SAM 模板中。

目前,模板的 Resources 部分中只定义了一个资源,即您的 Lambda 函数 LambdaIaCDemo。要向 AWS SAM 模板添加 Lambda 函数,请使用 AWS::Serverless::Function 资源类型。Lambda 函数资源的 Properties 定义函数的运行时系统、函数处理程序和其他配置选项。此处还定义了 AWS SAM 应该用于部署函数的函数源代码的路径。要了解有关 AWS SAM 中Lambda 函数资源的更多信息,请参阅《AWS SAM 开发人员指南》中的 AWS::Serverless::Function

除了函数属性和配置外,该模板还指定了函数的 AWS Identity and Access Management(IAM)policy。此策略授予函数向 Amazon CloudWatch Logs 写入日志的权限。当您在 Lambda 控制台中创建函数时,Lambda 会自动将此策略附加到您的函数。要了解有关为 AWS SAM 模板中的函数指定 IAM policy 的更多信息,请参阅 AWS SAM 开发者指南AWS::Serverless::Function 页面上的 policies 属性。

要了解有关 AWS SAM 模板结构的更多信息,请参阅AWS SAM 模板剖析

使用 AWS 基础设施编辑器 设计无服务器应用程序

要从函数的 AWS SAM 模板开始构建简单的无服务器应用程序,您可以将函数配置导出到基础设施编辑器,并激活基础设施编辑器的本地同步模式。本地同步会自动将您的函数代码和 AWS SAM 模板保存到本地生成计算机,并在您在基础设施编辑器中添加其他 AWS 资源时让保存的模板保持同步。

将函数导出到基础设施编辑器
  1. 函数概述窗格中,选择导出到应用程序编辑器

    为了将函数的配置和代码导出到基础设施编辑器,Lambda 在您的账户中创建了一个 Amazon S3 存储桶来临时存储此数据。

  2. 在对话框中,选择确认并创建项目以接受此存储桶的默认名称,并将函数的配置和代码导出到基础设施编辑器。

  3. (可选)要为 Lambda 创建的 Amazon S3 存储桶选择其他名称,请输入新名称并选择确认并创建项目。Amazon S3 存储桶的名称必须全局唯一,并遵守存储桶命名规则

    选择确认并创建项目,将打开基础设施编辑器控制台。在画布上,您将看到 Lambda 函数。

  4. 菜单下拉列表中,选择激活本地同步

  5. 在打开的对话框中选择选择文件夹,然后在本地生成计算机上选择一个文件夹。

  6. 选择激活以激活本地同步。

要将函数导出到基础设施编辑器,您需要拥有使用特定 API 操作的权限。如果您无法导出函数,请查看 所需的权限 并确保您拥有所需的权限。

注意

标准 Amazon S3 定价适用于您将函数导出到基础设施编辑器时由 Lambda 创建的存储桶。由 Lambda 放入存储桶的对象会在 10 天后自动删除,但是 Lambda 不会删除存储桶本身。

为避免给您的 AWS 账户 增加额外费用,请在将函数导出到基础设施编辑器后,按照删除存储桶中的说明进行操作。有关 Lambda 创建的 Amazon S3 存储桶的更多信息,请参阅 配合使用 AWS Lambda和 AWS 基础设施编辑器

在基础设施编辑器中设计您的无服务器应用程序

激活本地同步后,您在基础设施编辑器中所做的更改将反映在本地生成计算机上保存的 AWS SAM 模板中。现在,您可以将其他 AWS 资源拖放到基础设施编辑器画布上来构建应用程序。在此示例中,您添加了一个 Amazon SQS 简单队列作为 Lambda 函数的触发器,并添加了一个 DynamoDB 表供该函数写入数据。

  1. 通过执行以下操作,将 Amazon SQS 触发器添加到 Lambda 函数:

    1. 资源选项板的搜索字段中输入 SQS

    2. SQS 队列资源拖到画布上,然后将其放置在 Lambda 函数的左侧。

    3. 选择详细信息,然后在逻辑 ID 中输入 LambdaIaCQueue

    4. 选择保存

    5. 单击 SQS 队列卡上的订阅端口,然后将其拖到 Lambda 函数卡上的左侧端口,即可连接您的 Amazon SQS 和 Lambda 资源。两个资源之间出现一条线,表示连接成功。基础设施编辑器还会在画布底部显示一条消息,表明两个资源已连接成功。

  2. 通过执行以下操作,为您的 Lambda 函数添加一个 Amazon DynamoDB 表,供其写入数据:

    1. 资源选项板的搜索字段中输入 DynamoDB

    2. DynamoDB 表资源拖到画布上,然后将其放置在 Lambda 函数的右侧。

    3. 选择详细信息,然后在逻辑 ID 中输入 LambdaIaCTable

    4. 选择保存

    5. 单击 Lambda 函数卡的右侧端口,然后将其拖动到 DynamoDB 卡的左侧端口,即可将 DynamoDB 表连接到您的 Lambda 函数。

现在,您已经添加了这些额外资源,让我们看看基础设施编辑器创建的更新后的 AWS SAM 模板。

查看更新后的 AWS SAM 模板
  • 在基础设施编辑器画布上,选择模板以从画布视图切换到模板视图。

现在,您的 AWS SAM 模板应包含以下额外资源和属性:

  • 具有标识​符 LambdaIaCQueue 的 Amazon SQS 队列

    LambdaIaCQueue: Type: AWS::SQS::Queue Properties: MessageRetentionPeriod: 345600

    使用基础设施编辑器添加 Amazon SQS 队列时,基础设施编辑器会设置 MessageRetentionPeriod 属性。您也可以通过在 SQS 队列卡上选择详细信息并选中或取消选中 Fifo 队列来设置 FifoQueue 属性。

    要为队列设置其他属性,您可以手动编辑模板以添加这些属性。要了解有关 AWS::SQS::Queue 资源及其可用属性的更多信息,请参阅《AWS CloudFormation 用户指南》中的 AWS:: SQS::Queue

  • Lambda 函数定义中的一个 Events 属性,用于将 Amazon SQS 队列指定为函数的触发器

    Events: LambdaIaCQueue: Type: SQS Properties: Queue: !GetAtt LambdaIaCQueue.Arn BatchSize: 1

    Events 属性由一个事件类型和一组取决于类型的属性组成。要了解您可以配置用于触发 Lambda 函数的不同 AWS 服务 以及可以设置的属性,请参阅 AWS SAM 开发者指南中的 EventSource

  • 带有标识符 LambdaIaCTable 的 DynamoDB 表

    LambdaIaCTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: id AttributeType: S BillingMode: PAY_PER_REQUEST KeySchema: - AttributeName: id KeyType: HASH StreamSpecification: StreamViewType: NEW_AND_OLD_IMAGES

    使用基础设施编辑器添加 DynamoDB 表时,可以通过在 DynamoDB 表卡上选择详细信息并编辑键值来设置表的键。基础设施编辑器还为许多其他属性设置默认值,包括 BillingModeStreamViewType

    要详细了解这些属性以及可以添加到 AWS SAM 模板中的其他属性,请参阅《AWS CloudFormation 用户指南》中的 AWS::DynamoDB::Table

  • 一项新的 IAM policy,允许您的函数对您添加的 DynamoDB 表执行 CRUD 操作。

    Policies: ... - DynamoDBCrudPolicy: TableName: !Ref LambdaIaCTable

最终的 AWS SAM 模板应该如下所示。

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: An AWS Serverless Specification template describing your function. Resources: LambdaIaCDemo: Type: AWS::Serverless::Function Properties: CodeUri: . Description: '' MemorySize: 128 Timeout: 3 Handler: lambda_function.lambda_handler Runtime: python3.11 Architectures: - x86_64 EventInvokeConfig: MaximumEventAgeInSeconds: 21600 MaximumRetryAttempts: 2 EphemeralStorage: Size: 512 RuntimeManagementConfig: UpdateRuntimeOn: Auto SnapStart: ApplyOn: None PackageType: Zip Policies: - Statement: - Effect: Allow Action: - logs:CreateLogGroup Resource: arn:aws:logs:us-east-1:594035263019:* - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: - arn:aws:logs:us-east-1:594035263019:log-group:/aws/lambda/LambdaIaCDemo:* - DynamoDBCrudPolicy: TableName: !Ref LambdaIaCTable Events: LambdaIaCQueue: Type: SQS Properties: Queue: !GetAtt LambdaIaCQueue.Arn BatchSize: 1 Environment: Variables: LAMBDAIACTABLE_TABLE_NAME: !Ref LambdaIaCTable LAMBDAIACTABLE_TABLE_ARN: !GetAtt LambdaIaCTable.Arn LambdaIaCQueue: Type: AWS::SQS::Queue Properties: MessageRetentionPeriod: 345600 LambdaIaCTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: id AttributeType: S BillingMode: PAY_PER_REQUEST KeySchema: - AttributeName: id KeyType: HASH StreamSpecification: StreamViewType: NEW_AND_OLD_IMAGES

使用 AWS SAM(可选)部署您的无服务器应用程序

如果要使用 AWS SAM 来利用刚刚在基础设施编辑器中创建的模板部署无服务器应用程序,则需要先安装 AWS SAM CLI。为此,请遵循安装 AWS SAM CLI 中的说明。

在部署应用程序之前,您还需要更新基础设施编辑器随模板一起保存的函数代码。目前,基础设施编辑器保存的 lambda_function.py 文件仅包含您在创建函数时 Lambda 提供的基本“Hello world”代码。

要更新函数代码,请复制以下代码并将其粘贴到由基础设施编辑器保存到本地生成计算机的 lambda_function.py 文件中。激活“本地同步”模式时,您指定了基础设施编辑器要将此文件保存到的目录。

此代码接受的键值对来自您在基础设施编辑器中创建的 Amazon SQS 队列的消息。如果键和值都是字符串,则代码会使用它们向您的模板中定义的 DynamoDB 表写入项目。

import boto3 import os import json # define the DynamoDB table that Lambda will connect to tablename = os.environ['LAMBDAIACTABLE_TABLE_NAME'] # create the DynamoDB resource dynamo = boto3.client('dynamodb') def lambda_handler(event, context): # get the message out of the SQS event message = event['Records'][0]['body'] data = json.loads(message) # write event data to DDB table if check_message_format(data): key = next(iter(data)) value = data[key] dynamo.put_item( TableName=tablename, Item={ 'id': {'S': key}, 'Value': {'S': value} } ) else: raise ValueError("Input data not in the correct format") # check that the event object contains a single key value # pair that can be written to the database def check_message_format(message): if len(message) != 1: return False key, value = next(iter(message.items())) if not (isinstance(key, str) and isinstance(value, str)): return False else: return True
部署无服务器应用程序

要使用 AWS SAM CLI 部署应用程序,请执行以下步骤。为了正确构建和部署函数,必须在您的生成计算机和 PATH 上安装 Python 3.11 版本。

  1. 在基础设施编辑器保存 template.yamllambda_function.py 文件的目录运行以下命令。

    sam build

    此命令会收集应用程序的构建构件,并将其以适当的格式放置在适当的位置进行部署。

  2. 要部署您的应用程序并创建 AWS SAM 模板中指定的 Lambda、Amazon SQS 和 DynamoDB 资源,请运行以下命令。

    sam deploy --guided

    使用 --guided 标志意味着 AWS SAM 将向您显示提示,以指导您完成部署过程。对于此部署,请按 Enter 接受默认选项。

在部署过程中,AWS SAM 将在 AWS 账户 中创建以下资源:

  • 一个名为 sam-app 的 AWS CloudFormation 堆栈

  • 名称格式为 sam-app-LambdaIaCDemo-99VXPpYQVv1M 的 Lambda 函数

  • 名称格式为 sam-app-LambdaIaCQueue-xL87VeKsGiIo 的 Amazon SQS 队列

  • 名称格式为 sam-app-LambdaIaCTable-CN0S66C0VLNV 的 DynamoDB 表

AWS SAM 还会创建必要的 IAM 角色和策略,以便您的 Lambda 函数可以读取来自 Amazon SQS 队列的消息并对 DynamoDB 表执行 CRUD 操作。

测试已部署的应用程序(可选)

要确认您的无服务器应用程序已正确部署,请向您的 Amazon SQS 队列发送一条包含密钥值对的消息,并检查 Lambda 是否使用这些值将项目写入您的 DynamoDB 表。

测试您的无服务器应用程序
  1. 打开 Amazon SQS 控制台的队列页面,然后选择 AWS SAM 通过您的模板创建的队列。名称的格式为 sam-app-LambdaIaCQueue-xL87VeKsGiIo

  2. 选择发送和接收消息,然后将以下 JSON 粘贴到发送消息部分的消息正文中。

    { "myKey": "myValue" }
  3. 选择 Send message(发送消息)。

    将您的消息发送到队列会导致 Lambda 通过 AWS SAM 模板中定义的事件源映射调用您的函数。要确认 Lambda 已按预期调用您的函数,请确认项目已被添加到您的 DynamoDB 表。

  4. 打开 DynamoDB 控制台中的页面,然后选择您的表。名称的格式为 sam-app-LambdaIaCTable-CN0S66C0VLNV

  5. 选择 Explore table items(浏览表项目)。在返回的项目窗格中,您会看到一个带 id myKey myValue 的项目。