

# Acessando o DAX em contas da AWS
<a name="DAX.cross-account-access"></a>

Suponha que você tenha um cluster do DynamoDB Accelerator (DAX) em execução em uma conta da AWS (conta A) e que o cluster do DAX precise ser acessível de uma instância do Amazon Elastic Compute Cloud (Amazon EC2) em outra conta da AWS (conta B). Neste tutorial, isso é feito iniciando uma instância do EC2 na conta B com uma função do IAM da conta B. Então, você usa credenciais de segurança temporárias da instância do EC2 para assumir uma função do IAM da conta A. Por fim, você usa as credenciais de segurança temporárias da função do IAM da conta A para fazer chamadas de aplicação em uma conexão de emparelhamento da Amazon VPC para o cluster do DAX na conta A. Para realizar essas tarefas, é preciso ter acesso administrativo em ambas as contas da AWS.

**Importante**  
 Não é possível que um cluster do DAX acesse uma tabela do DynamoDB de uma conta diferente. 

**Topics**
+ [Configurar o IAM](#DAX.cross-account-access.iam-setup)
+ [Configurar uma VPC](#DAX.cross-account-access.vpc-setup)
+ [Modificar o cliente do DAX para permitir acesso entre contas](#DAX.cross-account-access.modify-client)

## Configurar o IAM
<a name="DAX.cross-account-access.iam-setup"></a>

1. Crie um arquivo de texto chamado `AssumeDaxRoleTrust.json` com o conteúdo a seguir, que permite que o Amazon EC2 trabalhe em seu nome.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "ec2.amazonaws.com"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

1. Na conta B, crie uma função que o Amazon EC2 possa usar ao executar instâncias.

   ```
   aws iam create-role \
       --role-name AssumeDaxRole \
       --assume-role-policy-document file://AssumeDaxRoleTrust.json
   ```

1. Crie um arquivo de texto chamado `AssumeDaxRolePolicy.json` com o seguinte conteúdo, que permite que o código executado na instância do EC2 na conta B assuma uma função do IAM na conta A. Substitua {{accountA}} pelo ID real da conta A.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "sts:AssumeRole",
               "Resource": "arn:aws:iam::{{111122223333}}:role/DaxCrossAccountRole"
           }
       ]
   }
   ```

------

1. Adicione essa política à função que acabou de criar.

   ```
   aws iam put-role-policy \
       --role-name AssumeDaxRole \
       --policy-name AssumeDaxRolePolicy \
       --policy-document file://AssumeDaxRolePolicy.json
   ```

1. Crie um perfil de instância para permitir que as instâncias usem a função.

   ```
   aws iam create-instance-profile \
       --instance-profile-name AssumeDaxInstanceProfile
   ```

1. Associe a função ao perfil de instância.

   ```
   aws iam add-role-to-instance-profile \
       --instance-profile-name AssumeDaxInstanceProfile \
       --role-name AssumeDaxRole
   ```

1. Crie um arquivo de texto chamado `DaxCrossAccountRoleTrust.json` com o seguinte conteúdo, que permite que a conta B assuma uma função da conta A. Substitua {{accountB}} pelo ID real da conta B.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::{{111122223333}}:role/AssumeDaxRole"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

1. Na conta A, crie a função que a conta B poderá assumir.

   ```
   aws iam create-role \
       --role-name DaxCrossAccountRole \
       --assume-role-policy-document file://DaxCrossAccountRoleTrust.json
   ```

1. Crie um arquivo de texto chamado `DaxCrossAccountPolicy.json` que permite acesso ao cluster do DAX. Substitua {{dax-cluster-arn}} pelo nome do recurso da Amazon (ARN) correto do cluster do 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}}"
           }
       ]
   }
   ```

------

1. Na conta A, adicione a política à função.

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

## Configurar uma VPC
<a name="DAX.cross-account-access.vpc-setup"></a>

1. Localize o grupo de sub-redes do cluster do DAX da conta A. Substitua {{cluster-name}} pelo nome do cluster do DAX que a conta B deve acessar.

   ```
   aws dax describe-clusters \
       --cluster-name {{cluster-name}}
       --query 'Clusters[0].SubnetGroup'
   ```

1. Usando o {{subnet-group}}, encontre a VPC do cluster.

   ```
   aws dax describe-subnet-groups \
       --subnet-group-name {{subnet-group}} \
       --query 'SubnetGroups[0].VpcId'
   ```

1. Usando o {{vpc-id}}, encontre o CIDR da VPC.

   ```
   aws ec2 describe-vpcs \
       --vpc {{vpc-id}} \
       --query 'Vpcs[0].CidrBlock'
   ```

1. Na conta B, crie uma VPC usando um CIDR não sobreposto diferente daquele encontrado na etapa anterior. Em seguida, crie pelo menos uma sub-rede. Você pode usar o [assistente de criação da VPC](https://docs.aws.amazon.com/vpc/latest/userguide/getting-started-ipv4.html#getting-started-create-vpc) no Console de gerenciamento da AWS ou a [AWS CLI](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-vpc.html).

1. Na conta B, solicite uma conexão de emparelhamento com a VPC da conta A conforme descrito em [Criar e aceitar uma conexão de emparelhamento da VPC](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html). Na conta A, aceite a conexão.

1. Na conta B, localize a nova tabela de roteamento da VPC. Substitua {{vpc-id}} pelo ID da VPC que você criou na conta B.

   ```
   aws ec2 describe-route-tables \
       --filters 'Name=vpc-id,Values={{vpc-id}}' \
       --query 'RouteTables[0].RouteTableId'
   ```

1. Adicione uma rota para enviar o tráfego destinado ao CIDR da conta A para a conexão de emparelhamento da VPC. Lembre-se de substituir cada {{espaço reservado de entrada de usuário}} pelos valores corretos para suas contas.

   ```
   aws ec2 create-route \
       --route-table-id {{accountB-route-table-id}} \
       --destination-cidr {{accountA-vpc-cidr}} \
       --vpc-peering-connection-id {{peering-connection-id}}
   ```

1. Na conta A, localize a tabela de rotas do cluster do DAX usando o {{vpc-id}} encontrado anteriormente.

   ```
   aws ec2 describe-route-tables \
       --filters 'Name=vpc-id, Values={{accountA-vpc-id}}' \
       --query 'RouteTables[0].RouteTableId'
   ```

1. Na conta A, adicione uma rota para enviar o tráfego destinado ao CIDR da conta B para a conexão de emparelhamento da VPC. Substitua cada {{espaço reservado de entrada de usuário}} pelos valores corretos para suas contas.

   ```
   aws ec2 create-route \
       --route-table-id {{accountA-route-table-id}} \
       --destination-cidr {{accountB-vpc-cidr}} \
       --vpc-peering-connection-id {{peering-connection-id}}
   ```

1. Na conta B, execute uma instância do EC2 na VPC que você criou anteriormente. Forneça o `AssumeDaxInstanceProfile`. Você pode usar o [assistente de inicialização](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/launching-instance.html) no Console de gerenciamento da AWS ou a [AWS CLI](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html). Anote o grupo de segurança da instância.

1. Na conta A, localize o grupo de segurança usado pelo cluster do DAX. Lembre-se de substituir {{cluster-name}} pelo nome do cluster do DAX.

   ```
   aws dax describe-clusters \
       --cluster-name {{cluster-name}} \
       --query 'Clusters[0].SecurityGroups[0].SecurityGroupIdentifier'
   ```

1. Atualize o grupo de segurança do cluster do DAX para permitir o tráfego de entrada do grupo de segurança da instância do EC2 que você criou na conta B. Lembre-se de substituir os {{espaços reservados de entrada do usuário}} pelos valores corretos para suas contas.

   ```
   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}}
   ```

Nesse ponto, uma aplicação na instância do EC2 da conta B pode usar o perfil de instância para assumir a função `arn:aws:iam::{{accountA-id}}:role/DaxCrossAccountRole` e usar o cluster do DAX.

## Modificar o cliente do DAX para permitir acesso entre contas
<a name="DAX.cross-account-access.modify-client"></a>

**nota**  
As credenciais do AWS Security Token Service (AWS STS) são temporárias. Alguns clientes lidam com a atualização automaticamente, enquanto outros exigem lógica adicional para atualizar as credenciais. Recomendamos seguir as orientações da documentação apropriada.

------
#### [ Java ]

Esta seção ajuda você a modificar seu código de cliente do DAX existente para permitir o acesso ao DAX entre contas. Caso ainda não tenha um código de cliente do DAX, você pode encontrar exemplos de código que funcionam no tutorial do [Java e DAX](DAX.client.run-application-java.md).

1. Adicione as seguintes importações.

   ```
   import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
   import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
   import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
   ```

1. Obtenha um provedor de credenciais do AWS STS e crie um objeto de cliente do DAX. Lembre-se de substituir cada {{espaço reservado de entrada de usuário}} pelos valores corretos para suas contas.

   ```
   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 seção ajuda você a modificar seu código de cliente do DAX existente para permitir o acesso ao DAX entre contas. Caso ainda não tenha um código de cliente do DAX, você pode encontrar exemplos de código que funcionam no tutorial do [.NET e DAX](DAX.client.run-application-dotnet.md).

1. Adicione o pacote [AWSSDK.SecurityToken](https://www.nuget.org/packages/AWSSDK.SecurityToken) NuGet à solução.

   ```
   <PackageReference Include="AWSSDK.SecurityToken" Version="{{latest version}}" />
   ```

1. Use os pacotes `SecurityToken` e `SecurityToken.Model`.

   ```
   using Amazon.SecurityToken;
   using Amazon.SecurityToken.Model;
   ```

1. Obtenha credenciais temporárias do `AmazonSimpleTokenService` e crie um objeto `ClusterDaxClient`. Lembre-se de substituir cada {{espaço reservado de entrada de usuário}} pelos valores corretos para suas contas.

   ```
   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 seção ajuda você a modificar seu código de cliente do DAX existente para permitir o acesso ao DAX entre contas. Caso ainda não tenha um código de cliente do DAX, você poderá encontrar [exemplos de código funcionais no GitHub](https://github.com/aws-samples/aws-dax-go-sample/blob/master/try_dax.go).

1. Importe os pacotes de AWS STS e sessão.

   ```
   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"
   )
   ```

1. Obtenha credenciais temporárias do `AmazonSimpleTokenService` e crie um objeto de cliente do DAX. Lembre-se de substituir cada {{espaço reservado de entrada de usuário}} pelos valores corretos para suas contas.

   ```
   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 seção ajuda você a modificar seu código de cliente do DAX existente para permitir o acesso ao DAX entre contas. Caso ainda não tenha um código de cliente do DAX, você pode encontrar exemplos de código que funcionam no tutorial do [Python e DAX](DAX.client.run-application-python.md).

1. Importar: `boto3`.

   ```
   import boto3
   ```

1. Obtenha credenciais temporárias do `sts` e crie um objeto do `AmazonDaxClient`. Lembre-se de substituir cada {{espaço reservado de entrada de usuário}} pelos valores corretos para suas contas.

   ```
   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 seção ajuda você a modificar seu código de cliente do DAX existente para permitir o acesso ao DAX entre contas. Caso ainda não tenha um código de cliente do DAX, você pode encontrar exemplos de código que funcionam no tutorial do [Node.js e DAX](DAX.client.run-application-nodejs.md). Lembre-se de substituir cada {{espaço reservado de entrada de usuário}} pelos valores corretos para suas contas.

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

------