api-gateway.tf
3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# VPC Link for connecting API Gateway to NLB
resource "aws_apigatewayv2_vpc_link" "user_management" {
  name               = "${var.api_gateway_name}-vpc-link"
  security_group_ids = [aws_security_group.vpc_link.id]
  subnet_ids         = data.aws_subnets.private.ids
  tags = merge(var.tags, {
    Name        = "${var.api_gateway_name}-vpc-link"
    Environment = var.environment
    Project     = "user-management"
  })
}
# HTTP API Gateway
resource "aws_apigatewayv2_api" "user_management" {
  name          = var.api_gateway_name
  protocol_type = "HTTP"
  description   = "User Management System HTTP API"
  
  # CORS 配置 - 允许所有来源(生产环境应限制)
  cors_configuration {
    allow_origins = ["*"]
    allow_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
    allow_headers = ["*"]
    max_age       = 300
  }
  tags = merge(var.tags, {
    Name        = var.api_gateway_name
    Environment = var.environment
    Project     = "user-management"
  })
}
# Integration with NLB via VPC Link
resource "aws_apigatewayv2_integration" "user_management" {
  api_id             = aws_apigatewayv2_api.user_management.id
  integration_type   = "HTTP_PROXY"
  integration_method = "ANY"
  integration_uri    = "http://${data.aws_lb.nlb.dns_name}"
  connection_type    = "VPC_LINK"
  connection_id      = aws_apigatewayv2_vpc_link.user_management.id
  # 传递所有请求参数
  request_parameters = {
    "overwrite:path" = "/$request.path.proxy"
  }
  depends_on = [data.aws_lb.nlb]
}
# 定义路由
locals {
  routes = {
    "root"        = "GET /"
    "api"         = "GET /api"
    "health"      = "GET /api/health"
    "users"       = "ANY /api/users"
    "user_detail" = "ANY /api/users/{id}"
    "catch_all"   = "ANY /{proxy+}"
  }
}
resource "aws_apigatewayv2_route" "routes" {
  for_each = local.routes
  api_id    = aws_apigatewayv2_api.user_management.id
  route_key = each.value
  target    = "integrations/${aws_apigatewayv2_integration.user_management.id}"
  # 为 OPTIONS 请求自动处理 CORS
  dynamic "cors_configuration" {
    for_each = each.key == "catch_all" ? [] : [1]
    content {
      allow_origins = ["*"]
      allow_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
      allow_headers = ["*"]
      max_age       = 300
    }
  }
}
# Production Stage
resource "aws_apigatewayv2_stage" "production" {
  api_id      = aws_apigatewayv2_api.user_management.id
  name        = var.environment
  auto_deploy = true
  # Access Logs
  access_log_settings {
    destination_arn = aws_cloudwatch_log_group.api_gateway.arn
    format = jsonencode({
      requestId               = "$context.requestId"
      sourceIp                = "$context.identity.sourceIp"
      requestTime             = "$context.requestTime"
      protocol                = "$context.protocol"
      httpMethod              = "$context.httpMethod"
      resourcePath            = "$context.resourcePath"
      routeKey                = "$context.routeKey"
      status                  = "$context.status"
      responseLength          = "$context.responseLength"
      integrationErrorMessage = "$context.integrationErrorMessage"
    })
  }
  tags = merge(var.tags, {
    Name        = "${var.api_gateway_name}-${var.environment}"
    Environment = var.environment
    Project     = "user-management"
  })
}
# CloudWatch Log Group
resource "aws_cloudwatch_log_group" "api_gateway" {
  name              = "/aws/apigateway/${var.api_gateway_name}"
  retention_in_days = 30
  tags = merge(var.tags, {
    Name        = "${var.api_gateway_name}-logs"
    Environment = var.environment
    Project     = "user-management"
  })
}