12 min to read
What is AWS Ingress Annotations?

Overview
Learn about AWS Load Balancer Controller Ingress Annotations and how they manage traffic routing to Kubernetes services using Application Load Balancers (ALB).
What is Ingress Annotations?
In AWS, the AWS load balancer controller configures and manages the behavior of the Application Load Balancer (ALB) that routes traffic to the Kubernetes service using annotations for incoming resources.
Annotations allow you to specify settings such as SSL, routing behavior, and security groups directly within the Kubernetes Ingress resource.
How Load Balancer Controller Works
- Create or update ALBs, their listeners, and target groups based on the specified annotations.
- Manage status checks, security settings, routing rules, SSL certificates, and other defined configurations.
- When annotations change, the controller updates ALB with new settings without manual intervention, allowing Kubernetes native resources to manage complex configurations.
Ingress Groups
- In AWS, ingress group is a feature that allows multiple ingress resources to be integrated into a single load balancer (ALB) to be managed.
- This allows applications from different Kubernetes namespaces or different teams to share the same ALB while setting different Ingress rules.
- ingress group can save network resources and increase management efficiency.
- Basically, ingress does not belong to ingress group, ingress is “implicit ingress group”, that is, it exists as an independent entity.
Ingress Group Name Settings
- Use the alb.ingress.kubernetes.io/group.name annotation to define the group name.
- An ingress resource with the same group name will share one ALB.
- ALB assigned to ingress group is ingress.k8s.aws/stack searches and finds AWS tags (which are tagged by listener rules) and takes the name of InressGroup as the value of this tag.
- For resources that do not use ingress group, the tag value is set in the format of namespace/ingressname.
- If you change the groupName assigned to the ingress resource, the ingress moves from the existing group to the new ingress Group, which is managed by the ALB of the new ingress Group.
- If there is no ALB in the new IngressGroup, a new ALB is automatically created.
- The ALB of the ingress group can be found by searching for the AWS tag ingress.k8s.aws/ stack tag with the name of the ingress group as a value.
- example:
alb.ingress.kubernetes.io/group.name: my-team.awesome-group
Ingress Group Ranking
- You can specify the order using the alb.ingress.kubernetes.io/group.order annotation.
- The ingress rule with a low number of order values is applied first, and specific priorities can be specified for the same path or host.
- example:
alb.ingress.kubernetes.io/group.order: 10
Ingress Group Example
In the example below, two ingress resources share a group called my-shared-group, so one ALB processes the request.
# Ingress for Service A
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: service-a-ingress
annotations:
alb.ingress.kubernetes.io/group.name: "my-shared-group"
alb.ingress.kubernetes.io/group.order: "10"
spec:
rules:
- host: "service-a.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-a
port:
number: 80
# Ingress for Service B
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: service-b-ingress
annotations:
alb.ingress.kubernetes.io/group.name: "my-shared-group"
alb.ingress.kubernetes.io/group.order: "20"
spec:
rules:
- host: "service-b.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-b
port:
number: 80
service-a
andservice-b
belong to the ingress groupmy-share-group
, respectively, andservice-a
is applied first as order 10.
Ingress Traffic Listening
Annotation | Description | Example |
---|---|---|
listen-ports |
Specify ports for ALB | [{"HTTP": 80}, {"HTTPS": 443}] |
ssl-redirect |
Enable SSL redirection | '443' |
ip-address-type |
IPv4 or dualstack support | ipv4 or dualstack |
listen-ports
- Specifies the port that the ALB receives.
- Example:
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}, {"HTTP": 8080}, {"HTTPS": 8443}]
- Since it applies to all Ingress within IngressGroup, each Ingress can define its own port, and the rule applies only to the ports specified in each Ingress.
- If the same receiving port is defined by multiple ingress within the IngressGroup, it is applied in the order of the IngressGroup.
- Default: If listen-ports is not specified, the default is {“HTTP”: 80} if the certificate is not used, and {“HTTPS”: 443} if the certificate is provided.
- Warning: You cannot have duplicate load balancer ports in the same group (Exception:
alb.ingress.kubernetes.io/group.order : 10
specified) - Since ALB integrates these settings for all Ingress in the group, defining listen-ports in one Ingress in the IngressGroup is sufficient.
ssl-redirect
- Enables SSL redirection by specifying the port on which HTTP traffic is redirected, typically HTTPS port 443.
- Example:
alb.ingress.kubernetes.io/ssl-redirect: '443'
- SSL redirection (ssl-redirect) affects all ingress in the group if defined in the ingressGroup.
- When SSL redirection is enabled, all HTTP listener are configured by default to redirect to HTTPS, ignoring other HTTP rules.
ip-address-type
- You can specify whether ALB should use ipv4 or dualstack for IPv4 and IPv6 traffic support.
- Example:
alb.ingress.kubernetes.io/ip-address-type: ipv4 or dualstack
- ipv4: Configure ALB to use only IPv4 addresses, i.e., handle IPv4 traffic exclusively.
- dualstack: ALB may support both IPv4 and IPv6 traffic. When set to dualstack, ALB has IPv4 and IPv6 addresses, allowing traffic to be routed in both address types.
customer-owned-ipv4-pool
- Specifies the customer-owned IPv4 address pool for ALB when using the Outpost environment.
- Warning: This comment cannot be changed and you will need to recreate Ingress to change or limit it.
- Example:
alb.ingress.kubernetes.io/customer-owned-ipv4-pool: ipv4pool-coip-xxxxxxx
Ingress Traffic Routing
alb.ingress.kubernetes.io/load-balancer-name
- All Ingress within IngressGroup must use the same load balancer name.
- The name cannot exceed 32 characters, and an error occurs when exceeded.
alb.ingress.kubernetes.io/target-type
- instance mode routes traffic to all ec2 instances in the cluster of NodePort open for service.
- When using instance mode, the service must use NodePort or Loadbalacner type.
- ip mode routes all traffic to pod.
- The network plug-in must use the secondary IP address of ENI for pod IP to use ip mode.
amazon-vpc-cni-k8s
- ip mode is required for sticky session to work with application load balancer. Service type is not important when using ip mode.
alb.ingress.kubernetes.io/target-node-labels
- Specifies the node to be included in the target group registration of the instance target type.
- Example:
alb.ingress.kubernetes.io/target-node-labels: label1=value1, label2=value2
alb.ingress.kubernetes.io/backend-protocol
- Specifies the protocol to use when padding traffic.
-
alb.ingress.kubernetes.io/backend-protocol-version
- Specifies the application protocol used to route traffic to the pod. It is only valid when HTTP or HTTPS is used as a backend protocol.
- Example:
alb.ingress.kubernetes.io/backend-protocol-version: HTTP2
alb.ingress.kubernetes.io/backend-protocol-version: GRPC
alb.ingress.kubernetes.io/actions.${action-name}
- Provides a method for configuring loadbalancer listener rules, such as redirecton operations.
- The serviceName of the annotation should be identical to the serviceName of the ingress rule, and the servicePort should be used-annotated unconditionally.
alb.ingress.kubernetes.io/conditions.${conditions-name}
- Provides a method for specifying routing conditions in addition to host/path conditions in ingress.
- The serviceName of the annotation should be identical to the serviceName of the ingress rule, and the servicePort should be used-annotated unconditionally.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: default
name: ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/actions.rule-path1: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"200","messageBody":"Host is www.example.com OR anno.example.com"}}
alb.ingress.kubernetes.io/conditions.rule-path1: >
[{"field":"host-header","hostHeaderConfig":{"values":["anno.example.com"]}}]
alb.ingress.kubernetes.io/actions.rule-path2: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"200","messageBody":"Path is /path2 OR /anno/path2"}}
alb.ingress.kubernetes.io/conditions.rule-path2: >
[{"field":"path-pattern","pathPatternConfig":{"values":["/anno/path2"]}}]
alb.ingress.kubernetes.io/actions.rule-path3: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"200","messageBody":"Http header HeaderName is HeaderValue1 OR HeaderValue2"}}
alb.ingress.kubernetes.io/conditions.rule-path3: >
[{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "HeaderName", "values":["HeaderValue1", "HeaderValue2"]}}]
alb.ingress.kubernetes.io/actions.rule-path4: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"200","messageBody":"Http request method is GET OR HEAD"}}
alb.ingress.kubernetes.io/conditions.rule-path4: >
[{"field":"http-request-method","httpRequestMethodConfig":{"Values":["GET", "HEAD"]}}]
alb.ingress.kubernetes.io/actions.rule-path5: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"200","messageBody":"Query string is paramA:valueA1 OR paramA:valueA2"}}
alb.ingress.kubernetes.io/conditions.rule-path5: >
[{"field":"query-string","queryStringConfig":{"values":[{"key":"paramA","value":"valueA1"},{"key":"paramA","value":"valueA2"}]}}]
alb.ingress.kubernetes.io/actions.rule-path6: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"200","messageBody":"Source IP is 192.168.0.0/16 OR 172.16.0.0/16"}}
alb.ingress.kubernetes.io/conditions.rule-path6: >
[{"field":"source-ip","sourceIpConfig":{"values":["192.168.0.0/16", "172.16.0.0/16"]}}]
alb.ingress.kubernetes.io/actions.rule-path7: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"200","messageBody":"multiple conditions applies"}}
alb.ingress.kubernetes.io/conditions.rule-path7: >
[{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "HeaderName", "values":["HeaderValue"]}},{"field":"query-string","queryStringConfig":{"values":[{"key":"paramA","value":"valueA"}]}},{"field":"query-string","queryStringConfig":{"values":[{"key":"paramB","value":"valueB"}]}}]
spec:
ingressClassName: alb
rules:
- host: www.example.com
http:
paths:
- path: /path1
pathType: Exact
backend:
service:
name: rule-path1
port:
name: use-annotation
- path: /path2
pathType: Exact
backend:
service:
name: rule-path2
port:
name: use-annotation
- path: /path3
pathType: Exact
backend:
service:
name: rule-path3
port:
name: use-annotation
- path: /path4
pathType: Exact
backend:
service:
name: rule-path4
port:
name: use-annotation
- path: /path5
pathType: Exact
backend:
service:
name: rule-path5
port:
name: use-annotation
- path: /path6
pathType: Exact
backend:
service:
name: rule-path6
port:
name: use-annotation
- path: /path7
pathType: Exact
backend:
service:
name: rule-path7
port:
name: use-annotation
Ingress Access Control
Feature | Annotation | Purpose |
---|---|---|
Scheme | alb.ingress.kubernetes.io/scheme |
Define ALB as internal or internet-facing |
CIDR | alb.ingress.kubernetes.io/inbound-cidrs |
Restrict IP ranges |
Security Groups | alb.ingress.kubernetes.io/security-groups |
Specify security groups |
alb.ingress.kubernetes.io/scheme
- Used in conjunction with AWS Application Load Balancer (ALB) to define the type of load balancer access in a Kubernetes Ingress configuration. This annotation informs AWS whether ALB is an Internet connection (public) or internal (private).
internet-facing
: make ALB accessible publicly via the internet.internal
: make ALB private by restricting it to be accessible only within a VPC or connected network.
alb.ingress.kubernetes.io/inbound-cidrs
- Restrict access to ALB by allowing only the specified IP range (CIDR) to be connected.
- It is particularly useful for controlling access to private applications or internal resources by limiting the range of IPs that can access ALB.
- If Ingress is part of IngressGroup, the inbound-cidrs annotation applies to all Ingress resources in the group.
- However, inbound-cidrs applies only to ports defined in that Ingress.
- Therefore, if multiple ingresses share the same ingress port, you must define inbound-cidrs only for one of those ingresses to prevent collisions.
- Specifying
alb.ingress.kubernetes.io/security-groups
in Ingress ignores inbound-cidrs annotations. - If you do not specify the inbound-cidrs annotation:
- 0.0.0.0/0 (all IPv4 addresses) will be allowed if the ALB’s IPAddressType is set to ipv4.
- 0.0.0.0/0 and ::/0 (all IPv4 and IPv6 addresses) will be allowed if the ALB’s IPAddressType is set to dualstack.
alb.ingress.kubernetes.io/security-groups
- Specifies the security group to connect to the load balancer.
- Without that announcement, the controller automatically creates a security group, connects the security group to the load balancer, and allows listen-ports access to inbound-cidrs and security-group-prefix-lists. The Node/Pod security group also modifies this security group to allow inbound traffic. In other words, if you want to apply the security group I created to Pod and Node, you can use it.
- Example
alb.ingress.kubernetes.io/security-groups: sg-xxxx, nameOfSg1, nameOfSg2
alb.ingress.kubernetes.io/manage-backend-security-group-rules
- When specifying security security groups, specify whether the controller configures security group rules on Node/Pod for traffic access.
- Applies only if you specify a security group through alb.ingress.kubernetes.io/security-groups .
- Example:
alb.ingress.kubernetes.io/manage-backend-security-group-rules: "true"
Best Practices
1. Ingress Groups: - Use meaningful group names
- Set appropriate order
- Share ALB efficiently
2. Security: - Use appropriate scheme
- Implement CIDR restrictions
- Configure security groups
3. Routing: - Choose correct target type
- Set proper protocols
- Define clear conditions
Comments