이동장면 - 1부 - AWS 솔루션 구성체

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

이동장면 - 1부

참고

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

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


      아키텍처 다이어그램

Hello 구조

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

참고

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

애플리케이션 디렉토리 생성 및 AWS CDK 초기화

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에서 프로젝트를 열고 탐색 할 수있는 좋은 시간입니다. 프로젝트 구조에 대한 자세한 내용은 해당 링크를 선택합니다.

프로젝트 기반 종속성 업데이트

주의

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

작은 정보

AWS 솔루션 구성의 최신 버전을 메모하고 해당 버전 번호를VERSION_NUMBER자리 표시자를 참조하십시오 (AWS 솔루션 구성 및 AWS CDK 패키지 모두에 대해). 구성 라이브러리의 모든 공개 릴리스를 확인하려면여기를 클릭하십시오..

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 핸들 코드

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 함수입니다 “안녕하세요, 구조! [URL 경로] 를 눌렀습니다.” 함수의 출력에는 HTTP 상태 코드와 HTTP 헤더도 포함됩니다. API Gateway 에서 사용자에게 HTTP 응답을 공식화하는 데 사용됩니다.

이 Lambda JavaScript 제공됩니다. 선택한 언어로 Lambda 함수를 작성하는 방법에 대한 자세한 내용은AWS Lambda 설명서.

AWS CDK 및 AWS 솔루션 구축 종속성 설치

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 람다 패턴 추가

이제 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 배포

작은 정보

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

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

cdk deploy

스택 출력

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

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

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

앱 테스트

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

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

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

Hello, AWS Solutions Constructs! You've hit /

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