provider "aws" {
  region = "us-east-1"
}

terraform {
  required_providers {
    aws = "3.19.0"
  }
}

resource "aws_apigatewayv2_api" "example" {
  name                       = "example-websocket-api"
  protocol_type              = "WEBSOCKET"
  route_selection_expression = "$request.body.action"
}

resource "aws_apigatewayv2_authorizer" "foo" {
    api_id           = aws_apigatewayv2_api.example.id
    authorizer_type  = "REQUEST"
    authorizer_uri   = aws_lambda_function.authorizer.invoke_arn
    identity_sources = ["route.request.header.Auth"]
    name             = "foo"
}

resource "aws_iam_role" "invocation_role" {
    name = "apigatewayv2_auth_invocation"
    path = "/"

    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_iam_role_policy" "invocation_policy" {
    name = "apigatewayv2_authorizer_policy"
    role = aws_iam_role.invocation_role.id

    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "lambda:InvokeFunction",
      "Effect": "Allow",
      "Resource": "${aws_lambda_function.authorizer.arn}"
    }
  ]
}
EOF
}

resource "aws_iam_role" "lambda" {
    name = "apigatewayv2_authorizer_lambda_role"

    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_lambda_function" "authorizer" {
    filename      = "lambda.zip"
    function_name = "apigatewayv2_authorizer"
    role          = aws_iam_role.lambda.arn
    handler       = "lambda.handler"
    runtime       = "nodejs12.x"
}
