亚马逊AWS官方博客

在中国区构建自动、弹性、安全的多账号体系——账号自动创建和初始化

为什么AWS推荐多账号架构?

在客户构建和部署工作负载时,他们往往需要某种机制来隔离其资源,这种隔离可以通过多个 AWS 账户来实现。一个 AWS 账户为您的 AWS 资源提供天然的安全性,访问权限和计费边界,并使您能够实现资源的独立性和隔离性。例如,默认情况下,您帐户以外的用户无权访问您的资源。同样,您消耗的 AWS 资源成本按照您的账户分摊。尽管您可能只用一个帐户开始 AWS 之旅,但随着工作负载的大小和复杂性增加,AWS 建议您设置多个帐户。使用多帐户环境是一种最佳做法,它具有以下优点:

  • 具有各种要求的快速创新:您可以将 AWS 账户分配给公司内的不同团队,项目或产品。独立的帐户提供了一种快速创新的机制,同时可以满足独特的安全要求。
  • 简化的账单:使用多个 AWS 账户可以帮助您确定哪个产品或服务线承担的花费,从而简化您分配 AWS 成本的方式。
  • 灵活的安全控制:您可以使用多个 AWS 账户来隔离具有特定安全要求或必须满足严格合规性准则的工作负载或应用程序,例如等保或 PCI DSS。
  • 轻松适应业务流程:您可以轻松地组织多个 AWS 账户,以最能反映公司业务流程的各种需求,例如不同的运营,法规和预算要求。

今天,许多大型企业已经普遍采用了多账号的公有云登录区(Landing Zone)设计,有些企业甚至有超过100个AWS中国区账号。那么,您可以会有顾虑,多账号的模式是否会对我们的运维和安全管理难度带来挑战?

 

中国区现状

如果您的业务在AWS海外区域,那么AWS原生服务Control Tower 可以帮助客户自动化的设置基准环境或登录区。深入的Control Tower介绍,详见https://thinkwithwp.com/cn/controltower/。然而,截止到作者撰写本博客时,AWS中国区尚未发布Control Tower这项AWS原生服务。于此同时,一些海外登录区Landing Zone的关键服务也尚未就绪,例如Organization下的资源控制策略(SCP,Service Control Policies),集中管理用户的账号访问AWS Single Sign-On等。作为这一系列的第一篇,本文讲向大家介绍如何利用AWS中国区现有的资源,来构建中国区“Control Tower”,实现多账号架构下登录区的账号自动创建和初始化。

 

设计思路

2020年6月24日,AWS Organization正式在中国区域推出(参考https://thinkwithwp.com/cn/about-aws/whats-new/2020/06/aws-organizations-is-now-available-in-the-aws-china-regions/)。有了这项服务,我们能够通过AWS API来创建新的AWS账号。在新账号创建的同时,我们还可以定义在新账号中产生一个角色,默认为“OrganizationAccountAccessRole”。通过这个角色,任何Organization Management主账号的身份可以通过跨账号assume role登录到新创建的账号,并获得管理员权限。我们可以通过这条路径,向新创建的子账号部署一个CloudFormation stack作为bootstrap启动脚本,创建我们需要的账号初始化资源。通常的登录区配置包括VPC及网络,IAM及联合身份认证,CloudTrail和Config安全日志,费用及预算管理,Security Hub等安全配置,监控与报警,等等。您可以根据自己的需求定制各类Template模版。

 

一些限制因素

但是在实践过程中,我们也发现了一些限制因素,其中最主要的包括:

  • 截止到作者撰写本博客时,中国区Organization不支持修改账号名称。这也就意味着除了在创建账号的时候输入账号名称,后续您将无法修改它。

解决方案:我们可以使用DynamoDB,额外记录所有账号的信息作为账号清单。

  • 截止到作者撰写本博客时,中国区S3桶策略中的条件(Condition)”aws:PrincipalOrgID”不生效。而我们希望存放在存储桶中的联合认证SAML Metadata文件仅允许自己Organization中的账号来访问。

解决方案:通过自动化的方式,在S3桶策略的条件”aws:PrincipalAccount”逐条加入账号ID来实现。

  • 当通过Organization API创建出账号后,虽然得到了账号ID并成功Assume Role登录该新账号。但是仍需要等待一段时间才能够部署CloudFormation Stack,这个时间大概在3-10分钟左右。如果都在一个Lambda中实现整个流程,可能会超时。Lambda最长Timeout仅可配置15分钟。

解决方案:引入AWS原生服务Step Functions来实现异常处理和等待重试。

 

流程图

以下是账号创建和初始化的流程图

  1. 通过Step Functions触发第一个创建账号Lambda Function。该Lambda Functions将:
  • 根据输入的账号名称、邮箱地址、OU名称,通过AWS Organization API创建全新的AWS账号,并将该账号移动到对应的OU中。
  • 将新账号ID更新到联合认证Metadata文件桶策略中,以便后续脚本可以下载该文件本地部署SAML配置。
  • 更新账号信息到主账号DynamoDB table中作为账号清单。
  1. 等待60秒;
  2. 进入第二个部署账号Lambda Function。注意,尽管我们等待了60秒后台准备账号,这里仍然会遇到部署CloudFormation Stack失败的情况,因此此处设置了Retry,一般3-10分钟内账号可以准备就绪,请耐心等待。在这个Lambda Function中,将:
  • 从本地S3桶中,获取需要部署到新账号的CloudFormation模版template;
  • 通过Assume Role的方式,Lambda获取新账号的临时Access Key,Secret Key以及一个token;
  • 根据template模版,Lambda创建部署CloudFormation Stack;
  • CloudFormation在新账号内部署相关登录区资源;
  • Lambda call API修改账号昵称。
  1. 初始化完毕。

 

安装

账号的创建依赖于AWS Organization。因此在开始前,请确认您已经开启的AWS Organization。您可以参考(https://docs.amazonaws.cn/organizations/latest/userguide/orgs_manage_create.html)。

为了实现上述流程图中的任务,我们需要至少在主账号上部署2个Lambda Function,一些S3存储桶,一张DynamoDB表,以及一个Step Functions State Machine,以及他们对应的一些IAM角色、策略、日志等。整个部署将通过CloudFormation脚本来完成。

前提条件

准备工作

该工具需要被安装在Organization主账号!!!

  1. 克隆Repository

https://github.com/jamniel/AWSChinaCreateAccount

 

  1. 创建Lambda Zip文件存储桶

在开始部署CloudFormation前,您首先需要上传Lambda函数zip文件到特定的S3存储桶中。因此在这里,我将新建一个S3存储桶来存放这些Lambda函数zip文件。当然,您也可以使用现有的S3存储桶。

aws s3api create-bucket --bucket $YOUR_LAMBDA_ZIP_BUCKET_NAME \
    --region cn-north-1 --create-bucket-configuration LocationConstraint=cn-north-1 
    --profile $Your_Profile

 

  1. 启用Block Public Access
aws s3api put-public-access-block \
    --bucket $YOUR_LAMBDA_ZIP_BUCKET_NAME \
    --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true" \
    --profile $Your_Profile

 

 

  1. 设置Server端加密
aws s3api put-bucket-encryption \
    --bucket $YOUR_LAMBDA_ZIP_BUCKET_NAME \
    --server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}' \
    --profile $Your_Profile

 

 

  1. 启动版本控制
aws s3api put-bucket-versioning --bucket $YOUR_LAMBDA_ZIP_BUCKET_NAME \
    --versioning-configuration Status=Enabled --profile $Your_Profile

 

  1. 上传Lambda函数zip文件
aws s3api put-object --bucket $YOUR_LAMBDA_ZIP_BUCKET_NAME \
    --key lambda_create_account.zip --body lambda_create_account.zip \
    --server-side-encryption AES256 --profile $Your_Profile

 

aws s3api put-object --bucket $YOUR_LAMBDA_ZIP_BUCKET_NAME \
    --key lambda_deploy_account.zip --body lambda_deploy_account.zip \
    --server-side-encryption AES256 --profile $Your_Profile

 

安装工具

  1. 定义CloudFormation参数输入文件json
Key 说明
InitialS3BucketName S3存储桶,用来存储需要部署到新账号的CloudFormation模版
ToolInstallS3Bucket S3存储桶,用来存储之前上传的Lambda函数zip文件
SAMLMetadataS3BucketName S3存储桶,用来存储SAML联合认证的IdP metadata xml文件(按需)

 

  1. 使用CloudFormation在主账号部署该账号创建工具
aws cloudformation create-stack --stack-name account-provision-toolkit \
    --template-body file://AccountCreationToolkitInstall.yml \
    --parameters file://parameters.json --capabilities CAPABILITY_NAMED_IAM \
    --region=cn-north-1 --profile $Your_Profile

 

  1. 上传账号初始化需要部署的Cloudformation模版到InitialS3BucketName对应的存储桶中。这个Repo中存在一个yml的模版。请根据自己的需求定义模版中的需要创建的资源。
aws s3api put-object --bucket $InitialS3BucketName \
    --key AccountInitial.yml --body AccountInitial.yml \
    --server-side-encryption AES256 --profile $Your_Profile

 

  1. 如果您有SAML联合认证,请将从IdP处下载的SAML metadata 文件上传至SAMLMetadataS3BucketName对应的存储桶。

 

使用

需要创建账号时,您只需要触发相应的Step Functions state machine即可。

aws stepfunctions start-execution \
  --state-machine-arn arn:aws-cn:states:cn-north-1:$YOUR_MANAGEMENT_ACCOUNT_ID:stateMachine:AccountInitialStateMachine \
  --input "{\"account_name\": \"$ACCOUNT_NAME\", \"account_email\": \"$ACCOUNT_EMAIL\", \"ou_name\": \"$OU_NAME\"}" \
  --profile $Your_Profile \
  --region cn-north-1

 

 

结束语

您也许已经意识到,创建账号只是AWS登陆区设计的第一步。如何在没有资源控制策略(SCP)的前提下在中国区实现安全护栏?如何对部署的登陆区资源进行日常更新维护?如何和公司的AD或者Azure AD进行联合身份认证?笔者会在此系列的后续博客中,向您介绍如何使用AWS IAM的Permission Boundary来实现安全护栏,如何将登陆区的构建同客户的CI/CD流水线相结合,如何集成联合认证实现SSO等。– Stay tuned.

本篇作者

陈晓东

亚马逊 AWS 专业服务团队资深云安全顾问。负责企业级客户的云安全咨询、安全架构设计和技术实施。在信息安全领域拥有多年架构设计、运维、咨询和团队管理经验,对公有云安全、DevSecOps、风险管理等有深入的研究和热情。