profile
viewpoint
Lewis Cowper lewiscowper Berlin https://lewiscowper.com Friendly software developer. Red hair, red beard. Looks like a highly caffeinated squirrel. Wickler of ents, feminist ally trying to improve

lewiscowper/ama 5

Ask me anything!

lewiscowper/backup 1

A go backup service

lewiscowper/1962 0

Versioned physical sculpture

lewiscowper/2015.jsconf.eu 0

Leaking future secrets

lewiscowper/64sts 0

pattern generator in 64 stitches

lewiscowper/8bitdash.github.io 0

8-bit web dashboard

lewiscowper/adstex 0

Find all citation keys in your LaTeX documents and search NASA ADS to generate corresponding bibtex entries.

lewiscowper/amas 0

Awesome & Marvelous Amas

lewiscowper/amp-by-example 0

Accelerated Mobile Pages in Action

lewiscowper/amphtml 0

AMP HTML source code, samples, and documentation. See below for more info.

fork lewiscowper/DecisionCapture

This repository is used to publish and share templates and guides on capturing decisions in agile software development. It is part of our research on rationale management in agile software development.

https://schubmat.github.io/DecisionCapture/

fork in 3 days

PR opened jansc/ncgopher

Fix typo
+1 -1

0 comment

1 changed file

pr created time in a month

push eventlewiscowper/ncgopher

Lewis Cowper

commit sha 09857b156e1f8652b6e9fb68550a858217b36947

Fix typo

view details

push time in a month

push eventlewiscowper/ncgopher

Lewis Cowper

commit sha 5f3304a725f34953d89f9185dc0ca1aaaa4adbca

Fix typo

view details

push time in a month

fork lewiscowper/ncgopher

A gopher and gemini client for the modern internet

fork in a month

fork lewiscowper/slides-1

Terminal based presentation tool

http://maaslalani.com/slides/

fork in a month

issue closedkubernetes-sigs/aws-load-balancer-controller

Unauthorized to perform: `elasticloadbalancing:CreateTargetGroup`

Describe the bug

I'm trying to set up a cluster with IRSA enabled, and having some difficulty with the load balancer controller and permissions. The error that I'm seeing is:

<RoleARN that has the IAM policy attached> is not authorized to perform: elasticloadbalancing:CreateTargetGroup

It is as if the resource tag elbv2.k8s.aws/cluster is not being correctly applied in this case (based on trying the policy that the role is attached to in the IAM policy simulator), and I'm not sure what the fix would look like.

Steps to reproduce

I'll post a load of relevant terraform config inside a <details> tag, but it could be something as simple as the annotations, which I'm defining as follows:

"kubernetes.io/ingress.class"                    = "alb"
"alb.ingress.kubernetes.io/scheme"               = "internal"
"alb.ingress.kubernetes.io/subnets"              = join(",", var.private_subnets)
"alb.ingress.kubernetes.io/listen-ports"         = jsonencode([{ "HTTP" : 80, "HTTPS" : 443 }])
"alb.ingress.kubernetes.io/actions.ssl-redirect" = jsonencode({ "Type" : "redirect", "RedirectConfig" : { "Protocol" : "HTTPS", "Port" : "443", "StatusCode" : "HTTP_301" } })

Terraform formatting aside, it doesn't seem unreasonable, but I may be missing an important annotation or default setting in the helm install, which I'm declaring as follows:

resource "helm_release" "lb_controller" {
  name       = "aws-load-balancer-controller"
  repository = "https://aws.github.io/eks-charts"
  chart      = "aws-load-balancer-controller"
  version    = "1.2.7"
  namespace  = var.system_namespace # set to "kube-system"

  set {
    name  = "clusterName"
    value = var.cluster_id # set to the ID/name of the cluster created with the eks terraform module.
  }

  set {
    name  = "defaultSSLPolicy"
    value = "ELBSecurityPolicy-TLS-1-2-2017-01"
  }

  set {
    name  = "serviceAccount.create"
    value = false
  }

  set {
    name  = "serviceAccount.name"
    value = var.lb_controller_service_account_name # set to "aws-load-balancer-controller"
  }
}

<details> <summary>Full logs when trying to create the target group</summary>

{
	"level": "info",
	"ts": 1634722998.856916,
	"logger": "controllers.ingress",
	"msg": "successfully built model",
	"model": "{\"id\":\"kube-system/traefik-ingress\",\"resources\":{\"AWS::EC2::SecurityGroup\":{\"ManagedLBSecurityGroup\":{\"spec\":{\"groupName\":\"k8s-kubesyst-traefiki-5bc437b435\",\"description\":\"[k8s] Managed SecurityGroup for LoadBalancer\",\"ingress\":[{\"ipProtocol\":\"tcp\",\"fromPort\":80,\"toPort\":80,\"ipRanges\":[{\"cidrIP\":\"0.0.0.0/0\"}]},{\"ipProtocol\":\"tcp\",\"fromPort\":443,\"toPort\":443,\"ipRanges\":[{\"cidrIP\":\"0.0.0.0/0\"}]}]}}},\"AWS::ElasticLoadBalancingV2::Listener\":{\"443\":{\"spec\":{\"loadBalancerARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::LoadBalancer/LoadBalancer/status/loadBalancerARN\"},\"port\":443,\"protocol\":\"HTTPS\",\"defaultActions\":[{\"type\":\"fixed-response\",\"fixedResponseConfig\":{\"contentType\":\"text/plain\",\"statusCode\":\"404\"}}],\"certificates\":[{\"certificateARN\":\"arn:aws:acm:eu-central-1:<snip>:certificate/dbd89c77-aadc-4528-8831-2865a78d9eb4\"}],\"sslPolicy\":\"ELBSecurityPolicy-TLS-1-2-2017-01\"}},\"80\":{\"spec\":{\"loadBalancerARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::LoadBalancer/LoadBalancer/status/loadBalancerARN\"},\"port\":80,\"protocol\":\"HTTP\",\"defaultActions\":[{\"type\":\"fixed-response\",\"fixedResponseConfig\":{\"contentType\":\"text/plain\",\"statusCode\":\"404\"}}]}}},\"AWS::ElasticLoadBalancingV2::ListenerRule\":{\"443:1\":{\"spec\":{\"listenerARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::Listener/443/status/listenerARN\"},\"priority\":1,\"actions\":[{\"type\":\"forward\",\"forwardConfig\":{\"targetGroups\":[{\"targetGroupARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/kube-system/traefik-ingress-traefik:80/status/targetGroupARN\"}}]}}],\"conditions\":[{\"field\":\"host-header\",\"hostHeaderConfig\":{\"values\":[\"<snip>\"]}},{\"field\":\"path-pattern\",\"pathPatternConfig\":{\"values\":[\"/*\"]}}]}},\"80:1\":{\"spec\":{\"listenerARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::Listener/80/status/listenerARN\"},\"priority\":1,\"actions\":[{\"type\":\"redirect\",\"redirectConfig\":{\"port\":\"443\",\"protocol\":\"HTTPS\",\"statusCode\":\"HTTP_301\"}}],\"conditions\":[{\"field\":\"host-header\",\"hostHeaderConfig\":{\"values\":[\"<snip>\"]}},{\"field\":\"path-pattern\",\"pathPatternConfig\":{\"values\":[\"/*\"]}}]}}},\"AWS::ElasticLoadBalancingV2::LoadBalancer\":{\"LoadBalancer\":{\"spec\":{\"name\":\"k8s-kubesyst-traefiki-27790a2047\",\"type\":\"application\",\"scheme\":\"internal\",\"ipAddressType\":\"ipv4\",\"subnetMapping\":[{\"subnetID\":\"subnet-00e47cec8afa489c4\"},{\"subnetID\":\"subnet-0830d26f11507d9bd\"},{\"subnetID\":\"subnet-0e3b0e29ba236054c\"}],\"securityGroups\":[{\"$ref\":\"#/resources/AWS::EC2::SecurityGroup/ManagedLBSecurityGroup/status/groupID\"}]}}},\"AWS::ElasticLoadBalancingV2::TargetGroup\":{\"kube-system/traefik-ingress-traefik:80\":{\"spec\":{\"name\":\"k8s-kubesyst-traefik-fd0c17a3a0\",\"targetType\":\"instance\",\"port\":31038,\"protocol\":\"HTTP\",\"protocolVersion\":\"HTTP1\",\"healthCheckConfig\":{\"port\":\"traffic-port\",\"protocol\":\"HTTP\",\"path\":\"/\",\"matcher\":{\"httpCode\":\"200\"},\"intervalSeconds\":15,\"timeoutSeconds\":5,\"healthyThresholdCount\":2,\"unhealthyThresholdCount\":2}}}},\"K8S::ElasticLoadBalancingV2::TargetGroupBinding\":{\"kube-system/traefik-ingress-traefik:80\":{\"spec\":{\"template\":{\"metadata\":{\"name\":\"k8s-kubesyst-traefik-fd0c17a3a0\",\"namespace\":\"kube-system\",\"creationTimestamp\":null},\"spec\":{\"targetGroupARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/kube-system/traefik-ingress-traefik:80/status/targetGroupARN\"},\"targetType\":\"instance\",\"serviceRef\":{\"name\":\"traefik\",\"port\":80},\"networking\":{\"ingress\":[{\"from\":[{\"securityGroup\":{\"groupID\":{\"$ref\":\"#/resources/AWS::EC2::SecurityGroup/ManagedLBSecurityGroup/status/groupID\"}}}],\"ports\":[{\"protocol\":\"TCP\"}]}]}}}}}}}}"
}
{
	"level": "info",
	"ts": 1634722999.6762848,
	"logger": "controllers.ingress",
	"msg": "creating targetGroup",
	"stackID": "kube-system/traefik-ingress",
	"resourceID": "kube-system/traefik-ingress-traefik:80"
}
{
	"level": "error",
	"ts": 1634722999.6940677,
	"logger": "controller",
	"msg": "Reconciler error",
	"controller": "ingress",
	"name": "traefik-ingress",
	"namespace": "kube-system",
	"error": "AccessDenied: User: arn:aws:sts::<snip>:assumed-role/aws-load-balancer-controller/1634720339013033551 is not authorized to perform: elasticloadbalancing:CreateTargetGroup on resource: arn:aws:elasticloadbalancing:eu-central-1:<snip>:targetgroup/k8s-kubesyst-traefik-fd0c17a3a0/*\n\tstatus code: 403, request id: 36b11be0-a59d-4566-be56-1d5d2216a348"
}
</details>

<details>
<summary>IAM Role/Service Account terraform config</summary>

Apologies for anything I've missed, these are actually set up in different modules, so if I've not added explanations of any variables etc that you need to also know, then please comment and I can add them.

data "aws_iam_policy_document" "lb_controller" { #bridgecrew:skip=CKV_AWS_111: "Ensure IAM policies does not allow write access without constraints" - If I knew the resources to limit this policy to, I would limit them. #bridgecrew:skip=CKV_AWS_109: "Ensure IAM policies does not allow permissions management / resource exposure without constraints" - If I knew the resources that would work, I would limit this policy to them. statement { effect = "Allow" actions = [ "iam:CreateServiceLinkedRole", ]

resources = ["*"]

condition {
  test     = "StringEquals"
  variable = "iam:AWSServiceName"
  values   = ["elasticloadbalancing.amazonaws.com"]
}

}

statement { effect = "Allow"

actions = [
  "ec2:DescribeAccountAttributes",
  "ec2:DescribeAddresses",
  "ec2:DescribeAvailabilityZones",
  "ec2:DescribeInternetGateways",
  "ec2:DescribeVpcs",
  "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"
]

resources = ["*"]

}

statement { effect = "Allow"

actions = [
  "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"
]

resources = ["*"]

}

statement { effect = "Allow"

actions = [
  "ec2:AuthorizeSecurityGroupIngress",
  "ec2:RevokeSecurityGroupIngress"
]

resources = ["*"]

}

statement { effect = "Allow"

actions = [
  "ec2:CreateSecurityGroup"
]

resources = ["*"]

}

statement { effect = "Allow"

actions = [
  "ec2:CreateTags"
]

resources = ["arn:aws:ec2:*:*:security-group/*"]

condition {
  test     = "StringEquals"
  variable = "ec2:CreateAction"
  values   = ["CreateSecurityGroup"]
}

condition {
  test     = "Null"
  variable = "aws:RequestTag/elbv2.k8s.aws/cluster"
  values   = ["false"]
}

}

statement { effect = "Allow"

actions = [
  "ec2:CreateTags",
  "ec2:DeleteTags"
]

resources = ["arn:aws:ec2:*:*:security-group/*"]

condition {
  test     = "Null"
  variable = "aws:RequestTag/elbv2.k8s.aws/cluster"
  values   = ["true"]
}

condition {
  test     = "Null"
  variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
  values   = ["false"]
}

}

statement { effect = "Allow"

actions = [
  "ec2:AuthorizeSecurityGroupIngress",
  "ec2:RevokeSecurityGroupIngress",
  "ec2:DeleteSecurityGroup"
]

resources = ["*"]

condition {
  test     = "Null"
  variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
  values   = ["false"]
}

}

statement { effect = "Allow"

actions = [
  "elasticloadbalancing:CreateLoadBalancer",
  "elasticloadbalancing:CreateTargetGroup"
]

resources = ["*"]

# Removing this condition leads to a target group successfully being created
# but this resource tag should be automatically set by the controller.
condition {
  test     = "Null"
  variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
  values   = ["false"]
}

}

statement { effect = "Allow"

actions = [
  "elasticloadbalancing:CreateListener",
  "elasticloadbalancing:DeleteListener",
  "elasticloadbalancing:CreateRule",
  "elasticloadbalancing:DeleteRule"
]

resources = ["*"]

}

statement { effect = "Allow"

actions = [
  "elasticloadbalancing:AddTags",
  "elasticloadbalancing:RemoveTags"
]

resources = [
  "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
  "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
  "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
]

condition {
  test     = "Null"
  variable = "aws:RequestTag/elbv2.k8s.aws/cluster"
  values   = ["true"]
}

condition {
  test     = "Null"
  variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
  values   = ["false"]
}

}

statement { effect = "Allow"

actions = [
  "elasticloadbalancing:AddTags",
  "elasticloadbalancing:RemoveTags"
]

resources = [
  "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
  "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
  "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
  "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
]

}

statement { effect = "Allow"

actions = [
  "elasticloadbalancing:ModifyLoadBalancerAttributes",
  "elasticloadbalancing:SetIpAddressType",
  "elasticloadbalancing:SetSecurityGroups",
  "elasticloadbalancing:SetSubnets",
  "elasticloadbalancing:DeleteLoadBalancer",
  "elasticloadbalancing:ModifyTargetGroup",
  "elasticloadbalancing:ModifyTargetGroupAttributes",
  "elasticloadbalancing:DeleteTargetGroup"
]

resources = ["*"]

condition {
  test     = "Null"
  variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
  values   = ["false"]
}

}

statement { effect = "Allow"

actions = [
  "elasticloadbalancing:RegisterTargets",
  "elasticloadbalancing:DeregisterTargets"
]

resources = ["arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"]

}

statement { effect = "Allow"

actions = [
  "elasticloadbalancing:SetWebAcl",
  "elasticloadbalancing:ModifyListener",
  "elasticloadbalancing:AddListenerCertificates",
  "elasticloadbalancing:RemoveListenerCertificates",
  "elasticloadbalancing:ModifyRule"
]

resources = ["*"]

} }

resource "aws_iam_policy" "lb_controller" { name_prefix = "${module.eks.cluster_id}-lb-controller" description = "EKS lb-controller policy for cluster ${module.eks.cluster_id}" policy = data.aws_iam_policy_document.lb_controller.json }

module "iam_assumable_role_admin_lb_controller" { source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc" version = "4.3.0"

create_role = true role_name = var.lb_controller_service_account_name # set to "aws-load-balancer-controller" provider_url = replace(module.eks.cluster_oidc_issuer_url, "https://", "") role_policy_arns = [aws_iam_policy.lb_controller.arn] oidc_fully_qualified_subjects = ["system:serviceaccount:${var.system_namespace}:${var.lb_controller_service_account_name}"] }

resource "kubernetes_service_account" "name" { metadata { name = var.lb_controller_service_account_name # set to "aws-load-balancer-controller" namespace = var.system_namespace # set to "kube-system"

annotations = {
  "eks.amazonaws.com/role-arn" : var.lb_controller_role_arn # Set to the ARN of the role 
}

} }

</details>

**Expected outcome**
When declaring an ingress, the load balancer controller should be able to create target groups as needed.

**Environment**

* AWS Load Balancer controller version: `v2.2.4`
* Kubernetes version: `v1.21.4-eks`
* Using EKS (yes/no), if so version? `eks.2`

closed time in a month

lewiscowper

issue commentkubernetes-sigs/aws-load-balancer-controller

Unauthorized to perform: `elasticloadbalancing:CreateTargetGroup`

@M00nF1sh omg thank you so much. I must have copy pasted the wrong block. Well that's embarrassing.

Thank you for taking the time to investigate, it works now. :)

lewiscowper

comment created time in a month

issue openedkubernetes-sigs/aws-load-balancer-controller

Unauthorized to perform: `elasticloadbalancing:CreateTargetGroup`

Describe the bug

I'm trying to set up a cluster with IRSA enabled, and having some difficulty with the load balancer controller and permissions. The error that I'm seeing is:

<RoleARN that has the IAM policy attached> is not authorized to perform: elasticloadbalancing:CreateTargetGroup

It is as if the resource tag elbv2.k8s.aws/cluster is not being correctly applied in this case (based on trying the policy that the role is attached to in the IAM policy simulator), and I'm not sure what the fix would look like.

Steps to reproduce

I'll post a load of relevant terraform config inside a <details> tag, but it could be something as simple as the annotations, which I'm defining as follows:

"kubernetes.io/ingress.class"                    = "alb"
"alb.ingress.kubernetes.io/scheme"               = "internal"
"alb.ingress.kubernetes.io/subnets"              = join(",", var.private_subnets)
"alb.ingress.kubernetes.io/listen-ports"         = jsonencode([{ "HTTP" : 80, "HTTPS" : 443 }])
"alb.ingress.kubernetes.io/actions.ssl-redirect" = jsonencode({ "Type" : "redirect", "RedirectConfig" : { "Protocol" : "HTTPS", "Port" : "443", "StatusCode" : "HTTP_301" } })

Terraform formatting aside, it doesn't seem unreasonable, but I may be missing an important annotation or default setting in the helm install, which I'm declaring as follows:

resource "helm_release" "lb_controller" {
  name       = "aws-load-balancer-controller"
  repository = "https://aws.github.io/eks-charts"
  chart      = "aws-load-balancer-controller"
  version    = "1.2.7"
  namespace  = var.system_namespace # set to "kube-system"

  set {
    name  = "clusterName"
    value = var.cluster_id # set to the ID/name of the cluster created with the eks terraform module.
  }

  set {
    name  = "defaultSSLPolicy"
    value = "ELBSecurityPolicy-TLS-1-2-2017-01"
  }

  set {
    name  = "serviceAccount.create"
    value = false
  }

  set {
    name  = "serviceAccount.name"
    value = var.lb_controller_service_account_name # set to "aws-load-balancer-controller"
  }
}

<details> <summary>IAM Role/Service Account terraform config</summary>

Apologies for anything I've missed, these are actually set up in different modules, so if I've not added explanations of any variables etc that you need to also know, then please comment and I can add them.

data "aws_iam_policy_document" "lb_controller" {
  #bridgecrew:skip=CKV_AWS_111: "Ensure IAM policies does not allow write access without constraints" - If I knew the resources to limit this policy to, I would limit them.
  #bridgecrew:skip=CKV_AWS_109: "Ensure IAM policies does not allow permissions management / resource exposure without constraints" - If I knew the resources that would work, I would limit this policy to them.
  statement {
    effect = "Allow"
    actions = [
      "iam:CreateServiceLinkedRole",
    ]

    resources = ["*"]

    condition {
      test     = "StringEquals"
      variable = "iam:AWSServiceName"
      values   = ["elasticloadbalancing.amazonaws.com"]
    }
  }

  statement {
    effect = "Allow"

    actions = [
      "ec2:DescribeAccountAttributes",
      "ec2:DescribeAddresses",
      "ec2:DescribeAvailabilityZones",
      "ec2:DescribeInternetGateways",
      "ec2:DescribeVpcs",
      "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"
    ]

    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "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"
    ]

    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "ec2:AuthorizeSecurityGroupIngress",
      "ec2:RevokeSecurityGroupIngress"
    ]

    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "ec2:CreateSecurityGroup"
    ]

    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "ec2:CreateTags"
    ]

    resources = ["arn:aws:ec2:*:*:security-group/*"]

    condition {
      test     = "StringEquals"
      variable = "ec2:CreateAction"
      values   = ["CreateSecurityGroup"]
    }

    condition {
      test     = "Null"
      variable = "aws:RequestTag/elbv2.k8s.aws/cluster"
      values   = ["false"]
    }
  }

  statement {
    effect = "Allow"

    actions = [
      "ec2:CreateTags",
      "ec2:DeleteTags"
    ]

    resources = ["arn:aws:ec2:*:*:security-group/*"]

    condition {
      test     = "Null"
      variable = "aws:RequestTag/elbv2.k8s.aws/cluster"
      values   = ["true"]
    }

    condition {
      test     = "Null"
      variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
      values   = ["false"]
    }
  }

  statement {
    effect = "Allow"

    actions = [
      "ec2:AuthorizeSecurityGroupIngress",
      "ec2:RevokeSecurityGroupIngress",
      "ec2:DeleteSecurityGroup"
    ]

    resources = ["*"]

    condition {
      test     = "Null"
      variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
      values   = ["false"]
    }
  }

  statement {
    effect = "Allow"

    actions = [
      "elasticloadbalancing:CreateLoadBalancer",
      "elasticloadbalancing:CreateTargetGroup"
    ]

    resources = ["*"]

    # Removing this condition leads to a target group successfully being created
    # but this resource tag should be automatically set by the controller.
    condition {
      test     = "Null"
      variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
      values   = ["false"]
    }
  }

  statement {
    effect = "Allow"

    actions = [
      "elasticloadbalancing:CreateListener",
      "elasticloadbalancing:DeleteListener",
      "elasticloadbalancing:CreateRule",
      "elasticloadbalancing:DeleteRule"
    ]

    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "elasticloadbalancing:AddTags",
      "elasticloadbalancing:RemoveTags"
    ]

    resources = [
      "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
      "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
      "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
    ]

    condition {
      test     = "Null"
      variable = "aws:RequestTag/elbv2.k8s.aws/cluster"
      values   = ["true"]
    }

    condition {
      test     = "Null"
      variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
      values   = ["false"]
    }
  }

  statement {
    effect = "Allow"

    actions = [
      "elasticloadbalancing:AddTags",
      "elasticloadbalancing:RemoveTags"
    ]

    resources = [
      "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
      "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
      "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
      "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
    ]
  }

  statement {
    effect = "Allow"

    actions = [
      "elasticloadbalancing:ModifyLoadBalancerAttributes",
      "elasticloadbalancing:SetIpAddressType",
      "elasticloadbalancing:SetSecurityGroups",
      "elasticloadbalancing:SetSubnets",
      "elasticloadbalancing:DeleteLoadBalancer",
      "elasticloadbalancing:ModifyTargetGroup",
      "elasticloadbalancing:ModifyTargetGroupAttributes",
      "elasticloadbalancing:DeleteTargetGroup"
    ]

    resources = ["*"]

    condition {
      test     = "Null"
      variable = "aws:ResourceTag/elbv2.k8s.aws/cluster"
      values   = ["false"]
    }
  }

  statement {
    effect = "Allow"

    actions = [
      "elasticloadbalancing:RegisterTargets",
      "elasticloadbalancing:DeregisterTargets"
    ]

    resources = ["arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "elasticloadbalancing:SetWebAcl",
      "elasticloadbalancing:ModifyListener",
      "elasticloadbalancing:AddListenerCertificates",
      "elasticloadbalancing:RemoveListenerCertificates",
      "elasticloadbalancing:ModifyRule"
    ]

    resources = ["*"]
  }
}

resource "aws_iam_policy" "lb_controller" {
  name_prefix = "${module.eks.cluster_id}-lb-controller"
  description = "EKS lb-controller policy for cluster ${module.eks.cluster_id}"
  policy      = data.aws_iam_policy_document.lb_controller.json
}

module "iam_assumable_role_admin_lb_controller" {
  source  = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
  version = "4.3.0"

  create_role                   = true
  role_name                     = var.lb_controller_service_account_name # set to "aws-load-balancer-controller"
  provider_url                  = replace(module.eks.cluster_oidc_issuer_url, "https://", "")
  role_policy_arns              = [aws_iam_policy.lb_controller.arn]
  oidc_fully_qualified_subjects = ["system:serviceaccount:${var.system_namespace}:${var.lb_controller_service_account_name}"]
}

resource "kubernetes_service_account" "name" {
  metadata {
    name      = var.lb_controller_service_account_name # set to "aws-load-balancer-controller"
    namespace = var.system_namespace # set to "kube-system"

    annotations = {
      "eks.amazonaws.com/role-arn" : var.lb_controller_role_arn # Set to the ARN of the role 
    }
  }
}

</details>

Expected outcome When declaring an ingress, the load balancer controller should be able to create target groups as needed.

Environment

  • AWS Load Balancer controller version: v2.2.4
  • Kubernetes version: v1.21.4-eks
  • Using EKS (yes/no), if so version? v1.21.4-eks

created time in a month

more