Hello everyone, I have created an EKS cluster and ...
# aws
n
Hello everyone, I have created an EKS cluster and installed ALB controller in it. I have defined an ingress of class
alb
which brings up a loadbalancer in AWS with dns name something like
<http://k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com|k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com>
Copy code
const albIngress = new k8s.networking.v1beta1.Ingress(`${projectName}-alb-ingress`, {
    metadata: {
        name: `${projectName}-alb-ingress`,
        namespace: 'kube-system',
        annotations: {
            '<http://kubernetes.io/ingress.class|kubernetes.io/ingress.class>': 'alb',
            '<http://alb.ingress.kubernetes.io/scheme|alb.ingress.kubernetes.io/scheme>': 'internet-facing',
            '<http://alb.ingress.kubernetes.io/target-type|alb.ingress.kubernetes.io/target-type>': 'ip',
        },
    },
    spec: {
        rules: [
            {
                http: {
                    paths: [
                        {
                            path: '/*',
                            backend: { serviceName: ingressNginxService.metadata.name, servicePort: 80 }
                        }
                    ]
                }
            }
        ]
    },
}, { provider: cluster.provider });

const www = new aws.route53.Record("www", {
    zoneId: '<Redacted>',
    name: 'dev-server',
    type: 'A',
    aliases: [{
        name: albIngress.status.loadBalancer.ingress[0].hostname, // <http://k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com|k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com>
        zoneId: exampleZone.zoneId, // <---------------------------------- how do i get the zone id?
        evaluateTargetHealth: true,
    }],
});
The problem is when creating a route53 record for this loadbalancer, i need a
zoneId
, where do i get it from? Any help is appreciated
b
You can call
getZone
(or
lookupZone
, it is called different in different languages) if you have an existing R53 zone.
n
Would that work for a loadbalancer’s dns name which is automatically assigned by AWS like
<http://k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com|k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com>
?
b
That’s not going to be a Zone ID. A Zone ID is a hosted zone inside Route 53
So you need to specify which Hosted Zone you want to create this record in.
It’s also odd this is an A record, since you’re pointing at a CNAME
n
What you are saying does make sense but I am not sure what to do. I want to create an A record for the loadbalancer’s dns name like (
<http://dev-server.myzone.com|dev-server.myzone.com>
). All i get from the ingress resource is this name -
<http://k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com|k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com>
(this shows as A record in EC2 -> loadbalancer). In the pulumi method to create an A record, I need 2 zone Id’s. One for the hosted zone in which to create the record, which I do have. Another one for the alias’s zoneId which I don’t have. This 2nd zone id is what I am trying to find how to get. Or is there any other way to create an A record for
<http://k8s-kubesyst-octestal-f8d469242e-698581751.ap-south-1.elb.amazonaws.com>
?
b
You should create a CNAME record in Route53
n
Let me try that
b
I don’t have a TypeScript example but here is one in Go:
Copy code
_, err = route53.NewRecord(ctx, dnsConfig.DNSName, &route53.RecordArgs{
		ZoneId: pulumi.String(dnsConfig.HostedZone.ZoneId),
		Name:   pulumi.String(dnsConfig.DNSName),
		Type:   pulumi.String("CNAME"),
		Ttl:    <http://pulumi.Int|pulumi.Int>(60),
		Records: pulumi.StringArray{
			contourServiceLB,
		},
	}, pulumi.Provider(dnsConfig.Provider))
	if err != nil {
		return nil, err
	}
Very similar to what you’re trying to do - you would replace
contourServiceLB
with the
albIngress.status.loadBalancer.ingress[0].hostname
b
just to be clear, you can use an A record in Route53 because it supports
ALIAS
records: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html you're still going to need a zone id to pass to a CNAME
n
@bored-table-20691 Adding a cname record like so worked!
Copy code
const route53Record = new aws.route53.Record(`${projectName}-route53-record`, {
    zoneId: hostedZone.then(zone => zone.zoneId),
    name: hostedZone.then(zone => `dev-server.${zone.name}`),
    type: 'CNAME',
    ttl: 60,
    records: [albIngress.status.loadBalancer.ingress[0].hostname],
}, { dependsOn: [albIngress] });
I was initially trying to use the
aliases
from
new aws.route53.Record
which was not really needed. Used
records
and specified the hostname which did the trick! Thanks for your help.
p
@nice-pharmacist-5320: I had to do something very similar. Aliases are a bit better because they reduce the number of DNS queries a client has to perform to get an IP address. Here’s how I did it, if you’re interested. NB: In my case, there was a bit of a race condition between k8s creating the ALB controller and the ALB actually existing, so I used
ts-retry
to help with that.
Copy code
import { retry } from 'ts-retry';

ingress.status.loadBalancer.ingress.apply(async () => {
  // The load balancer isn't available immediately after the Ingress is provisioned.
  // This retries `getLoadBalancer` a few times before giving up.
  // Uses the ts-retry module: <https://www.npmjs.com/package/ts-retry>
  const lb = await retry(() => {
    return aws.lb.getLoadBalancer({ name: `${args.env.name}-${args.env.namespace}-lb` }, { parent: this });
  }, { delay: 2000, maxTry: 5 });
  new aws.route53.Record(name, {
    name: args.env.name,
    aliases: [{ name: lb.dnsName, zoneId: lb.zoneId, evaluateTargetHealth: true }],
    type: 'A',
    zoneId: args.zoneId
  }, { parent: this });
});
Also worth noting that I gave the LB a name in the controller annotations:
Copy code
annotations: {
          ...
          '<http://alb.ingress.kubernetes.io/load-balancer-name|alb.ingress.kubernetes.io/load-balancer-name>': `${args.env.name}-${args.env.namespace}-lb`,
          ...
        }
That makes the
getLoadBalancer
function call a lot easier. Finally, my setup was in a
ComponentResource
definition, that’s why you see
parent: this
a lot. No need for that in your case.
n
That’s brilliant. I am going to use this setup, it is so much better. Thanks @prehistoric-london-9917
👍 1
@prehistoric-london-9917 Hey, do you mind sharing the full component resource? I also want to create a component resource for it but I am not able to find right abstraction for the ALB
p
Hi @nice-pharmacist-5320: There’s a lot of IP in that component, so I don’t think I could share the whole thing. I might be able to dig out the ALB bits, though. Let me see what I can do.
This is a rough shot at what a component resource with just the ingress stuff would look like. It’s worth noting: the AIB Ingress Controller is created when I create the cluster, so it already exists when this runs. Obviously, you’ll need to tailor this to your situation. There are some placeholder values, etc. I haven’t tested it, but this would be roughly where I’d start.