http-api-gateway ---> vpcリンク --> 対象VPCのALB
の経路で処理を行うAWS http-api-gateway と vpcリンクのterraformコードのメモ書きです。
http-api-gatewayの認可にはLambdaを使用しています。
こちらのコードの紹介は今回省略します。
内容としては、requestのheaderにAuthorizationが含まれ想定通りの値が入っていたら通信を許可するといったものです。
http_api.tf
http-api-gateway
とvpcリンク
についてのコードです。
http-api-gateway 統合
の部分でhttp-api-gateway``vpcリンク``対象VPCのALB
の紐付けを行っています。
# http-gateway用のvpcリンク
resource "aws_apigatewayv2_vpc_link" "this" {
name = "test-vpc-link"
security_group_ids = [var.security_group_id]
subnet_ids = var.private_subnet_ids
tags = {
Usage = "test-vpc-link"
}
}
# http-api-gateway本体
resource "aws_apigatewayv2_api" "this" {
name = "test-http-gateway"
protocol_type = "HTTP"
}
# http-api-gateway ルート
resource "aws_apigatewayv2_route" "this_route" {
api_id = aws_apigatewayv2_api.this.id
# ルート キー。 HTTP API の場合、ルート キーは $default にするか、HTTP メソッドとリソース パスの組み合わせ (GET /pets など) にすることができます。
route_key = "ANY /{proxy+}"
# http-api-gateway 統合との紐付け。integrations/IntegrationID という形式。
target = "integrations/${aws_apigatewayv2_integration.this.id}"
# ルートの承認タイプ。Lambda オーソライザーを使用する場合は CUSTOM です。
authorization_type = "CUSTOM"
# http-api-gateway 認可をアタッチ
authorizer_id = aws_apigatewayv2_authorizer.this.id
}
# http-api-gateway 統合
resource "aws_apigatewayv2_integration" "this" {
api_id = aws_apigatewayv2_api.this.id
# HTTP API プライベート統合の場合、HTTP_PROXY を使用します
integration_type = "HTTP_PROXY"
# HTTP API プライベート統合の場合、Application Load Balancer リスナー、Network Load Balancer リスナー、または AWS Cloud Map サービスの ARN を指定します
integration_uri = var.alb_listener_arn
# インテグレーションに送信されるペイロードの形式。有効な値: 1.0、2.0。デフォルトは 1.0 です。
payload_format_version = "1.0"
# 統合の HTTP メソッド。 integration_type が MOCK でない場合は指定する必要があります
integration_method = "ANY"
# 統合の VPC リンクを使用する場合に設定
connection_type = "VPC_LINK"
# 接続するVPC_LINKを指定
connection_id = aws_apigatewayv2_vpc_link.this.id
}
# http-api-gateway 認可
resource "aws_apigatewayv2_authorizer" "this" {
api_id = aws_apigatewayv2_api.this.id
name = "test-authorizer"
# オーソライザーのタイプ。Lambdaを使う場合はREQUESTを指定
authorizer_type = "REQUEST"
# オーソライザーに使用するLambda関数をarnで指定する
authorizer_uri = var.lambda_func_authandcert_invoke_arn
# ID ソースの指定
identity_sources = ["$request.header.Authorization"]
# ペイロード形式のバージョン。REST APIと連携する場合は1.0
authorizer_payload_format_version = "1.0"
# Lambda 関数を呼び出すためのアクセス権限がついたロールを指定
authorizer_credentials_arn = aws_iam_role.invocation_role.arn
# キャッシュされたオーソライザーの結果の存続時間 (TTL) (秒単位)
authorizer_result_ttl_in_seconds = 0
}
# http-api-gateway ステージ
resource "aws_apigatewayv2_stage" "this" {
api_id = aws_apigatewayv2_api.this.id
name = "$default"
auto_deploy = true
access_log_settings {
destination_arn = aws_cloudwatch_log_group.api_gateway_this.arn
format = jsonencode({ "requestId" : "$context.requestId", "ip" : "$context.identity.sourceIp", "requestTime" : "$context.requestTime", "httpMethod" : "$context.httpMethod", "routeKey" : "$context.routeKey", "status" : "$context.status", "protocol" : "$context.protocol", "responseLength" : "$context.responseLength" })
}
}
# cloudwatch_log_group
resource "aws_cloudwatch_log_group" "api_gateway_this" {
name = "/aws/apigateway/test-http-gateway"
# ログの保存期間
retention_in_days = 0
}
iam_role.tf
http-api-gateway 認可のauthorizer_credentials_arn
に指定するiamロールの設定です。
こちらがないとhttp-api-gatewayからLambdaが実行できません。
resource "aws_iam_role" "invocation_role" {
name = "api-gateway-auth-invocation"
path = "/"
managed_policy_arns = [aws_iam_policy.policy_lambda_invokefunction.arn]
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": [
"apigateway.amazonaws.com",
"lambda.amazonaws.com"
]
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_policy" "policy_lambda_invokefunction" {
name = "policy-618033"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["lambda:InvokeFunction"]
Effect = "Allow"
Resource = "*"
},
]
})
}
Lambdaのロール
実行するLambdaについての補足です。
Lambdaには下記信頼関係ポリシーとAWSLambdaBasicExecutionRole
ポリシーを設定しておきます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}