Use terraform or ACK apigatewayv2 EKS operator to set up apigateway in AWS
The daigram
1
2mock-restapi.example.dev(route53) -----> apigateway -----> vpclink -------> private aws nlb (eks ingress) ---> app servcie
Use Terraform to create apigateway restapi resource
to apply the resources and mapping the apigateway domain name to route53 to access the eks services
- create the route53 and domain name and vpc link to access eks services
1resource "aws_api_gateway_vpc_link" "to-private-nlb" {
2 name = "to-private-nlb"
3 description = "rest api to private nlb"
4 target_arns = ["arn:aws:elasticloadbalancing:xxxxx:xxxxx:loadbalancer/net/xxxxxx/xxxxxx"]
5}
6
7data "aws_route53_zone" "example_dev" {
8 name = "example.dev."
9 private_zone = false
10}
11
12resource "aws_api_gateway_domain_name" "mock_restapi_example_dev" {
13 domain_name = "mock-restapi.example.dev"
14 regional_certificate_arn = "arn:aws:acm:xxxxxx:xxxxxxx:certificate/xxxxxx-xxxxxx-xxx-xxxxx"
15
16 endpoint_configuration {
17 types = ["REGIONAL"]
18 }
19}
20
21resource "aws_route53_record" "mock_restapi_example_dev" {
22 name = aws_api_gateway_domain_name.mock_restapi_example_dev.domain_name
23 type = "A"
24 zone_id = data.aws_route53_zone.example_dev.id
25
26 alias {
27 evaluate_target_health = true
28 name = aws_api_gateway_domain_name.mock_restapi_example_dev.regional_domain_name
29 zone_id = aws_api_gateway_domain_name.mock_restapi_example_dev.regional_zone_id
30 }
31}
- create the rest api resource and method and integration
1resource "aws_api_gateway_rest_api" "mock_rest_api" {
2 name = "mock-rest-api"
3 description = "Testing for integration the private NLB"
4
5 endpoint_configuration {
6 types = ["REGIONAL"]
7 }
8}
9
10resource "aws_api_gateway_resource" "root" {
11 rest_api_id = aws_api_gateway_rest_api.mock_rest_api.id
12 parent_id = aws_api_gateway_rest_api.mock_rest_api.root_resource_id
13 path_part = "{proxy+}"
14}
15
16
17resource "aws_api_gateway_method" "all" {
18 rest_api_id = aws_api_gateway_rest_api.mock_rest_api.id
19 resource_id = aws_api_gateway_resource.root.id
20 http_method = "ANY"
21 authorization = "NONE"
22
23 request_parameters = {
24 "method.request.path.proxy" = true
25 }
26}
27
28resource "aws_api_gateway_integration" "vpclink_integration" {
29 rest_api_id = aws_api_gateway_rest_api.mock_rest_api.id
30 resource_id = aws_api_gateway_resource.root.id
31 http_method = aws_api_gateway_method.all.http_method
32 # request_templates = {
33 # "application/json" = ""
34 # "application/xml" = "#set($inputRoot = $input.path('$'))\n{ }"
35 # }
36
37 request_parameters = {
38 "integration.request.path.proxy" = "method.request.path.proxy"
39 # "integration.request.header.X-hpa" = "method.request.header.path"
40 }
41
42 type = "HTTP"
43 uri = "https://private-nlb.example.dev/{proxy}"
44 integration_http_method = "ANY"
45 passthrough_behavior = "WHEN_NO_MATCH"
46 content_handling = "CONVERT_TO_TEXT"
47
48 connection_type = "VPC_LINK"
49 connection_id = aws_api_gateway_vpc_link.to-private-nlb.id
50}
- Create request and response integration and domain base path mapping to route53 record
1resource "aws_api_gateway_method_response" "all" {
2 rest_api_id = aws_api_gateway_rest_api.mock_rest_api.id
3 resource_id = aws_api_gateway_resource.root.id
4 http_method = aws_api_gateway_method.all.http_method
5 status_code = "200"
6}
7
8resource "aws_api_gateway_integration_response" "all" {
9 rest_api_id = aws_api_gateway_rest_api.mock_rest_api.id
10 resource_id = aws_api_gateway_resource.root.id
11 http_method = aws_api_gateway_method.all.http_method
12 status_code = aws_api_gateway_method_response.all.status_code
13
14 depends_on = [
15 aws_api_gateway_method.all,
16 aws_api_gateway_integration.vpclink_integration
17 ]
18}
19
20resource "aws_api_gateway_base_path_mapping" "mock_rest_api" {
21 api_id = aws_api_gateway_rest_api.mock_rest_api.id
22 domain_name = aws_api_gateway_domain_name.mock_restapi_example_dev.id
23 stage_name = aws_api_gateway_stage.main.stage_name
24
25
26 depends_on = [
27 aws_api_gateway_deployment.mock_rest_api,
28 aws_api_gateway_stage.main
29 ]
30}
- create the deployment and stage and method setting to enable logs and metrics
1resource "aws_api_gateway_deployment" "mock_rest_api" {
2 rest_api_id = aws_api_gateway_rest_api.mock_rest_api.id
3
4 triggers = {
5 redeployment = sha1(jsonencode(aws_api_gateway_rest_api.mock_rest_api.body))
6 }
7
8 lifecycle {
9 create_before_destroy = true
10 }
11
12 depends_on = [
13 aws_api_gateway_domain_name.mock_restapi_example_dev,
14 aws_api_gateway_method.all,
15 aws_api_gateway_integration.vpclink_integration
16 ]
17}
18
19resource "aws_api_gateway_stage" "main" {
20 deployment_id = aws_api_gateway_deployment.mock_rest_api.id
21 rest_api_id = aws_api_gateway_rest_api.mock_rest_api.id
22 stage_name = "main"
23
24
25 depends_on = [
26 aws_api_gateway_method.all,
27 aws_api_gateway_integration.vpclink_integration
28 ]
29}
30
31resource "aws_api_gateway_method_settings" "mock_rest_api" {
32 rest_api_id = aws_api_gateway_rest_api.mock_rest_api.id
33 stage_name = aws_api_gateway_stage.main.stage_name
34 method_path = "*/*"
35
36 settings {
37 metrics_enabled = true
38 logging_level = "INFO"
39 }
40}
Use ACK operator and apigatewayv2 to create
- to install the ACK operator apigatewayv2 controller
1# login to aws ecr public registry
2aws ecr-public get-login-password --region us-east-1 | helm registry login --username AWS --password-stdin public.ecr.aws
3# pull the apigatewayv2 controller helm chart
4helm pull oci://public.ecr.aws/aws-controllers-k8s/apigatewayv2-chart
5# install the helm chart to eks cluster
6helm install --create-namespace -n ack-system ack-apigatewayv2-controller ./apigatewayv2 --set=aws.region=us-east-1
- and create eks crd resources
1apiVersion: apigatewayv2.services.k8s.aws/v1alpha1
2kind: VPCLink
3metadata:
4 name: "mock-httpapi-to--private-nlb"
5 namespace: "default"
6spec:
7 name: "mock-httpapi-to-istio-private-nlb"
8 # securityGroupIDs:
9 # - ""
10 subnetIDs:
11 - "subnet-xxxxxxx"
12 - "subnet-xxxxxxx"
13 - "subnet-xxxxxxx"
14 tags: { "Team": "xxxxxx", "Environment": "Dev"}
15
16---
17apiVersion: apigatewayv2.services.k8s.aws/v1alpha1
18kind: API
19metadata:
20 name: "mock-httpapi-testing"
21 namespace: "default"
22spec:
23 name: "mock-httpapi-testing"
24 protocolType: HTTP
25
26---
27apiVersion: apigatewayv2.services.k8s.aws/v1alpha1
28kind: Integration
29metadata:
30 name: "mock-httpapi-testing"
31 namespace: "default"
32spec:
33 apiRef:
34 from:
35 name: "mock-httpapi-testing"
36 integrationType: HTTP_PROXY
37 integrationURI: "arn:aws:elasticloadbalancing:us-east-1:xxxxxxxx:listener/net/istio-private-ingress-gateway/xxxxx/xxxxxx"
38 connectionType: "VPC_LINK"
39 connectionRef:
40 from:
41 name: "mock-httpapi-to-istio-private-nlb"
42 integrationMethod: ANY
43 payloadFormatVersion: "1.0"
44---
45apiVersion: apigatewayv2.services.k8s.aws/v1alpha1
46kind: Authorizer
47metadata:
48 name: "mock-httpapi-testing"
49 namespace: "default"
50spec:
51 name: "mock-httpapi-testing"
52 apiRef:
53 from:
54 name: "mock-httpapi-testing"
55 authorizerType: "JWT"
56 identitySource:
57 - "$request.header.Authorization"
58 jwtConfiguration:
59 audience:
60 - "openid"
61 issuer: "https://service.xxxxxxx.dev/sso"
62---
63apiVersion: apigatewayv2.services.k8s.aws/v1alpha1
64kind: Route
65metadata:
66 name: "mock-httpapi-testing"
67 namespace: "default"
68spec:
69 apiRef:
70 from:
71 name: "mock-httpapi-testing"
72 routeKey: "ANY /{proxy+}"
73 targetRef:
74 from:
75 name: "mock-httpapi-testing"
76 authorizationType: "JWT"
77 authorizerRef:
78 from:
79 name: "mock-httpapi-testing"
80---
81apiVersion: apigatewayv2.services.k8s.aws/v1alpha1
82kind: Stage
83metadata:
84 name: "mock-httpapi-testing"
85 namespace: "default"
86spec:
87 apiRef:
88 from:
89 name: "mock-httpapi-testing"
90 stageName: "main"
91 autoDeploy: true
92 description: "auto deployed stage for mock-httpapi-testing"
Caution the apigateway has restricts
- The ACK support HTTP APIS and WebSocket API current only ACK service
- integration the apigatewayv2 with EKS
- apigatewayv2 support (http api, websocket api), apigateway support(Rest api)
- While HTTP APIs are designed with minimal features so that they can be offered at a lower price. Choose REST APIs if you need features such as API keys, per-client throttling, request validation, AWS WAF integration, or private API endpoints. Choose HTTP APIs if you don’t need the features included with REST APIs. REST API vs HTTP API
- Maximum integration timeout: 30s (No Increased)
- Payload size(10MB) (No Increased)
- Timeout for Lambda authorizer response(10s No increased)