aws-load-balancer-controller: [aws-load-balancer-controller] Not accessing service account
Describe the bug
The aws-load-balancer-controller installs correctly, however it seems to not be using the serviceaccount role/arn that has been created. I get the following error:
{"level":"error","ts":1651073143.6192567,"logger":"controller-runtime.manager.controller.ingress","msg":"Reconciler error","name":"test-geeiq","namespace":"","error":"AccessDenied: User: arn:aws:sts::700849607999:assumed-role/worker-group-eks-node-group-20220427070929725900000001/i-015251056f40ce440 is not authorized to perform: elasticloadbalancing:DescribeLoadBalancers because no identity-based policy allows the elasticloadbalancing:DescribeLoadBalancers action\n\tstatus code: 403, request id: 89923814-caf4-46d6-af29-eb5650d91017"}
The missing permissions clearly exist in the role/serviec account that has been created. Im abit confused by the User in the above error log, should it not be using the service account?
Steps to reproduce
locals {
k8s_aws_lb_service_account_namespace = "kube-system"
k8s_aws_lb_service_account_name = "aws-load-balancer-controller"
}
...
resource "helm_release" "aws_loadbalancer_controller" {
name = "aws-load-balancer-controller"
repository = "https://aws.github.io/eks-charts"
chart = "aws-load-balancer-controller"
namespace = local.k8s_aws_lb_service_account_namespace
set {
name = "clusterName"
value = data.terraform_remote_state.eks.outputs.cluster_id
}
set {
name = "region"
value = local.region
}
set {
name = "rbac.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn"
value = module.iam_assumable_role_aws_lb.iam_role_arn
}
set {
name = "rbac.serviceAccount.create"
value = true
}
set {
name = "rbac.serviceAccount.name"
value = local.k8s_aws_lb_service_account_name
}
set {
name = "nodeSelector.geeiq/node-type"
value = "worker"
}
depends_on = [
aws_iam_policy.aws_loadbalancer_controller
]
}
Expected outcome
Should be authorised.
Environment
- Chart name: aws-load-balancer-controller
- Chart version: 2.4.1
- Kubernetes version: 1.22
- Using EKS (yes/no), if so version? yes 1.22
Additional Context:
helm get values aws-load-balancer-controller -n kube-system
USER-SUPPLIED VALUES:
clusterName: geeiq-test-k8s
nodeSelector:
geeiq/node-type: worker
rbac:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<redacted>:role/geeiq-test-k8s-aws-loadbalancer-controller
create: true
name: aws-load-balancer-controller
region: eu-west-2
aws_role
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<redacted>:oidc-provider/oidc.eks.eu-west-2.amazonaws.com/id/<redacted>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.eu-west-2.amazonaws.com/id/<redacted>:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller"
}
}
}
]
}
policy
{
"Statement": [
{
"Action": [
"iam:CreateServiceLinkedRole"
],
"Condition": {
"StringEquals": {
"iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeInternetGateways",
"ec2:DescribeVpcs",
"ec2:DescribeVpcPeeringConnections",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeInstances",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeTags",
"ec2:GetCoipPoolUsage",
"ec2:DescribeCoipPools",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeListenerCertificates",
"elasticloadbalancing:DescribeSSLPolicies",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:DescribeTags"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"cognito-idp:DescribeUserPoolClient",
"acm:ListCertificates",
"acm:DescribeCertificate",
"iam:ListServerCertificates",
"iam:GetServerCertificate",
"waf-regional:GetWebACL",
"waf-regional:GetWebACLForResource",
"waf-regional:AssociateWebACL",
"waf-regional:DisassociateWebACL",
"wafv2:GetWebACL",
"wafv2:GetWebACLForResource",
"wafv2:AssociateWebACL",
"wafv2:DisassociateWebACL",
"shield:GetSubscriptionState",
"shield:DescribeProtection",
"shield:CreateProtection",
"shield:DeleteProtection"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:CreateSecurityGroup"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:CreateTags"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
},
"StringEquals": {
"ec2:CreateAction": "CreateSecurityGroup"
}
},
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:security-group/*"
},
{
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:security-group/*"
},
{
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress",
"ec2:DeleteSecurityGroup"
],
"Condition": {
"Null": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateTargetGroup"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:CreateRule",
"elasticloadbalancing:DeleteRule"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": [
"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
]
},
{
"Action": [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags"
],
"Effect": "Allow",
"Resource": [
"arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
"arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
"arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
"arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
]
},
{
"Action": [
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",
"elasticloadbalancing:SetSubnets",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:DeleteTargetGroup"
],
"Condition": {
"Null": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets"
],
"Effect": "Allow",
"Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"
},
{
"Action": [
"elasticloadbalancing:SetWebAcl",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:ModifyRule"
],
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
}
kubectl describe deployment aws-load-balancer-controller -n kube-system
Name: aws-load-balancer-controller
Namespace: kube-system
CreationTimestamp: Wed, 27 Apr 2022 16:13:08 +0100
Labels: app.kubernetes.io/instance=aws-load-balancer-controller
app.kubernetes.io/managed-by=Helm
app.kubernetes.io/name=aws-load-balancer-controller
app.kubernetes.io/version=v2.4.1
helm.sh/chart=aws-load-balancer-controller-1.4.1
Annotations: deployment.kubernetes.io/revision: 1
meta.helm.sh/release-name: aws-load-balancer-controller
meta.helm.sh/release-namespace: kube-system
Selector: app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app.kubernetes.io/instance=aws-load-balancer-controller
app.kubernetes.io/name=aws-load-balancer-controller
Annotations: prometheus.io/port: 8080
prometheus.io/scrape: true
Service Account: aws-load-balancer-controller
Containers:
aws-load-balancer-controller:
Image: 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon/aws-load-balancer-controller:v2.4.1
Ports: 9443/TCP, 8080/TCP
Host Ports: 0/TCP, 0/TCP
Command:
/controller
Args:
--cluster-name=geeiq-test-k8s
--ingress-class=alb
--aws-region=eu-west-2
Liveness: http-get http://:61779/healthz delay=30s timeout=10s period=10s #success=1 #failure=2
Environment: <none>
Mounts:
/tmp/k8s-webhook-server/serving-certs from cert (ro)
Volumes:
cert:
Type: Secret (a volume populated by a Secret)
SecretName: aws-load-balancer-tls
Optional: false
Priority Class Name: system-cluster-critical
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: aws-load-balancer-controller-685b7dd97f (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 24m deployment-controller Scaled up replica set aws-load-balancer-controller-685b7dd97f to 2
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 16
Ok, I think I got it. Apparently I had to set the annotation manually, like this:
I inferred this from this comment.
I finally found out the issue.
I have been using
rbac.serviceAccount.*which was appropriate in an older version of this chart but the new values areserviceAccount.*@kaykhancheckpoint, unless the service account has the
eks.amazonaws.com/role-arn: <role>annotation before the lb controller pods start up, the IRSA configuration doesn’t get injected to the controller pods. It looks like your workflow is not adding the annotation. You want to setup the service account with the annotation and the necessary IRSA setup first, then install the helm chart by setting the helm values--set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller.Just on the first one i can see the service account does not have that annotation.
Id assume it should given that i have set that in helm
If IRSA was configured, I’d expect to see
arn:aws:iam::<redacted>:role/geeiq-test-k8s-aws-loadbalancer-controllerinstead ofarn:aws:sts::700849607999:assumed-role/worker-group-eks-node-group-20220427070929725900000001/i-015251056f40ce440in the error logs.Please verify the following
If your IRSA got setup after the controller pod, you will have to restart the lb controller deployment.