本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
跨 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 CLI。 AWS Management Console
-
從帳戶 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);
});