

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Introducción a AWS Solutions
<a name="getting-started-with-aws-solutions-constructs"></a>

 En este tema se describe cómo instalar y configurar AWS Cloud Development Kit (AWS CDK), AWS Solutions Constructs y crear su primera aplicación de AWS CDK utilizando patrones de AWS Solutions Constructs. 

**nota**  
Las versiones de CDK de AWS son compatibles con AWS Solutions Constructs ≥ 1.46.0. 

**sugerencia**  
 ¿Quieres cavar más profundo? Pruebe el[Taller de CDK](https://cdkworkshop.com/)para un recorrido más profundo por un proyecto del mundo real. 

**sugerencia**  
 Para obtener más información acerca de cómo empezar a utilizar el Cloud Development Kit de AWS (CDK de AWS), consulte la[Guía para desarrolladores de CDK de AWS](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html). 

## Prerequisites
<a name="prerequisites"></a>

 AWS Solutions Constructs se basa en el CDK de AWS, por lo que debe instalar Node.js (>= 10.3.0), incluso aquellos que trabajan en idiomas distintos de TypeScript o JavaScript. Esto se debe a que el[CDK DE AWS](https://github.com/aws/aws-cdk)y AWS Solutions Constructs se desarrollan en TypeScript y se ejecutan en Node.js. Los enlaces para otros idiomas compatibles utilizan este back-end y conjunto de herramientas. 

 Debe proporcionar sus credenciales y una región de AWS para utilizar la CLI de AWS CDK, tal y como se describe en Especificar sus credenciales y región. 

 Otros requisitos previos dependen de su lenguaje de desarrollo, de la siguiente manera. 


|  **Idioma**  |  **Requisitos previos**  | 
| --- | --- | 
|  ![\[Python\]](http://docs.aws.amazon.com/es_es/solutions/latest/constructs/images/python.png)Python  |  Python >= 3.6  | 
|  ![\[TypeScript\]](http://docs.aws.amazon.com/es_es/solutions/latest/constructs/images/typescript.png)TypeScript  |  TypeScript >= 2.7  | 
|  ![\[Java\]](http://docs.aws.amazon.com/es_es/solutions/latest/constructs/images/java.png)Java | Java >= 1.8 | 

## Instalación del CDK de AWS
<a name="installing-the-aws-cdk"></a>

 Para instalar y configurar el CDK de AWS, consulte la Guía para desarrolladores de CDK de AWS:[Instalación del CDK de AWS](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install). 

## Uso de componentes de soluciones de AWS
<a name="working-with-the-aws-solutions-constructs-library"></a>

 El flujo de trabajo típico para crear una nueva aplicación cuando se trabaja con AWS Solutions Constructs sigue el mismo enfoque que el CDK de AWS. 

1.  Cree el directorio de aplicaciones. 

1.  Inicialización de la aplicación. 

1.  Agregue las dependencias de patrones de AWS Solutions Constructs. 

1.  Añade código adicional a la aplicación. 

1.  Compile la aplicación, si es necesario. 

1.  Implemente los recursos definidos en la aplicación. 

1.  Probar la aplicación. 

 Si hay algún problema, realice un bucle a través de modificar, compilar (si es necesario), implementar y probar de nuevo. 

# Tutorial - Parte 1
<a name="walkthrough-part-1"></a>

**nota**  
Construcciones de AWS Solutions se admite en las versiones de AWS CDK ≥ 1.46.0. 

 Este tutorial le guía a través de cómo crear e implementar una aplicación sencilla de AWS CDK «Hello Constructs» que utiliza un patrón de AWS Solutions Constructs, desde la inicialización del proyecto hasta la implementación de la plantilla de AWS CloudFormation resultante. La aplicación Hello Constructs creará la siguiente solución simple: 

![\[Diagrama de la arquitectura\]](http://docs.aws.amazon.com/es_es/solutions/latest/constructs/images/tutorial-part1.png)


## Construcciones de Hello
<a name="hello-konstruk"></a>

 Comencemos a crear nuestra primera aplicación AWS CDK mediante el desarrollo basado en patrones. 

**nota**  
 Esta es una modificación de muestra de`Hello CDK!`desde las[Taller de CDK](https://cdkworkshop.com/). Si es la primera vez que utiliza AWS CDK, le recomendamos comenzar con este taller para obtener un tutorial práctico y cómo aprovechar el CDK en la creación de un proyecto del mundo real. 

## Creación del directorio de aplicaciones e inicialización del CDK de AWS
<a name="creating-the-app-directory-and-initializing-the-aws-cdk"></a>

 Cree un directorio para su aplicación CDK y, a continuación, cree una aplicación de AWS CDK en ese directorio. 

------
#### [ TypeScript ]

```
  mkdir hello-constructs     
  cd hello-constructs     
  cdk init --language typescript
```

------
#### [ Python ]

```
  mkdir hello-constructs     
  cd hello-constructs     
  cdk init --language python
```

------

**sugerencia**  
Ahora es un buen momento para abrir el proyecto en su IDE favorito y explorar. Para obtener más información acerca de la estructura del proyecto, seleccione el vínculo apropiado:  
[TypeScript](https://cdkworkshop.com/20-typescript/20-create-project/300-structure.html)
[Python](https://cdkworkshop.com/30-python/20-create-project/300-structure.html)

## Actualizar dependencias de la base del proyecto
<a name="update-project-base-dependencies-to-use-aws-cdk"></a>

**aviso**  
Para garantizar una funcionalidad adecuada, AWS Solutions Constructs y los paquetes CDK de AWS deben utilizar el mismo número de versión dentro del proyecto. Por ejemplo, si utiliza AWS Solutions Constructs v.1.52.0, también debe utilizar AWS CDK v.1.52.0. 

**sugerencia**  
 Tome nota de la versión más reciente de AWS Solutions Constructs y aplique ese número de versión al`VERSION_NUMBER`en los pasos siguientes (para los paquetes de AWS Solutions Constructs y AWS CDK). Para comprobar todas las versiones públicas de la biblioteca de componentes fijos,[Click here](https://github.com/awslabs/aws-solutions-constructs/releases).

------
#### [ TypeScript ]

Edite el`package.json`con la siguiente información: 

```
  "devDependencies": {
    "@aws-cdk/assert": "VERSION_NUMBER",
    "@types/jest": "^24.0.22",
    "@types/node": "10.17.5",
    "jest": "^24.9.0",
    "ts-jest": "^24.1.0",
    "aws-cdk": "VERSION_NUMBER",
    "ts-node": "^8.1.0",
    "typescript": "~3.7.2"
  },
  "dependencies": {
    "@aws-cdk/core": "VERSION_NUMBER",
    "source-map-support": "^0.5.16"
  }
```

------
#### [ Python ]

Edite el`setup.py`con la siguiente información:

```
install_requires=[
    "aws-cdk.core==VERSION_NUMBER",
],
```

------

 Instale las dependencias base de proyectos. 

------
#### [ TypeScript ]

```
npm install      
```

------
#### [ Python ]

```
source .venv/bin/activate
pip install -r requirements.txt
```

------

 Cree y ejecute la aplicación y confirme que cree una pila vacía. 

------
#### [ TypeScript ]

```
 npm run build 
 cdk synth
```

------
#### [ Python ]

```
 cdk synth           
```

------

 Debería ver una pila como la siguiente, donde`CDK-VERSION`es la versión del CDK. (Su salida puede diferir ligeramente de lo que se muestra aquí). 

------
#### [ TypeScript ]

```
Resources:
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
          Modules: aws-cdk=CDK-VERSION,@aws-cdk/core=VERSION_NUMBER,@aws-cdk/cx-api=VERSION_NUMBER,jsii-runtime=node.js/10.17.0
```

------
#### [ Python ]

```
Resources:
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
          Modules: aws-cdk=CDK-VERSION,@aws-cdk/core=VERSION_NUMBER,@aws-cdk/cx-api=VERSION_NUMBER,jsii-runtime=Python/3.7.7
```

------

## Código del controlador Lambda
<a name="lambda-handler-code"></a>

 Comenzaremos con el código de controlador de AWS Lambda. 

 Creación de un directorio de`lambda`En la raíz del árbol de proyecto. 

------
#### [ TypeScript ]

Añadir un archivo denominado`lambda/hello.js`con el siguiente contenido: 

```
exports.handler = async function(event) {
  console.log("request:", JSON.stringify(event, null, 2));
  return {
    statusCode: 200,
    headers: { "Content-Type": "text/plain" },
    body: `Hello, AWS Solutions Constructs! You've hit ${event.path}\n`
  };
};
```

------
#### [ Python ]

Añadir un archivo denominado`lambda/hello.py`con el siguiente contenido:

```
import json

def handler(event, context):
    print('request: {}'.format(json.dumps(event)))
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'text/plain'
        },
        'body': 'Hello, CDK! You have hit {}\n'.format(event['path'])
    }
```

------

 Esta es una simple función de Lambda que devuelve el texto «Hola, Constructs\$1 Has presionado [ruta URL]». La salida de la función también incluye el código de estado HTTP y los encabezados HTTP. Estos son utilizados por API Gateway para formular la respuesta HTTP al usuario. 

 Este Lambda se proporciona en JavaScript. Para obtener más información sobre cómo escribir funciones de Lambda en el idioma de su elección, consulte la[Documentación de AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html).

## Instalar las dependencias de AWS CDK y AWS Solutions Constructs
<a name="install-the-aws-cdk-and-aws-solutions-constructs-library-dependencies"></a>

 Los componentes fijos de soluciones de AWS se suministran con una amplia biblioteca de componentes fijos. La biblioteca está dividida en módulos, uno para cada patrón bien diseñado. Por ejemplo, si desea definir una API de descanso de Amazon API Gateway para una función de AWS Lambda, necesitaremos utilizar la`aws-apigateway-lambda`Biblioteca de patrones. 

 También tenemos que añadir la biblioteca de construcción de AWS Lambda y Amazon API Gateway desde el CDK de AWS. 

 Instale el módulo AWS Lambda y todas sus dependencias en nuestro proyecto: 

**nota**  
Recuerde sustituir la versión correcta y coincidente que se utilizará tanto para AWS Solutions Constructs como para AWS CDK en el`VERSION_NUMBER`campos de marcador de posición para cada comando. Las versiones incorrectas entre los paquetes pueden causar errores.

------
#### [ TypeScript ]

```
 npm install -s @aws-cdk/aws-lambda@VERSION_NUMBER       
```

------
#### [ Python ]

```
 pip install aws_cdk.aws_lambda==VERSION_NUMBER 
```

------

 A continuación, instale el módulo Amazon API Gateway y todas sus dependencias en nuestro proyecto: 

------
#### [ TypeScript ]

```
 npm install -s @aws-cdk/aws-apigateway@VERSION_NUMBER         
```

------
#### [ Python ]

```
 pip install aws_cdk.aws_apigateway==VERSION_NUMBER          
```

------

 Por último, instale los constructos de soluciones de AWS`aws-apigateway-lambda`y todas sus dependencias en nuestro proyecto: 

------
#### [ TypeScript ]

```
 npm install -s @aws-solutions-constructs/aws-apigateway-lambda@VERSION_NUMBER        
```

------
#### [ Python ]

```
 pip install aws_solutions_constructs.aws_apigateway_lambda==VERSION_NUMBER          
```

------

## Agregar un patrón de Amazon API Gateway/AWS Lambda a su pila
<a name="add-an-aws-api-gatewayaws-lambda-pattern-to-your-stack"></a>

 Ahora definamos el patrón de AWS Solutions Constructs para implementar una Amazon API Gateway con un proxy de AWS Lambda. 

------
#### [ TypeScript ]

Edite el archivo`lib/hello-constructs.ts`con lo siguiente:

```
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as api from '@aws-cdk/aws-apigateway';
import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda';

export class HelloConstructsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
    const api_lambda_props: ApiGatewayToLambdaProps = {
      lambdaFunctionProps: {
        code: lambda.Code.fromAsset('lambda'),
        runtime: lambda.Runtime.NODEJS_12_X,
        handler: 'hello.handler'
      },
      apiGatewayProps: {
        defaultMethodOptions: {
          authorizationType: api.AuthorizationType.NONE
        }
      }
    };

    new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props);
  }
}
```

------
#### [ Python ]

Edite el archivo`hello_constructs/hello_constructs_stack.py`con lo siguiente: 

```
from aws_cdk import (
    aws_lambda as _lambda,
    aws_apigateway as apigw,
    core,
)

from aws_solutions_constructs import (
    aws_apigateway_lambda as apigw_lambda
)

class HelloConstructsStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # The code that defines your stack goes here

        apigw_lambda.ApiGatewayToLambda(
            self, 'ApiGatewayToLambda',
            lambda_function_props=_lambda.FunctionProps(
                runtime=_lambda.Runtime.PYTHON_3_7,
                code=_lambda.Code.asset('lambda'),
                handler='hello.handler',
            ),
            api_gateway_props=apigw.RestApiProps(
                default_method_options=apigw.MethodOptions(
                    authorization_type=apigw.AuthorizationType.NONE
                )
            )
        )
```

------

 Eso es todo. Esto es todo lo que necesita hacer para definir una API Gateway que proxie todas las solicitudes a una función de AWS Lambda. Vamos a comparar nuestra nueva pila con la original: 

------
#### [ TypeScript ]

```
npm run build    
cdk diff
```

------
#### [ Python ]

```
cdk diff       
```

------

 La salida debe tener el siguiente aspecto: 

```
Stack HelloConstructsStack
IAM Statement Changes
┌───┬─────────────────────────────┬────────┬─────────────────────────────┬─────────────────────────────┬──────────────────────────────┐
│   │ Resource                    │ Effect │ Action                      │ Principal                   │ Condition                    │
├───┼─────────────────────────────┼────────┼─────────────────────────────┼─────────────────────────────┼──────────────────────────────┤
│ + │ ${LambdaFunction.Arn}       │ Allow  │ lambda:InvokeFunction       │ Service:apigateway.amazonaw │ "ArnLike": {                 │
│   │                             │        │                             │ s.com                       │   "AWS:SourceArn": "arn:${AW │
│   │                             │        │                             │                             │ S::Partition}:execute-api:${ │
│   │                             │        │                             │                             │ AWS::Region}:${AWS::AccountI │
│   │                             │        │                             │                             │ d}:${RestApi0C43BF4B}/${Rest │
│   │                             │        │                             │                             │ Api/DeploymentStage.prod}/*/ │
│   │                             │        │                             │                             │ {proxy+}"                    │
│   │                             │        │                             │                             │ }                            │
│ + │ ${LambdaFunction.Arn}       │ Allow  │ lambda:InvokeFunction       │ Service:apigateway.amazonaw │ "ArnLike": {                 │
│   │                             │        │                             │ s.com                       │   "AWS:SourceArn": "arn:${AW │
│   │                             │        │                             │                             │ S::Partition}:execute-api:${ │
│   │                             │        │                             │                             │ AWS::Region}:${AWS::AccountI │
│   │                             │        │                             │                             │ d}:${RestApi0C43BF4B}/test-i │
│   │                             │        │                             │                             │ nvoke-stage/*/{proxy+}"      │
│   │                             │        │                             │                             │ }                            │
│ + │ ${LambdaFunction.Arn}       │ Allow  │ lambda:InvokeFunction       │ Service:apigateway.amazonaw │ "ArnLike": {                 │
│   │                             │        │                             │ s.com                       │   "AWS:SourceArn": "arn:${AW │
│   │                             │        │                             │                             │ S::Partition}:execute-api:${ │
│   │                             │        │                             │                             │ AWS::Region}:${AWS::AccountI │
│   │                             │        │                             │                             │ d}:${RestApi0C43BF4B}/${Rest │
│   │                             │        │                             │                             │ Api/DeploymentStage.prod}/*/ │
│   │                             │        │                             │                             │ "                            │
│   │                             │        │                             │                             │ }                            │
│ + │ ${LambdaFunction.Arn}       │ Allow  │ lambda:InvokeFunction       │ Service:apigateway.amazonaw │ "ArnLike": {                 │
│   │                             │        │                             │ s.com                       │   "AWS:SourceArn": "arn:${AW │
│   │                             │        │                             │                             │ S::Partition}:execute-api:${ │
│   │                             │        │                             │                             │ AWS::Region}:${AWS::AccountI │
│   │                             │        │                             │                             │ d}:${RestApi0C43BF4B}/test-i │
│   │                             │        │                             │                             │ nvoke-stage/*/"              │
│   │                             │        │                             │                             │ }                            │
├───┼─────────────────────────────┼────────┼─────────────────────────────┼─────────────────────────────┼──────────────────────────────┤
│ + │ ${LambdaFunctionServiceRole │ Allow  │ sts:AssumeRole              │ Service:lambda.amazonaws.co │                              │
│   │ .Arn}                       │        │                             │ m                           │                              │
├───┼─────────────────────────────┼────────┼─────────────────────────────┼─────────────────────────────┼──────────────────────────────┤
│ + │ ${LambdaRestApiCloudWatchRo │ Allow  │ sts:AssumeRole              │ Service:apigateway.amazonaw │                              │
│   │ le.Arn}                     │        │                             │ s.com                       │                              │
├───┼─────────────────────────────┼────────┼─────────────────────────────┼─────────────────────────────┼──────────────────────────────┤
│ + │ arn:aws:logs:${AWS::Region} │ Allow  │ logs:CreateLogGroup         │ AWS:${LambdaRestApiCloudWat │                              │
│   │ :${AWS::AccountId}:*        │        │ logs:CreateLogStream        │ chRole}                     │                              │
│   │                             │        │ logs:DescribeLogGroups      │                             │                              │
│   │                             │        │ logs:DescribeLogStreams     │                             │                              │
│   │                             │        │ logs:FilterLogEvents        │                             │                              │
│   │                             │        │ logs:GetLogEvents           │                             │                              │
│   │                             │        │ logs:PutLogEvents           │                             │                              │
├───┼─────────────────────────────┼────────┼─────────────────────────────┼─────────────────────────────┼──────────────────────────────┤
│ + │ arn:aws:logs:${AWS::Region} │ Allow  │ logs:CreateLogGroup         │ AWS:${LambdaFunctionService │                              │
│   │ :${AWS::AccountId}:log-grou │        │ logs:CreateLogStream        │ Role}                       │                              │
│   │ p:/aws/lambda/*             │        │ logs:PutLogEvents           │                             │                              │
└───┴─────────────────────────────┴────────┴─────────────────────────────┴─────────────────────────────┴──────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Parameters
[+] Parameter AssetParameters/ba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340a/S3Bucket AssetParametersba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340aS3Bucket9780A3BC: {"Type":"String","Description":"S3 bucket for asset \"ba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340a\""}
[+] Parameter AssetParameters/ba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340a/S3VersionKey AssetParametersba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340aS3VersionKey37F36FFB: {"Type":"String","Description":"S3 key for asset version \"ba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340a\""}
[+] Parameter AssetParameters/ba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340a/ArtifactHash AssetParametersba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340aArtifactHash80199FBC: {"Type":"String","Description":"Artifact hash for asset \"ba91444ebd644d9419e8cfee417f3aaa728507dd428788a2fc40574646c4340a\""}

Conditions
[+] Condition CDKMetadataAvailable: {"Fn::Or":[{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ca-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-northwest-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-central-1"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-3"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"me-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"sa-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-2"]}]}]}

Resources
[+] AWS::Logs::LogGroup ApiGatewayToLambda/ApiAccessLogGroup ApiGatewayToLambdaApiAccessLogGroupE2B41502 
[+] AWS::IAM::Role LambdaFunctionServiceRole LambdaFunctionServiceRole0C4CDE0B 
[+] AWS::Lambda::Function LambdaFunction LambdaFunctionBF21E41F 
[+] AWS::ApiGateway::RestApi RestApi RestApi0C43BF4B 
[+] AWS::ApiGateway::Deployment RestApi/Deployment RestApiDeployment180EC503d2c6df3c8dc8b7193b98c1a0bff4e677 
[+] AWS::ApiGateway::Stage RestApi/DeploymentStage.prod RestApiDeploymentStageprod3855DE66 
[+] AWS::ApiGateway::Resource RestApi/Default/{proxy+} RestApiproxyC95856DD 
[+] AWS::Lambda::Permission RestApi/Default/{proxy+}/ANY/ApiPermission.HelloConstructsStackRestApiFDB18C2E.ANY..{proxy+} RestApiproxyANYApiPermissionHelloConstructsStackRestApiFDB18C2EANYproxyE43D39B3 
[+] AWS::Lambda::Permission RestApi/Default/{proxy+}/ANY/ApiPermission.Test.HelloConstructsStackRestApiFDB18C2E.ANY..{proxy+} RestApiproxyANYApiPermissionTestHelloConstructsStackRestApiFDB18C2EANYproxy0B23CDC7 
[+] AWS::ApiGateway::Method RestApi/Default/{proxy+}/ANY RestApiproxyANY1786B242 
[+] AWS::Lambda::Permission RestApi/Default/ANY/ApiPermission.HelloConstructsStackRestApiFDB18C2E.ANY.. RestApiANYApiPermissionHelloConstructsStackRestApiFDB18C2EANY5684C1E6 
[+] AWS::Lambda::Permission RestApi/Default/ANY/ApiPermission.Test.HelloConstructsStackRestApiFDB18C2E.ANY.. RestApiANYApiPermissionTestHelloConstructsStackRestApiFDB18C2EANY81DBDF56 
[+] AWS::ApiGateway::Method RestApi/Default/ANY RestApiANYA7C1DC94 
[+] AWS::ApiGateway::UsagePlan RestApi/UsagePlan RestApiUsagePlan6E1C537A 
[+] AWS::Logs::LogGroup ApiAccessLogGroup ApiAccessLogGroupCEA70788 
[+] AWS::IAM::Role LambdaRestApiCloudWatchRole LambdaRestApiCloudWatchRoleF339D4E6 
[+] AWS::ApiGateway::Account LambdaRestApiAccount LambdaRestApiAccount 

Outputs
[+] Output RestApi/Endpoint RestApiEndpoint0551178A: {"Value":{"Fn::Join":["",["https://",{"Ref":"RestApi0C43BF4B"},".execute-api.",{"Ref":"AWS::Region"},".",{"Ref":"AWS::URLSuffix"},"/",{"Ref":"RestApiDeploymentStageprod3855DE66"},"/"]]}}
```

 Eso es bonito. Este sencillo ejemplo con un patrón bien diseñado de AWS Solutions Constructs añadió 21 nuevos recursos a su pila. 

## Implementar cdk
<a name="cdk-deploy"></a>

**sugerencia**  
Antes de poder implementar su primera aplicación de AWS CDK que contenga una función Lambda, debe iniciar su entorno de AWS. Esto crea un depósito provisional que el CDK de AWS utiliza para implementar pilas que contienen activos. Si esta es la primera vez que utiliza AWS CDK para implementar activos, deberá ejecutar el`cdk bootstrap`para implementar la pila del kit de herramientas CDK en su entorno de AWS. 

 ¿Listo para la implementación? 

```
cdk deploy
```

## Salida de la pila
<a name="stack-outputs"></a>

 Cuando se haya completado la implementación, notará esta línea: 

```
Outputs:
HelloConstructsStack.RestApiEndpoint0551178A = https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/
```

 Se trata de una salida de pila que se agrega automáticamente mediante el patrón AWS Solutions Constructs e incluye la URL del extremo API Gateway. 

## Probar su aplicación
<a name="testing-your-app"></a>

 Vamos a tratar de llegar a este punto final con`curl`. Copie la URL y ejecute (es probable que su prefijo y Región sean diferentes). 

```
curl https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/
```

 La salida debe tener el siguiente aspecto: 

```
Hello, AWS Solutions Constructs! You've hit /
```

 Si esta es la salida que recibiste, ¡tu aplicación funciona\$1 

# Tutorial - Parte 2
<a name="walkthrough-part-2"></a>

**nota**  
AWS Solutions Constructs es compatible con las versiones de AWS CDK ≥ 1.46.0. 

 Este tutorial le guiará a través de cómo modificar la aplicación «Hello Constructs» creada en[Parte 1](walkthrough-part-1.md). Nuestra modificación agregará un contador de visitas de sitios utilizando el patrón AWS Lambda al DynamoDB de AWS Solutions Constructs. La modificación de la aplicación Hello Constructs dará como resultado la siguiente solución: 

![\[alt text not found\]](http://docs.aws.amazon.com/es_es/solutions/latest/constructs/images/tutorial-part2.png)


## Código de Hit Counter Lambda
<a name="hit-counter-lambda-code"></a>

 Comencemos escribiendo el código para la función Hit Counter AWS Lambda. Esta función: 
+  aumentar un contador relacionado con la ruta de la API en una tabla de Amazon DynamoDB, 
+  invocar la función Hello AWS Lambda descendente, 
+  y devolver la respuesta al usuario final. 

------
#### [ TypeScript ]

Añadir un archivo denominado`lambda/hitcounter.js`con el siguiente contenido:

```
  const { DynamoDB, Lambda } = require('aws-sdk');

exports.handler = async function(event) {
  console.log("request:", JSON.stringify(event, undefined, 2));

  // create AWS SDK clients
  const dynamo = new DynamoDB();
  const lambda = new Lambda();

  // update dynamo entry for "path" with hits++
  await dynamo.updateItem({
    TableName: process.env.DDB_TABLE_NAME,
    Key: { path: { S: event.path } },
    UpdateExpression: 'ADD hits :incr',
    ExpressionAttributeValues: { ':incr': { N: '1' } }
  }).promise();

  // call downstream function and capture response
  const resp = await lambda.invoke({
    FunctionName: process.env.DOWNSTREAM_FUNCTION_NAME,
    Payload: JSON.stringify(event)
  }).promise();

  console.log('downstream response:', JSON.stringify(resp, undefined, 2));

  // return response back to upstream caller
  return JSON.parse(resp.Payload);
};
```

------
#### [ Python ]

Añadir un archivo denominado`lambda/hitcounter.py`con el siguiente contenido:

```
import json
import os
import boto3

ddb = boto3.resource('dynamodb')
table = ddb.Table(os.environ['DDB_TABLE_NAME'])
_lambda = boto3.client('lambda')


def handler(event, context):
    print('request: {}'.format(json.dumps(event)))
    table.update_item(
        Key={'path': event['path']},
        UpdateExpression='ADD hits :incr',
        ExpressionAttributeValues={':incr': 1}
    )

    resp = _lambda.invoke(
        FunctionName=os.environ['DOWNSTREAM_FUNCTION_NAME'],
        Payload=json.dumps(event),
    )

    body = resp['Payload'].read()

    print('downstream response: {}'.format(body))
    return json.loads(body)
```

------

## Instalar las nuevas dependencias
<a name="install-the-new-dependencies"></a>

**nota**  
Recuerde sustituir la versión correcta y coincidente que se utilizará tanto para AWS Solutions Constructs como para AWS CDK en el`VERSION_NUMBER`campos de marcador de posición para cada comando. Debe ser idéntico al número de versión utilizado para las dependencias en la primera parte de este tutorial. Las versiones incorrectas entre los paquetes pueden causar errores.

 Como de costumbre, primero tenemos que instalar las dependencias que necesitamos para la actualización de nuestra solución. En primer lugar, tenemos que instalar la biblioteca de construcción de DynamoDB: 

------
#### [ TypeScript ]

```
      npm install -s @aws-cdk/aws-dynamodb@VERSION_NUMBER
```

------
#### [ Python ]

```
      pip install aws_cdk.aws_dynamodb==VERSION_NUMBER
```

------

 Por último, instale los constructos de soluciones de AWS`aws-lambda-dynamodb`y todas sus dependencias en nuestro proyecto: 

------
#### [ TypeScript ]

```
      npm install -s @aws-solutions-constructs/aws-lambda-dynamodb@VERSION_NUMBER
```

------
#### [ Python ]

```
      pip install aws_solutions_constructs.aws_lambda_dynamodb==VERSION_NUMBER   
```

------

## Defina los recursos
<a name="define-the-resources"></a>

 Ahora, actualicemos nuestro código de pila para acomodar nuestra nueva arquitectura. 

 Primero, vamos a importar nuestras nuevas dependencias y mover la función «Hola» fuera del`aws-apigateway-lambda`que hemos creado en la parte 1. 

------
#### [ TypeScript ]

Editar el archivo`lib/hello-constructs.ts`con lo siguiente:

```
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as api from '@aws-cdk/aws-apigateway';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda';
import { LambdaToDynamoDB, LambdaToDynamoDBProps } from '@aws-solutions-constructs/aws-lambda-dynamodb';

export class HelloConstructsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    const helloFunc = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_12_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });

    const api_lambda_props: ApiGatewayToLambdaProps = {
      lambdaFunctionProps: {
        code: lambda.Code.fromAsset('lambda'),
        runtime: lambda.Runtime.NODEJS_12_X,
        handler: 'hello.handler'
      },
      apiGatewayProps: {
        defaultMethodOptions: {
          authorizationType: api.AuthorizationType.NONE
        }
      }
    };

    new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props);
  }
}
```

------
#### [ Python ]

Editar el archivo`hello_constructs/hello_constructs_stack.py`con lo siguiente:

```
from aws_cdk import (
    aws_lambda as _lambda,
    aws_apigateway as apigw,
    aws_dynamodb as ddb,
    core,
)

from aws_solutions_constructs import (
    aws_apigateway_lambda as apigw_lambda,
    aws_lambda_dynamodb as lambda_ddb
)

class HelloConstructsStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # The code that defines your stack goes here

        self._handler = _lambda.Function(
          self, 'HelloHandler',
          runtime=_lambda.Runtime.PYTHON_3_7,
          handler='hello.handler',
          code=_lambda.Code.asset('lambda'),
        )

        apigw_lambda.ApiGatewayToLambda(
            self, 'ApiGatewayToLambda',
            lambda_function_props=_lambda.FunctionProps(
                runtime=_lambda.Runtime.PYTHON_3_7,
                code=_lambda.Code.asset('lambda'),
                handler='hello.handler',
            ),
            api_gateway_props=apigw.RestApiProps(
                default_method_options=apigw.MethodOptions(
                    authorization_type=apigw.AuthorizationType.NONE
                )
            )
        )
```

------

 A continuación, vamos a añadir el`aws-lambda-dynamodb`para construir el servicio de contador de visitas para nuestra arquitectura actualizada. 

![\[alt text not found\]](http://docs.aws.amazon.com/es_es/solutions/latest/constructs/images/tutorial-part2a.png)


 En la siguiente actualización se definen las propiedades de la`aws-lambda-dynamodb`mediante la definición de la función AWS Lambda con el controlador de contador de visitas. Además, la tabla de Amazon DynamoDB se define con un nombre`Hits`y una clave de partición de`path`. 

------
#### [ TypeScript ]

Editar el archivo`lib/hello-constructs.ts`con lo siguiente:

```
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as api from '@aws-cdk/aws-apigateway';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda';
import { LambdaToDynamoDB, LambdaToDynamoDBProps } from '@aws-solutions-constructs/aws-lambda-dynamodb';

export class HelloConstructsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    const helloFunc = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_12_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });

    // hit counter, aws-lambda-dynamodb pattern
    const lambda_ddb_props: LambdaToDynamoDBProps = {
      lambdaFunctionProps: {
          code: lambda.Code.asset(`lambda`),
          runtime: lambda.Runtime.NODEJS_12_X,
          handler: 'hitcounter.handler',
          environment: {
              DOWNSTREAM_FUNCTION_NAME: helloFunc.functionName
          }
      },
      dynamoTableProps: {
          tableName: 'Hits',
          partitionKey: { name: 'path', type: dynamodb.AttributeType.STRING }
      }
    };

    const hitcounter = new LambdaToDynamoDB(this, 'LambdaToDynamoDB', lambda_ddb_props);

    const api_lambda_props: ApiGatewayToLambdaProps = {
      lambdaFunctionProps: {
        code: lambda.Code.fromAsset('lambda'),
        runtime: lambda.Runtime.NODEJS_12_X,
        handler: 'hello.handler'
      },
      apiGatewayProps: {
        defaultMethodOptions: {
          authorizationType: api.AuthorizationType.NONE
        }
      }
    };

    new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props);
  }
}
```

------
#### [ Python ]

Editar el archivo`hello_constructs/hello_constructs_stack.py`con lo siguiente:

```
from aws_cdk import (
    aws_lambda as _lambda,
    aws_apigateway as apigw,
    aws_dynamodb as ddb,
    core,
)

from aws_solutions_constructs import (
    aws_apigateway_lambda as apigw_lambda,
    aws_lambda_dynamodb as lambda_ddb
)

class HelloConstructsStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # The code that defines your stack goes here

        self.hello_func = _lambda.Function(
          self, 'HelloHandler',
          runtime=_lambda.Runtime.PYTHON_3_7,
          handler='hello.handler',
          code=_lambda.Code.asset('lambda'),
        )

        #  hit counter, aws-lambda-dynamodb pattern
        self.hit_counter = lambda_ddb.LambdaToDynamoDB(
            self, 'LambdaToDynamoDB',
            lambda_function_props=_lambda.FunctionProps(
                runtime=_lambda.Runtime.PYTHON_3_7,
                code=_lambda.Code.asset('lambda'),
                handler='hitcounter.handler',
                environment={
                    'DOWNSTREAM_FUNCTION_NAME': self.hello_func.function_name
                }
            ),
            dynamo_table_props=ddb.TableProps(
                table_name='Hits',
                partition_key={
                    'name': 'path',
                    'type': ddb.AttributeType.STRING
                }
            )
        )

        apigw_lambda.ApiGatewayToLambda(
            self, 'ApiGatewayToLambda',
            lambda_function_props=_lambda.FunctionProps(
                runtime=_lambda.Runtime.PYTHON_3_7,
                code=_lambda.Code.asset('lambda'),
                handler='hello.handler',
            ),
            api_gateway_props=apigw.RestApiProps(
                default_method_options=apigw.MethodOptions(
                    authorization_type=apigw.AuthorizationType.NONE
                )
            )
        )
```

------

 A continuación, tenemos que conceder la función Contador de visitas creada a partir de la`aws-lambda-dynamodb`patrón agregado anteriormente permiso para invocar nuestra función Hello. 

------
#### [ TypeScript ]

Editar el archivo`lib/hello-constructs.ts`con lo siguiente:

```
  import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as api from '@aws-cdk/aws-apigateway';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda';
import { LambdaToDynamoDB, LambdaToDynamoDBProps } from '@aws-solutions-constructs/aws-lambda-dynamodb';

export class HelloConstructsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    // hello function responding to http requests 
    const helloFunc = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_12_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });

    // hit counter, aws-lambda-dynamodb pattern
    const lambda_ddb_props: LambdaToDynamoDBProps = {
      lambdaFunctionProps: {
          code: lambda.Code.asset(`lambda`),
          runtime: lambda.Runtime.NODEJS_12_X,
          handler: 'hitcounter.handler',
          environment: {
              DOWNSTREAM_FUNCTION_NAME: helloFunc.functionName
          }
      },
      dynamoTableProps: {
          tableName: 'Hits',
          partitionKey: { name: 'path', type: dynamodb.AttributeType.STRING }
      }
    };

    const hitcounter = new LambdaToDynamoDB(this, 'LambdaToDynamoDB', lambda_ddb_props);

    // grant the hitcounter lambda role invoke permissions to the hello function
    helloFunc.grantInvoke(hitcounter.lambdaFunction);

    const api_lambda_props: ApiGatewayToLambdaProps = {
      lambdaFunctionProps: {
        code: lambda.Code.fromAsset('lambda'),
        runtime: lambda.Runtime.NODEJS_12_X,
        handler: 'hello.handler'
      },
      apiGatewayProps: {
        defaultMethodOptions: {
          authorizationType: api.AuthorizationType.NONE
        }
      }
    };

    new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props);
  }
}
```

------
#### [ Python ]

Editar el archivo`hello_constructs/hello_constructs_stack.py`con lo siguiente:

```
from aws_cdk import (
    aws_lambda as _lambda,
    aws_apigateway as apigw,
    aws_dynamodb as ddb,
    core,
)

from aws_solutions_constructs import (
    aws_apigateway_lambda as apigw_lambda,
    aws_lambda_dynamodb as lambda_ddb
)

class HelloConstructsStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # The code that defines your stack goes here

        self.hello_func = _lambda.Function(
          self, 'HelloHandler',
          runtime=_lambda.Runtime.PYTHON_3_7,
          handler='hello.handler',
          code=_lambda.Code.asset('lambda'),
        )

        #  hit counter, aws-lambda-dynamodb pattern
        self.hit_counter = lambda_ddb.LambdaToDynamoDB(
            self, 'LambdaToDynamoDB',
            lambda_function_props=_lambda.FunctionProps(
                runtime=_lambda.Runtime.PYTHON_3_7,
                code=_lambda.Code.asset('lambda'),
                handler='hitcounter.handler',
                environment={
                    'DOWNSTREAM_FUNCTION_NAME': self.hello_func.function_name
                }
            ),
            dynamo_table_props=ddb.TableProps(
                table_name='Hits',
                partition_key={
                    'name': 'path',
                    'type': ddb.AttributeType.STRING
                }
            )
        )

        # grant the hitcounter lambda role invoke permissions to the hello function
        self.hello_func.grant_invoke(self.hit_counter.lambda_function)

        apigw_lambda.ApiGatewayToLambda(
            self, 'ApiGatewayToLambda',
            lambda_function_props=_lambda.FunctionProps(
                runtime=_lambda.Runtime.PYTHON_3_7,
                code=_lambda.Code.asset('lambda'),
                handler='hello.handler',
            ),
            api_gateway_props=apigw.RestApiProps(
                default_method_options=apigw.MethodOptions(
                    authorization_type=apigw.AuthorizationType.NONE
                )
            )
        )
```

------

 Por último, tenemos que actualizar nuestro`aws-apigateway-lambda`para utilizar nuestra nueva función de contador de visitas que se aprovisionó con el`aws-lambda-dynamodb`patrón anterior. 

------
#### [ TypeScript ]

Editar el archivo`lib/hello-constructs.ts`con lo siguiente:

```
  import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as api from '@aws-cdk/aws-apigateway';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda';
import { LambdaToDynamoDB, LambdaToDynamoDBProps } from '@aws-solutions-constructs/aws-lambda-dynamodb';

export class HelloConstructsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    // hello function responding to http requests 
    const helloFunc = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_12_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });

    // hit counter, aws-lambda-dynamodb pattern
    const lambda_ddb_props: LambdaToDynamoDBProps = {
      lambdaFunctionProps: {
          code: lambda.Code.asset(`lambda`),
          runtime: lambda.Runtime.NODEJS_12_X,
          handler: 'hitcounter.handler',
          environment: {
              DOWNSTREAM_FUNCTION_NAME: helloFunc.functionName
          }
      },
      dynamoTableProps: {
          tableName: 'Hits',
          partitionKey: { name: 'path', type: dynamodb.AttributeType.STRING }
      }
    };

    const hitcounter = new LambdaToDynamoDB(this, 'LambdaToDynamoDB', lambda_ddb_props);

    // grant the hitcounter lambda role invoke permissions to the hello function
    helloFunc.grantInvoke(hitcounter.lambdaFunction);

    const api_lambda_props: ApiGatewayToLambdaProps = {
      existingLambdaObj: hitcounter.lambdaFunction,
      apiGatewayProps: {
        defaultMethodOptions: {
          authorizationType: api.AuthorizationType.NONE
        }
      }
    };

    new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props);
  }
}
```

------
#### [ Python ]

Editar el archivo`hello_constructs/hello_constructs_stack.py`con lo siguiente:

```
from aws_cdk import (
    aws_lambda as _lambda,
    aws_apigateway as apigw,
    aws_dynamodb as ddb,
    core,
)

from aws_solutions_constructs import (
    aws_apigateway_lambda as apigw_lambda,
    aws_lambda_dynamodb as lambda_ddb
)

class HelloConstructsStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # The code that defines your stack goes here

        self.hello_func = _lambda.Function(
          self, 'HelloHandler',
          runtime=_lambda.Runtime.PYTHON_3_7,
          handler='hello.handler',
          code=_lambda.Code.asset('lambda'),
        )

        #  hit counter, aws-lambda-dynamodb pattern
        self.hit_counter = lambda_ddb.LambdaToDynamoDB(
            self, 'LambdaToDynamoDB',
            lambda_function_props=_lambda.FunctionProps(
                runtime=_lambda.Runtime.PYTHON_3_7,
                code=_lambda.Code.asset('lambda'),
                handler='hitcounter.handler',
                environment={
                    'DOWNSTREAM_FUNCTION_NAME': self.hello_func.function_name
                }
            ),
            dynamo_table_props=ddb.TableProps(
                table_name='Hits',
                partition_key={
                    'name': 'path',
                    'type': ddb.AttributeType.STRING
                }
            )
        )

        # grant the hitcounter lambda role invoke permissions to the hello function
        self.hello_func.grant_invoke(self.hit_counter.lambda_function)

        apigw_lambda.ApiGatewayToLambda(
            self, 'ApiGatewayToLambda',
            existing_lambda_obj=self.hit_counter.lambda_function,
            api_gateway_props=apigw.RestApiProps(
                default_method_options=apigw.MethodOptions(
                    authorization_type=apigw.AuthorizationType.NONE
                )
            )
        )
```

------

## Revisar los cambios
<a name="review-the-changes"></a>

 Construyamos nuestro proyecto y revisemos los cambios en nuestros recursos que se producirán cuando implementemos esto: 

```
npm run build
cdk diff
```

 Nuestra salida debe tener el siguiente aspecto: 

```
Stack HelloConstructsStack
IAM Statement Changes
┌───┬───────────────────────────────────┬────────┬───────────────────────────────────┬────────────────────────────────────┬───────────┐
│   │ Resource                          │ Effect │ Action                            │ Principal                          │ Condition │
├───┼───────────────────────────────────┼────────┼───────────────────────────────────┼────────────────────────────────────┼───────────┤
│ + │ ${HelloHandler.Arn}               │ Allow  │ lambda:InvokeFunction             │ AWS:${LambdaFunctionServiceRole}   │           │
├───┼───────────────────────────────────┼────────┼───────────────────────────────────┼────────────────────────────────────┼───────────┤
│ + │ ${HelloHandler/ServiceRole.Arn}   │ Allow  │ sts:AssumeRole                    │ Service:lambda.amazonaws.com       │           │
├───┼───────────────────────────────────┼────────┼───────────────────────────────────┼────────────────────────────────────┼───────────┤
│ + │ ${LambdaToDynamoDB/DynamoTable.Ar │ Allow  │ dynamodb:BatchGetItem             │ AWS:${LambdaFunctionServiceRole}   │           │
│   │ n}                                │        │ dynamodb:BatchWriteItem           │                                    │           │
│   │                                   │        │ dynamodb:DeleteItem               │                                    │           │
│   │                                   │        │ dynamodb:GetItem                  │                                    │           │
│   │                                   │        │ dynamodb:GetRecords               │                                    │           │
│   │                                   │        │ dynamodb:GetShardIterator         │                                    │           │
│   │                                   │        │ dynamodb:PutItem                  │                                    │           │
│   │                                   │        │ dynamodb:Query                    │                                    │           │
│   │                                   │        │ dynamodb:Scan                     │                                    │           │
│   │                                   │        │ dynamodb:UpdateItem               │                                    │           │
└───┴───────────────────────────────────┴────────┴───────────────────────────────────┴────────────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬─────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                    │ Managed Policy ARN                                                             │
├───┼─────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${HelloHandler/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴─────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Resources
[+] AWS::IAM::Role HelloHandler/ServiceRole HelloHandlerServiceRole11EF7C63 
[+] AWS::Lambda::Function HelloHandler HelloHandler2E4FBA4D 
[+] AWS::DynamoDB::Table LambdaToDynamoDB/DynamoTable LambdaToDynamoDBDynamoTable53C1442D 
[+] AWS::IAM::Policy LambdaFunctionServiceRole/DefaultPolicy LambdaFunctionServiceRoleDefaultPolicy126C8897 
[~] AWS::Lambda::Function LambdaFunction LambdaFunctionBF21E41F 
 ├─ [+] Environment
 │   └─ {"Variables":{"DOWNSTREAM_FUNCTION_NAME":{"Ref":"HelloHandler2E4FBA4D"},"DDB_TABLE_NAME":{"Ref":"LambdaToDynamoDBDynamoTable53C1442D"}}}
 ├─ [~] Handler
 │   ├─ [-] hello.handler
 │   └─ [+] hitcounter.handler
 └─ [~] DependsOn
     └─ @@ -1,3 +1,4 @@
        [ ] [
        [+]   "LambdaFunctionServiceRoleDefaultPolicy126C8897",
        [ ]   "LambdaFunctionServiceRole0C4CDE0B"
        [ ] ]
```

## cdk/
<a name="cdk-deploy-1"></a>

 Bien, ¿listo para la implementación? 

```
cdk deploy
```

## Salida de la pila
<a name="stack-outputs-1"></a>

 Cuando se haya completado la implementación, notará lo siguiente: 

```
Outputs:
HelloConstructsStack.RestApiEndpoint0551178A = https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/
```

## Probar su aplicación
<a name="testing-your-app-1"></a>

 Tratemos de golpear este punto final con rizo. Copie la URL y ejecute (es probable que su prefijo y región sean diferentes). 

```
curl https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/
```

 La salida debe tener el siguiente aspecto: 

```
Hello, AWS Solutions Constructs! You've hit /
```

 Ahora vamos a revisar el`Hits`Tabla de Amazon DynamoDB. 

1.  Vaya a la consola de DynamoDB. 

1.  Asegúrese de que se encuentra en la región donde creó la tabla. 

1.  Select**Tablas**en el panel de navegación y seleccione la casilla**Hits**Tabla de. 

1.  Abra la tabla y seleccione «Elementos». 

1.  Deberías ver cuántos aciertos tienes por cada camino.  
![\[alt text not found\]](http://docs.aws.amazon.com/es_es/solutions/latest/constructs/images/tutorial-part2b.png)

1.  Intente acceder a una nueva ruta y actualice la vista Elementos. Debería ver un nuevo elemento con un`hits`cuenta de uno. 

 Si esta es la salida que recibiste, ¡tu aplicación funciona\$1 

# Casos de uso de ejemplo
<a name="sample-use-cases"></a>

 Esta biblioteca incluye una colección de implementaciones de casos de uso funcionales para demostrar el uso de patrones arquitectónicos de componentes fijos. Estos se pueden usar de la misma manera que los patrones arquitectónicos, y pueden ser conceptualizados como una abstracción adicional de «nivel superior» de esos patrones. Los siguientes casos de uso se proporcionan como ejemplos funcionales: 

## Sitio web estático de AWS S3
<a name="aws-static-s3-website"></a>

 Este patrón de caso de uso (`aws-s3-static-website`) implementa una distribución de Amazon CloudFront, un depósito de Amazon S3 y un recurso personalizado basado en AWS Lambda para copiar el contenido del sitio web estático para el sitio web de demostración de Wild Rydes (parte del`aws-serverless-web-app`Aplicación). 

**Código fuente (aws-s3-static-website)**  
 [https://github.com/awslabs/aws-solutions-constructs/tree/master/source/use\$1cases/aws-s3-static-website](https://github.com/awslabs/aws-solutions-constructs/tree/master/source/use_cases/aws-s3-static-website) 

## Controlador de imágenes sencillo sin servidor de AWS
<a name="aws-simple-erverless-image-handler"></a>

 Este patrón de caso de uso (`aws-serverless-image-handler`) implementa una distribución de Amazon CloudFront, una API de REST de Amazon API Gateway, una función de AWS Lambda y los permisos/lógicos necesarios para aprovisionar una API de controlador de imágenes funcional para servir contenido de imagen desde uno o más depósitos de Amazon S3 dentro de la cuenta de implementación. 

**Código fuente (aws-serverless-image-handler)**  
 [https://github.com/awslabs/aws-solutions-constructs/tree/master/source/use\$1cases/aws-serverless-image-handler](https://github.com/awslabs/aws-solutions-constructs/tree/master/source/use_cases/aws-serverless-image-handler) 

## Aplicación web sin servidor de AWS
<a name="aws-serverless-web-app"></a>

 Este patrón de caso de uso (`aws-serverless-web-app`) implementa una sencilla aplicación web sin servidor que permite a los usuarios solicitar viajes en unicornio a la flota de Wild Rydes. La aplicación presentará a los usuarios una interfaz de usuario basada en HTML para indicar la ubicación donde les gustaría ser recogidos y se interconectará en el back-end con un servicio web RESTful para enviar la solicitud y enviar un unicornio cercano. La aplicación también proporcionará facilidades para que los usuarios se registren en el servicio e inicien sesión antes de solicitar viajes. 

**Código fuente (aws-serverless-web-app)**  
 [https://github.com/awslabs/aws-solutions-constructs/tree/master/source/use\$1cases/aws-serverless-web-app](https://github.com/awslabs/aws-solutions-constructs/tree/master/source/use_cases/aws-serverless-web-app) 