aws-cdk icon indicating copy to clipboard operation
aws-cdk copied to clipboard

ECS - ServiceConnect : There is no way to reference ServiceConnect Discovery URL which is needed to build APIGatewayv2 Integration

Open anassar-lab opened this issue 1 year ago • 2 comments

Describe the feature

Extend the CDK ability to build API Gateway Integration that references Service Connect, similar to the capability offered for Service Discovery, see the link: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigatewayv2_integrations-readme.html#cloud-map-service-discovery.

This is currently possible from the console, using the Private integration target that references the ServiceConnect CloudMap entry:

Screenshot 2024-08-26 114553

Which generates an integration with the below properties: image (16)

Use Case

Use CDK natively to build an integration between an ECS service that has service connect enabled and an API Gateway using private integration.

Proposed Solution

There are a number of options, but I was trying to get a reference for the ServiceConnect Discovery URI and pass that as a parameter the HttpIntegration method, but I wasn't able to do that. The ServiceConnect discovery URL can be viewed as shown below: Screenshot 2024-08-26 120330

The URL can be constructed using the pattern serviceArn:'arn:aws:servicediscovery:<region-id:<aws_account_id>:service/<service_id> which requires a reference to the CloudMap service ID.

const httpIntegration = new apigatewayv2.HttpIntegration(this, 'MyHttpIntegration', {
            httpApi: httpEndpoint,
            integrationType: apigatewayv2.HttpIntegrationType.HTTP_PROXY,
            connectionId: 'connectionId',
            connectionType: apigatewayv2.HttpConnectionType.VPC_LINK,
            integrationUri:  **___<This URI is needed>___**
            method: apigatewayv2.HttpMethod.ANY, 
            timeout: cdk.Duration.minutes(30), 
          });

Other Information

No response

Acknowledgements

  • [ ] I may be able to implement this feature request
  • [ ] This feature might incur a breaking change

CDK version used

2.148.0 (build e5740c0)

Environment details (OS name and version, etc.)

Microsoft Windows 11 Enterprise - 23H2

anassar-lab avatar Aug 26 '24 02:08 anassar-lab

Selecting service connect namespace is an option while adding API Gateway integration in AWS console. (Followed example https://github.com/aws-samples/ecs-service-connect-yelb-sample-app)

ashishdhingra avatar Aug 28 '24 17:08 ashishdhingra

@ashishdhingra , yes it is possible via console, see the screenshot attached in the feature description, but the main goal is to be able to accomplish the same via CDK.

zoro273 avatar Aug 28 '24 21:08 zoro273

If not using CDK to provision ECS cluster, then it's possible to retrieve service using fromServiceAttributes:

const { Stack } = require('aws-cdk-lib');
// const sqs = require('aws-cdk-lib/aws-sqs');
const servicediscovery = require('aws-cdk-lib/aws-servicediscovery');
const apigatewayv2 = require('aws-cdk-lib/aws-apigatewayv2');
const ec2 = require('aws-cdk-lib/aws-ec2');
const { HttpServiceDiscoveryIntegration } = require('aws-cdk-lib/aws-apigatewayv2-integrations');;

class SD extends Stack {
  /**
   *
   * @param {Construct} scope
   * @param {string} id
   * @param {StackProps=} props
   */
  constructor(scope, id, props) {
    super(scope, id, props);
    const vpc = ec2.Vpc.fromLookup(this, 'MyVpc', {
      vpcId: 'vpcid'
    });
    const vpcLink = apigatewayv2.VpcLink.fromVpcLinkAttributes(this, 'servicediscoveryLink', {
      vpcLinkId: 'vpclinkid',
      vpc
    })
    const service = servicediscovery.Service.fromServiceAttributes(this, 'servicediscovery', {
      namespace: 'local',
      dnsRecordType: servicediscovery.DnsRecordType.A_AAAA,
      routingPolicy: servicediscovery.RoutingPolicy.WEIGHTED,
      serviceArn:'arn:aws:servicediscovery:ap-southeast-2:<aws_account_id>:service/<service_id>',
      serviceName: 'Demo',
      serviceId: 'service_id',
      discoveryType: servicediscovery.DiscoveryType.DNS_AND_API,
    })
    const httpEndpoint = new apigatewayv2.HttpApi(this, 'HttpProxyPrivateApi', {
      defaultIntegration: new HttpServiceDiscoveryIntegration('Labgroups', service, {
        vpcLink,
        method: apigatewayv2.HttpMethod.ANY
      }),
    });
  }
}

However when creating from ECS construct, it's not exposing CloudMap configurations it has created hence unable to refer to them convinently. Also is that's possible to put some examples in the CDK documentation that does this? Thank you.

MirandaDora avatar Aug 29 '24 06:08 MirandaDora

@MirandaDora serviceId: 'service_id', attribute is also not retrievable from cloudformation or CDK, so this has to be passed in manually to the template after the service is created in a prior step, is my understanding correct ?

anassar-lab avatar Aug 29 '24 06:08 anassar-lab