

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# AWS 솔루션 구성 시작하기
<a name="getting-started-with-aws-solutions-constructs"></a>

 이 항목에서는 AWS CDK (Cloud Development Kit), AWS 솔루션 구성을 설치 및 구성하고 AWS 솔루션 구축 패턴을 사용하여 첫 번째 AWS CDK 앱을 만드는 방법에 대해 설명합니다.

**참고**  
AWS 솔루션 구문은 AWS CDK 버전 이상 1.46.0에서 지원됩니다.

**작은 정보**  
 더 깊이 파고 싶습니까? 사용해보기[CDK 워크샵](https://cdkworkshop.com/)에서 실제 프로젝트에 대한 심층적 인 투어를 제공합니다.

**작은 정보**  
 AWS CDK (AWS Cloud Development Kit) 시작하기에 대한 자세한 내용은[AWS CDK 개발자 안내서](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html).

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

 AWS 솔루션 구문은 AWS CDK를 기반으로 구축되므로 TypeScript 스크립트 또는 JavaScript 이외의 언어로 작업하는 경우에도 Node.js (>= 10.3.0) 를 설치해야 합니다. 이 때문에[AWS CDK](https://github.com/aws/aws-cdk)및 AWS 솔루션 구문은 TypeScript 터로 개발되었으며 Node.js 에서 실행됩니다. 지원되는 다른 언어에 대한 바인딩은이 백엔드 및 도구 집합을 사용합니다.

 자격 증명 및 리전 지정에 설명된 대로 AWS CDK CLI를 사용하려면 자격 증명과 AWS 리전을 제공해야 합니다.

 기타 전제 조건은 다음과 같이 개발 언어에 따라 다릅니다.


|  **언어**  |  **사전 조건**  | 
| --- | --- | 
|  ![\[Python\]](http://docs.aws.amazon.com/ko_kr/solutions/latest/constructs/images/python.png)Python  |  Python 3.6  | 
|  ![\[TypeScript\]](http://docs.aws.amazon.com/ko_kr/solutions/latest/constructs/images/typescript.png)TypeScript  |  TypeScript >= 2.7  | 
|  ![\[Java\]](http://docs.aws.amazon.com/ko_kr/solutions/latest/constructs/images/java.png)Java | Java 1.8 | 

## AWS CDK 설치
<a name="installing-the-aws-cdk"></a>

 AWS CDK를 설치 및 구성하려면 AWS CDK 개발자 가이드 ([AWS CDK 설치](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install).

## AWS 솔루션 구성 작업
<a name="working-with-the-aws-solutions-constructs-library"></a>

 AWS 솔루션 구성으로 작업할 때 새 앱을 만드는 일반적인 워크플로는 AWS CDK와 동일한 접근 방식을 따릅니다.

1.  앱 디렉토리를 만듭니다.

1.  앱을 초기화합니다.

1.  AWS 솔루션 구성 패턴 종속성을 추가합니다.

1.  앱에 추가 코드를 추가합니다.

1.  필요한 경우 앱을 컴파일합니다.

1.  앱에 정의된 리소스를 배포합니다.

1.  앱을 테스트합니다.

 문제가 있으면 수정, 컴파일 (필요한 경우), 배포 및 다시 테스트하십시오.

# 이동장면 - 1부
<a name="walkthrough-part-1"></a>

**참고**  
AWS 솔루션 구조는 AWS CDK 버전 1.46.0 이상에서 지원됩니다.

 이 자습서에서는 프로젝트 초기부터 결과 AWS CloudFormation 템플릿 배포에 이르기까지 AWS 솔루션 구조의 패턴을 사용하는 간단한 “Hello Constructs” AWS CDK 앱을 만들고 배포하는 방법을 안내합니다. Hello 구성 응용 프로그램은 다음과 같은 간단한 솔루션을 만듭니다: 

![\[아키텍처 다이어그램\]](http://docs.aws.amazon.com/ko_kr/solutions/latest/constructs/images/tutorial-part1.png)


## Hello 구조
<a name="hello-konstruk"></a>

 패턴 기반 개발을 사용하여 첫 번째 AWS CDK 앱 구축을 시작해 보겠습니다.

**참고**  
 이것은의 샘플 수정입니다`Hello CDK!`( 사용)[CDK 워크숍](https://cdkworkshop.com/). AWS CDK를 처음 사용하는 경우 이 워크숍부터 실습 연습과 CDK를 활용하여 실제 프로젝트를 구축하는 방법을 권장합니다.

## 애플리케이션 디렉토리 생성 및 AWS CDK 초기화
<a name="creating-the-app-directory-and-initializing-the-aws-cdk"></a>

 CDK 앱의 디렉토리를 생성한 다음 해당 디렉토리에 AWS CDK 앱을 생성합니다.

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

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

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

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

------

**작은 정보**  
이제 좋아하는 IDE에서 프로젝트를 열고 탐색 할 수있는 좋은 시간입니다. 프로젝트 구조에 대한 자세한 내용은 해당 링크를 선택합니다.  
[TypeScript](https://cdkworkshop.com/20-typescript/20-create-project/300-structure.html)
[Python](https://cdkworkshop.com/30-python/20-create-project/300-structure.html)

## 프로젝트 기반 종속성 업데이트
<a name="update-project-base-dependencies-to-use-aws-cdk"></a>

**주의**  
적절한 기능을 보장하기 위해 AWS 솔루션 구성과 AWS CDK 패키지는 프로젝트 내에서 동일한 버전 번호를 사용해야 합니다. 예를 들어 AWS 솔루션 구성 v.1.52.0을 사용하는 경우 AWS CDK v.1.52.0도 사용해야 합니다.

**작은 정보**  
 AWS 솔루션 구성의 최신 버전을 메모하고 해당 버전 번호를`VERSION_NUMBER`자리 표시자를 참조하십시오 (AWS 솔루션 구성 및 AWS CDK 패키지 모두에 대해). 구성 라이브러리의 모든 공개 릴리스를 확인하려면[여기를 클릭하십시오.](https://github.com/awslabs/aws-solutions-constructs/releases).

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

편집`package.json`파일에 다음 정보가 포함됩니다.

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

편집`setup.py`파일에 다음 정보가 포함됩니다.

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

------

 프로젝트 기반 종속성을 설치하십시오.

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

```
npm install      
```

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

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

------

 앱을 빌드하고 실행하고 빈 스택을 생성하는지 확인합니다.

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

```
 npm run build 
 cdk synth
```

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

```
 cdk synth           
```

------

 다음과 같이 스택이 표시되어야 합니다.`CDK-VERSION`는 CDK의 버전입니다. (출력은 여기에 표시된 것과 약간 다를 수 있습니다.) 

------
#### [ 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
```

------

## Lambda 핸들 코드
<a name="lambda-handler-code"></a>

 AWS Lambda 핸들러 코드부터 시작하겠습니다.

 디렉터리 생성`lambda`프로젝트 트리의 루트에 추가합니다.

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

이라는 파일을 추가합니다.`lambda/hello.js`다음의 콘텐츠가 포함됩니다.

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

이라는 파일을 추가합니다.`lambda/hello.py`다음의 콘텐츠가 포함됩니다.

```
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'])
    }
```

------

 이것은 텍스트를 반환하는 간단한 Lambda 함수입니다 “안녕하세요, 구조\$1 [URL 경로] 를 눌렀습니다.” 함수의 출력에는 HTTP 상태 코드와 HTTP 헤더도 포함됩니다. API Gateway 에서 사용자에게 HTTP 응답을 공식화하는 데 사용됩니다.

 이 Lambda JavaScript 제공됩니다. 선택한 언어로 Lambda 함수를 작성하는 방법에 대한 자세한 내용은[AWS Lambda 설명서](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html).

## AWS CDK 및 AWS 솔루션 구축 종속성 설치
<a name="install-the-aws-cdk-and-aws-solutions-constructs-library-dependencies"></a>

 AWS 솔루션 구문은 광범위한 구조 라이브러리와 함께 제공됩니다. 라이브러리는 잘 설계된 각 패턴에 대해 하나씩 모듈로 나뉩니다. 예를 들어 AWS Lambda 함수에 Amazon API Gateway 레스트 API를 정의하려는 경우`aws-apigateway-lambda`패턴 라이브러리를 생성합니다.

 또한 AWS CDK에서 AWS Lambda 및 Amazon API Gateway 구성 라이브러리를 추가해야 합니다.

 AWS Lambda 모듈과 모든 종속성을 프로젝트에 설치합니다.

**참고**  
AWS 솔루션 구문과 AWS CDK 모두에 사용할 올바른 일치 버전을`VERSION_NUMBER`각 명령에 대한 자리 표시자 필드입니다. 패키지 간에 버전이 일치하지 않으면 오류가 발생할 수 있습니다.

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

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

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

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

------

 그런 다음 Amazon API Gateway 모듈과 모든 종속성을 프로젝트에 설치하십시오.

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

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

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

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

------

 마지막으로, AWS 솔루션 구문을 설치합니다.`aws-apigateway-lambda`모듈과 모든 종속성을 프로젝트에 추가합니다.

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

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

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

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

------

## 스택에 Amazon API 게이트웨이/AWS 람다 패턴 추가
<a name="add-an-aws-api-gatewayaws-lambda-pattern-to-your-stack"></a>

 이제 AWS Lambda 프록시를 사용하여 Amazon API Gateway 구현하기 위한 AWS 솔루션 구성 패턴을 정의해 보겠습니다.

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

파일을 편집합니다.`lib/hello-constructs.ts`에서 다음을 사용합니다.

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

파일을 편집합니다.`hello_constructs/hello_constructs_stack.py`에서 다음을 사용합니다.

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

------

 그게 다야 AWS Lambda 함수에 대한 모든 요청을 프록시하는 API Gateway 정의하기 위해 필요한 모든 작업입니다. 새로운 스택을 원래 스택과 비교해 보겠습니다.

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

```
npm run build    
cdk diff
```

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

```
cdk diff       
```

------

 출력은 다음과 같아야 합니다.

```
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"},"/"]]}}
```

 그건 좋은 일이야 AWS 솔루션 구조에서 잘 설계된 패턴 하나를 사용한 이 간단한 예제는 스택에 21개의 새로운 리소스를 추가했습니다.

## cdk 배포
<a name="cdk-deploy"></a>

**작은 정보**  
Lambda 함수가 포함된 첫 번째 AWS CDK 앱을 배포하려면 먼저 AWS 환경을 부트스트랩해야 합니다. 이렇게 하면 AWS CDK가 자산을 포함하는 스택을 배포하는 데 사용하는 스테이징 버킷이 생성됩니다. AWS CDK를 사용하여 자산을 배포하는 것이 처음인 경우`cdk bootstrap`를 사용하여 CDK 툴킷 스택을 AWS 환경에 배포할 수 있습니다.

 좋아, 배포할 준비가 되셨나요?

```
cdk deploy
```

## 스택 출력
<a name="stack-outputs"></a>

 배포가 완료되면 다음 줄을 확인할 수 있습니다.

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

 이는 AWS 솔루션 구성 패턴에 의해 자동으로 추가되는 스택 출력이며 API Gateway 엔드포인트의 URL을 포함합니다.

## 앱 테스트
<a name="testing-your-app"></a>

 이 끝점을 사용하려고합시다.`curl`. URL을 복사하고 실행하십시오 (접두사와 지역이 다를 수 있음).

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

 출력은 다음과 같아야 합니다.

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

 이것이 당신이받은 출력 인 경우, 앱이 작동합니다\$1

# 이동장면 - 부품 2
<a name="walkthrough-part-2"></a>

**참고**  
AWS 솔루션 구성은 AWS CDK 버전 

 이 자습서에서는 에서 만든 “Hello Constructs” 앱을 수정하는 방법을 안내합니다.[파트](walkthrough-part-1.md). 수정하면 AWS Lambda를 사용하여 AWS 솔루션 구문에서 DynamoDB 패턴에 사이트 히트 카운터가 추가됩니다. Hello Constructs 앱을 수정하면 다음과 같은 해결책이 생성됩니다.

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


## Lambda 코드 히트
<a name="hit-counter-lambda-code"></a>

 먼저 히트 카운터 AWS Lambda 함수에 대한 코드를 작성해 보겠습니다. 이 함수는 다음을 수행합니다.
+  는 Amazon DynamoDB 테이블의 API 경로와 관련된 카운터를 증가시키고 
+  다운스트림 Hello AWS Lambda 함수를 호출합니다.
+  를 호출하고 최종 사용자에게 응답을 반환합니다.

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

이라는 파일을 추가합니다.`lambda/hitcounter.js`다음의 콘텐츠가 포함된 것들과 변경됩니다.

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

이라는 파일을 추가합니다.`lambda/hitcounter.py`다음의 콘텐츠가 포함된 것들과 변경됩니다.

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

------

## 새 종속성 설치
<a name="install-the-new-dependencies"></a>

**참고**  
AWS 솔루션 구문과 AWS CDK 모두에 사용할 올바른 일치 버전을`VERSION_NUMBER`각 명령에 대한 자리 표시자 필드 이 연습의 첫 번째 부분에서 종속성에 사용된 버전 번호와 동일해야 합니다. 패키지 간에 버전이 일치하지 않으면 오류가 발생할 수 있습니다.

 평소와 같이 솔루션 업데이트에 필요한 종속성을 먼저 설치해야합니다. 먼저 DynamoDB 구성 라이브러리를 설치해야 합니다.

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

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

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

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

------

 마지막으로, AWS 솔루션 구문을 설치합니다.`aws-lambda-dynamodb`모듈과 모든 종속성을 프로젝트에 추가합니다.

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

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

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

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

------

## 리소스를 정의합니다.
<a name="define-the-resources"></a>

 이제 새로운 아키텍처를 수용하기 위해 스택 코드를 업데이트해 보겠습니다.

 첫째, 우리는 우리의 새로운 종속성을 가져 와서 외부의 “안녕하세요”기능을 이동하려고합니다`aws-apigateway-lambda`우리가 파트 1에서 만든 패턴.

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

파일을 편집합니다.`lib/hello-constructs.ts`다음의 것들과 변경됩니다.

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

파일을 편집합니다.`hello_constructs/hello_constructs_stack.py`다음의 것들과 변경됩니다.

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

------

 다음으로, 우리는 추가 할 것입니다`aws-lambda-dynamodb`패턴을 사용하여 업데이트 된 아키텍처에 대한 히트 카운터 서비스를 구축 할 수 있습니다.

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


 다음 업데이트는 아래의 속성을 정의`aws-lambda-dynamodb`패턴을 사용하여 히트 카운터 처리기를 사용하여 AWS Lambda 함수를 정의합니다. 또한 Amazon DynamoDB 테이블은`Hits`의 파티션 키`path`.

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

파일을 편집합니다.`lib/hello-constructs.ts`다음의 것들과 변경됩니다.

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

파일을 편집합니다.`hello_constructs/hello_constructs_stack.py`다음의 것들과 변경됩니다.

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

------

 다음으로, 우리는에서 생성 된 히트 카운터 함수를 부여해야합니다`aws-lambda-dynamodb`패턴은 우리의 Hello 함수를 호출 할 수있는 권한 위에 추가되었습니다.

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

파일을 편집합니다.`lib/hello-constructs.ts`다음의 것들과 변경됩니다.

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

파일을 편집합니다.`hello_constructs/hello_constructs_stack.py`다음의 것들과 변경됩니다.

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

------

 마지막으로 원본을 업데이트해야합니다.`aws-apigateway-lambda`패턴을 사용하여 프로비저닝된 새로운 히트 카운터 함수를 활용할 수 있습니다.`aws-lambda-dynamodb`패턴을 사용합니다.

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

파일을 편집합니다.`lib/hello-constructs.ts`다음의 것들과 변경됩니다.

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

파일을 편집합니다.`hello_constructs/hello_constructs_stack.py`다음의 것들과 변경됩니다.

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

------

## 변경 사항 검토
<a name="review-the-changes"></a>

 프로젝트를 빌드하고 배포 할 때 발생할 리소스의 변경 사항을 검토해 보겠습니다.

```
npm run build
cdk diff
```

 출력은 다음과 같아야 합니다.

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

 좋아, 배포할 준비가 되셨나요?

```
cdk deploy
```

## 스택 출력
<a name="stack-outputs-1"></a>

 배포가 완료되면 다음 줄을 확인할 수 있습니다.

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

## 앱 테스트
<a name="testing-your-app-1"></a>

 이 끝점을 컬로 치려고 노력합시다. URL을 복사하고 실행하십시오 (접두사와 지역이 다를 수 있음).

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

 출력은 다음과 같아야 합니다.

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

 이제 검토해 보겠습니다.`Hits`Amazon DynamoDB DB 테이블 

1.  DynamoDB 콘솔로 이동합니다.

1.  테이블을 생성한 리전에 있는지 확인합니다.

1.  Select**테이블**탐색 창에서**Hits**테이블을 생성합니다.

1.  테이블을 열고 “항목”을 선택하십시오.

1.  각 경로에 대해 얼마나 많은 히트 곡을 볼 수 있습니다.  
![\[alt text not found\]](http://docs.aws.amazon.com/ko_kr/solutions/latest/constructs/images/tutorial-part2b.png)

1.  새 경로를 누르고 항목 보기를 새로 고치십시오. 새 항목이 표시되어야 합니다.`hits`하나의 카운트.

 이것이 당신이받은 출력 인 경우, 앱이 작동합니다\$1

# 예제 사용 사례
<a name="sample-use-cases"></a>

 이 라이브러리에는 구조 아키텍처 패턴의 사용을 보여주기 위해 기능적 유스 케이스 구현의 컬렉션이 포함되어 있습니다. 이들은 아키텍처 패턴과 같은 방식으로 사용할 수 있으며 이러한 패턴의 추가 “상위 수준”추상화로 개념화 될 수 있습니다. 다음과 같은 사용 사례가 기능적 예제로 제공됩니다.

## AWS 정적 S3 웹 사이트
<a name="aws-static-s3-website"></a>

 이 유스 케이스 패턴 (`aws-s3-static-website`) 는 Amazon CloudFront 배포, Amazon S3 버킷 및 AWS 람다 기반 사용자 지정 리소스를 구현하여 Wild Rydes 데모 웹 사이트의 정적 웹 사이트 콘텐츠를 복사합니다 (`aws-serverless-web-app`구현입니다).

**소스 코드 (AWS-s3-정적 웹 사이트)**  
 [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) 

## AWS 단순 서버를 사용하지 않는 이미지 처리기
<a name="aws-simple-erverless-image-handler"></a>

 이 유스 케이스 패턴 (`aws-serverless-image-handler`) 는 Amazon CloudFront 배포, Amazon API Gateway REST API, AWS Lambda 함수 및 배포 계정 내의 하나 이상의 Amazon S3 버킷에서 이미지 콘텐츠를 제공하기 위한 기능 이미지 처리기 API를 프로비저닝하는 데 필요한 권한/논리를 구현합니다.

**소스 코드 (AWS 서버리스 이미지 처리기)**  
 [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) 

## AWS 서버리스 웹 앱
<a name="aws-serverless-web-app"></a>

 이 유스 케이스 패턴 (`aws-serverless-web-app`) 는 사용자가 Wild Rydes 함대에서 유니콘 라이드를 요청할 수 있는 간단한 서버를 사용하지 않는 웹 애플리케이션을 구현합니다. 응용 프로그램은 사용자에게 선택하고자하는 위치를 나타내는 HTML 기반 사용자 인터페이스를 제공하고 요청을 제출하고 근처의 유니콘을 디스패치하기 위해 RESTful 웹 서비스와 백엔드에서 인터페이스합니다. 또한 이 응용 프로그램은 사용자가 서비스에 등록하고 승차 요청 전에 로그인 할 수있는 기능을 제공합니다.

**소스 코드 (aws-서버-웹 응용 프로그램)**  
 [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) 