Accesso a DAX attraverso account AWS - Amazon DynamoDB

Accesso a DAX attraverso account AWS

Si immagini di avere un cluster DynamoDB Accelerator (DAX) in esecuzione in un account AWS (account A) e che il cluster DAX debba essere accessibile da un'istanza Amazon Elastic Compute Cloud (Amazon EC2) in un altro account AWS (account B). In questo tutorial puoi eseguire questa operazione avviando un'istanza EC2 nell'account B con un ruolo dall'account B. Quindi puoi utilizzare le credenziali di sicurezza temporanee dell'istanza EC2 per assumere un ruolo IAM dall'account A. Infine, utilizzi le credenziali di sicurezza temporanee per assumere il ruolo IAM nell'account A per effettuare chiamate all'applicazione tramite una connessione peering di Amazon VPC al cluster DAX nell'account A. Per eseguire queste attività è necessario l'accesso amministrativo in entrambi gli account AWS.

Importante

Non è possibile fare in modo che un cluster DAX acceda a una tabella DynamoDB da un account diverso.

Configurazione di IAM

  1. Crea un file di testo denominato AssumeDaxRoleTrust.json con il seguente contenuto che consente a Amazon EC2 di lavorare per conto tuo.

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
  2. Nell'account B, creare un ruolo che Amazon EC2 può utilizzare durante l'avvio delle istanze.

    aws iam create-role \ --role-name AssumeDaxRole \ --assume-role-policy-document file://AssumeDaxRoleTrust.json
  3. Crea un file di testo denominato AssumeDaxRolePolicy.json con il contenuto seguente che consente al codice in esecuzione sull'istanza EC2 nell'account B di assumere un ruolo IAM nell'account A. Sostituisci accountA con l'ID effettivo dell'account A.

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::111122223333:role/DaxCrossAccountRole" } ] }
  4. Aggiungi la policy al ruolo appena creato.

    aws iam put-role-policy \ --role-name AssumeDaxRole \ --policy-name AssumeDaxRolePolicy \ --policy-document file://AssumeDaxRolePolicy.json
  5. Crea un profilo di istanza per consentire alle istanze di utilizzare il ruolo.

    aws iam create-instance-profile \ --instance-profile-name AssumeDaxInstanceProfile
  6. Associa il ruolo al profilo di istanza.

    aws iam add-role-to-instance-profile \ --instance-profile-name AssumeDaxInstanceProfile \ --role-name AssumeDaxRole
  7. Crea un file di testo denominato DaxCrossAccountRoleTrust.json con il contenuto seguente che consente all'account B di assumere un ruolo dell'account A. Sostituisci accountB con l'ID effettivo dell'account B.

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/AssumeDaxRole" }, "Action": "sts:AssumeRole" } ] }
  8. Nell'account A, crea il ruolo che l'account B può assumere.

    aws iam create-role \ --role-name DaxCrossAccountRole \ --assume-role-policy-document file://DaxCrossAccountRoleTrust.json
  9. Crea un file di testo denominato DaxCrossAccountPolicy.json che consente l'accesso al cluster DAX. Sostituisci dax-cluster-arn con l'Amazon Resource Name (ARN) corretto del tuo cluster DAX.

    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" } ] }
  10. Nell'account A, aggiungi la policy al ruolo.

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

Configurazione VPC

  1. Individuare il gruppo di sottoreti del cluster DAX dell'account A. Sostituisci cluster-name con il nome del cluster DAX a cui l'account B deve accedere.

    aws dax describe-clusters \ --cluster-name cluster-name --query 'Clusters[0].SubnetGroup'
  2. Utilizzando il subnet-group, individua il VPC del cluster.

    aws dax describe-subnet-groups \ --subnet-group-name subnet-group \ --query 'SubnetGroups[0].VpcId'
  3. Utilizzando il vpc-id, trova il CIDR del VPC.

    aws ec2 describe-vpcs \ --vpc vpc-id \ --query 'Vpcs[0].CidrBlock'
  4. Dall'account B, crea un VPC utilizzando un CIDR diverso, non sovrapposto rispetto a quello trovato nel passaggio precedente. Quindi, crea almeno una subnet. È possibile utilizzare la creazione guidata VPC nella AWS Management Console o l'AWS CLI.

  5. Dall'account B, richiedi una connessione peering al VPC dell'account A come descritto in Creazione e accettazione di una connessione peering VPC. Dall'account A, accetta la connessione.

  6. Dall'account B, trova la tabella di routing del nuovo VPC. Sostituisci vpc-id con l'ID del VPC creato nell'account B.

    aws ec2 describe-route-tables \ --filters 'Name=vpc-id,Values=vpc-id' \ --query 'RouteTables[0].RouteTableId'
  7. Aggiungi un percorso per inviare il traffico destinato al CIDR dell'account A alla connessione peering VPC. Ricordati di sostituire ogni segnaposto di input utente con i valori corretti per i tuoi account.

    aws ec2 create-route \ --route-table-id accountB-route-table-id \ --destination-cidr accountA-vpc-cidr \ --vpc-peering-connection-id peering-connection-id
  8. Dall'account A, individuare la tabella di routing del cluster DAX utilizzando il vpc-id trovato in precedenza.

    aws ec2 describe-route-tables \ --filters 'Name=vpc-id, Values=accountA-vpc-id' \ --query 'RouteTables[0].RouteTableId'
  9. Dall'account A, aggiungi un percorso per inviare il traffico destinato al CIDR dell'account B alla connessione peering VPC. Sostituisci ogni segnaposto di input utente con i valori corretti per gli account.

    aws ec2 create-route \ --route-table-id accountA-route-table-id \ --destination-cidr accountB-vpc-cidr \ --vpc-peering-connection-id peering-connection-id
  10. Dall'account B, avvia un'istanza EC2 nel VPC creato in precedenza. Assegnarle il nome AssumeDaxInstanceProfile. Puoi utilizzare la procedura guidata di avvio nella AWS Management Console o l'AWS CLI. Prendi nota del gruppo di sicurezza dell'istanza.

  11. Dall'account A, individua il gruppo di sicurezza utilizzato dal cluster DAX. Ricorda di sostituire cluster-name con il nome del cluster DAX.

    aws dax describe-clusters \ --cluster-name cluster-name \ --query 'Clusters[0].SecurityGroups[0].SecurityGroupIdentifier'
  12. Aggiorna il gruppo di sicurezza del cluster DAX per consentire il traffico in ingresso dal gruppo di sicurezza dell'istanza EC2 creata nell'account B. Ricorda di sostituire i segnaposto di input utente con i valori corretti per gli account.

    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

A questo punto, un'applicazione nell'istanza EC2 dell'account B è in grado di utilizzare il profilo dell'istanza per assumere il ruolo arn:aws:iam::accountA-id:role/DaxCrossAccountRole e utilizzare il cluster DAX.

Modifica del client DAX per consentire l'accesso multi-account

Nota

Le credenziali AWS Security Token Service (AWS STS) sono temporanee. Alcuni client gestiscono automaticamente l'aggiornamento, mentre altri richiedono una logica aggiuntiva per aggiornare le credenziali. Consigliamo di seguire le indicazioni della documentazione appropriata.

Java

Questa sezione consente di modificare il codice client DAX esistente per consentire l'accesso DAX tra account. Se non hai già un codice client DAX, puoi trovare esempi di codice funzionanti nel tutorial Java e DAX.

  1. Aggiungi le seguenti importazioni:

    import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider; import com.amazonaws.services.securitytoken.AWSSecurityTokenService; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
  2. Ottenere un provider di credenziali da AWS STS e creare un oggetto client DAX. Ricordati di sostituire ogni segnaposto di input utente con i valori corretti per i tuoi account.

    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

Questa sezione consente di modificare il codice client DAX esistente per consentire l'accesso DAX tra account. Se non hai già un codice client DAX, puoi trovare esempi di codice funzionanti nel tutorial .NET e DAX.

  1. Aggiungi il pacchetto NuGet AWSSDK.SecurityToken alla soluzione.

    <PackageReference Include="AWSSDK.SecurityToken" Version="latest version" />
  2. Usa i pacchetti SecurityToken.Model e SecurityToken.

    using Amazon.SecurityToken; using Amazon.SecurityToken.Model;
  3. Ottieni le credenziali temporanee da AmazonSimpleTokenService e crea un oggetto ClusterDaxClient. Ricordati di sostituire ogni segnaposto di input utente con i valori corretti per i tuoi account.

    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

Questa sezione consente di modificare il codice client DAX esistente per consentire l'accesso DAX tra account. Se non hai già il codice del client DAX, è possibile trovare esempi di codice funzionanti su GitHub.

  1. Importa i pacchetti AWS STS e di sessione.

    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. Ottenere le credenziali temporanee da AmazonSimpleTokenService e creare un oggetto client DAX. Ricordati di sostituire ogni segnaposto di input utente con i valori corretti per i tuoi account.

    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

Questa sezione consente di modificare il codice client DAX esistente per consentire l'accesso DAX tra account. Se non hai già un codice client DAX, puoi trovare esempi di codice funzionanti nel tutorial Python e DAX.

  1. Importa boto3.

    import boto3
  2. Ottieni credenziali temporanee da sts e crea un oggetto AmazonDaxClient. Ricordati di sostituire ogni segnaposto di input utente con i valori corretti per i tuoi account.

    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

Questa sezione consente di modificare il codice client DAX esistente per consentire l'accesso DAX tra account. Se non hai già un codice client DAX, puoi trovare esempi di codice funzionanti nel tutorial Node.js e DAX. Ricordati di sostituire ogni segnaposto di input utente con i valori corretti per i tuoi account.

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); });