Node.js
AWS
lambda
Terraform
AWSLambda

AWS Lambda (Node.js)の環境変数をTerraformから設定する

More than 1 year has passed since last update.


はじめに

先月(2016/11/18)に AWS Lambda が 環境変数をサポート しました。

それに合わせて、Terraformバージョン0.7.12で対応 しました。

この記事では、TerraformからAWS Lambdaの環境変数を設定する方法を紹介します。

なお、Terraform のバージョンは2016/12/11時点での最新 0.7.13 を使っています。


Terraformのバージョン

$ terraform.exe -v

Terraform v0.7.13


環境変数のうれしさ

環境変数を使うと、関数(zip)内のパラメータの変更が容易になります。

今までだったらパラメータを使う時、例えば以下のような方法が取っていたかとおもいます。


  • 関数内に直書き

  • 関数名に入れてパース

  • DBに持たせる

しかし、関数内に直書きしていると、関数の何かのパラメータが変わるたびにzipファイルを作り直してアップロードしなくてはなりませんでした。

関数名に入れてパースは事故の元になりそうです。

DBに持たせるのは手軽さに欠けます。

今回のLambdaによる環境変数のサポートで、手軽かつスマートにパラメータを使用・変更できるようになりました。

※ ただし、環境変数のサイズには上限(4 KB)があります。


環境変数の使い方


設定方法(Terraform側)

environment 引数の中に 属性名を variables、値をMap形式で書きます。


aws_lambda_function.tf

    environment {

variables = {
key1 = "aaaabbbb"
key2 = "aaaa\nbbbb"
key3 = "${var.value3}"
key4 = "${var.value4}"
key6 = "${var.value6}"
}
}

※ 下にaws_lambda_functionリソース全体も書いてあります。


取得方法(Node.js側)

process.env 変数から取得


Node.js

const value1 = process.env.key1;

const value2 = process.env.key2;
const keyName = "key3"
const value3 = process.env[keyName];


サンプル

https://github.com/tksugimoto/terraform_aws-lambda-environment-variables-sample


Terraform


variables.tf

variable "value3" {

default = "aaaa\nbbbb"
}
variable "value4" {
default = "aaaa\\nbbbb"
}
variable "value6" {
default = "日本語もOK"
}


lambda-function.tf

resource "aws_lambda_function" "env_test" {

function_name = "${var.prefix}"
role = "${aws_iam_role.iam_for_lambda.arn}"
runtime = "nodejs4.3"
handler = "index.handler"
filename = "index.zip"
source_code_hash = "${base64sha256(file("index.zip"))}"
environment {
variables = {
key1 = "aaaabbbb"
key2 = "aaaa\nbbbb"
key3 = "${var.value3}"
key4 = "${var.value4}"
key6 = "${var.value6}"
}
}
}


Node.js


index.js

exports.handler = () => {

console.log("Fired!");

const value1 = process.env.key1;
console.log(`key1: ${value1}`);

const value2 = process.env.key2;
console.log(`key2: ${value2}`);

const keyName = "key3"
const value3 = process.env[keyName];
console.log(`key3: ${value3}`);

console.log(`key4: ${process.env.key4}`);
console.log(`key5: ${process.env.key5}`);
console.log(`typeof key5: ${typeof process.env.key5}`);
console.log(`key6: ${process.env.key6}`);
};



備考


改行は \n ではなく \\n 推奨


理由1) マネジメントコンソール上で変数の値内の改行を確認できない

マネジメントコンソールの環境変数表示画像

※ key名でソートしてくれないみたいです



  • key2, key3\n をいれてあるが改行が見えない



    • key4 には \\n (value4)を渡したので、表示が \n になっています




  • 下の出力結果では改行されているので内部では改行が存在するようです


    key1-4の出力結果

    2016-12-11T06:02:02.678Z    55e4239f-bf67-11e6-956c-4d9dde297bec    key1: aaaabbbb
    
    2016-12-11T06:02:02.678Z 55e4239f-bf67-11e6-956c-4d9dde297bec key2: aaaa
    bbbb
    2016-12-11T06:02:02.678Z 55e4239f-bf67-11e6-956c-4d9dde297bec key3: aaaa
    bbbb
    2016-12-11T06:02:02.678Z 55e4239f-bf67-11e6-956c-4d9dde297bec key4: aaaa
    bbbb




理由2) マネジメントコンソール上から編集すると、改行がなくなる

例) key2, key3, key4cccc をマネジメントコンソール上から追加した場合

マネジメントコンソール上で改行が表示されていなかった key2, key3 の改行が消えました


key1-4の出力結果(マネジメントコンソールで編集後)

2016-12-11T06:14:46.537Z    1d359235-bf69-11e6-bdcc-73d201f9fb5d    key1: aaaabbbb

2016-12-11T06:14:46.537Z 1d359235-bf69-11e6-bdcc-73d201f9fb5d key2: aaaabbbbcccc
2016-12-11T06:14:46.537Z 1d359235-bf69-11e6-bdcc-73d201f9fb5d key3: aaaabbbbcccc
2016-12-11T06:14:46.537Z 1d359235-bf69-11e6-bdcc-73d201f9fb5d key4: aaaa
bbbbcccc


日本語も使用可


key6の出力結果

2016-12-11T06:02:02.678Z    55e4239f-bf67-11e6-956c-4d9dde297bec    key6: 日本語もOK



カンマ , が使えない

Terraform関係なく、AWS Lambdaの環境変数の仕様です。

terraform apply すると以下のエラーメッセージが出ます。


エラーメッセージ

ValidationException: 1 validation error detected: Value at 'environment.variables' failed to satisfy constraint: Map value must satisfy constraint: [Member must satisfy regular expression pattern: [^,]*]


terraform plan ではエラーになりません。


指定していないkeyの環境変数を取得すると undefined になる

Terraform関係なく、AWS Lambda (Node.js) の環境変数の仕様です。


key5の出力結果

2016-12-11T06:02:02.678Z    55e4239f-bf67-11e6-956c-4d9dde297bec    key5: undefined

2016-12-11T06:02:02.678Z 55e4239f-bf67-11e6-956c-4d9dde297bec typeof key5: undefined

※ String型の undefined (文字列)ではなく undefined型です。

process.env.key5.replace("unde", "----")

のようにmethodをつなげるとエラーになります。


エラーメッセージ

TypeError: Cannot read property 'replace' of undefined




あとがき


  • Terraformのcodeのシンタックスハイライトって何を指定すると良いんでしょう?

    text だと読みづらいので js (JavaScript) を指定してみましたが、一部おかしくなります。。


  • Amazon Web Services Advent Calendar 2016 - Qiita がガラ空きだったので入れておきました。