はじめに
SREエンジニアやってます。@hayaosatoです。
今回はサーバレスなアーキテクチャを組む上で超便利なAWS Lambda(以下、Lambda)をAmazon SQS(以下、SQS)から呼び出してみたいと思います。
コードはこちら
アーキテクチャ
Lambda
Lambdaのリソースは以下のように作ることができます。
アプリケーションはslack通知のスクリプトにしました。
// IAM Role for Lambda Function
resource "aws_iam_role" "default" {
name = var.service_name
description = "IAM Rolw for ${var.service_name}"
assume_role_policy = file("${var.service_name}_role.json")
}
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
}
// Lambda Function Resources
resource "aws_cloudwatch_log_group" "default" {
name = "/aws/lambda/${var.service_name}"
retention_in_days = 7
}
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
}
}
}
Lambda関数をTerraformで作成する際は是非ともarchiveリソースのarchive_file
を利用していただきたいです。
これを利用することでzipを生成してそれをそのままLambda関数に適応できるので非常に楽です。
つまりはこの構成をそのままCIに組み込んでCIツールからterraform apply
すればいい感じですね。
SQS
SQSのリソースは以下のように作ることができます。
resource "aws_sqs_queue" "default" {
name = "${var.service_name}.fifo"
fifo_queue = true
content_based_deduplication = true
}
SQSとLambdaの連携
TerraformにはLambdaのトリガ設定のためのリソースとしてlambda_event_source_mappingというものがあります。
今回はこれを使います。
resource "aws_lambda_event_source_mapping" "default" {
event_source_arn = aws_sqs_queue.default.arn
function_name = aws_lambda_function.default.arn
}
また、このリソースは現在SQSとDynamoDB,Kinesisにしか対応していないため、SNSからの連携はできません(コードにSNSと連携させようと作ったリソースの残骸が。。。)
event_source_arn
に指定できないリソースのARNを入れてしまうと、無限にcreating...
になります。
ただ、S3からのイベントは普通に実行できます。
結果
作ったリソースで実際にキューを発行して実行してみます。
できました
最後に
やっぱりサーバレスっていいですね