aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.51k stars 3.85k forks source link

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

Open anassar-lab opened 2 weeks ago

anassar-lab commented 2 weeks ago

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

CDK version used

2.148.0 (build e5740c0)

Environment details (OS name and version, etc.)

Microsoft Windows 11 Enterprise - 23H2

ashishdhingra commented 2 weeks ago

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)

zoro273 commented 2 weeks ago

@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.

MirandaDora commented 2 weeks ago

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.

anassar-lab commented 2 weeks ago

@MirandaDora _serviceId: 'serviceid', 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 ?