亚马逊AWS官方博客

在亚马逊云科技Marketplace上的SaaS架构设计——如何支持跨多账户对接

为了给企业提供更加易用的应用层软件,越来越多的软件提供商推出了SaaS产品。亚马逊云科技Marketplace(以下简称Marketplace)是一个提供甄选的数字化产品的平台,能够帮助SaaS厂商降低销售成本,触达更多的客户,是很多SaaS厂商的首选。

通过软件即服务(SaaS)产品,您部署了在亚马逊云科技提供的基础设施上的软件,并允许买家可以直接通过Marketplace来使用您的软件。您需要在您的软件中管理客户访问、账户创建、资源配置和账户管理。

在Marketplace中上架您基于SaaS模式的软件过程中,您需要与Marketplace SaaS提供的多个API进行对接,具体对接的方式您可以参考卖家指南

在您的SaaS中,建议您将与Marketplace SaaS API进行接口集成的部分作为独立模块进行研发和管理,并运行在您的亚马逊云科技账号中。

但因为商务上的诸多因素,很多Marketplace的卖家的亚马逊云科技账号与运行SaaS系统以及对接模块的亚马逊云科技账号并不是同一个账号,而Marketplace SaaS API调用的权限仅会对作为卖家的亚马逊云科技账号打开,那该如何在SaaS架构中安全的获取Marketplace SaaS API调用权限呢?

在这篇文章中,我将介绍在多个亚马逊云科技账户中构建Marketplace SaaS的API对接的最佳实践!

 

概述

对于亚马逊云科技Marketplace中基于SaaS交付的产品中,有多种价格模型可以选择,因为本篇文章中只会涉及接口调用权限的内容,所以在下文中,将以基于订阅的价格模型作为举例。

对SaaS订阅的API、ResolveCustomer和BatchMeterUsage的调用必须由Marketplace卖家账户的凭证来进行权限的获取。这并代表着您的SaaS代码需要在Marketplace卖方账户中运行。在架构设计中,最好的方式是在一个单独的亚马逊云科技账户中管理您的生产代码,并使用跨账户角色和sts:AssumeRole来获得临时凭证,然后可以用来调用Marketplace的计量API。

 

案例背景

在本文章的举例中,有两个亚马逊云科技的账户:

亚马逊云科技Marketplace卖家账户

这是您的企业在亚马逊云科技上注册为卖家的账户。API调用必须从这个账户的相关权限验证后才能进行。

生产代码的亚马逊云科技账户

这是您的SaaS系统所运行的亚马逊云科技账户。

在最佳SaaS on Marketplace架构设计中,使用单一的账户还是多账户各有利弊,单一的亚马逊云科技账户作为Marketplace账户可以简化管理,并避免了客户在查看ISV的产品和服务时出现任何混淆。

但将卖方账户与产品账户分开意味着每个SaaS服务都可以有自己的亚马逊账户,这提供了一个良好的安全和管理边界。当一个卖家有多个产品时,可以使用多个AWS账户来进一步分离各团队的环境。

使用不同的亚马逊云科技Marketplace卖家和生产账户的情况下,有2个亚马逊云科技账户在发挥作用。注册为Marketplace卖方的AWS账户(Seller-Account)和生产代码所在的AWS账户(SaaS-Account)。

 

SaaS架构设计

卖家账户在Marketplace上进行了注册并上架了产品,所以该账户有调用计量API的权限。这时,卖家需要确认了该账户有调用Marketplace API权限后,在该账户创建一个IAM角色,在策略配置上允许访问计量API,以及从生产账户来承接该角色的服务,具体承接角色的服务可以根据您的Marketplace SaaS API对接模块的部署方式来决定。

在本文章的例子中,卖方账户中的IAM角色被称为saas-account-role。这有附加的AWSMarketplaceMeteringFullAccess管理策略。IAM角色有一个信任关系,如下所示。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam:: SaaS-Account:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "xxxxxxx"
        }
      }
    }
  ]
}

SaaS应用程序以及与Marketplace API对接的模块部署在生产账户中。该账户没有权限来调用卖家账号上架的那款产品计量API。在您的SaaS架构设计中,应该在这个账号中创建一个IAM角色以及策略,本文章中所举的例子中,与Marketplace API对接的模块部署在Amazon EC2实例中,这时您所创建的角色信任实体应该为Amazon EC2,并在策略中授予sts:AssumeRole的权限,通过EC2实例配置文件将该角色附加到运行SaaS Marketplace API对接的模块的EC2实例。这为该实例提供了临时凭证,可用于签署对亚马逊云科技API调用的请求。这些临时凭证用于调用 sts:AssumeRole 方法,该方法从卖方账户返回临时凭证。这些都是用来调用Marketplace计量API的。

执行sts:AssumeRole命令所需的权限是。

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam:: Seller-Account:role/saas-account-role"
    }
}

为了使SaaS应用程序的Marketplace API对接的模块能够对Marketplace计量API进行调用,它必须能获取并承接卖家账户中的角色。这是通过调用sts:AssumeRole方法来完成的。如果成功的话,这个调用会返回临时凭证(秘密/访问密钥)。然后,这些凭证可以用来调用计量API。

下面的代码片段显示了您如何调用 assume_role函数来获得卖方账户的临时凭证,该片段为Python代码,其他语言的代码可以参考不同语言的API文档。

import boto3

sts_client = boto3.client('sts')

assumedRoleObject = sts_client.assume_role(
    RoleArn="arn:aws:iam::Seller-Account:role/saas-account-role ",
    RoleSessionName="AssumeRoleSession1",
    ExternalId="xxxxxxx")

credentials = assumedRoleObject['Credentials']

client = boto3.client('marketplace-metering','us-east-1', 
    aws_access_key_id = credentials['AccessKeyId'], 
    aws_secret_access_key=credentials['SecretAccessKey'], 
    aws_session_token = credentials['SessionToken'])

至此,您的应用程序模块初始化的客户端将会具备调用卖家账户的Marketplace API权限,您可以根据您卖家账户上架的产品id,直接进行多个API的调用以完成与Marketplace的集成。

 

总结

该文章中说明了在SaaS架构设计中,如何在多账号的背景下安全的获得Marketplace API的权限并独立分离卖家账号与SaaS应用程序账号,请尽可能的避免直接在卖家账号中创建用户,并将用户的身份凭证以明文的方式永久的配置在您的应用程序中。

 

本篇作者

张明月

合作伙伴解决方案架构师