本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
跨 AWS 帳戶存取 DAX
假設有一個 DynamoDB Accelerator (DAX) 叢集在一個 AWS 帳戶 (帳戶 A) 中執行,且 DAX 叢集需要從另一個 AWS 帳戶 (帳戶 B) 中的 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體存取。在本教學課程中,您使用來自帳戶 B 的 IAM 角色在帳戶 B 中啟動 EC2 執行個體,然後使用 EC2 執行個體的臨時安全登入資料來擔任帳戶 A 的 IAM 角色。最後,您使用在帳戶 A 中擔任 IAM 角色的臨時安全登入資料,透過 Amazon VPC 對等連線對帳戶 A 中的 DAX 叢集進行應用程式呼叫。為了執行這些工作,您在兩個 AWS
帳戶中都需要具備系統管理存取權。
 DAX 叢集無法從其他帳戶存取 DynamoDB 資料表。
 
        設定 IAM 
        - 
                
使用下列內容建立名為 AssumeDaxRoleTrust.json 的文字檔案,這可讓 Amazon EC2 代表您工作。
                
    - JSON
 - 
            
     
         
        - 
             
                
                
{
    "Version": "2012-10-17"		 	 	 ,
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
             
         
    
 
         
             - 
                
在帳戶 B 中,建立 Amazon EC2 可在啟動執行個體時使用的角色。
                aws iam create-role \
    --role-name AssumeDaxRole \
    --assume-role-policy-document file://AssumeDaxRoleTrust.json
             - 
                
使用下列內容建立名為 AssumeDaxRolePolicy.json 的文字檔案,這會允許在帳戶 B 中的 EC2 執行個體上執行的程式碼擔任帳戶 A 中的 IAM 角色。將 accountA 取代為帳戶 A 的實際 ID。
                
    - JSON
 - 
            
     
         
        - 
             
                
                
{
    "Version": "2012-10-17"		 	 	 ,
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::111122223333:role/DaxCrossAccountRole"
        }
    ]
}
             
         
    
 
         
             - 
                
將該政策新增至您剛建立的角色。
                aws iam put-role-policy \
    --role-name AssumeDaxRole \
    --policy-name AssumeDaxRolePolicy \
    --policy-document file://AssumeDaxRolePolicy.json
             - 
                
建立執行個體描述檔以允許執行個體使用該角色。
                aws iam create-instance-profile \
    --instance-profile-name AssumeDaxInstanceProfile
             - 
                
將角色與執行個體描述檔建立關聯。
                aws iam add-role-to-instance-profile \
    --instance-profile-name AssumeDaxInstanceProfile \
    --role-name AssumeDaxRole
             - 
                
使用下列內容建立名為 DaxCrossAccountRoleTrust.json 的文字檔案,這可讓帳戶 B 擔任帳戶 A 角色。將帳戶B取代為帳戶 B 的實際 ID。
                
    - JSON
 - 
            
     
         
        - 
             
                
                
{
    "Version": "2012-10-17"		 	 	 ,
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:role/AssumeDaxRole"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
             
         
    
 
         
             - 
                
在帳戶 A 中,建立帳戶 B 可以擔任的角色。
                aws iam create-role \
    --role-name DaxCrossAccountRole \
    --assume-role-policy-document file://DaxCrossAccountRoleTrust.json
             - 
                
建立一個名為 DaxCrossAccountPolicy.json 的文字檔案以允許存取 DAX 叢集。將 dax-cluster-arn 取代為 DAX 叢集的正確 Amazon Resource Name (ARN)。
                
    - JSON
 - 
            
     
         
        - 
             
                
                
{
    "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"
            ],
            "Resource": "arn:aws:dax:us-east-1:111122223333:cache/dax-cluster-name"
        }
    ]
}
             
         
    
 
         
             - 
                
在帳戶 A 中,將政策新增至角色。
                aws iam put-role-policy \
    --role-name DaxCrossAccountRole \
    --policy-name DaxCrossAccountPolicy \
    --policy-document file://DaxCrossAccountPolicy.json
             
 
     
        設定 VPC
        - 
                
尋找帳戶 A DAX 叢集的子網路群組。將 cluster-name 取代為帳戶 B 必須存取的 DAX 叢集名稱。
                aws dax describe-clusters \
    --cluster-name cluster-name
    --query 'Clusters[0].SubnetGroup'
             - 
                
使用該子網路群組尋找該叢集的 VPC。
                aws dax describe-subnet-groups \
    --subnet-group-name subnet-group \
    --query 'SubnetGroups[0].VpcId'
             - 
                
使用該 vpc-id 尋找該 VPC 的 CIDR。
                aws ec2 describe-vpcs \
    --vpc vpc-id \
    --query 'Vpcs[0].CidrBlock'
             - 
                
從帳戶 B,使用不同於上一個步驟中找到的 CIDR 的非重疊 CIDR 來建立 VPC。然後,建立至少一個子網路。您可以使用 中的 VPC 建立精靈 AWS Management Console 或 AWS CLI。
             - 
                
從帳戶 B,請求與帳戶 A VPC 的對等連線,如建立和接受 VPC 對等互連中所述。從帳戶 A 接受連線。
             - 
                
從帳戶 B 尋找新 VPC 的路由表。將 vpc-id 取代為您在帳戶 B 中建立的 VPC ID。
                aws ec2 describe-route-tables \
    --filters 'Name=vpc-id,Values=vpc-id' \
    --query 'RouteTables[0].RouteTableId'
             - 
                
新增路由,將目的地為帳戶 A CIDR 的流量傳送至 VPC 對等連線。請記得將每個 user input placeholder 取代為您帳戶的正確值。
                aws ec2 create-route \
    --route-table-id accountB-route-table-id \
    --destination-cidr accountA-vpc-cidr \
    --vpc-peering-connection-id peering-connection-id
             - 
                
使用您之前找到的 vpc-id,從帳戶 A 尋找 DAX 叢集的路由表。
                aws ec2 describe-route-tables \
    --filters 'Name=vpc-id, Values=accountA-vpc-id' \
    --query 'RouteTables[0].RouteTableId'
             - 
                
從帳戶 A,新增路由,將目的地為帳戶 B CIDR 的流量傳送至 VPC 對等連線。使用您帳戶的正確值取代每個 user input placeholder。
                aws ec2 create-route \
    --route-table-id accountA-route-table-id \
    --destination-cidr accountB-vpc-cidr \
    --vpc-peering-connection-id peering-connection-id
             - 
                
從帳戶 B,在先前建立的 VPC 中啟動 EC2 執行個體。將其命名為 AssumeDaxInstanceProfile。您可以使用 中的啟動精靈 AWS Management Console 或 AWS CLI。記下執行個體的安全群組。
             - 
                
從帳戶 A 尋找 DAX 叢集所使用的安全群組。記得將 cluster-name 取代為您的 DAX 叢集名稱。
                aws dax describe-clusters \
    --cluster-name cluster-name \
    --query 'Clusters[0].SecurityGroups[0].SecurityGroupIdentifier'
             - 
                
更新 DAX 叢集的安全群組,以允許來自您在帳戶 B 中建立之 EC2 執行個體的安全群組的傳入流量。請記得使用正確的帳戶值取代 user input placeholders。
                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 教學課程中找到可行的程式碼範例。
                    - 
                            
新增以下匯入專案。
                            import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
                         - 
                            
從 取得登入資料提供者 AWS STS 並建立 DAX 用戶端物件。請記得將每個 user input placeholder 取代為您帳戶的正確值。
                            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 教學課程中找到可行的程式碼範例。
                    - 
                            
將 AWSSDK.SecurityToken NuGet 套件新增到解決方案。
                            <PackageReference Include="AWSSDK.SecurityToken" Version="latest version" />
                         - 
                            
使用 SecurityToken 和 SecurityToken.Model 套件。
                            using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
                         - 
                            
從 AmazonSimpleTokenService 取得臨時登入資料並建立 ClusterDaxClient 物件。請記得將每個 user input placeholder 取代為您帳戶的正確值。
                            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 上找到可行的程式碼範例。
                    - 
                            
匯入 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"
)
                         - 
                            
從 AmazonSimpleTokenService 取得臨時登入資料並建立 DAX 用戶端物件。請記得將每個 user input placeholder 取代為您帳戶的正確值。
                            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 教學課程中找到可行的程式碼範例。
                    - 
                            
匯入 boto3。
                            import boto3
                         - 
                            
從 sts 取得臨時登入資料並建立 AmazonDaxClient 物件。請記得將每個 user input placeholder 取代為您帳戶的正確值。
                            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 教學課程中找到可行的程式碼範例。請記得將每個 user input placeholder 取代為您帳戶的正確值。
                    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);
});