

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Tutorial: Configurando o Lambda para ElastiCache acesso em uma VPC
<a name="LambdaRedis"></a>

Neste tutorial, você pode aprender como criar um cache ElastiCache sem servidor, criar uma função Lambda, testar a função Lambda e, opcionalmente, limpá-la depois.

**Topics**
+ [Etapa 1: Criar um cache ElastiCache sem servidor.](#LambdaRedis.step1)
+ [Etapa 2: criar uma função Lambda para ElastiCache](#LambdaRedis.step2)
+ [Etapa 3: Teste a função Lambda com ElastiCache](#LambdaRedis.step3)
+ [Etapa 4: limpar (opcional)](#LambdaRedis.step4)

## Etapa 1: Criar um cache ElastiCache sem servidor.
<a name="LambdaRedis.step1"></a>

Para criar um cache de tecnologia sem servidor, siga estas etapas.

### Etapa 1.1: criar um cache de tecnologia sem servidor
<a name="LambdaRedis.step1.1"></a>

Nesta etapa, você cria um cache sem servidor na Amazon VPC padrão na região us-east-1 em sua conta usando a (CLI). AWS Command Line Interface Para obter informações sobre como criar cache sem servidor usando o ElastiCache console ou a API, consulte. [Criar um cache de tecnologia sem servidor Redis OSS](GettingStarted.serverless-redis.step1.md)

```
aws elasticache create-serverless-cache \
  --serverless-cache-name cache-01  \
--description "ElastiCache IAM auth application" \
--engine valkey
```

Observe que o valor do campo Status está definido como`CREATING`. ElastiCache cria seu cache em cerca de um minuto.

### Etapa 1.2: copiar o endpoint do cache de tecnologia sem servidor
<a name="LambdaRedis.step1.2"></a>

Verifique se, ElastiCache para Redis, o OSS terminou de criar o cache com o `describe-serverless-caches` comando.

```
aws elasticache describe-serverless-caches \
--serverless-cache-name cache-01
```

Copie o endereço do endpoint mostrado na saída. Você precisará desse endereço ao criar o pacote de implantação da função do Lambda.

### Etapa 1.3: criar o perfil do IAM
<a name="LambdaRedis.step1.3"></a>



1. Crie um documento de política de confiança do IAM, conforme mostrado abaixo, para o perfil que permita que sua conta assuma o novo perfil. Salve a política em um arquivo chamado *trust-policy.json*.

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

****  

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

------

1. Crie um documento de política do IAM, conforme mostrado abaixo. Salve a política em um arquivo chamado *policy.json*.

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

****  

   ```
   {
   "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
   "Effect" : "Allow",
         "Action" : [
           "elasticache:Connect"
         ],
         "Resource" : [
           "arn:aws:elasticache:us-east-1:123456789012:serverlesscache:cache-01",
           "arn:aws:elasticache:us-east-1:123456789012:user:iam-user-01"
         ]
       }
     ]
   }
   ```

------

1. Criar um perfil do IAM.

   ```
   aws iam create-role \
   --role-name "elasticache-iam-auth-app" \
   --assume-role-policy-document file://trust-policy.json
   ```

1. Crie a política do IAM.

   ```
   aws iam create-policy \
     --policy-name "elasticache-allow-all" \
     --policy-document file://policy.json
   ```

1. Anexe a política do IAM à função.

   ```
   aws iam attach-role-policy \
    --role-name "elasticache-iam-auth-app" \
    --policy-arn "arn:aws:iam::123456789012:policy/elasticache-allow-all"
   ```

### Etapa 1.4: criar um usuário padrão
<a name="LambdaRedis.step1.4"></a>

1. Crie um novo usuário padrão.

   ```
   aws elasticache create-user \
     --user-name default \
   --user-id default-user-disabled \
   --engine redis \
   --authentication-mode Type=no-password-required \
   --access-string "off +get ~keys*"
   ```

1. Crie um novo IAM-enabled usuário.

   ```
   aws elasticache create-user \
     --user-name iam-user-01 \
   --user-id iam-user-01 \
   --authentication-mode Type=iam \
   --engine redis \
   --access-string "on ~* +@all"
   ```

1. Crie um grupo de usuários e anexe o usuário.

   ```
   aws elasticache create-user-group \
     --user-group-id iam-user-group-01 \
   --engine redis \
   --user-ids default-user-disabled iam-user-01
   
   aws elasticache modify-serverless-cache \
     --serverless-cache-name cache-01  \
   --user-group-id iam-user-group-01
   ```

## Etapa 2: criar uma função Lambda para ElastiCache
<a name="LambdaRedis.step2"></a>

Para criar uma função Lambda para acessar o ElastiCache cache, siga estas etapas.

### Etapa 2.1: criar uma função do Lambda
<a name="LambdaRedis.step2.1"></a>

Neste tutorial, fornecemos um exemplo de código em Python para sua função do Lambda.

**Python**

O exemplo a seguir, o código Python lê e grava um item no seu ElastiCache cache. Copie o código e o salve em um arquivo chamado `app.py`. Não se esqueça de substituir o valor `elasticache_endpoint` no código pelo endereço do endpoint que você copiou na etapa anterior. 

```
from typing import Tuple, Union
from urllib.parse import ParseResult, urlencode, urlunparse

import botocore.session
import redis
from botocore.model import ServiceId
from botocore.signers import RequestSigner
from cachetools import TTLCache, cached
import uuid

class ElastiCacheIAMProvider(redis.CredentialProvider):
    def __init__(self, user, cache_name, is_serverless=False, region="us-east-1"):
        self.user = user
        self.cache_name = cache_name
        self.is_serverless = is_serverless
        self.region = region

        session = botocore.session.get_session()
        self.request_signer = RequestSigner(
            ServiceId("elasticache"),
            self.region,
            "elasticache",
            "v4",
            session.get_credentials(),
            session.get_component("event_emitter"),
        )

    # Generated IAM tokens are valid for 15 minutes
    @cached(cache=TTLCache(maxsize=128, ttl=900))
    def get_credentials(self) -> Union[Tuple[str], Tuple[str, str]]:
        query_params = {"Action": "connect", "User": self.user}
        if self.is_serverless:
            query_params["ResourceType"] = "ServerlessCache"
        url = urlunparse(
            ParseResult(
                scheme="https",
                netloc=self.cache_name,
                path="/",
                query=urlencode(query_params),
                params="",
                fragment="",
            )
        )
        signed_url = self.request_signer.generate_presigned_url(
            {"method": "GET", "url": url, "body": {}, "headers": {}, "context": {}},
            operation_name="connect",
            expires_in=900,
            region_name=self.region,
        )
        # RequestSigner only seems to work if the URL has a protocol, but
        # Elasticache only accepts the URL without a protocol
        # So strip it off the signed URL before returning
        return (self.user, signed_url.removeprefix("https://"))

def lambda_handler(event, context):
    username = "iam-user-01" # replace with your user id
    cache_name = "cache-01" # replace with your cache name
    elasticache_endpoint = "cache-01-xxxxx.serverless.use1.cache.amazonaws.com" # replace with your cache endpoint
    creds_provider = ElastiCacheIAMProvider(user=username, cache_name=cache_name, is_serverless=True)
    redis_client = redis.Redis(host=elasticache_endpoint, port=6379, credential_provider=creds_provider, ssl=True, ssl_cert_reqs="none")
    
    key='uuid'
    # create a random UUID - this will be the sample element we add to the cache
    uuid_in = uuid.uuid4().hex
    redis_client.set(key, uuid_in)
    result = redis_client.get(key)
    decoded_result = result.decode("utf-8")
    # check the retrieved item matches the item added to the cache and print
    # the results
    if decoded_result == uuid_in:
        print(f"Success: Inserted {uuid_in}. Fetched {decoded_result} from Valkey.")
    else:
        raise Exception(f"Bad value retrieved. Expected {uuid_in}, got {decoded_result}")
        
    return "Fetched value from Valkey"
```

Esse código usa a biblioteca redis-py do Python para colocar itens no cache e recuperá-los. Esse código usa cachetools para armazenar em cache os tokens IAM Auth gerados por 15 minutos. Para criar um pacote de implantação contendo redis-py e cachetools, realize as etapas a seguir.

No diretório do projeto que contém o arquivo de código-fonte app.py, crie um pacote de pasta no qual instalar as bibliotecas redis-py e cachetools.

```
mkdir package
```

Instale redis-py, cacheetools usando pip.

```
pip install --target ./package redis
pip install --target ./package cachetools
```

Crie um arquivo .zip contendo as bibliotecas redis-py e cachetools. No Linux e no MacOS, execute o comando a seguir. No Windows, use o utilitário zip preferencial para criar um arquivo .zip com as bibliotecas redis-py and cachetools na raiz.

```
cd package
zip -r ../my_deployment_package.zip .
```

Adicione o código de função ao arquivo .zip. No Linux e no MacOS, execute o comando a seguir. No Windows, use o utilitário zip preferencial para adicionar app.py à raiz do arquivo .zip.

```
cd ..
zip my_deployment_package.zip app.py
```

### Etapa 2.2: Criar o perfil do IAM (perfil de execução)
<a name="LambdaRedis.step2.2"></a>

Anexe a política AWS gerenciada nomeada `AWSLambdaVPCAccessExecutionRole` à função.

```
aws iam attach-role-policy \
 --role-name "elasticache-iam-auth-app" \
 --policy-arn "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
```

### Etapa 2.3: fazer upload do pacote de implantação (criar função do Lambda)
<a name="LambdaRedis.step2.3"></a>

Nesta etapa, você cria a função Lambda (AccessValkey) usando o comando AWS CLI create-function. 

No diretório do projeto que contém o arquivo .zip do pacote de implantação, execute o seguinte comando `create-function` da CLI do Lambda.

Para a opção de perfil, use o ARN da função de execução criada na etapa anterior. Para vpc-config, insira listas separadas por vírgulas das sub-redes da VPC padrão e o ID do grupo de segurança da VPC padrão. É possível encontrar esses valores no console do Amazon VPC. Para encontrar as sub-redes da sua VPC padrão, escolha Suas **VPCs e, em seguida, escolha a VPC padrão da sua** conta AWS . Para localizar o grupo de segurança dessa VPC, vá para **Segurança** e escolha **Grupos de segurança**. Não se esqueça de selecionar a região us-east-1.

```
aws lambda create-function \
--function-name AccessValkey  \
--region us-east-1 \
--zip-file fileb://my_deployment_package.zip \
--role arn:aws:iam::123456789012:role/elasticache-iam-auth-app \
--handler app.lambda_handler \
--runtime python3.12  \
--timeout 30 \
--vpc-config SubnetIds=comma-separated-vpc-subnet-ids,SecurityGroupIds=default-security-group-id
```

## Etapa 3: Teste a função Lambda com ElastiCache
<a name="LambdaRedis.step3"></a>

Nesta etapa, você invoca a função do Lambda manualmente usando o comando de invocação. Quando a função Lambda é executada, ela gera um UUID e o grava no ElastiCache cache que você especificou no seu código Lambda. Depois, a função do Lambda recupera o item do cache.

1. Invoque a função Lambda AccessValkey () usando AWS Lambda o comando invoke.

   ```
   aws lambda invoke \
   --function-name AccessValkey  \
   --region us-east-1 \
   output.txt
   ```

1. Verifique se a função do Lambda foi executada com êxito, da seguinte forma:
   + Analise o arquivo output.txt.
   + Verifique os resultados em CloudWatch Logs abrindo o CloudWatch console e escolhendo o grupo de registros para sua função (/aws/lambda/AccessValkey). O fluxo de logs deve conter uma saída semelhante à mostrada a seguir:

     ```
     Success: Inserted 826e70c5f4d2478c8c18027125a3e01e. Fetched 826e70c5f4d2478c8c18027125a3e01e from Valkey.
     ```
   + Analise os resultados no AWS Lambda console.

## Etapa 4: limpar (opcional)
<a name="LambdaRedis.step4"></a>

Para limpar, siga estas etapas.

### Etapa 4.1: excluir a função do Lambda
<a name="LambdaRedis.step4.1"></a>

```
aws lambda delete-function \
 --function-name AccessValkey
```

### Etapa 4.2: excluir o cache de tecnologia sem servidor
<a name="LambdaRedis.step4.2"></a>

Excluir o cache.

```
aws elasticache delete-serverless-cache \
 --serverless-cache-name cache-01
```

Remover usuários e grupos de usuários.

```
aws elasticache delete-user \
 --user-id default-user-disabled

aws elasticache delete-user \
 --user-id iam-user-01

aws elasticache delete-user-group \
 --user-group-id iam-user-group-01
```

### Etapa 4.3: remover políticas e o perfil do IAM
<a name="LambdaRedis.step4.3"></a>

```
aws iam detach-role-policy \
 --role-name "elasticache-iam-auth-app" \
 --policy-arn "arn:aws:iam::123456789012:policy/elasticache-allow-all"
 
aws iam detach-role-policy \
--role-name "elasticache-iam-auth-app" \
--policy-arn "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
 
aws iam delete-role \
 --role-name "elasticache-iam-auth-app"
  
 aws iam delete-policy \
  --policy-arn "arn:aws:iam::123456789012:policy/elasticache-allow-all"
```