Apexでfunctionをデプロイするとトリガーが登録されないのであとで追加することになる。 これを手作業で行うこともできるのだが、せっかくなのでアプリケーションと一緒に管理したい。 そんなときのためにterraformコマンドをラップしたapex infraが用意されている。
TerraformでVPCを管理するmoduleを作る - sambaiz-net
functionsと同列にinfrastructureディレクトリを作成してtfファイルを置く。 その下に環境ごとのディレクトリを作成することもできて、その場合は –env で指定した環境のものが使われる。
- functions
- infrastructure
main.tf
variables.tf
- modules
- cloudwatch_schedule
main.tf
variables.tf
project.json
functionをデプロイするとそのARNが変数で取れるようになる。
$ apex list --tfvars
apex_function_hello="arn:aws:lambda:ap-northeast-1:*****:function:usetf_hello"
今回設定するトリガーはCloudwatch Eventのスケジューリング。作成するリソースは以下の通り。
- aws_cloudwatch_event_ruleでイベントルール(今回はschedule)を作成
- aws_cloudwatch_event_targetでルールにターゲット(今回はLambda)を設定
- aws_lambda_permissionでルールに対象Lambdaをinvokeする権限を付ける
$ cat infrastructure/modules/cloudwatch_schefule/variables.tf
variable "lambda_function_name" {}
variable "lambda_function_arn" {}
variable "schedule_expression" {
description = "cloudwatch schedule expression e.g. \"cron(0/5 * * * ? *)\""
}
$ cat infrastructure/modules/cloudwatch_schefule/main.tf
resource "aws_cloudwatch_event_rule" "lambda" {
name = "lambda_rule_${var.lambda_function_name}"
description = "invoke lambda ${var.lambda_function_name}"
schedule_expression = "${var.schedule_expression}"
}
resource "aws_cloudwatch_event_target" "lambda" {
target_id = "lambda_target_${var.lambda_function_name}"
rule = "${aws_cloudwatch_event_rule.lambda.name}"
arn = "${var.lambda_function_arn}"
}
resource "aws_lambda_permission" "lambda" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = "${aws_cloudwatch_event_target.lambda.arn}"
principal = "events.amazonaws.com"
source_arn = "${aws_cloudwatch_event_rule.lambda.arn}"
}
$ cat infrastructure/variables.tf
variable "apex_function_names" {
type="map"
}
variable "apex_function_hello" {}
$ cat infrastructure/main.tf
terraform {
backend "s3" {
bucket = "sambaiz-terraform"
key = "usetf.tfstate"
region = "ap-northeast-1"
}
}
module "hello_trigger" {
source = "./modules/cloudwatch_schedule"
lambda_function_name = "${var.apex_function_names["hello"]}"
lambda_function_arn = "${var.apex_function_hello}"
schedule_expression = "cron(0/5 * * * ? *)"
}
initしてbackendを初期化してmoduleを準備する。
$ apex infra init
$ ls infrastructure/.terraform/modules/*****
main.tf variables.tf
planするとこんな感じ。ApexによってfunctionのARNが渡っていることが分かる。
$ apex infra plan
+ module.hello_trigger.aws_cloudwatch_event_rule.lambda
arn: "<computed>"
description: "invoke lambda usetf_hello"
is_enabled: "true"
name: "lambda_rule_usetf_hello"
schedule_expression: "cron(0/5 * * * ? *)"
+ module.hello_trigger.aws_cloudwatch_event_target.lambda
arn: "arn:aws:lambda:ap-northeast-1:*****:function:usetf_hello"
rule: "lambda_rule_usetf_hello"
target_id: "lambda_target_usetf_hello"
+ module.hello_trigger.aws_lambda_permission.lambda
action: "lambda:InvokeFunction"
function_name: "arn:aws:lambda:ap-northeast-1:*****:function:usetf_hello"
principal: "events.amazonaws.com"
source_arn: "${aws_cloudwatch_event_rule.lambda.arn}"
statement_id: "AllowExecutionFromCloudWatch"
applyするとトリガーが登録される。
$ apex infra apply
$ apex logs hello
...
/aws/lambda/usetf_hello 2017-11-12T13:20:14.561Z 37e75818-c7ac-11e7-a333-111863808b13 processing event:
...
/aws/lambda/usetf_hello 2017-11-12T13:25:15.182Z eb178941-c7ac-11e7-bde0-998ea9659640 processing event:
参考
ApexとTerraformでCloudWatch EventsによりInvokeされるLambda関数をデプロイする | Developers.IO