GithubHelp home page GithubHelp logo

aws-samples / aws-marketplace-serverless-saas-integration Goto Github PK

View Code? Open in Web Editor NEW
119.0 20.0 72.0 6.94 MB

Example of serverless integration for SaaS products listed on the AWS Marketplace.

License: MIT No Attribution

JavaScript 83.93% HTML 11.26% CSS 4.81%
aws marketplace saas serverless aws-marketplace

aws-marketplace-serverless-saas-integration's Introduction

AWS Marketplace - Serverless integration for SaaS products (Example)

This project provides example of serverless integration for SaaS products listed on the AWS Marketplace.

If you are a new seller on AWS Marketplace, we advise you to check the following resources:

Project Structure

The sample in this repository demonstrates how to use AWS SAM (Serverless application model) to integrate your SaaS product with AWS Marketplace and how to perform:

Register new customers

With SaaS subscriptions and SaaS contracts, your customers subscribe to your products through AWS Marketplace, but access the product on environment you manage in your AWS account. After subscribing to the product, your customer is directed to a website you create and manage as a part of your SaaS product to register their account and configure the product.

When creating your product, you provide a URL to your registration landing page. AWS Marketplace uses that URL to redirect customers to your registration landing page after they subscribe. On your software's registration URL, you collect whatever information is required to create an account for the customer. AWS Marketplace recommends collecting your customer’s email addresses if you plan to contact them through email for usage notifications.

The registration landing page needs to be able to identify and accept the x-amzn-marketplace-token token in the form data from AWS Marketplace with the customer’s identifier for billing. It should then pass that token value to the AWS Marketplace Metering Service and AWS Marketplace Entitlement Service APIs to resolve for the unique customer identifier and corresponding product code.

NOTE: Deploying the static landing page is optional. You can choose to use your existing SaaS registration page, after collecting the data you should call the register new subscriber endpoint. Please see the deployment section.

Implementation

In this sample we created CloudFront Distribution, which can be configured to use domain/CNAME by your choice. The POST request coming from AWS Marketplace is intercepted by the Edge src/redirect.js, which transforms the POST request to a GET request, and passes the x-amzn-marketplace-token in the query string. A static landing page hosted on S3 which takes the users inputs defined in the html form and submits them to the /subscriber API Gateway endpoint. <<<confirm

The handler for the /subscriber endpoint is defined in the src/register-new-subscriber.js file. This lambda function calls the resolveCustomerAPI and validates the token. If the token is valid, a customer record is created in the AWSMarketplaceSubscribers DynamoDB table and the data the customer submitted in the html form is stored. <<< add links

Grant and revoke access to your product

Grant access to new subscribers

Once the resolveCustomer endpoint return successful response, the SaaS vendors must to provide access to the solution to the new subscriber. Based on the type of listing contract or subscription we have defined different conditions in the grant-revoke-access-to-product.js stream handler that is executed on adding new or updating existing rows.

In our implementation the Marketplace Tech Admin (The email address you have entered when deploying), will receive email when new environment needs to be provisioned or existing environment needs to be updated. AWS Marketplace strongly recommends automating the access and environment management which can be achieved by modifying the grant-revoke-access-to-product.js function.

The property successfully subscribed is set when successful response is returned from the SQS entitlement handler for SaaS Contract based listings or after receiving **subscribe-success message from the Subscription SNS Topic in the case of AWS SaaS subscriptions in the subscription-sqs-handler.js.

Update entitlement levels to new subscribers (SaaS Contracts only)

Each time the entitlement is update we receive message on the SNS topic. The lambda function entitlement-sqs.js on each message is calling the marketplaceEntitlementService and storing the response in the dynamoDB.

We are using the same DynamoDB stream to detect changes in the entailment for SaaS contracts. When the entitlement is update notification is sent to the MarketplaceTechAdmin.

Revoke access to customers with expired contracts and cancelled subscriptions

The revoke access logic is implemented in a similar manner as the grant access logic.

In our implementation the MarketplaceTechAdmin receives email when the contract expires or the subscription is cancelled. AWS Marketplace strongly recommends automating the access and environment management which can be achieved by modifying the grant-revoke-access-to-product.js function.

Metering for usage

For SaaS subscriptions, the SaaS provider must meter for all usage, and then customers are billed by AWS based on the metering records provided. For SaaS contracts, you only meter for usage beyond a customer’s contract entitlements. When your application meters usage for a customer, your application is providing AWS with a quantity of usage accrued. Your application meters for the pricing dimensions that you defined when you created your product, such as gigabytes transferred or hosts scanned in a given hour.

Implementation

We have created MeteringSchedule CloudWatch Event rule that is triggered every hour. The metering-hourly-job.js gets triggered by this rule and it's querying all of the pending/unreported metering records from the AWSMarketplaceMeteringRecords table using the PendingMeteringRecordsIndex. All of the pending records are aggregated based on the customerIdentifier and dimension name, and sent to the SQSMetering queue. The records in the AWSMarketplaceMeteringRecords table are expected to be inserted programmatically by your SaaS application. In this case you will have to give permissions to the service in charge of collecting usage data in your existing SaaS product to be able to write to AWSMarketplaceMeteringRecords table.

The lambda function metering-sqs.js is sending all of the queued metering records to the AWS Marketplace Metering service. After every call to the batchMeterUsage endpoint the rows are updated in the AWSMarketplaceMeteringRecords table, with the response returned from the Metering Service, which can be found in the metering_response field. If the request was unsuccessful the metering_failed value with be set to true and you will have to investigate the issue the error will be also stored in the metering_response field.

The new records in the AWSMarketplaceMeteringRecords table should be stored in the following format:

{
  "create_timestamp": {
    "N": "113123"
  },
  "customerIdentifier": {
    "S": "ifAPi5AcF3"
  },
  "dimension_usage": {
    "L": [
      {
        "M": {
          "dimension": {
            "S": "users"
          },
          "value": {
            "N": "3"
          }
        }
      },
      {
        "M": {
          "dimension": {
            "S": "admin_users"
          },
          "value": {
            "N": "1"
          }
        }
      }
    ]
  },
  "metering_pending": {
    "S": "true"
  }
}

Where the create_timestamp is the sort key and customerIdentifier is the partition key, and they are both forming the Primary key. Note:The new records format is in DynamoDB JSON format. It is different than JSON. The accepted time stamp is UNIX timestamp in UTC time.

After the record is submitted to AWS Marketplace BatchMeterUsage API, it will be updated and it will look like this:

{
  "create_timestamp": 113123,
  "customerIdentifier": "ifAPi5AcF3",
  "dimension_usage": [
    {
      "dimension": "admin_users",
      "value": 3
    }
  ],
  "metering_failed": false,
  "metering_response": "{\"Results\":[{\"UsageRecord\":{\"Timestamp\":\"2020-06-24T04:04:53.776Z\",\"CustomerIdentifier\":\"ifAPi5AcF3\",\"Dimension\":\"admin_users\",\"Quantity\":3},\"MeteringRecordId\":\"35155d37-56cb-423f-8554-5c4f3e3ff56d\",\"Status\":\"Success\"}],\"UnprocessedRecords\":[]}"
}

Deploying the sample application using the SAM CLI

The Serverless Application Model Command Line Interface (SAM CLI) is an extension of the AWS CLI that adds functionality for building and testing Lambda applications. To learn more about SAM, visit the AWS SAM developer guide.

To build and deploy your application, you must sign in to the AWS Management Console with IAM permissions for the resources that the templates deploy. For more information, see AWS managed policies for job functions. Your organization may choose to use a custom policy with more restrictions. These are the AWS services that you need permissions to create as part of the deployment:

  • AWS IAM role
  • Amazon CloudWatch Logs
  • Amazon CloudFront
  • Amazon S3 bucket
  • AWS CloudFormation stack
  • AWS Lambda function
  • Amazon API Gateway
  • Amazon DynamoDB database
  • Amazon SQS queue
  • Amazon SNS topic
  • Amazon EventBridge

Note

For simplicity, we use AWS CloudShell to deploy the application since it has the required tools pre-installed. If you wish to run the deployment in an alternate shell, you'll need to install Docker community edition, Node.js 10 (including NPM), AWS CLI, and SAM CLI.

To build and deploy your application for the first time, complete the following steps.

  1. Using the AWS account registered as your AWS Marketplace Seller account, open AWS CloudShell.

  2. Clone the aws-marketplace-serverless-saas-integration repository and change to the root of the repository.

git clone https://github.com/aws-samples/aws-marketplace-serverless-saas-integration.git
  1. Change to the root directory of the repository
cd aws-marketplace-serverless-saas-integration
  1. Build the application using SAM.
sam build
  1. Deploy the application using the SAM guided experience.
sam deploy --guided --capabilities CAPABILITY_NAMED_IAM
  1. Follow the SAM guided experience to configure the deployment. Reference the following table for solution parameters.

    Parameter name Description
    Stack Name Name of the resulting CloudFormation stack.
    AWS Region Name of the region that the solution is being deployed in. Default value: us-east-1
    WebsiteS3BucketName S3 bucket to store the HTML files; Mandatory if CreateRegistrationWebPage is set to true; will be created
    NewSubscribersTableName Name for the New Subscribers Table; Default value: AWSMarketplaceSubscribers
    AWSMarketplaceMeteringRecordsTableName Name for the Metering Records Table; Default value: AWSMarketplaceMeteringRecords
    TypeOfSaaSListing allowed values: contracts_with_subscription, contracts, subscriptions; Default value: contracts_with_subscription
    ProductCode Product code provided from AWS Marketplace
    MarketplaceTechAdminEmail Email to be notified on changes requiring action
    MarketplaceSellerEmail (Optional) Seller email address, verified in SES and in 'Production' mode. See Verify an email address for instruction to verify email addresses.
    SNSAccountID AWS account ID hosting the Entitlements and Subscriptions SNS topics. Leave as default.
    SNSRegion AWS region that the Entitlements and Subscriptions SNS topics are hosted in. Leave as default.
    CreateCrossAccountRole Creates a cross-account role granting access to the NewSubscribersTableName and AWSMarketplaceMeteringRecordsTableName tables. Default value: false.
    CrossAccountId (Optional) AWS account ID for the cross-account role.
    CrossAccountRoleName (Optional) Role name for the cross-account role.
    CreateRegistrationWebPage Creates a registration page. Default value: true
  2. Wait for the stack to complete successfully.

  3. Check the email account for MarketplaceTechAdminEmail and approve the subscription to the SNS topic.

  4. If a registration page was created, copy the web files into the WebsiteS3BucketName.

aws s3 cp ./web/ s3://<NAME_OF_THE_BUCKET_SELECTED_FOR_WebsiteS3BucketName>/ --recursive

Diagram of created resources

Based on the value of the TypeOfSaaSListing parameter different set of resources will be created.

In the case of contracts_with_subscription all of the resources depicted on the diagram below will be created.

In the case of a contracts, the resources market with orange circles will not be created.

In the case of a subscriptions the resources market with purple circles will not be created.

The landing page is optional. Use the CreateRegistrationWebPage parameter.

Cleanup

To delete the sample application that you created, use the AWS CLI. Assuming you used your project name for the stack name, you can run the following:

aws cloudformation delete-stack --stack-name app

Security

See CONTRIBUTING for more information.

License

This library is licensed under the MIT-0 License. See the LICENSE file.

Post deployment steps

Registration page is true

  1. Update the MarketplaceFulfillmentUrl in your AWS Marketplace Management Portal with the value from the output key 'MarketplaceFulfillmentUrl'. The value would be in a the form of a AWS cloudfront based url.
  2. Replace the baseUrl value in the web/script.js file from the web template provided with the value from the output key 'RedirectUrl'.
  3. Replace the RedirectUrl value in the lambda environment variable with the value from the output key 'RedirectUrl'. Navigate to the AWS Console, look for AWS Lambda service, filter to the lambda with name ....Redirect... . Select the lambda function, go to configuration tab and then select the environment variable.
  4. Ensure the email address used is a verified identity/domain in Amazon Simple Email Service.
  5. Ensure your Amazon Simple Email Service account is a production account.

Registration page is false

  1. Update the MarketplaceFulfillmentUrl in your AWS Marketplace Management Portal with the value from the output key 'MarketplaceFulfillmentUrl'. The value would be in the form of an AWS API gateway url.
  2. Replace the baseUrl value in the web/script.js file from the web template provided with the value from the output key 'RedirectUrl'.
  3. Ensure the email address used is a verified identity/domain in Amazon Simple Email Service.
  4. Ensure your Amazon Simple Email Service account is a production account.

aws-marketplace-serverless-saas-integration's People

Contributors

amazon-auto avatar charleswhchan avatar chotafakir avatar cloudbennett avatar dependabot[bot] avatar gargana avatar gitvchandra avatar gjoshevski avatar jcvalerio avatar jesusrod avatar jimzucker avatar joserolles avatar kumarpawan1 avatar kwwaikar avatar lenopip avatar lhtan-dev avatar linhlam-mp avatar lulzneko avatar mandusm avatar mbatchelor avatar ozzambra avatar sgawsmp avatar stian-a-johansen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-marketplace-serverless-saas-integration's Issues

Invalid parameter: TopicArn Reason: An ARN must have at least 6 elements

Describe the bug

We are deploying landing page for our Marketplace integration. While deploying facing following issues:
Invalid parameter: TopicArn Reason: An ARN must have at
least 6 elements, not 1 (Service: AmazonSNS; Status Code:
400; Error Code: InvalidParameter; Request ID:
98904f2c-9377-56e1-b024-17dcd6a302ad; Proxy: null)User: arn:aws:iam::xxxxxxx:user/xxxxxx is
not authorized to perform: SNS:Subscribe on resource:
arn:aws:sns:us-east-1:287250355862:aws-mp-entitlement-
notification-XXXXXXXX (Service: AmazonSNS;
Status Code: 403; Error Code: AuthorizationError; Request
ID: da0cfc82-d12a-5dfd-b1a6-a472cb4f9071; Proxy: null)
To resolve this issue we commented out EntitlementSQSHandler block from template.yaml.

We were able to deploy the landing page. However when we tried to access web page. It displays following error:

This XML file does not appear to have any style information associated with it. The document tree is shown below.

AccessDenied
Access Denied
Z9161D15XV37JFVH
zrlf9xukKblFljCwM3uMD0j60Vj54fQZrfoHNiXl7wvOVzMt7cwGzXJTN3CB/LJUE0fLVuDvGg0=

Documentation Improvements

Some notes on the documentation that may help others:

You have to create these manually before executing the CLI Commands:

  <DEPLOYMENT_ARTEFACT_S3_BUCKET>
  <MARKETPLACE_ENTITLEMENT_SNS_TOPIC>  - This must be the full topic ARN (FIFO does not work - use STANDARD)
  <MARKETPLACE_SUBSCRIPTION_SNS_TOPIC>  - This must be the full topic ARN (FIFO does not work - use STANDARD)

You provide these strings before executing the CLI Commands:

<STACK_NAME>
<MARKETPLACE_PRODUCT_CODE>
<MARKETPLACE_TECH_ADMIN_EMAIL>

This is created BY CLOUDFORMATION on your behalf:

<WEBSITE_BUCKET_NAME> - Make sure you supply a valid and unique name

Your stack may take 30 minutes to finish because it deploys a new Cloudfront distribution
which takes 15-30 minutes to deploy.

Go to Cloudfront to get your "website" URL. It will look something like: https://d2foiuiyrqbfrhj.cloudfront.net
You should be able to load it into any web browser and get a registration page.

Question on SaaS Contract registartion

This actually is a question and not a bug. In register-new-subscriber.js, on line 56, why are you sending a message yourself? From the documentation, it seems like Amazon would send a message with action = entitlement-updated and we are expected to process the SNS message. This confused me a bit. Can you help clarify?

Other than that, the code provided is top notch and helped us understand the marketplace workflow very clearly. Thanks a lot for putting in the efforts.

Lambda@Edge function returns 502 error

Describe the bug
Upon filling the sample app form and submitting it, I get a generic cloudfront 502 error page.

Please see also: aws-ia/cloudformation-aws-marketplace-saas#54

To Reproduce
Steps to reproduce the behavior:

  1. Install the sample app as described
  2. try to buy the marketplace product

Expected behavior
The provided sample app should complete the way it should....

Apparently, the form sends the data as multipart/form-data, but the Lambda@edge function expects application/x-www-form-urlencoded.

Doing a resolveCustomer() call using temporary credentials.

This might be useful for sites that want to have unauthenticated users doing the resolveCustomer() call.

I am successfully generating an AccessKey, SecretKey, and SessionToken associated with a Role that permits the temporary user to make resolveCustomer() calls.

I can prove that these credentials can successfully do a resolveCustomer() call by setting env vars:
(without setting these, it can't find credentials).

export AWS_ACCESS_KEY_ID=xxxxx
export AWS_SECRET_ACCESS_KEY=yyyyy
export AWS_SESSION_TOKEN=zzzz

And then doing the relevant CLI call:

aws meteringmarketplace resolve-customer --registration-token asdfa --region us-west-2

This should return an "InvalidToken" error.

Works great. However, I want to do this using the JavaScript SDK v3.

My attempt looks like this:

const tempCredentials =  {
  accessKeyId: AccessKeyId,
  secretAccessKey: SecretAccessKey,
  sessionToken: SessionToken
};

 const marketplacemetering = new MarketplaceMeteringClient({
   region: 'us-west-2',
   credentials: tempCredentials
 });

 const resolveCustomerParams = {
     RegistrationToken: 'asdfa',
 };

 const resolve = new ResolveCustomerCommand(resolveCustomerParams);

 try {

    const data = await marketplacemetering.send(resolve);
    return data;

 } catch (error)  {

   return error;

 }

The call returns "TypeError: Failed to fetch" which usually means that the Api call is just not setup properly.
What I'm expecting is a 400 error of type InvalidToken.
Any thoughts?

API Gateway resource in the template

Hello, and thanks for the solution.
Am I missing something regarding the API Gateway resource? Where does the value for "${ServerlessRestApi}" come from and where is the trigger for the function "RegisterNewMarketplaceCustomer" defined?

Enhance instructions to make amendments

The app is great, a quick start guide on how to make simple changes and update the stack would be great., ie I want to modify the registration lambda. Since it is not editable I have to learn how this stack works to re-deploy, can you give me some pointers?

email not working

We were able to get the stack working but when the website says you are getting an email it never comes.

Any hints on where to look will be welcome

entitlement-sqs.js: Cannot read property 'ExpirationDate' of undefined

Describe the bug
After AWS Support deleted a test SaaS subscription (to cleanup internal testing), the serverless integration reported the following errors. The lambda function is invoked repeatedly ($$$) but fails to process the message

2022-10-28T17:24:25.283Z        b0ebcf90-1d41-5b3e-af18-94460ebaf1c0	INFO	entitlementsResponse { Entitlements: [] }

2022-10-28T17:24:25.283Z	6a4209b2-28b4-5344-a57a-52643ac848d8	ERROR	Invoke Error 	{"errorType":"TypeError","errorMessage":"Cannot read property 'ExpirationDate' of undefined","stack":["TypeError: Cannot read property 'ExpirationDate' of undefined","    at /var/task/entitlement-sqs.js:31:71","    at runMicrotasks (<anonymous>)","    at processTicksAndRejections (internal/process/task_queues.js:97:5)","    at async Promise.all (index 0)","    at async Runtime.exports.handler (/var/task/entitlement-sqs.js:10:3)"]}

suspect the problem is in the following line in entitlement-sqs.js

      const isExpired = new Date(entitlementsResponse.Entitlements[0].ExpirationDate) < new Date();

To Reproduce
Steps to reproduce the behavior:

  1. AWS Support deleted existing subscription (created from internal testing)

Expected behavior
{ Entitlements: [] } is handled gracefully by the serverless integration.

The template does not support cross-account access to the marketplace resources

The best practice for setting up our marketplace is to use a separate account for hosting this template.

We created and have an approved offering in our billing account and we have setup a cross-account role and tested it to access the marketplace sns topic.

How ever the Cloud formation template does not seem to support this.

we chatted with premium support but needhelp modifying the steps we are taking or the cloudformation to use our cross account role.

This is what support said:

You were having issues deploying the ‘Serverless integration for SaaS products’ sample CloudFormation stack [1]. You are receiving the following errors:


User: arn:aws:iam::232109169367:user/dilip-marketplace is not authorized to perform: SNS:Subscribe on resource: arn:aws:sns:us-east-1:287250355862:aws-mp-entitlement-notification-e4p71lg2jqw2dh4sjkxbcyuyo

Invalid parameter: TopicArn Reason: An ARN must have at least 6 elements, not 1

You are trying to subscribe to the SNS topic with an IAM role in another AWS Account which is whitelisted for the subscription. A previous Engineer Eman suggested to use a Lambda custom resource to first assume the whitelisted IAM role then subscribe to the SNS topic programmatically using the assumed role [2]. You mentioned in the chat that you had made changes in the stack to assume the role but you were still receiving the same errors. Please correct me if my understanding is wrong.

When deploying a CloudFormation stack, it will assume the IAM role that made the deploy API call (unless a Service Role is specified) to create the underlying CloudFormation resources. In this case, IAM user ‘dilip-marketplace’ is being assumed by CloudFormation to create the resources. However, when it attempts to create resource ‘SubscriptionSQSHandlerMySQSEvent’, the SNS topic sees that ‘dilip-marketplace’ role is in an AWS Account that has not been whitelisted and rejects the subscription attempt.

I can see you were working with an IAM Support Engineer to create the IAM role ‘arn:aws:iam::865330066347:role/marketplace-cross-account-role’ that should have cross account role access to subscribe to the SNS topic. With this in mind, we need a way of assuming the role ‘marketplace-cross-account-role’ in CloudFormation to perform the SNS subscription.

There is no native functionality in CloudFormation to individually assume roles for each resource. However, an ’AWS::CloudFormation::CustomResource’ [3] can be used to replace the ‘AWS::SNS::Subscription’ resource type with a Lambda function that first assumes the role ‘arn:aws:iam::865330066347:role/marketplace-cross-account-role’ then uses that assumed role to subscribe to the SNS topic using AWS SDK that calls the ‘subscribe’ API call [4].

Therefore, ‘SubscriptionSQSHandlerMySQSEvent’ resource needs to be replaced with a custom resource that uses a Lambda function to assume the role ‘arn:aws:iam::865330066347:role/marketplace-cross-account-role’ and make the subscribe API call.

It’s likely that the ‘EntitlementSNSTopic’ will also need to be replaced with a custom Lambda resource so it can assume the ‘marketplace-cross-account-role’ IAM role and subscribe to the SNS topic.

Stack - Unlaunchable in other regions

Is your feature request related to a problem? Please describe.

We couldn't run the stack because it only supports the N. Virginia region today and we use Ohio, with strict guard rails in place to prevent notifications being received from other regions.

Describe the solution you'd like
Create the stack so that it can be deployed in any region that supports the services.

Describe alternatives you've considered
Manual integration and custom deployment.

Additional context
Add any other context or screenshots about the feature request here.

Upgrade runtimes to nodeJS16

Is your feature request related to a problem? Please describe.
The nodeJS12 runtime is being deprecated and the stack will need upgrading to ensure that it's valid after support has ended

Describe the solution you'd like
Node16 is in active LTS so this would be ideal to implement
https://github.com/nodejs/Release#release-schedule

Describe alternatives you've considered
Node14 would work but require a replacement again in the near future.

Additional context
N/A

Enable "Vendor Metered Tagging" feature as part of SaaS CFT

Is your feature request related to a problem? Please describe.

The problem: customers does not have a clear visibility into their cost usage from SaaS provider if there is no tagging around the usage. Customers will only receive one bill that includes all the activities associated with the SaaS subscription.

Describe the solution you'd like

Enabling Vendor-metered tagging feature in the SaaS CFT solution would allow vendors to tag the usage that relevant to the customers, so customers can better understand their resource usage. The solution consist of adding the extra tagging field that SaaS vendors can supply, and support metering payload up to 1MB, because it is a new requirement after enabling tagging field.

Additional context

Documentation Link: https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_BatchMeterUsage.html

This feature is especially important for SaaS product as we have limited information about SaaS user account. This will benefit both vendors and the customers for the long term, below are few value prepositions:

  1. Customers will be able to understand the breadth of the value the seller provide for their business units.
  2. This will directly reduce manual work for customers in terms of reconcile costs.
  3. Increase revenue for ISVs, because better tagging will help customers increase usage if they can understand and analyze allocation usage in detail.

Question on design for Marketplace metering

Very helpful repo, thank you. I had a question regarding the motivation behind the design of how metering records are submitted to Marketplace.

What is the motivation/reason for having the metering-hourly-job.js function send records to a SQS queue, and having another function to read records from this queue and submit to Marketplace? Would it still work to have the metering-hourly-job.js function both aggregate the records and submit to Marketplace and record the response in the table? Are there any downsides about using this approach?

Thank you.

The Metering record sample format provided in the doc is invalid

Describe the bug
The Readme file provides a sample metering record format to submit the records to the Metering Records DynamoDB table created by the application. The below provided record format is invalid.

{
"create_timestamp": 113123,
"customerIdentifier": "ifAPi5AcF3",
"dimension_usage": [
{
"dimension": "users",
"value": 3
},
{
"dimension": "admin_users",
"value": 1
}
],
"metering_pending": "true"
}

To Reproduce
Steps to reproduce the behavior:
1.Deploy the serverless application with SaaS CCP or subscription model
2. Try to submit a dummy metering record in the format provided
3.

Expected behavior
The document should provide the correct metering record format to be accepted by the metering DynamoDB table.

Screenshots
If applicable, add screenshots to help explain your problem.
image

Desktop (please complete the following information):

  • OS: [e.g. iOS] Windows
  • Browser [e.g. chrome, safari] Firefox

Additional context
Add any other context about the problem here.

template.yaml has typo

Describe the bug
Attempt to use sam deploy failed because SQSMeteringRecrods.Arn doesn't exist. It should be SQSMeteringRecords.Arn

To Reproduce
Steps to reproduce the behavior:

  1. Follow instructions
  2. Once you get to the sam deploy step, it will fail with the following error:
    Error: Failed to create changeset for the stack: my-stack, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Template error: instance of Fn::GetAtt references undefined resource SQSMeteringRecrods

Expected behavior
It should succeed in deployment

Desktop (please complete the following information):
Using Cloud9 deployment following directions

QOL - improvement

Is your feature request related to a problem? Please describe.
The current quickstart template does not inform customers should enter a bucket with lower case characters.

Describe the solution you'd like
In the Quick-start template - s3 website bucket description should indicate that the bucket name should be lower case characters per s3 requirements.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Request to define an IAM policy for this solution

Is your feature request related to a problem? Please describe.
Please define a IAM policy that can be attached to a IAM user and provide restricted access to the seller AWS account to deploy the serverless solution.

This is a top ask from seller teams to manage their seller AWS account permissions.

SQS Infinite Loop with Empty Entitlements

Describe the bug

When the AWS Marketplace service returns empty entitlements the application errors and is thrown into an infinite loop.

To Reproduce
Steps to reproduce the behavior:

You can test this with an event that has empty entitlements:
Screen Shot 2022-08-01 at 9 13 38 AM

For a simple example. Comment out this line in entitlement-sqs.js:
const entitlementsResponse = await marketplaceEntitlementService.getEntitlements(entitlementParams).promise();

And replace it with something like:

const entitlementsResponse = {'Entitlements': []}

Then, trigger the function.

  1. The function will error as shown in the screenshot (Which happened because a response from AWS in that structure was returned when actually calling the entitlements service).

Expected behavior
Either the marketplace service API call doesn't return an empty entitlement, OR a DLQ and better error handling is added to this application so that events like this are sent to the DLQ instead of being retried.

Screenshots

Screen Shot 2022-08-01 at 8 48 43 AM

Desktop (please complete the following information):

  • OS: Mac
  • Browser: Chrome

Additional context
Also feel free to reach out: fernando.medina.corey(at)telcodr(dot)com to discuss.

Documentation issue in README

Describe the bug
Post deployment steps - Registration page is true:

Steps 2 and 3 aren't possible since 'RedirectUrl' is either not present or hard to find.

To Reproduce
Steps to reproduce the behavior:

  1. Run through steps 1-9 using 'contracts' TypeOfSaaSListing, running in CloudShell.
  2. Run Cleanup step.

Expected behavior
I'm expecting to see a 'RedirectUrl' in the list of outputs but it's not there.

Screenshots
Screenshot 2024-06-20 at 2 43 09 PM

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

SAM deployment fails when `CreateRegistrationWebPage` is set to `false`

Describe the bug
When parameter CreateRegistrationWebPage is set to false deployment fails due to the fact that the Output - LandingPageUrl references CloudfrontDistribution which is only created when CreateRegistrationWebPage is true .

To Reproduce
Deploy the app with CreateRegistrationWebPage set to false

Expected behavior
The stack will fail complaining about an unresolvable reference

Screenshots
If applicable, add screenshots to help explain your problem.
Screen Shot 2022-08-17 at 11 15 00 AM

Desktop (please complete the following information):
n/a

Smartphone (please complete the following information):
n/a

Additional context
Add any other context about the problem here.

Empty entitleResponse object within the entitlement-sqs.js script

Describe the bug
Running into a runtime error on the entitlementService script with the following log:
`2022-03-14T21:05:27.152Z 60da1f47-10a8-5a34-adc1-45eea0e044ea INFO entitlementsResponse
{}

2022-03-14T21:05:27.152Z 60da1f47-10a8-5a34-adc1-45eea0e044ea ERROR Invoke Error
{
"errorType": "TypeError",
"errorMessage": "Cannot read property '0' of undefined",
"stack": [
"TypeError: Cannot read property '0' of undefined",
" at /var/task/entitlement-sqs.js:33:67",
" at runMicrotasks ()",
" at processTicksAndRejections (internal/process/task_queues.js:97:5)",
" at async Promise.all (index 0)",
" at async Runtime.exports.handler (/var/task/entitlement-sqs.js:8:3)"
]
}`

To Reproduce
Steps to reproduce the behavior:

  1. Follow the AWS recommended quick start guide to deploy the stack
  2. Test creating a contract subscription
  3. The email to seller was never received, after investigation, determined that the entitlement-sqs.js is generating the fatal error with the log above, hence the record was never pushed onto the SNS queue.

Expected behavior
This line in the entitlement-sqs.js, const entitlementsResponse = await marketplaceEntitlementService.getEntitlements(entitlementParams).promise(); should not be returning an empty object.

Desktop (please complete the following information):

  • OS: iOS
  • Browser: chrome

Additional context
Add any other context about the problem here.

delete fails - lambda and s3

deleting gets these errors:

2021-05-20 17:28:05 UTC-0700 | ezops-saas-landing-page | DELETE_FAILED | The following resource(s) failed to delete: [LambdaEdgeRedirectPostRequests, WebsiteS3Bucket].

2021-05-20 17:28:00 UTC-0700 | LambdaEdgeRedirectPostRequests | DELETE_FAILED | Resource handler returned message: "Lambda was unable to delete arn:aws:lambda:us-east-1:865330066347:function:ezops-saas-landing-page-LambdaEdgeRedirectPostRequ-A1QyBSJhg0vw:1 because it is a replicated function. Please see our documentation for Deleting Lambda@Edge Functions and Replicas. (Service: Lambda, Status Code: 400, Request ID: 58deb957-2045-4ae0-b70a-df7de067f6ac, Extended Request ID: null)" (RequestToken: 9af66a2e-668d-959e-de3d-6012b95e0c8b, HandlerErrorCode: InvalidRequest)

2021-05-20 17:27:58 UTC-0700 | WebsiteS3Bucket | DELETE_FAILED | The bucket you tried to delete is not empty (Service: Amazon S3; Status Code: 409; Error Code: BucketNotEmpty; Request ID: FSJY3WDFDNFQK39A; S3 Extended Request ID: 9S/i72ctBdW2bXE0U+URCSLAAl0vMIIgFwRSPHi2P+YIE6oLOQhMc34HC2D6Nmvmt2DvWfPH8GE=; Proxy: null)
2021

Enable Subscription SNS topic for SaaS Contract pricing model

Is your feature request related to a problem? Please describe.
The Subscription SNS topic was not available for SaaS Contract model. This topic covers the subscription status of a marketplace customer. It is now available for all SaaS pricing models.

Describe the solution you'd like
Setup the logic to subscribe to Subscription SNS topic for SaaS contract product and send the message to the Seller via the Support SNS topic.

Additional context
https://docs.aws.amazon.com/marketplace/latest/userguide/saas-notification.html#saas-sns-subscription-message-body

Specifying a long stack name causes and error while creating the SQSMetering Queue

Describe the bug
Specifying a long stack name causes and error while creating the SQSMetering Queue

To Reproduce
Steps to reproduce the behavior:

  1. Launch the solution with a long stack name. (80 Chars)

Expected behavior
SQSMetering Queue resource fails to create.

The name of a FIFO queue can only include alphanumeric characters, hyphens, or underscores, must end with .fifo suffix and be 1 to 80 in length.

Additional context
We are consuming the project as part of an automation:
aws-ia/cloudformation-aws-marketplace-saas#6

SQS Policy code is incorrect with typos and not functional

Describe the bug
The create entitlement logic has SQSpolice instead of policy.

      - CreateEntitlementLogic
      - Statement:
        - Sid: SQSPolice <- typo 
          Effect: Allow
          Action:
            - sqs:SendMessage
          Resource: !GetAtt EntitlementSQSQueue.Arn
      - !Ref "AWS::NoValue"

ARN is used instead of Queuename:

SQSSendMessagePolicy requires a queueName.

More info here: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-template-list.html#sqs-send-message-policy

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.