API Gateway HTTP API calling Keycloak ECS

0

We have ECS with Keycloak and ALB (public subnets) configured. Currently, Keycloak is available at idp.dev.example.com (CNAME domain name from ALB and record name idp.dev.example.com). I also have my API Gateway HTTP API under dev.example.com. Now, we have added a few more services with the pattern dev.example.com/core, etc., and we would like to move Keycloak to dev.example.com/idp. I tried some configurations using CDK TypeScript, but nothing worked. I would appreciate some tips on how or where to start if someone could walk me through config in the console would be also supper helpful.

If needed I can also provide some code snippets.

Mostly I tried creating a new HttpRoute, which worked for the AppRunner service, but it does not for the ECS with ALB.

Greetings

3 Answers
1

If I understood your question well, in order to create a route for ECS you must create a listener with a rule that should include the conditions for the path-based routing (i.e., /idp).

Make sure your ECS is registered with a Target Group through the above listener and get your ECS Task to have the necessary mappings in order to work.

profile picture
EXPERT
answered a month ago
0

Currently, we have like this:

Creating ALB

const applicationLoadBalancer = new elbv2.ApplicationLoadBalancer(
      this,
      'alb',
      {
        vpc,
        vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }),
        internetFacing: true,
      }
    );

Adding listener, with certificate:

const listener = applicationLoadBalancer.addListener(
      'http-listener',
      {
        protocol: elbv2.ApplicationProtocol.HTTPS,
        certificates: [
          {
            certificateArn: platformCertificate.certificateArn,
          },
        ],
      }
    );

And addTargets

    listener.addTargets('ecs-targets', {
      targets: [fargateService],
      healthCheck: {
        path: "/health",
        enabled: true,
        protocol: elbv2.Protocol.HTTP,
        timeout: cdk.Duration.seconds(30),
        interval: cdk.Duration.seconds(45),
        healthyThresholdCount: 3,
        unhealthyThresholdCount: 3,
      },
      slowStart: cdk.Duration.seconds(60),
      stickinessCookieDuration: cdk.Duration.days(1),
      port: 8080,
      protocol: elbv2.ApplicationProtocol.HTTP,
    });

In the end we create CNAME

new route53.CnameRecord(this, 'cname', {
      domainName: applicationLoadBalancer.loadBalancerDnsName,
      recordName: `idp.${platformUrl}`,
      zone: hostedZone,
    });

And this is working in idp.example.com as expected.

Now I tried to add conditions conditions: [elbv2.ListenerCondition.pathPatterns(["/idp"])] and create new route like we are doing in the AppRunner

    new apigateway.HttpRoute(this, 'add-route-idp', {
      httpApi,
      routeKey: apigateway.HttpRouteKey.with("/idp", apigateway.HttpMethod.ANY),
      integration: new integrations.HttpUrlIntegration(
        'idp-integration',
        `http://idp.${platformUrl}`
      ),
    });

I know I am missing some knowledge here about ALB especially. In perfect scenario I would also like to avoid creating CNAME record and just map loadbalancerDNS to my route with /idp.

Marko
answered a month ago
0

You're on the right track, Anyway these are the 3 steps that I would suggest:

  1. Add a new listener rule to your ALB that forwards requests from dev.example.com/idp to the appropriate target group associated with your Keycloak ECS service.
  2. Create a new route in API Gateway with the path /idp. The integration URL should point to your ALB’s DNS name.
  3. Instead of creating a CNAME record for idp.${platformUrl}, create an A record for dev.example.com that aliases to your ALB.
profile picture
EXPERT
answered a month ago