はじめに
こんにちは、SREエンジニアやっています、@hayaosatoです。
今回はAmazon SNS(以下、SNS)からAWSLambda(以下、Lambda)を呼び出すためのトリガをTerraformで構築してみようと思います。
コードはこちら
前回、似たようなことをSQSからのトリガ設定をTerraformで実装したのですが、
その際に利用したlambda_event_source_mappingでは、一部のリソースでしかLambdaのトリガを設定することができませんでした。
そこで、今回はLambdaにおけるそのほかのリソースへをトリガにするlambda_permissionを利用してSNSからのトリガを構築してみようと思います。
Lambda
アプリケーションはSQSの時と同様、Slack通知を行うアプリケーションにしています。
arvhive_file
でLambda関数用のzipファイルを作成して、生成したzipファイルをLambda関数としてアップします。
data archive_file "default" {
type = "zip"
source_dir = "src"
output_path = var.output_path
}
resource "aws_lambda_function" "default" {
filename = var.output_path
function_name = var.service_name
role = aws_iam_role.default.arn
handler = "lambda_function.lambda_handler"
source_code_hash = data.archive_file.default.output_base64sha256
runtime = "python3.6"
environment {
variables = {
SLACK_API_KEY = var.SLACK_API_KEY
}
}
}
また、SlackのAPIトークンは環境変数から利用しているので、Lambdaにも環境変数を定義します。
IAM
Lambdaを実行するためのIAM Roleも定義する必要があるので、このリソースも合わせて作っておきます。
resource "aws_iam_policy" "default" {
name = var.service_name
description = "IAM Policy for ${var.service_name}"
policy = file("${var.service_name}-policy.json")
}
resource "aws_iam_role_policy_attachment" "default" {
role = aws_iam_role.default.name
policy_arn = aws_iam_policy.default.arn
}
SNS
SNSに関しては、サブスクリプションでLambda関数を指定してリソースを作成してあげる必要があります。
resource "aws_sns_topic" "default" {
name = var.service_name
delivery_policy = file("sns_delivery_policy.json")
}
resource "aws_sns_topic_subscription" "default" {
topic_arn = aws_sns_topic.default.arn
protocol = "lambda"
endpoint = aws_lambda_function.default.arn
}
連携
ここからが本題で、Lambda関数に対してSNSからのトリガを設定してあげます。
resource "aws_lambda_permission" "default" {
statement_id = "AllowExecutionFromSNS"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.default.function_name
principal = "sns.amazonaws.com"
source_arn = aws_sns_topic.default.arn
}
もし、S3からのトリガを設定したい場合は
resource "aws_lambda_permission" "s3_trigger" {
statement_id = "AllowExecutionFromS3Bucket"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.default.arn
principal = "s3.amazonaws.com"
source_arn = aws_s3_bucket.default.arn
}
のようになります。
結果
sample.tfvarsにSlackのAPIトークンを記入して、
$ terraform apply -var-file sample.tfvars
最後に
Lambdaへのトリガ設定もTerraformで設定できるようになりました。
サーバレスが捗りますね