跨 AWS 账户访问 DAX - Amazon DynamoDB
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

跨 AWS 账户访问 DAX

假设您的一个 DynamoDB Accelerator (DAX) 集群在一个 AWS 账户(账户 A)中运行,并且需要能够从另一个 AWS 账户(账户 B)中的 Amazon Elastic Compute Cloud (Amazon EC2) 实例访问 DAX 集群。在本教程中,您可以通过使用账户 B 中的 IAM 角色启动账户 B 中的 EC2 实例来做到这一点。然后,您可以使用 EC2 实例中的临时安全凭证来代入账户 A 中的 IAM 角色。最后,您可以通过代入账户 A 中的 IAM 角色来使用临时安全凭证,以通过与账户 A 中的 DAX 集群的Amazon VPC 对等连接来进行应用程序调用。要执行这些任务,您将需要两个 AWS 账户中的管理访问权限。

设置 IAM

  1. 使用以下内容创建一个名为 AssumeDaxRoleTrust.json 的文本文件,这将允许 Amazon EC2 代表您工作。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
  2. 在账户 B 中,创建一个 Amazon EC2 可在启动实例时使用的角色。

    aws iam create-role \ --role-name AssumeDaxRole \ --assume-role-policy-document file://AssumeDaxRoleTrust.json
  3. 使用以下内容创建一个名为 AssumeDaxRolePolicy.json 的文本文件,从而允许在账户 B 中的 EC2 实例上运行的代码代入账户 A 中的 IAM 角色。将 accountA 替换为账户 A 的实际 ID。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::accountA:role/DaxCrossAccountRole" } ] }
  4. 将该策略添加到您刚刚创建的角色。

    aws iam put-role-policy \ --role-name AssumeDaxRole \ --policy-name AssumeDaxRolePolicy \ --policy-document file://AssumeDaxRolePolicy.json
  5. 创建实例配置文件以允许实例使用该角色。

    aws iam create-instance-profile \ --instance-profile-name AssumeDaxInstanceProfile
  6. 将该角色与实例配置文件关联。

    aws iam add-role-to-instance-profile \ --instance-profile-name AssumeDaxInstanceProfile \ --role-name AssumeDaxRole
  7. 使用以下内容创建一个名为 DaxCrossAccountRoleTrust.json 的文本文件,这将允许账户 B 代入账户 A 角色。将 accountB 替换为账户 B 的实际 ID。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::accountB:role/AssumeDaxRole" }, "Action": "sts:AssumeRole" } ] }
  8. 在账户 A 中,创建账户 B 可代入的角色。

    aws iam create-role \ --role-name DaxCrossAccountRole \ --assume-role-policy-document file://DaxCrossAccountRoleTrust.json
  9. 创建一个名为 DaxCrossAccountPolicy.json 的文本文件来允许访问 DAX 集群。将 dax-cluster-arn 替换为 DAX 集群的正确 Amazon 资源名称 (ARN)。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dax:GetItem", "dax:BatchGetItem", "dax:Query", "dax:Scan", "dax:PutItem", "dax:UpdateItem", "dax:DeleteItem", "dax:BatchWriteItem", "dax:ConditionCheckItem", "dax:DefineAttributeList", "dax:DefineAttributeListId", "dax:DefineKeySchema", "dax:Endpoints" ], "Resource": "dax-cluster-arn" } ] }
  10. 在账户 A 中,将策略添加到角色。

    aws iam put-role-policy \ --role-name DaxCrossAccountRole \ --policy-name DaxCrossAccountPolicy \ --policy-document file://DaxCrossAccountPolicy.json

设置 VPC

  1. 查找账户 A 的 DAX 集群的子网组。将 cluster-name 替换为账户 B 必须访问的 DAX 集群的名称。

    aws dax describe-clusters \ --cluster-name cluster-name --query 'Clusters[0].SubnetGroup'
  2. 使用该 subnet-group 来查找集群的 VPC。

    aws dax describe-subnet-groups \ --subnet-group-name subnet-group \ --query 'SubnetGroups[0].VpcId'
  3. 使用该 vpc-id 来查找 VPC 的 CIDR。

    aws ec2 describe-vpcs \ --vpc vpc-id \ --query 'Vpcs[0].CidrBlock'
  4. 从账户 B 中,使用与上一步中找到的 CIDR 不重叠的其他 CIDR 创建 VPC。然后,创建至少一个子网。您可以使用 AWS 管理控制台中的 VPC 创建向导AWS CLI

  5. 从账户 B 中,请求与账户 A VPC 的对等连接,如创建并接受 VPC 对等连接中所述。从账户 A 中,接受连接。

  6. 从账户 B 中,查找新 VPC 的路由表。将 vpc-id 替换为您在账户 B 中创建的 VPC 的 ID。

    aws ec2 describe-route-tables \ --filters 'Name=vpc-id,Values=vpc-id' \ --query 'RouteTables[0].RouteTableId'
  7. 添加一条路由,以将发送到账户 A 的 CIDR 的流量发送到 VPC 对等连接。请记住,将每个用户输入占位符替换为您帐户的正确值。

    aws ec2 create-route \ --route-table-id accountB-route-table-id \ --destination-cidr accountA-vpc-cidr \ --vpc-peering-connection-id peering-connection-id
  8. 在账户 A 中,使用之前找到的 vpc-id 查找 DAX 集群的路由表。

    aws ec2 describe-route-tables \ --filters 'Name=vpc-id, Values=accountA-vpc-id' \ --query 'RouteTables[0].RouteTableId'
  9. 在账户 A 中,添加一条路由以将发送到账户 B 的 CIDR 的流量发送到 VPC 对等连接。将每个用户输入占位符替换为您账户的正确值。

    aws ec2 create-route \ --route-table-id accountA-route-table-id \ --destination-cidr accountB-vpc-cidr \ --vpc-peering-connection-id peering-connection-id
  10. 从账户 B 中,在您之前创建的 VPC 中启动 EC2 实例。为它提供 AssumeDaxInstanceProfile。您可以使用 AWS 管理控制台中的启动向导AWS CLI。记下实例的安全组。

  11. 在账户 A 中,查找 DAX 集群使用的安全组。请记住将 cluster-name 替换为您的 DAX 集群的名称。

    aws dax describe-clusters \ --cluster-name cluster-name \ --query 'Clusters[0].SecurityGroups[0].SecurityGroupIdentifier'
  12. 更新 DAX 集群的安全组,以允许来自您在账户 B 中创建的 EC2 实例安全组的入站流量。请记住将用户输入占位符替换为您账户的正确值。

    aws ec2 authorize-security-group-ingress \ --group-id accountA-security-group-id \ --protocol tcp \ --port 8111 \ --source-group accountB-security-group-id \ --group-owner accountB-id

此时,账户 B 的 EC2 实例上的应用程序可以使用实例配置文件来代入 arn:aws:iam::accountA-id:role/DaxCrossAccountRole 角色和使用 DAX 集群。

修改 DAX 客户端以允许跨账户访问

注意

AWS Security Token Service (AWS STS) 凭证是临时凭证。一些客户端会自动处理刷新,而其他客户端则需要额外的逻辑才能刷新凭证。建议您遵循相应文档的指导信息。

Java

此部分帮助您修改现有的 DAX 客户端代码以允许跨账户 DAX 访问。如果您没有 DAX 客户端代码,则可在Java 和 DAX教程中查找工作代码示例。

  1. 添加以下导入。

    import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider; import com.amazonaws.services.securitytoken.AWSSecurityTokenService; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
  2. 从 DAX 中获取凭证提供程序并创建 AWS STS 客户端对象。请记住,将每个用户输入占位符替换为您帐户的正确值。

    AWSSecurityTokenService awsSecurityTokenService = AWSSecurityTokenServiceClientBuilder .standard() .withRegion(region) .build(); STSAssumeRoleSessionCredentialsProvider credentials = new STSAssumeRoleSessionCredentialsProvider.Builder("arn:aws:iam::accountA:role/RoleName", "TryDax") .withStsClient(awsSecurityTokenService) .build(); DynamoDB client = AmazonDaxClientBuilder.standard() .withRegion(region) .withEndpointConfiguration(dax_endpoint) .withCredentials(credentials) .build();
.NET

此部分帮助您修改现有的 DAX 客户端代码以允许跨账户 DAX 访问。如果您没有 DAX 客户端代码,则可在.NET 和 DAX教程中查找工作代码示例。

  1. AWSSDK.SecurityToken NuGet 程序包添加到解决方案。

    <PackageReference Include="AWSSDK.SecurityToken" Version="latest version" />
  2. 使用 SecurityTokenSecurityToken.Model 程序包。

    using Amazon.SecurityToken; using Amazon.SecurityToken.Model;
  3. AmazonSimpleTokenService 中获取临时凭证并创建 ClusterDaxClient 对象。请记住,将每个用户输入占位符替换为您帐户的正确值。

    IAmazonSecurityTokenService sts = new AmazonSecurityTokenServiceClient(); var assumeRoleResponse = sts.AssumeRole(new AssumeRoleRequest { RoleArn = "arn:aws:iam::accountA:role/RoleName", RoleSessionName = "TryDax" }); Credentials credentials = assumeRoleResponse.Credentials; var clientConfig = new DaxClientConfig(dax_endpoint, port) { AwsCredentials = assumeRoleResponse.Credentials }; var client = new ClusterDaxClient(clientConfig);
Go

此部分帮助您修改现有的 DAX 客户端代码以允许跨账户 DAX 访问。如果您没有 DAX 客户端代码,则可查找 GitHub 上的工作代码示例

  1. 导入 AWS STS 和会话程序包。

    import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" "github.com/aws/aws-sdk-go/aws/credentials/stscreds" )
  2. AmazonSimpleTokenService 中获取临时凭证并创建 DAX 客户端对象。请记住,将每个用户输入占位符替换为您帐户的正确值。

    sess, err := session.NewSession(&aws.Config{ Region: aws.String(region)}, ) if err != nil { return nil, err } stsClient := sts.New(sess) arp := &stscreds.AssumeRoleProvider{ Duration: 900 * time.Second, ExpiryWindow: 10 * time.Second, RoleARN: "arn:aws:iam::accountA:role/role_name", Client: stsClient, RoleSessionName: "session_name", }cfg := dax.DefaultConfig() cfg.HostPorts = []string{dax_endpoint} cfg.Region = region cfg.Credentials = credentials.NewCredentials(arp) daxClient := dax.New(cfg)
Python

此部分帮助您修改现有的 DAX 客户端代码以允许跨账户 DAX 访问。如果您没有 DAX 客户端代码,则可在Python 和 DAX教程中查找工作代码示例。

  1. 导入 boto3

    import boto3
  2. sts 中获取临时凭证并创建 AmazonDaxClient 对象。请记住,将每个用户输入占位符替换为您帐户的正确值。

    sts = boto3.client('sts') stsresponse = sts.assume_role(RoleArn='arn:aws:iam::accountA:role/RoleName',RoleSessionName='tryDax') credentials = botocore.session.get_session()['Credentials'] dax = amazondax.AmazonDaxClient(session, region_name=region, endpoints=[dax_endpoint], aws_access_key_id=credentials['AccessKeyId'], aws_secret_access_key=credentials['SecretAccessKey'], aws_session_token=credentials['SessionToken']) client = dax
Node.js

此部分帮助您修改现有的 DAX 客户端代码以允许跨账户 DAX 访问。如果您没有 DAX 客户端代码,则可在Node.js 和 DAX教程中查找工作代码示例。请记住,将每个用户输入占位符替换为您帐户的正确值。

const AmazonDaxClient = require('amazon-dax-client'); const AWS = require('aws-sdk'); const region = 'region'; const endpoints = [daxEndpoint1, ...]; const getCredentials = async() => { return new Promise((resolve, reject) => { const sts = new AWS.STS(); const roleParams = { RoleArn: 'arn:aws:iam::accountA:role/RoleName', RoleSessionName: 'tryDax', }; sts.assumeRole(roleParams, (err, session) => { if(err) { reject(err); } else { resolve({ accessKeyId: session.Credentials.AccessKeyId, secretAccessKey: session.Credentials.SecretAccessKey, sessionToken: session.Credentials.SessionToken, }); } }); }); }; const createDaxClient = async() => { const credentials = await getCredentials(); const daxClient = new AmazonDaxClient({endpoints: endpoints, region: region, accessKeyId: credentials.accessKeyId, secretAccessKey: credentials.secretAccessKey, sessionToken: credentials.sessionToken}); return new AWS.DynamoDB.DocumentClient({service: daxClient}); }; createDaxClient().then((client) => { client.get(...); ... }).catch((error) => { console.log('Caught an error: ' + error); });