web-dev-qa-db-ja.com

同じコードによるTerraformラムダsource_code_hashの更新

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"
    }
  }
}

terraform planコマンドを実行すると、source_code_hashが変更されたためラムダリソースを更新する必要があると表示されますが、ラムダ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"

Pythonソースが毎回圧縮され、ソースが変更されるためです。Pythonコードに変更がない場合、どうすれば回避できますか? Python codebaseを変更しなかった場合、つまり、なぜハッシュが変更されるのか)私の仮説は一貫していますか?

6
Arcones

これはmain.pyをハッシュしているがdist/subscriber-lambda.Zipをアップロードしているためです。 Terraformは、ハッシュを、ファイルがラムダにアップロードされたときに計算したハッシュと比較します。ハッシュは2つの異なるファイルで行われるため、最終的には異なるハッシュになります。アップロードされているのとまったく同じファイルでハッシュを実行してみてください。

1
ODYN-Kon

@ ODYN-Konが提供するものとは対照的に、私の回答を追加します。

リソース「aws_lambda_function」のソースコードハッシュフィールドは、アップロードしたZipのハッシュと比較されません。代わりに、ハッシュは、Terraformが最後に実行されたときから保存された状態に対してチェックされるだけです。したがって、次にTerraformを実行するときに、実際のpythonファイルのハッシュが計算され、変更されているかどうかが確認されます。変更されている場合は、Zipが変更され、Lambda関数がリソースをもう一度実行する必要があります。source_code_hashには、任意の値を設定するか、完全に省略することができます。任意の文字列の定数に設定できます。Terraformの設定を編集しない限り、リソースは変更されません。

ここで、TerraformがZipファイルを更新したと想定するという問題があります。 Zipアーカイブにディレクトリまたはファイルが1つしかない場合、Terraformデータソースのarchive_fileを使用してZipファイルを作成できます。ディレクトリとファイルが必要なため、使用できない場合があります(JSワールド:ソース+ node_modules /)。しかし、これを使用する方法は次のとおりです。

_data "archive_file" "lambdaCode" {
  type = "Zip"
  source_file = "lambda_process_firewall_updates.js"
  output_path = "${var.lambda_Zip}"
}
_

あるいは、「source_file」ステートメントを_source_dir = "node_modules"_に置き換えると、ディレクトリ全体をアーカイブできます。

これを行うと、Zipアーカイブファイルのハッシュコードを参照して、フィールドsource_hashの_resource "aws_lambda_function" "lambda" {_として_"${data.archive_file.lambdaCode.output_base64sha256}"_ブロックに挿入できます。その後、Zipが変更されるたびに、ラムダ関数が更新されます。また、データソースアーカイブファイルは、source_fileが変更されるたびにZipを再生成する必要があることを認識しています。

今、私はあなたのケースの根本的な原因まで掘り下げていませんが、うまくいけば、より良い場所に到達するためにいくつかの助けを与えました。次の方法でTerraformの保存された状態を確認できます。_tf state list_-保存された状態の項目をリストします。ラムダ関数ブロックに一致するものを見つけて、_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コードも見に行きましたが、雨の日のプロジェクトです。私が使用する1つのバリエーションは、source_code_hashを"${base64sha256(file("my-lambda.Zip"))}"にすることです。しかし、それでも私はtfを2回実行する必要があります。

1
Kevin Buchs

他の人が言ったように、Zipはファイル名とハッシュで使用する必要があります。

ラムダ定義で間違ったハッシュ関数を使用すると、同様のレクリエーションの問題が発生する可能性があることにも触れておきます。たとえば、filesha256(.Zip)も毎回ラムダを再作成します。 source_code_hashで説明されているように、filebase64sha256( "file.Zip")(terraform 0.11.12+)またはbase64sha256(file( "file.Zip"))を使用する必要があります here

1
adavea