在 Amazon Web Services account 间自动复制 Amazon RDS 实例 - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 Amazon Web Services account 间自动复制 Amazon RDS 实例

由 Parag Nagwekar (AWS) 和 Arun Chandapillai (AWS) 编写

环境:生产

技术:数据库;;无服务器 DevOps;基础架构

工作负载:所有其他工作负载

Amazon Web Services:AWS Lambda、Amazon RDS、适用于 Python 的 Amazon SDK (Boto3)、AWS Step Functions、Amazon SNS

Summary

此模式向您展示如何使用 AWS Step Functions 和 AWS Lambda 自动执行跨不同 Amazon Web Services account 复制、跟踪和回滚 Amazon Relational Database Service (Amazon RDS) 数据库实例的过程。您可以使用此自动化来执行 RDS 数据库实例的大规模复制,而不会影响性能或运营开销 - 无论您的组织规模如何。您还可以使用这种模式来帮助您的组织遵守强制性的数据治理策略或合规要求,这些策略或合规要求在不同的 Amazon Web Services account 和 AWS 区域之间复制和冗余您的数据。大规模 Amazon RDS 数据的跨账户复制是低效且容易出错的手动过程,可能成本高昂且耗时,但此模式中的自动化可以帮助您安全、有效且高效地实现跨账户复制。

先决条件和限制

先决条件

  • 两个 Amazon Web Services account。

  • 在源 Amazon Web Services account 中启动和运行的 RDS 数据库实例

  • 目标 Amazon Web Services account 中 RDS 数据库实例子网组

  • 在源 Amazon Web Services account 中创建并与目标账户共享的 AWS Key Management Service (AWS KMS) 密钥(有关策略详细信息,请参阅此模式的其他信息部分。)

  • 目标 Amazon Web Services account 中的 AWS KMS 密钥,用于加密目标账户的数据库

产品版本

  • Python 3.9(使用 AWS Lambda)

  • PostgreSQL 11.3、13.x 和 14.x

架构

技术堆栈

  • Amazon Relational Database Service(Amazon RDS)

  • Amazon Simple Notification Service (Amazon SNS)

  • AWS Key Management Service (AWS KMS)

  • AWS Lambda

  • AWS Secrets Manager

  • AWS Step Functions

目标架构

下图显示了一种架构,用于使用 Step Functions 编排 RDS 数据库实例从源账户(账户 A)到目标账户(账户 B)的定时按需复制。

在源账户(图中的账户 A)中,Step Functions 状态机执行以下操作:

  1. 从账户 A 的 RDS 数据库实例创建快照

  2. 使用账户 A 中的 AWS KMS 密钥复制并加密快照。为了确保传输过程中的加密,无论数据库实例是否加密,快照都会被加密。

  3. 通过授予账户 B 对快照的访问权限,与账户 B 共享数据库快照。

  4. 向 SNS 主题推送通知,然后 SNS 主题调用账户 B 中的 Lambda 函数。

在目标账户(图中的账户 B)中,Lambda 函数运行 Step Functions 状态机来编排以下内容:

  1. 将共享快照从账户 A 复制到账户 B,同时使用账户 A 中的 AWS KMS 密钥首先解密数据,然后使用账户 B 中的 AWS KMS 密钥加密数据。

  2. 从 Secrets Manager 中读取密钥,以捕获当前数据库实例的名称。

  3. 使用新名称和 Amazon RDS 的默认 AWS KMS 密钥,从快照中恢复数据库实例。

  4. 读取新数据库的端点并使用新的数据库端点更新 Secrets Manager 中的密钥,然后为以前的数据库实例添加标签,以便日后将其删除。

  5. 保留数据库最新 N 个实例,并删除所有其他实例。

工具

AWS 工具

  • Amazon Relational Database Service (Amazon RDS) 可帮助您在 Amazon Web Services Cloud 中设置、操作和扩展关系数据库。

  • Amazon Simple Notification Service (Amazon SNS) 可帮助您协调和管理发布者与客户端(包括 Web 服务器和电子邮件地址)之间的消息交换。

  • AWS CloudFormation 可帮助您设置 AWS 资源,快速一致地配置这些资源,并在 AWS 账户和区域的整个生命周期中对其进行管理。

  • AWS Key Management Service (AWS KMS) 可帮助您创建和控制加密密钥,以帮助保护您的数据。

  • AWS Lambda 是一项计算服务,可帮助您运行代码,而无需预置或管理服务器。它仅在需要时运行您的代码,并且能自动扩缩,因此您只需为使用的计算时间付费。

  • 适用于 Python 的 Amazon SDK (Boto3) 是一款软件开发套件,可帮助您将 Python 应用程序、库或脚本与 Amazon Web Services 集成。

  • AWS Secrets Manager 帮助您将代码中的硬编码凭证(包括密码)替换为对 Secrets Manager 的 API 调用,以便以编程方式检索密钥。

  • AWS Step Functions 是一项无服务器编排服务,可帮助您搭配使用 Lambda 函数和其他服务来构建业务关键型应用程序。

代码

此模式的代码可在 GitHub 跨账户 RDS 复制存储库中找到。

操作说明

任务描述所需技能

在源账户中部署 CloudFormation 堆栈。

  1. 登录源账户(账户 A)的 AWS 管理控制台并打开CloudFormation 控制台

  2. 在导航窗格中,选择 Stacks(堆栈)

  3. 选择创建堆栈,然后选择使用现有的资源(导入资源)

  4. 识别资源页面,选择下一步

  5. Select Template(选择模板)页面上,选择 Upload a template(上传模板)

  6. 选择 “选择文件”,从 “ GitHub 跨账户 RDS 复制” 存储库中选择Cloudformation-SourceAccountRDS.yaml文件,然后选择 “下一步”。

  7. 堆栈名称中,输入资源堆栈的名称。

  8. Parameters(参数)部分中,指定在堆栈模板中定义的以下参数:

    • 对于 DestinationAccountNumber,输入您的目标 RDS 数据库实例的账号。

    • 对于 KeyName,请输入您的 AWS KMS 密钥。

    • 对于 ScheduleExpression,输入 cron 表达式(默认值为每天上午 12:00)。

    • 对于 SourceDBIdentifier,输入数据库来源的描述。

    • 对于 SourceDB SnapshotName,请输入快照的名称或接受默认名称。

  9. 选择 Next(下一步)。

  10. 配置堆栈选项页面上,保留默认设置,然后选择下一步

  11. 查看集合配置并选择 Submit(提交)。

  12. 选择堆栈资源选项卡,然后记下 SNS 主题的 Amazon 资源名称(ARN)。

云管理员、云架构师

在目标账户中部署 CloudFormation 堆栈。

  1. 登录目标账户(账户 B)的 AWS 管理控制台并打开CloudFormation 控制台

  2. 在导航窗格中,选择 Stacks(堆栈)

  3. 选择创建堆栈,然后选择使用现有的资源(导入资源)

  4. 识别资源页面,选择下一步

  5. Select Template(选择模板)页面上,选择 Upload a template(上传模板)

  6. 选择文件,从 GitHub 跨账户 RDS 复制存储库中选择Cloudformation-DestinationAccountRDS.yaml文件,然后选择下一步

  7. 堆栈名称中,输入资源堆栈的名称。

  8. Parameters(参数)部分中,指定在堆栈模板中定义的以下参数:

    • 对于 DatabaseName,输入数据库的名称。

    • 引擎,输入与源数据库匹配的数据库引擎类型。

    • 对于 DB InstanceClass,请输入首选数据库实例类型或接受默认值。

    • 子网组,请输入现有 VPC 子网组。有关创建子网组的说明,请参阅 Amazon RDS 用户指南中的步骤 2:创建数据库子网组

    • 对于 SecretName,请输入路径和密钥名称,或者接受默认值。

    • SGID,请输入目标集群的安全组 ID。

    • KMSKey,请输入目标账户中 KMS 密钥的 ARN。

    • 对于 NoOfOlderInstances,输入要为回滚保留的 RDS 数据库实例的旧副本数量。

  9. 选择 Next(下一步)。

  10. 配置堆栈选项页面上,保留默认设置,然后选择下一步

  11. 查看集合配置并选择 Submit(提交)。

  12. 选择堆栈的资源选项卡,记下其物理 ID 和 InvokeStepFunction ARN。

云架构师、 DevOps 工程师、云管理员

验证目标账户中是否创建了 RDS 数据库实例。

  1. 登录 AWS 管理控制台并打开 Amazon RDS 控制台

  2. 在导航窗格中,选择数据库,然后验证新 RDS 数据库实例是否出现在新集群下。

云管理员、云架构师、 DevOps 工程师

将 Lambda 函数订阅至 SNS 主题。

您必须运行以下 AWS 命令行界面(AWS CLI)命令才能将目标账户(账户 B)中的 Lambda 函数订阅源账户(账户 A)中的 SNS 主题。

在账户 A 中,运行以下命令:

aws sns add-permission \ --label lambda-access --aws-account-id <DestinationAccount> \ --topic-arn <Arn of SNSTopic > \ --action-name Subscribe ListSubscriptionsByTopic

在账户 B 中,运行以下命令:

aws lambda add-permission \ --function-name <Name of InvokeStepFunction> \ --source-arn <Arn of SNSTopic > \ --statement-id function-with-sns \ --action lambda:InvokeFunction \ --principal sns.amazonaws.com

在账户 B 中,运行以下命令:

aws sns subscribe \ --protocol "lambda" \ --topic-arn <Arn of SNSTopic> \ --notification-endpoint <Arn of InvokeStepFunction>
云管理员、云架构师、数据库管理员

将源账户中的 RDS 数据库实例与目标账户同步。

通过在源账户中启动 Step Functions 状态机,启动按需数据库复制。

  1. 打开 Step Functions 控制台

  2. 在导航窗格中,选择状态管理器

  3. 选择状态机。

  4. 执行选项卡,选择您的函数,然后选择开始执行以启动工作流。

注意:调度程序可帮助您按计划自动运行复制,但默认情况下调度程序处于关闭状态。您可以在目标账户 CloudFormation 堆栈的 “资源” 选项卡中找到计划程序的 Amazon CloudWatch 规则名称。有关如何修改 CloudWatch 事件规则的说明,请参阅 CloudWatch 用户指南中的删除或禁用 CloudWatch 事件规则

云架构师、 DevOps 工程师、云管理员

需要时,可以将数据库回滚至之前的任何副本。

  1. 打开 Secrets Manager 控制台

  2. 从密钥列表中,选择您之前使用 CloudFormation 模板创建的密钥。您的应用程序使用该密钥来访问目标集群中的数据库。

  3. 在秘密详细信息页面上的秘密值部分中,选择检索秘密值,然后选择编辑

  4. 输入数据库端点详细信息。

云管理员、数据库管理员、工程师 DevOps

相关资源

其他信息

您可以使用以下示例策略,在 Amazon Web Services account 之间共享您的 AWS KMS 密钥。

{ "Version": "2012-10-17", "Id": "cross-account-rds-kms-key", "Statement": [ { "Sid": "Enable user permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<SourceAccount>:root" }, "Action": "kms:*", "Resource": "*" }, { "Sid": "Allow administration of the key", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<DestinationAccount>:root" }, "Action": [ "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*", "kms:Update*", "kms:Revoke*", "kms:Disable*", "kms:Get*", "kms:Delete*", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion" ], "Resource": "*" }, { "Sid": "Allow use of the key", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::<DestinationAccount>:root", "arn:aws:iam::<SourceAccount>:root" ] }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey", "kms:CreateGrant" ], "Resource": "*" } ] }