Terraform Lambda source_code_hash使用相同的代码更新

Arc*_*nes 5 aws-lambda terraform

我已经使用Terraform成功部署了一个AWS Lambda:

resource "aws_lambda_function" "lambda" {
  filename                       = "dist/subscriber-lambda.zip"
  function_name                  = "test_get-code"
  role                           = <my_role>
  handler                        = "main.handler"
  timeout                        = 14
  reserved_concurrent_executions = 50
  memory_size                    = 128
  runtime                        = "python3.6"
  tags                           = <my map of tags>
  source_code_hash               = "${base64sha256(file("../modules/lambda/lambda-code/main.py"))}"
  kms_key_arn                    = <my_kms_arn>
  vpc_config {
    subnet_ids         = <my_list_of_private_subnets>
    security_group_ids = <my_list_of_security_groups>
  }
  environment {
    variables = {
      environment = "dev"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,当我运行terraform plan命令时,它说我的lambda资源需要更新,因为source_code_hash已经更改了,但是我没有更新lambda Python代码库(在相同仓库的文件夹中版本化):

  ~ module.app.module.lambda.aws_lambda_function.lambda
  last_modified:                     "2018-10-05T07:10:35.323+0000" => <computed>
  source_code_hash:                  "jd6U44lfe4124vR0VtyGiz45HFzDHCH7+yTBjvr400s=" => "JJIv/AQoPvpGIg01Ze/YRsteErqR0S6JsqKDNShz1w78"
Run Code Online (Sandbox Code Playgroud)

我想这是因为它每次都会压缩我的Python源,并且源会更改。如果Python代码没有变化,如何避免这种情况?如果我不更改Python代码库,我的假设是否连贯(我的意思是,为什么哈希会发生变化)?

Kon*_*Kon 10

这是因为您只是在对main.py进行哈希处理,但正在上传dist/subscriber-lambda.zip。Terraform 将哈希值与它在文件上传到 lambda 时计算的哈希值进行比较。由于散列是在两个不同的文件上完成的,因此最终会得到不同的散列。尝试在正在上传的完全相同的文件上运行哈希。

  • 知道如何在 CI/CD 场景中解决这个问题吗?例如,我遇到了这个问题,因为当 CI/CD 启动时,它会构建并压缩我的代码。然后它运行 terraform apply。源实际上没有改变,但 zip 的哈希值已经改变。我希望 terraform 知道在这种情况下不需要重新部署。 (2认同)

Kev*_*chs 6

我将添加我的答案以与@ODYN-Kon 提供的答案形成对比。

资源“aws_lambda_function”中的源代码哈希字段不会与您上传的 zip 的某些哈希进行比较。相反,只是根据 Terraform 上次运行时保存的状态检查哈希。因此,下次运行 Terraform 时,它会计算实际 Python 文件的哈希值,以查看它是否已更改。如果是,则假定 zip 已更改并且需要再次运行 Lambda 函数资源。source_code_hash 可以具有您想要赋予的任何值,也可以完全省略。您可以将其设置为某个任意字符串的常量,然后除非您编辑 Terraform 配置,否则它将永远不会改变。

现在,问题在于 Terraform 假设您更新了 zip 文件。假设您在 zip 存档中只有一个目录或一个文件,您可以使用 Terraform 数据源 archive_file 创建 zip 文件。我有一个无法使用它的情况,因为我需要一个目录和一个文件(JS 世界:source + node_modules/)。但这里是你可以如何使用它:

data "archive_file" "lambdaCode" {
  type = "zip"
  source_file = "lambda_process_firewall_updates.js"
  output_path = "${var.lambda_zip}"
}
Run Code Online (Sandbox Code Playgroud)

或者,如果将“source_file”语句替换为 source_dir = "node_modules"

完成此操作后,您可以引用 zip 存档文件的哈希码以插入resource "aws_lambda_function" "lambda" {块中"${data.archive_file.lambdaCode.output_base64sha256}"字段 source_hash 一样。然后,只要 zip 更改,lambda 函数就会更新。而且,数据源存档文件知道,无论何时 source_file 更改,它都必须重新生成 zip。

现在,我还没有深入研究您的情况的根本原因,但希望能提供一些帮助以达到更好的效果。您可以通过以下方式检查 Terraform 的保存状态:tf state list- 列出保存状态的项目。您可以找到与您的 lambda 功能块匹配的那个,然后执行tf state show <state-name>。例如,对于我正在研究的一个:

tf state show aws_lambda_function.test-lambda-networking 给出大约 30 行输出,包括:

source_code_hash = 2fKX9v/duluQF0H6O9+iRnID2gokhfpXIXpxyeVBUM0=

您可以通过命令行命令比较哈希。MacOS 上的示例:sha256sum my-lambda.zip,其中 sha256sum 由brew install coreutils.

如前所述,当您有多个未隔离到单个目录的 zip 元素时,archive_file 的使用不起作用。我认为这可能发生了很多,所以我希望 Hashicorp 人能扩展 archive_file 以支持多个。我什至去看了 Go 代码,但那是一个下雨天的项目。我使用的一种变体是将 source_code_hash 设为"${base64sha256(file("my-lambda.zip"))}". 但这仍然需要我运行 tf 两次。

  • 根据此 /sf/ask/3686357111/ 和我自己的测试,terraform 存储上传的 zip 的哈希值,无论您提供什么作为 source_code_hash (2认同)

小智 6

这对我有用,并且在代码未更改时也不会触发 Lambda 函数的更新

data "archive_file" "lambda_zip" {                                                                                                                                                                                   
  type        = "zip"                                                                                                                                                                                                
  source_dir  = "../dist/go"                                                                                                                                                                                         
  output_path = "../dist/lambda_package.zip"                                                                                                                                                                         
}                                                                                                                                                                                                                    


resource "aws_lambda_function" "aggregator_func" {                                                                                                                                                                   
  description      = "MyFunction"                                                                                                                                                                       
  function_name    = "my-func-${local.env}"                                                                                                                                                                  
  filename         = data.archive_file.lambda_zip.output_path                                                                                                                                                        
  runtime          = "go1.x"                                                                                                                                                                                         
  handler          = "main"                                                                                                                                                                                    
  source_code_hash = data.archive_file.lambda_zip.output_base64sha256                                                                                                                                                
  role             = aws_iam_role.function_role.arn                                                                                                                                                                  


  timeout = 120                                                                                                                                                                                                      
  publish = true                                                                                                                                                                                                     

  tags = {                                                                                                                                                                                                           
    environment = local.env                                                                                                                                                                                                                                                                                                                                                                    
  }                                                                                                                                                                                                                  
}                              
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

3520 次

最近记录:

5 年,10 月 前