Skip to content

Commit a3c89d6

Browse files
committed
inboud_security_groups
Add referencing existing security groups for inbound traffic Add referencing existing security groups for inbound traffic Add inboud security groups Add inboud security group Add annotation Add annotations Add annotationsss Add annotationssss
1 parent 9e2cbe7 commit a3c89d6

File tree

6 files changed

+276
-84
lines changed

6 files changed

+276
-84
lines changed

docs/guide/ingress/annotations.md

+18
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,24 @@ Access control for LoadBalancer can be controlled with following annotations:
530530
```
531531
alb.ingress.kubernetes.io/inbound-cidrs: 10.0.0.0/24
532532
```
533+
- <a name="inbound-security-groups">`alb.ingress.kubernetes.io/inbound-security-groups`</a> specifies the SecurtityGroups that are allowed to access LoadBalancer.
534+
535+
!!!note "Merge Behavior"
536+
`inbound-security-groups` is merged across all Ingresses in IngressGroup, but is exclusive per listen-port.
537+
538+
- the `inbound-security-groups` will only impact the ports defined for that Ingress.
539+
- if same listen-port is defined by multiple Ingress within IngressGroup, `inbound-security-groups` should only be defined on one of the Ingress.
540+
541+
!!!warning ""
542+
this annotation will be ignored if `alb.ingress.kubernetes.io/security-groups` is specified.
543+
544+
!!!tip ""
545+
Both name or ID of securityGroups are supported. Name matches a `Name` tag, not the `groupName` attribute.
546+
547+
!!!example
548+
```
549+
alb.ingress.kubernetes.io/inbound-security-groups: sg-xxxx, nameOfSg1, nameOfSg2
550+
```
533551

534552
- <a name="security-group-prefix-lists">`alb.ingress.kubernetes.io/security-group-prefix-lists`</a> specifies the managed prefix lists that are allowed to access LoadBalancer.
535553

pkg/annotations/constants.go

+59-43
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,64 @@
11
package annotations
22

33
const (
4+
// AnnotationCheckPoint is the annotation used to store a checkpoint for resources.
5+
// It contains an opaque value that represents the last known reconciled state.
6+
AnnotationCheckPoint = "elbv2.k8s.aws/checkpoint"
7+
8+
// AnnotationCheckPointTimestamp is the annotation used to store the last checkpointed time. The value is stored in seconds.
9+
AnnotationCheckPointTimestamp = AnnotationCheckPoint + "-timestamp"
10+
411
// IngressClass
512
IngressClass = "kubernetes.io/ingress.class"
613

714
AnnotationPrefixIngress = "alb.ingress.kubernetes.io"
815
// Ingress annotation suffixes
9-
IngressSuffixLoadBalancerName = "load-balancer-name"
10-
IngressSuffixGroupName = "group.name"
11-
IngressSuffixGroupOrder = "group.order"
12-
IngressSuffixTags = "tags"
13-
IngressSuffixIPAddressType = "ip-address-type"
14-
IngressSuffixScheme = "scheme"
15-
IngressSuffixSubnets = "subnets"
16-
IngressSuffixCustomerOwnedIPv4Pool = "customer-owned-ipv4-pool"
17-
IngressSuffixLoadBalancerAttributes = "load-balancer-attributes"
18-
IngressSuffixWAFv2ACLARN = "wafv2-acl-arn"
19-
IngressSuffixWAFACLID = "waf-acl-id"
20-
IngressSuffixWebACLID = "web-acl-id" // deprecated, use "waf-acl-id" instead.
21-
IngressSuffixShieldAdvancedProtection = "shield-advanced-protection"
22-
IngressSuffixSecurityGroups = "security-groups"
23-
IngressSuffixListenPorts = "listen-ports"
24-
IngressSuffixSSLRedirect = "ssl-redirect"
25-
IngressSuffixInboundCIDRs = "inbound-cidrs"
26-
IngressSuffixCertificateARN = "certificate-arn"
27-
IngressSuffixSSLPolicy = "ssl-policy"
28-
IngressSuffixTargetType = "target-type"
29-
IngressSuffixBackendProtocol = "backend-protocol"
30-
IngressSuffixBackendProtocolVersion = "backend-protocol-version"
31-
IngressSuffixTargetGroupAttributes = "target-group-attributes"
32-
IngressSuffixHealthCheckPort = "healthcheck-port"
33-
IngressSuffixHealthCheckProtocol = "healthcheck-protocol"
34-
IngressSuffixHealthCheckPath = "healthcheck-path"
35-
IngressSuffixHealthCheckIntervalSeconds = "healthcheck-interval-seconds"
36-
IngressSuffixHealthCheckTimeoutSeconds = "healthcheck-timeout-seconds"
37-
IngressSuffixHealthyThresholdCount = "healthy-threshold-count"
38-
IngressSuffixUnhealthyThresholdCount = "unhealthy-threshold-count"
39-
IngressSuffixSuccessCodes = "success-codes"
40-
IngressSuffixAuthType = "auth-type"
41-
IngressSuffixAuthIDPCognito = "auth-idp-cognito"
42-
IngressSuffixAuthIDPOIDC = "auth-idp-oidc"
43-
IngressSuffixAuthOnUnauthenticatedRequest = "auth-on-unauthenticated-request"
44-
IngressSuffixAuthScope = "auth-scope"
45-
IngressSuffixAuthSessionCookie = "auth-session-cookie"
46-
IngressSuffixAuthSessionTimeout = "auth-session-timeout"
47-
IngressSuffixTargetNodeLabels = "target-node-labels"
48-
IngressSuffixManageSecurityGroupRules = "manage-backend-security-group-rules"
49-
IngressSuffixMutualAuthentication = "mutual-authentication"
50-
IngressSuffixSecurityGroupPrefixLists = "security-group-prefix-lists"
16+
IngressSuffixLoadBalancerName = "load-balancer-name"
17+
IngressSuffixGroupName = "group.name"
18+
IngressSuffixGroupOrder = "group.order"
19+
IngressSuffixTags = "tags"
20+
IngressSuffixIPAddressType = "ip-address-type"
21+
IngressSuffixScheme = "scheme"
22+
IngressSuffixSubnets = "subnets"
23+
IngressSuffixCustomerOwnedIPv4Pool = "customer-owned-ipv4-pool"
24+
IngressSuffixLoadBalancerAttributes = "load-balancer-attributes"
25+
IngressSuffixWAFv2ACLARN = "wafv2-acl-arn"
26+
IngressSuffixWAFACLID = "waf-acl-id"
27+
IngressSuffixWebACLID = "web-acl-id" // deprecated, use "waf-acl-id" instead.
28+
IngressSuffixShieldAdvancedProtection = "shield-advanced-protection"
29+
IngressSuffixSecurityGroups = "security-groups"
30+
IngressSuffixListenPorts = "listen-ports"
31+
IngressSuffixSSLRedirect = "ssl-redirect"
32+
IngressSuffixInboundCIDRs = "inbound-cidrs"
33+
IngressSuffixCertificateARN = "certificate-arn"
34+
IngressSuffixSSLPolicy = "ssl-policy"
35+
IngressSuffixTargetType = "target-type"
36+
IngressSuffixBackendProtocol = "backend-protocol"
37+
IngressSuffixBackendProtocolVersion = "backend-protocol-version"
38+
IngressSuffixTargetGroupAttributes = "target-group-attributes"
39+
IngressSuffixHealthCheckPort = "healthcheck-port"
40+
IngressSuffixHealthCheckProtocol = "healthcheck-protocol"
41+
IngressSuffixHealthCheckPath = "healthcheck-path"
42+
IngressSuffixHealthCheckIntervalSeconds = "healthcheck-interval-seconds"
43+
IngressSuffixHealthCheckTimeoutSeconds = "healthcheck-timeout-seconds"
44+
IngressSuffixHealthyThresholdCount = "healthy-threshold-count"
45+
IngressSuffixUnhealthyThresholdCount = "unhealthy-threshold-count"
46+
IngressSuffixSuccessCodes = "success-codes"
47+
IngressSuffixAuthType = "auth-type"
48+
IngressSuffixAuthIDPCognito = "auth-idp-cognito"
49+
IngressSuffixAuthIDPOIDC = "auth-idp-oidc"
50+
IngressSuffixAuthOnUnauthenticatedRequest = "auth-on-unauthenticated-request"
51+
IngressSuffixAuthScope = "auth-scope"
52+
IngressSuffixAuthSessionCookie = "auth-session-cookie"
53+
IngressSuffixAuthSessionTimeout = "auth-session-timeout"
54+
IngressSuffixTargetNodeLabels = "target-node-labels"
55+
IngressSuffixManageSecurityGroupRules = "manage-backend-security-group-rules"
56+
IngressSuffixMutualAuthentication = "mutual-authentication"
57+
IngressSuffixSecurityGroupPrefixLists = "security-group-prefix-lists"
58+
IngressSuffixlsAttsAnnotationPrefix = "listener-attributes"
59+
IngressLBSuffixMultiClusterTargetGroup = "multi-cluster-target-group"
60+
IngressSuffixLoadBalancerCapacityReservation = "minimum-load-balancer-capacity"
61+
IngressSuffixInboundSecurityGroups = "inbound-security-groups"
5162

5263
// NLB annotation suffixes
5364
// prefixes service.beta.kubernetes.io, service.kubernetes.io
@@ -88,4 +99,9 @@ const (
8899
SvcLBSuffixManageSGRules = "aws-load-balancer-manage-backend-security-group-rules"
89100
SvcLBSuffixEnforceSGInboundRulesOnPrivateLinkTraffic = "aws-load-balancer-inbound-sg-rules-on-private-link-traffic"
90101
SvcLBSuffixSecurityGroupPrefixLists = "aws-load-balancer-security-group-prefix-lists"
91-
)
102+
SvcLBSuffixlsAttsAnnotationPrefix = "aws-load-balancer-listener-attributes"
103+
SvcLBSuffixMultiClusterTargetGroup = "aws-load-balancer-multi-cluster-target-group"
104+
ScvLBSuffixEnablePrefixForIpv6SourceNat = "aws-load-balancer-enable-prefix-for-ipv6-source-nat"
105+
ScvLBSuffixSourceNatIpv6Prefixes = "aws-load-balancer-source-nat-ipv6-prefixes"
106+
SvcLBSuffixLoadBalancerCapacityReservation = "aws-load-balancer-minimum-load-balancer-capacity"
107+
)

pkg/ingress/model_build_listener.go

+27-4
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,25 @@ type listenPortConfig struct {
107107
sslPolicy *string
108108
tlsCerts []string
109109
mutualAuthentication *elbv2model.MutualAuthenticationAttributes
110+
securityGroupIDs []string
110111
}
111112

112113
func (t *defaultModelBuildTask) computeIngressListenPortConfigByPort(ctx context.Context, ing *ClassifiedIngress) (map[int64]listenPortConfig, error) {
113114
explicitTLSCertARNs := t.computeIngressExplicitTLSCertARNs(ctx, ing)
114115
explicitSSLPolicy := t.computeIngressExplicitSSLPolicy(ctx, ing)
115116
var prefixListIDs []string
116117
t.annotationParser.ParseStringSliceAnnotation(annotations.IngressSuffixSecurityGroupPrefixLists, &prefixListIDs, ing.Ing.Annotations)
118+
119+
securityGroupIDs, err := t.computeIngressExplicitSecurityGroupIDs(ctx, ing)
120+
if err != nil {
121+
return nil, err
122+
}
123+
117124
inboundCIDRv4s, inboundCIDRV6s, err := t.computeIngressExplicitInboundCIDRs(ctx, ing)
118125
if err != nil {
119126
return nil, err
120127
}
128+
121129
mutualAuthenticationAttributes, err := t.computeIngressMutualAuthentication(ctx, ing)
122130
if err != nil {
123131
return nil, err
@@ -146,10 +154,11 @@ func (t *defaultModelBuildTask) computeIngressListenPortConfigByPort(ctx context
146154
listenPortConfigByPort := make(map[int64]listenPortConfig, len(listenPorts))
147155
for port, protocol := range listenPorts {
148156
cfg := listenPortConfig{
149-
protocol: protocol,
150-
inboundCIDRv4s: inboundCIDRv4s,
151-
inboundCIDRv6s: inboundCIDRV6s,
152-
prefixLists: prefixListIDs,
157+
protocol: protocol,
158+
inboundCIDRv4s: inboundCIDRv4s,
159+
inboundCIDRv6s: inboundCIDRV6s,
160+
prefixLists: prefixListIDs,
161+
securityGroupIDs: securityGroupIDs,
153162
}
154163
if protocol == elbv2model.ProtocolHTTPS {
155164
if len(explicitTLSCertARNs) == 0 {
@@ -225,6 +234,20 @@ func (t *defaultModelBuildTask) computeIngressListenPorts(_ context.Context, ing
225234
return portAndProtocols, nil
226235
}
227236

237+
func (t *defaultModelBuildTask) computeIngressExplicitSecurityGroupIDs(ctx context.Context, ing *ClassifiedIngress) ([]string, error) {
238+
var rawSecurityGroups []string
239+
if exists := t.annotationParser.ParseStringSliceAnnotation(annotations.IngressSuffixInboundSecurityGroups, &rawSecurityGroups, ing.Ing.Annotations); !exists {
240+
return nil, nil
241+
}
242+
243+
securityGroupIDs, err := t.sgResolver.ResolveViaNameOrID(ctx, rawSecurityGroups)
244+
if err != nil {
245+
return nil, fmt.Errorf("invalid %v settings on Ingress: %v: %w", annotations.IngressSuffixInboundSecurityGroups, k8s.NamespacedName(ing.Ing), err)
246+
}
247+
248+
return securityGroupIDs, nil
249+
}
250+
228251
func (t *defaultModelBuildTask) computeIngressExplicitInboundCIDRs(_ context.Context, ing *ClassifiedIngress) ([]string, []string, error) {
229252
var rawInboundCIDRs []string
230253
fromIngressClassParams := false

pkg/ingress/model_build_managed_sg.go

+12
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ func (t *defaultModelBuildTask) buildManagedSecurityGroupIngressPermissions(_ co
109109
},
110110
})
111111
}
112+
for _, sgID := range cfg.securityGroupIDs {
113+
permissions = append(permissions, ec2model.IPPermission{
114+
IPProtocol: "tcp",
115+
FromPort: awssdk.Int64(port),
116+
ToPort: awssdk.Int64(port),
117+
UserIDGroupPairs: []ec2model.UserIDGroupPair{
118+
{
119+
GroupID: sgID,
120+
},
121+
},
122+
})
123+
}
112124
}
113125
return permissions
114126
}

pkg/ingress/model_builder.go

+15
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ func (t *defaultModelBuildTask) mergeListenPortConfigs(_ context.Context, listen
310310
var mergedMtlsAttributesProvider *types.NamespacedName
311311
var mergedMtlsAttributes *elbv2model.MutualAuthenticationAttributes
312312

313+
var mergedSecurityGroupProvider *types.NamespacedName
314+
mergedSecurityGroups := sets.NewString()
315+
313316
for _, cfg := range listenPortConfigs {
314317
if mergedProtocolProvider == nil {
315318
mergedProtocolProvider = &cfg.ingKey
@@ -343,6 +346,17 @@ func (t *defaultModelBuildTask) mergeListenPortConfigs(_ context.Context, listen
343346
}
344347
}
345348

349+
if len(cfg.listenPortConfig.securityGroupIDs) != 0 {
350+
cfgSecurityGroups := sets.NewString(cfg.listenPortConfig.securityGroupIDs...)
351+
if mergedSecurityGroupProvider == nil {
352+
mergedSecurityGroupProvider = &cfg.ingKey
353+
mergedSecurityGroups = cfgSecurityGroups
354+
} else if !mergedSecurityGroups.Equal(cfgSecurityGroups) {
355+
return listenPortConfig{}, errors.Errorf("conflicting security groups, %v: %v | %v: %v",
356+
*mergedSecurityGroupProvider, mergedSecurityGroups.List(), cfg.ingKey, cfgSecurityGroups.List())
357+
}
358+
}
359+
346360
if cfg.listenPortConfig.sslPolicy != nil {
347361
if mergedSSLPolicyProvider == nil {
348362
mergedSSLPolicyProvider = &cfg.ingKey
@@ -389,6 +403,7 @@ func (t *defaultModelBuildTask) mergeListenPortConfigs(_ context.Context, listen
389403
sslPolicy: mergedSSLPolicy,
390404
tlsCerts: mergedTLSCerts,
391405
mutualAuthentication: mergedMtlsAttributes,
406+
securityGroupIDs: mergedSecurityGroups.List(),
392407
}, nil
393408
}
394409

0 commit comments

Comments
 (0)