Acceso a DAX a través de las cuentas de AWS - Amazon DynamoDB

Acceso a DAX a través de las cuentas de AWS

Imagine que tiene un clúster de DynamoDB Accelerator (DAX) ejecutándose en una cuenta de AWS (cuenta A) y que el clúster de DAX debe ser accesible desde una instancia de Amazon Elastic Compute Cloud (Amazon EC2) en otra cuenta de AWS (cuenta B). En este tutorial, lo logrará lanzando una instancia EC2 en la cuenta B con un rol de IAM de la cuenta B. A continuación, utiliza las credenciales de seguridad temporales de la instancia EC2 para asumir un rol de IAM de la cuenta A. Por último, utiliza las credenciales de seguridad temporales de asumir el rol de IAM en la cuenta A para realizar llamadas a la aplicación a través de una interconexión de Amazon VPC al clúster de DAX en la cuenta A. Para realizar estas tareas necesitará acceso administrativo en ambas cuentas de AWS.

importante

No es posible hacer que un clúster DAX acceda a una tabla de DynamoDB desde una cuenta diferente.

Configurar IAM

  1. Cree un archivo de texto denominado AssumeDaxRoleTrust.json con el siguiente contenido, que permite a Amazon EC2 trabajar en su nombre.

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
  2. En la cuenta B, cree un rol que Amazon EC2 pueda utilizar al lanzar instancias.

    aws iam create-role \ --role-name AssumeDaxRole \ --assume-role-policy-document file://AssumeDaxRoleTrust.json
  3. Cree un archivo de texto denominado AssumeDaxRolePolicy.json con el siguiente contenido, que permite que el código que se ejecuta en la instancia EC2 en la cuenta B asuma un rol de IAM en la cuenta A. Reemplace accountA por el ID real de la cuenta A.

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::accountA:role/DaxCrossAccountRole" } ] }
  4. Agregue esa política al rol que acaba de crear.

    aws iam put-role-policy \ --role-name AssumeDaxRole \ --policy-name AssumeDaxRolePolicy \ --policy-document file://AssumeDaxRolePolicy.json
  5. Cree un perfil de instancia para permitir que las instancias utilicen el rol.

    aws iam create-instance-profile \ --instance-profile-name AssumeDaxInstanceProfile
  6. Asocie el rol con el perfil de instancia.

    aws iam add-role-to-instance-profile \ --instance-profile-name AssumeDaxInstanceProfile \ --role-name AssumeDaxRole
  7. Cree un archivo de texto denominado DaxCrossAccountRoleTrust.json con el siguiente contenido, lo que permite a la cuenta B asumir un rol de cuenta A. Reemplace cuentaB por el ID real de la cuenta B.

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::accountB:role/AssumeDaxRole" }, "Action": "sts:AssumeRole" } ] }
  8. En la cuenta A, cree el rol que la cuenta B puede asumir.

    aws iam create-role \ --role-name DaxCrossAccountRole \ --assume-role-policy-document file://DaxCrossAccountRoleTrust.json
  9. Cree un archivo de texto denominado DaxCrossAccountPolicy.json que permita el acceso al clúster de DAX. Reemplace dax-cluster-arn por el nombre de recurso de Amazon (ARN) correcto de su clúster de DAX.

    { "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": "dax-cluster-arn" } ] }
  10. En la cuenta A, agregue la política al rol.

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

Configurar una VPC

  1. Busque el grupo de subred del clúster de DAX de la cuenta A. Reemplace cluster-name por el nombre del clúster de DAX al que debe tener acceso la cuenta B.

    aws dax describe-clusters \ --cluster-name cluster-name --query 'Clusters[0].SubnetGroup'
  2. Utilizando ese grupo de subred, busque la VPC del clúster.

    aws dax describe-subnet-groups \ --subnet-group-name subnet-group \ --query 'SubnetGroups[0].VpcId'
  3. Usando ese vpc-id, busque el CIDR de la VPC.

    aws ec2 describe-vpcs \ --vpc vpc-id \ --query 'Vpcs[0].CidrBlock'
  4. Desde la cuenta B, cree una VPC utilizando un CIDR diferente y no superpuesto que el encontrado en el paso anterior. A continuación, cree al menos una subred. Puede utilizar el asistente de creación de VPC en la AWS Management Console o en la AWS CLI.

  5. Desde la cuenta B, solicite una interconexión a la VPC de la cuenta A como se describe en Creación y aceptación de una conexión de emparejamiento de VPC. Desde la cuenta A, acepte la conexión.

  6. En la cuenta B, busque la nueva tabla de ruteo de la VPC. Reemplace vpc-id por el ID de la VPC que creó en la cuenta B.

    aws ec2 describe-route-tables \ --filters 'Name=vpc-id,Values=vpc-id' \ --query 'RouteTables[0].RouteTableId'
  7. Agregue una ruta para enviar tráfico destinado al CIDR de la cuenta A a la interconexión de VPC. Recuerde reemplazar cada marcador de posición de entrada de usuario por los valores correctos para sus cuentas.

    aws ec2 create-route \ --route-table-id accountB-route-table-id \ --destination-cidr accountA-vpc-cidr \ --vpc-peering-connection-id peering-connection-id
  8. En la cuenta A, busque la tabla de enrutamiento del clúster de DAX utilizando el vpc-id que encontró anteriormente.

    aws ec2 describe-route-tables \ --filters 'Name=vpc-id, Values=accountA-vpc-id' \ --query 'RouteTables[0].RouteTableId'
  9. Desde la cuenta A, agregue una ruta para enviar tráfico destinado al CIDR de la cuenta B a la interconexión de VPC. Reemplace cada marcador de posición de entrada de usuario por los valores correctos para sus cuentas.

    aws ec2 create-route \ --route-table-id accountA-route-table-id \ --destination-cidr accountB-vpc-cidr \ --vpc-peering-connection-id peering-connection-id
  10. Desde la cuenta B, lance una instancia EC2 en la VPC que creó anteriormente. Dele el AssumeDaxInstanceProfile. Puede utilizar el asistente de inicio en la AWS Management Console o en la AWS CLI. Tome nota del grupo de seguridad de la instancia.

  11. En la cuenta A, busque el grupo de seguridad utilizado por el clúster de DAX. Recuerde sustituir cluster-name por el nombre de su clúster de DAX.

    aws dax describe-clusters \ --cluster-name cluster-name \ --query 'Clusters[0].SecurityGroups[0].SecurityGroupIdentifier'
  12. Actualice el grupo de seguridad del clúster de DAX para permitir el tráfico entrante desde el grupo de seguridad de la instancia EC2 que creó en la cuenta B. Recuerde sustituir los marcadores de posición de entrada del usuario por los valores correctos para sus cuentas.

    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

En este punto, una aplicación en la instancia EC2 de la cuenta B puede utilizar el perfil de instancias para asumir el rol arn:aws:iam::accountA-id:role/DaxCrossAccountRole y utilizar el clúster de DAX.

Modificar el cliente de DAX para permitir el acceso entre cuentas

nota

Las credenciales de AWS Security Token Service (AWS STS) son credenciales temporales. Algunos clientes manejan la actualización automáticamente, mientras que otros requieren lógica adicional para actualizar las credenciales. Le recomendamos que siga las instrucciones de la documentación correspondiente.

Java

Esta sección le ayuda a modificar el código de cliente de DAX existente para permitir el acceso de DAX entre cuentas. Si aún no tiene código de cliente de DAX, puede encontrar ejemplos de código de trabajo en el tutorial Java y DAX.

  1. Agregue las siguientes importaciones:

    import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider; import com.amazonaws.services.securitytoken.AWSSecurityTokenService; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
  2. Obtenga un proveedor de credenciales de AWS STS y cree un objeto cliente de DAX. Recuerde reemplazar cada marcador de posición de entrada de usuario por los valores correctos para sus cuentas.

    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

Esta sección le ayuda a modificar el código de cliente de DAX existente para permitir el acceso de DAX entre cuentas. Si aún no tiene código de cliente de DAX, puede encontrar ejemplos de código de trabajo en el tutorial .NET y DAX.

  1. Agregue el paquete NuGet AWSSDK.SecurityToken a la solución.

    <PackageReference Include="AWSSDK.SecurityToken" Version="latest version" />
  2. Utilice los paquetes SecurityToken y SecurityToken.Model.

    using Amazon.SecurityToken; using Amazon.SecurityToken.Model;
  3. Obtenga credenciales temporales de AmazonSimpleTokenService y cree un objeto de ClusterDaxClient. Recuerde reemplazar cada marcador de posición de entrada de usuario por los valores correctos para sus cuentas.

    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

Esta sección le ayuda a modificar el código de cliente de DAX existente para permitir el acceso de DAX entre cuentas. Si aún no tiene código de cliente de DAX, puede encontrar ejemplos de código en funcionamiento en GitHub.

  1. Importe los paquetes de AWS STS y de sesión.

    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. Obtener credenciales temporales de AmazonSimpleTokenService y crear un objeto cliente de DAX. Recuerde reemplazar cada marcador de posición de entrada de usuario por los valores correctos para sus cuentas.

    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

Esta sección le ayuda a modificar el código de cliente de DAX existente para permitir el acceso de DAX entre cuentas. Si aún no tiene código de cliente de DAX, puede encontrar ejemplos de código de trabajo en el tutorial Python y DAX.

  1. Importe boto3.

    import boto3
  2. Obtenga credenciales temporales de sts y cree un objeto AmazonDaxClient. Recuerde reemplazar cada marcador de posición de entrada de usuario por los valores correctos para sus cuentas.

    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

Esta sección le ayuda a modificar el código de cliente de DAX existente para permitir el acceso de DAX entre cuentas. Si aún no tiene código de cliente de DAX, puede encontrar ejemplos de código de trabajo en el tutorial Node.js y DAX. Recuerde reemplazar cada marcador de posición de entrada de usuario por los valores correctos para sus cuentas.

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