aws-appsync-community icon indicating copy to clipboard operation
aws-appsync-community copied to clipboard

[Feature Request] Option to add OpenSearch Serverless collection as a Data source type

Open Waqiah opened this issue 1 year ago • 2 comments

Hello team,

Initially I would like to be able to create an OpenSearch Collection, which is an OpenSearch Serverless resource via CDK. However according to this documentation, the API datasource properties are API, domain, description, name and serviceRole. The domain property is the OpenSearch domain endpoint URL and not the OpenSearch Collection endpoint.

When I saw that this option was not available in CDK, I navigated to the AppSync Console and tried to create a test API (MyAppSyncApi), however I see the option to add an OpenSearch Serverless collection is not available under Data source types. Hoping to have the OpenSearch Serverless collection supported.

In the meantime, please let me know if there are any workarounds (if possible) to achieve the above use case

Waqiah avatar Aug 07 '24 17:08 Waqiah

Thank you for the feature request.

In the mean time, you can use an HTTP data source to interact with your OS collection. See some example of the HTTP interface here: https://docs.aws.amazon.com/opensearch-service/latest/developerguide/serverless-clients.html#serverless-signing

onlybakam avatar Aug 09 '24 18:08 onlybakam

For reference, here's a sample setup:

  AppSyncOpenSearchCollectionDataSourceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: appsync.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: appsyncopensearchcollectiondatasource
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: aoss:APIAccessAll
                Resource: !GetAtt OpenSearchCollection.Arn
  AppSyncOpenSearchCollectionDataSource:
    Type: AWS::AppSync::DataSource
    Properties:
      ApiId: !GetAtt AppSyncGraphQLApi.ApiId
      Name: OpenSearchCollection
      Type: HTTP
      ServiceRoleArn: !GetAtt AppSyncOpenSearchCollectionDataSourceRole.Arn
      HttpConfig:
        Endpoint: !GetAtt OpenSearchCollection.CollectionEndpoint
        AuthorizationConfig:
          AuthorizationType: AWS_IAM
          AwsIamConfig:
            SigningRegion: !Ref AWS::Region
            SigningServiceName: aoss
  AppSyncQueryDocumentsResolver:
    Type: AWS::AppSync::Resolver
    Properties:
      ApiId: !GetAtt AppSyncGraphQLApi.ApiId
      Code: |
        import { util } from "@aws-appsync/utils";

        export function request(ctx) {
          const body = {
            from: ctx.args.from || 0,
            size: ctx.args.size || 10,
            query: { match_all: {} },
          };
          return {
            version: "2018-05-29",
            method: "POST",
            params: { headers: { "Content-Type": "application/json" }, body },
            resourcePath: "/my-index/_search",
          };
        }

        export function response(ctx) {
          const { statusCode, body } = ctx.result;
          if (statusCode === 200) {
            const data = JSON.parse(body);
            return {
              total: data.hits.total.value,
              hits: data.hits.hits.map((hit) => hit._source),
            };
          }
          util.appendError(body, `${statusCode}`);
        }

      DataSourceName: !GetAtt AppSyncOpenSearchCollectionDataSource.Name
      TypeName: Query
      FieldName: documents
      Runtime:
        Name: APPSYNC_JS
        RuntimeVersion: 1.0.0
    DependsOn:
      - AppSyncGraphQLSchema
  AppSyncGraphQLSchema:
    Type: AWS::AppSync::GraphQLSchema
    Properties:
      ApiId: !GetAtt AppSyncGraphQLApi.ApiId
      Definition: |
        schema {
          query: Query
        }

        type Document {
          id: ID!
        }

        type DocumentsConnection {
          total: Int!
          hits: [Document!]!
        }

        type Query {
          documents(from: Int, size: Int): DocumentsConnection!
        }

This assumes the existence of these other resources:

  • OpenSearchCollection of Type AWS::OpenSearchServerless::Collection, containing an index named my-index
  • AppSyncGraphQLApi of Type AWS::AppSync::GraphQLApi

ericbn avatar Dec 12 '25 13:12 ericbn