LoginSignup
2

More than 3 years have passed since last update.

posted at

updated at

Organization

Terraformで構築するAmazon SNSからAWS Lambdaを呼び出すためのトリガ

はじめに

こんにちは、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

すると
スクリーンショット 2019-12-03 15.49.29.png
できました。

最後に

Lambdaへのトリガ設定もTerraformで設定できるようになりました。
サーバレスが捗りますね

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2