AWS API Gateway as Ingress Controller Advanced settings — Part 02

Danushka Fernando
3 min readOct 13, 2020

In my previous blog[1] I mentioned about the features I added to the API GW Ingress Controller in the first cut. But as our project evolved I included few more cool features and this time I am going to talk about them.

Separating out Ingress rules and API resources published via API GW.

Ingress controller was earlier defining APIs based on ingress rules. So it was difficult to define API resources and methods that were exposed publicly and keep some resources private. And also it was difficult to expose certain methods as ingress rules cannot define methods.

So I came up with a solution of an annotation which can be use to define the public APIs. With this we can define which resource and which method is exposed publicly and everything else will be private.

Annotation to define public api resources is as below.

apigateway.ingress.kubernetes.io/public-resources

Here is a sample json value that you can provide. Its an array and you can define any number of resources. And you should minify the json and add it to ingress configuration.

[
{
"path":"/api/v1/foobar",
"caching_enabled":true,
"method":[
"GET",
"POST"
]
}
]

And if you have path, query or header params and if you want to proxy them that also can be added to the same configuration. And also you can add constant path query or header params also which will be passed to the backend. Here is the api resource path struct looks like. So you can define mentioned properties within above json. Use json property names mentioned before the property name.

type APIResource struct { 
Path string `json:"path"`
CachingEnabled bool `json:"caching_enabled"`
Methods []Method `json:"method"`
PathParams []ConstantParam `json:"cons_path_params"`
QueryParams []ConstantParam `json:"cons_query_params"`
HeaderParams []ConstantParam `json:"cons_header_params"`
ProxyPathParams []Param `json:"path_params"`
ProxyQueryParams []Param `json:"query_params"`
ProxyHeaderParams []Param `json:"header_params"`
}
type Param struct {
Param string `json:"param"`
Required bool `json:"required"`
}
type ConstantParam struct {
Key string `json:"key"`
Value string `json:"value"`
}

Allowing to create multiple APIs in APIGW with its own api resources, authorizers and usage plans.

This can be named as the most cool feature I added. Lets say you have multiple APIs you want to create. You can definitely create multiple ingresses. But the problem with that is it will create multiple VPC links multiple NLBs and so on. But those can be shared with the APIs when we use same backend. So idea here is to let share everything else other than APIGW resources. And apart from this I added the capability to provide the authorizer configs here also. Different apis can have different authorizer configs, resources and usage plan configs.

I defined an ingress annotation to define this as below.

apigateway.ingress.kubernetes.io/aws-api-configs

Input is again a json and its an array. Following are the two new structs I added to support this feature. Input to the above annotation should be an array of AWSAPIDefinition type.

type AWSAPIDefinition struct { 
Name string `json:"name,omitempty"`
Context string `json:"context"`
AuthenticationEnabled bool `json:"authentication_enabled"`
APIKeyEnabled bool `json:"api_key_enabled"`
Authorization_Enabled bool `json:"authorization_enabled"`
UsagePlans []UsagePlan `json:"usage_plans"`
Authorizers []AWSAPIAuthorizer `json:"authorizers"`
APIs []APIResource `json:"apis"`
BinaryMediaTypes []string `json:"binary_media_types"`
}
type AWSAPIAuthorizer struct {
IdentitySource string `json:"id_source"`
AuthorizerType string `json:"authorizer_type,omitempty"` //can be TOKEN, COGNITO_USER_POOLS or REQUEST
AuthorizerAuthType string `json:"authorizer_auth_type"`
AuthorizerName string `json:"authorizer_name"`
IdentityValidationExpression string `json:"id_validation_exp"`
AuthorizerResultTtlInSeconds int `json:"authorizer_result_ttl_secs"`
AuthorizerUri string `json:"lambda_arn"`
ProviderARNs []string `json:"provider_arns"`
}

Other feature additions to enable Gateway Cache, Request timeout, Enabling request compression and allowing to configure TLS policy to the custom domain.

Few more minor feature additions are done which are not included in previous cut and not mentioned in the previous blog entry and related annotations can be found in README with some sample values.

Hope this helps. Good luck !!!

References

[1] https://blog.usejournal.com/api-gateway-as-ingress-controller-advanced-settings-cfda5ce06d41

[2] https://github.com/danushkaf/amazon-apigateway-ingress-controller

[3] https://github.com/danushkaf/amazon-apigateway-ingress-controller/blob/master/README.md#example

[4] https://github.com/danushkaf/amazon-apigateway-ingress-controller/blob/master/pkg/cloudformation/types.go

--

--