skip to Main Content

I’m using the EKS Construct to create an EKS cluster in CDK. I’m adding the NGINX helm chart to the cluster and I want to export the ingress LoadBalancer URL. The EKS Construct exposes a .getServiceLoadBalancer() method, but it wants a service name. I’m not sure how to get the name of the LoadBalancer service to pass it into that method. Feels like I’m missing something. Example:

export class EksClusterStack extends cdk.NestedStack {
  elbUrl: string;

  constructor(scope: cdk.Construct, id: string, props?: cdk.NestedStackProps) {
    super(scope, id, props);

    const clusterAdmin = new iam.Role(this, 'AdminRole', {
      assumedBy: new iam.AccountRootPrincipal()
    });
    
    const cluster = new eks.Cluster(this, 'Cluster', {
      mastersRole: clusterAdmin,
      version: eks.KubernetesVersion.V1_18,
      defaultCapacity: 2,
    });
            
    const nginx = cluster.addHelmChart('NginxIngress', {
      chart: 'nginx-ingress',
      repository: 'https://helm.nginx.com/stable',
    });

    this.elbUrl = cluster.getServiceLoadBalancerAddress('{Where do I get the service name?}') //<- This is what I can't figure out
}

I looked at the properties on the helm chart, and it doesn’t seem to expose anything that fits the bill. Appreciate any insight. Thanks!

2

Answers


  1. Chosen as BEST ANSWER

    In my particular case, I just needed a way to define the name of the ingress controller so it wouldn't be auto-generated. Doing so would then let me query that ingress controller for its ELB address. The fix is to give the the ingress controller helm chart a release name. Once deployed, CDK appends -nginx-ingress to the end of the release name, but given the release name, you can calculate the k8s Service name. Here's a working version:

    import * as cdk from '@aws-cdk/core';
    import * as eks from '@aws-cdk/aws-eks';
    import * as iam from '@aws-cdk/aws-iam';
    
    export class SimpleEks extends cdk.NestedStack {
      elbUrl: string;
    
      constructor(scope: cdk.Construct, id: string, props?: cdk.NestedStackProps) {
        super(scope, id, props);
    
        const ingressControllerReleaseName = 'ingress-controller'
    
        const clusterAdmin = new iam.Role(this, 'AdminRole', {
          assumedBy: new iam.AccountRootPrincipal()
        });
    
        const cluster = new eks.Cluster(this, 'cluster', {
          clusterName: 'cluster',
          mastersRole: clusterAdmin,
          version: eks.KubernetesVersion.V1_18,
          defaultCapacity: 2,
        });
    
        const ingressControllerChart = cluster.addHelmChart('IngressController', {
          chart: 'nginx-ingress',
          repository: 'https://helm.nginx.com/stable',
          release: ingressControllerReleaseName, //This fixes the service name so it's predictable and not auto-generated
        });
    
        const albAddress = new eks.KubernetesObjectValue(this, 'elbAddress', {
          cluster,
          objectType: 'Service',
          objectName: `${ingressControllerReleaseName}-nginx-ingress`, //This is what I was missing
          jsonPath: '.status.loadBalancer.ingress[0].hostname',
        });
        // I haven't tried the below code, but I suspect it might work as well as getSvcLBAddress is just a convenience method over `eks.KubernetesObjectValue()`
        //const elb = cluster.getServiceLoadBalancerAddress(`${ingressControllerReleaseName}-nginx-ingress`);
    
    
        const elb = albAddress.value; //This is what I needed to get.
      }
    }
    

  2. What you have deployed is the ingress controller helm chart which it self doesn’t expose anything but rather scans any K8S objects of type Ingress. In this case you should deploy an Ingress after you deploy the ingress controller and you can’t use the pre-built function to get the LoadBalancerAddress for you.

    Example:

            self.alb_domain_name = eks.KubernetesObjectValue(
                self, 'Query',
                cluster=cluster,
                object_type='Ingress',
                object_name='cluster-ingress', # this is your ingress name
                object_namespace='my-ingress-controller', # in which namespace your ingress is deployed
                json_path='.status.loadBalancer.ingress[0].hostname' # this json path will get you the hostname for the deployed AWS ELB/ALB
            )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search