使用Terraform部署GO AWS lambda功能
#aws #网络开发人员 #go #terraform

概述

在本文中,我们将使用Terraform将一个简单的Golang Hello-World lambda函数部署到AWS中,并介绍所有必要的步骤来执行此操作。我们部署的所有资源都有一个免费的层,因此将花费我们0 $。

如果您不想错过类似的文章,请订阅TheDevBookð©。

中的新文章更新

AWS Lambda是一种流行的云计算服务,还允许开发人员在无需管理基础架构的情况下运行其代码。借助AWS Lambda,您只为所消耗的计算资源付费,使其成为运行应用程序的经济有效解决方案。有关AWS Lambda检查What is AWS lambda的更多详细信息。

在本教程中,我们将探索如何使用Terraform部署Lambda函数,Terraform是将基础结构作为代码提供的强大工具。 Terraform是一种流行的开源工具,使您能够将基础架构定义和管理为代码。使用Terraform,您可以在一个文件中定义和管理基础架构的所有组件,包括AWS Lambda功能。这使得版本可容易控制您的基础架构并随着时间的推移管理更改。

先决条件

要部署lambda函数,我们需要拥有一个AWS帐户并首先设置Terraform。有关如何完成的详细指南,可以在the guide中找到Configure环境部分。

注意:我们将使用具有管理权限的配置文件tutorial-terraform-profile,这不是安全性的最佳使用方法,因为安全问题,但出于测试目的而方便。

我们还需要安装go来进行教程来编译我们的GO代码。可以在official docs中找到Go安装说明。

项目结构

项目结构包含多个Terraform文件和带有hello-world Go Lambda函数代码的Lambda目录。

tutorial/
|-- lambda/
|   `-- hello-world
|      `-- main.go
|-- iam.tf
|-- lambda.tf
|-- locals.tf
`-- main.tf

基本设置

首先,我们需要提供基本的Terraform设置,指定要使用的依赖项,并设置AWS提供商。

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
    archive = {
      source = "hashicorp/archive"
    }
    null = {
      source = "hashicorp/null"
    }
  }

  required_version = ">= 1.3.7"
}

provider "aws" {
  region  = "us-east-1"
  profile = "tutorial-terraform-profile"

  default_tags {
    tags = {
      app = "tutorial-terraform"
    }
  }
}

terraform块定义了Terraform配置本身,并指定所需的Terraform提供商和所需的Terraform版本,即>= 1.3.7required_providers部分列出了将在Terraform配置中使用的提供商。在教程中,我们需要:

  • aws-创建AWS资源;
  • archive-在Terraform内管理存档文件,例如zip文件;就我们的案例而言,我们需要以Zip格式进行存档二进制以上传到lambda;
  • null-运行本地命令;在我们的情况下,我们将使用go build命令来构建GO二进制。

provider "aws"块指定了AWS提供商设置,其中包括AWS区域(us-east-1)和AWS配置文件(tutorial-terraform-profile)用于身份验证。

注意:您需要在Terraform AWS提供商

中指定.aws/config中的适当配置文件

default_tags部分设置了将应用于Terraform创建的AWS资源的默认标签,在这种情况下,标签app = "tutorial-terraform"

标签主要用于过滤资源,跟踪使用和成本

身份和访问管理设置

// allow lambda service to assume (use) the role with such policy
data "aws_iam_policy_document" "assume_lambda_role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }
  }
}

// create lambda role, that lambda function can assume (use)
resource "aws_iam_role" "lambda" {
  name               = "AssumeLambdaRole"
  description        = "Role for lambda to assume lambda"
  assume_role_policy = data.aws_iam_policy_document.assume_lambda_role.json
}

我们将asherole用于主lambda,以允许lambdas这个特殊的角色。这意味着只有lambdas才能承担此角色。

data "aws_iam_policy_document" "allow_lambda_logging" {
  statement {
    effect = "Allow"
    actions = [
      "logs:CreateLogStream",
      "logs:PutLogEvents",
    ]

    resources = [
      "arn:aws:logs:*:*:*",
    ]
  }
}

// create a policy to allow writing into logs and create logs stream
resource "aws_iam_policy" "function_logging_policy" {
  name        = "AllowLambdaLoggingPolicy"
  description = "Policy for lambda cloudwatch logging"
  policy      = data.aws_iam_policy_document.allow_lambda_logging.json
}

// attach policy to out created lambda role
resource "aws_iam_role_policy_attachment" "lambda_logging_policy_attachment" {
  role       = aws_iam_role.lambda.id
  policy_arn = aws_iam_policy.function_logging_policy.arn
}

Go Lambda功能代码

GO中的Lambda的Hello World函数是主包中的一个简单可执行代码:

package main

import (
    "context"
    "fmt"

    "github.com/aws/aws-lambda-go/lambda"
)

func HandleRequest(ctx context.Context, event interface{}) (string, error) {
    fmt.Println("event", event)

    return "Hello world", nil
}

func main() {
    lambda.Start(HandleRequest)
}

我们使用github.com/aws/aws-lambda-go/lambda软件包来确定主函数为lambda。我们需要在main函数lambda.Start(HandleRequest)中运行以处理触发lambda的事件。在处理程序函数HandleRequest中,我们将收到事件和事件本身的上下文。

Go Lambda功能资源

要部署AWS lambda函数,我们需要为lambda创建二进制文件并以zip格式上传:

// build the binary for the lambda function in a specified path
resource "null_resource" "function_binary" {
  provisioner "local-exec" {
    command = "GOOS=linux GOARCH=amd64 CGO_ENABLED=0 GOFLAGS=-trimpath go build -mod=readonly -ldflags='-s -w' -o ${local.binary_path} ${local.src_path}"
  }
}

// zip the binary, as we can use only zip files to AWS lambda
data "archive_file" "function_archive" {
  depends_on = [null_resource.function_binary]

  type        = "zip"
  source_file = local.binary_path
  output_path = local.archive_path
}

// create the lambda function from zip file
resource "aws_lambda_function" "function" {
  function_name = "hello-world"
  description   = "My first hello world function"
  role          = aws_iam_role.lambda.arn
  handler       = local.binary_name
  memory_size   = 128

  filename         = local.archive_path
  source_code_hash = data.archive_file.function_archive.output_base64sha256

  runtime = "go1.x"
}

我们首先使用null_resource编译了二进制文件以执行本地命令并运行GO构建。之后,我们将拥有一个二进制tf_generated/hello-world

之后,我们需要在ZIP中存档我们的二进制文件,因为Lambda仅接受ZIP存档上传。为此,我们使用archive_file并将文件指定到我们的二进制文件。

要创建AWS lambda函数,我们需要使用aws_lambda_function资源。此步骤中指定了函数的名称,描述,IAM角色,处理程序,内存大小,ZIP存档和运行时。

除了lambda功能外,我们还需要创建
CloudWatch日志组,使用AWS_CLOUDWATCH_LOG_GROUP资源从已部署的函数中收集日志。这使您可以以集中式的方式监视和调试该函数的性能。

// create log group in cloudwatch to gather logs of our lambda function
resource "aws_cloudwatch_log_group" "log_group" {
  name              = "/aws/lambda/${aws_lambda_function.function.function_name}"
  retention_in_days = 7
}

部署GO LAMBDA功能

在部署资源之前,我们需要初始化Terraform:

terraform init

之后,我们准备计划我们的资源。这意味着我们不会先创建它们,而只是为了验证Terraform代码是正确的,并检查将创建的资源:

terraform plan

我们会看到类似的东西:

...

Terraform will perform the following actions:

  # data.archive_file.function_archive will be read during apply
  # (depends on a resource or a module with changes pending)
 <= data "archive_file" "function_archive" {
      + id                  = (known after apply)
      + output_base64sha256 = (known after apply)
      + output_md5          = (known after apply)
      + output_path         = "./tf_generated/hello-world.zip"
      + output_sha          = (known after apply)
      + output_size         = (known after apply)
      + source_file         = "./tf_generated/hello-world"
      + type                = "zip"
    }

  # aws_cloudwatch_log_group.log_group will be created
  + resource "aws_cloudwatch_log_group" "log_group" {
      + arn               = (known after apply)
      + id                = (known after apply)

...

Plan: 6 to add, 0 to change, 0 to destroy.

总共我们将创建6个资源:

  • 编译的GO代码的二进制文件
  • 二进制的拉链档案
  • IAM的日志策略
  • liam的lambda角色
  • IAM策略附件(这是一个独立的资源)
  • lambda函数

看起来正确,我们可以创建我们的资源。我们需要运行:

terraform apply

和type yes确认应用资源。

Deploy AWS resources

注意:我们可以使用-auto -approve进行自动批准,但更适合在CI/CD管道中自动运行。对于手动部署,可以更好地避免此参数,以仔细检查将要创建的资源。

Lambda功能部署的验证

可以在部署后,我们可以检查已部署的lambda。我们需要转到lambda部分,以搜索AWS控制台:

Lambda search

在那里我们可以找到hello-world函数。

Select lambda function

进入功能,我们可以看到lambda函数版本的详细信息。要测试它,有一个名为Test的选项卡:

Test lambda function

我们需要指定event-nameevent JSON,然后单击Test以运行该功能:

Lambda input setup

之后,我们看到了执行摘要。该功能返回“ Hello World”消息ð

Lambda execution success

在执行摘要中,我们可以看到功能运行的持续时间和计费持续时间(我们将在什么时候付款)。有一个直接链接到该函数的日志。

Select lambda logs

在日志中,我们可以看到事件,我们传递给函数:

Lambda logs

破坏资源

销毁我们需要运行的所有资源:

和键入yes确认。

Destroy resources

结论

我们用Terraform部署了AWS lambda功能。通过遵循本教程中的步骤,您将能够轻松地管理Lambda功能,并确保在基础架构之间保持一致性。让我们成为真实的人,谁不喜欢他们的生活中的一点自动化?

ðâ€如果您喜欢这篇文章

如果您喜欢这篇文章,并希望在软件工程领域的最新和最伟大的信息中保持最新信息,请确保在TheDevBook中订阅新文章更新。

Subscribe

快乐的编码ð»