Exemplarische Vorgehensweise - Teil 1 - Konstrukte für AWS S-Lösungen

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Exemplarische Vorgehensweise - Teil 1

Anmerkung

AWS Solutions Constructs wird in AWS CDK-Versionen ≥ 1.46.0 unterstützt.

In diesem Lernprogramm erfahren Sie, wie Sie eine einfache AWS CDK-App „Hello Constructs“ erstellen und bereitstellen, die ein Muster aus AWS Solutions Constructs verwendet, von der Initialisierung des Projekts bis zur Bereitstellung der resultierenden AWS CloudFormation Vorlage. Die Hello Constructs App erstellt die folgende einfache Lösung:

Architekturdiagramm

Hello Konstrukte

Beginnen wir mit der Erstellung unserer ersten AWS CDK-App mit der musterbasierten Entwicklung.

Anmerkung

Dies ist eine Beispieländerung vonHello CDK!ausCDK-Werkstatt. Wenn Sie zum ersten Mal das AWS CDK verwenden, empfehlen wir Ihnen, mit diesem Workshop zu beginnen, um eine praktische exemplarische Vorgehensweise zu erhalten und wie Sie das CDK beim Erstellen eines realen Projekts nutzen können.

Erstellen des App-Verzeichnisses und Initialisierung des AWS CDK

Erstellen Sie ein Verzeichnis für Ihre CDK-App, und erstellen Sie dann eine AWS CDK-App in diesem Verzeichnis.

TypeScript
mkdir hello-constructs cd hello-constructs cdk init --language typescript
Python
mkdir hello-constructs cd hello-constructs cdk init --language python
Tipp

Jetzt ist ein guter Zeitpunkt, um das Projekt in Ihrer Lieblings-IDE zu öffnen und zu erkunden. Wählen Sie den entsprechenden Link aus, um mehr über die Projektstruktur zu erfahren:

Aktualisieren von Projektbasis-Abhängigkeiten

Warnung

Um eine ordnungsgemäße Funktionalität sicherzustellen, müssen AWS Solutions Constructs und AWS CDK-Pakete dieselbe Versionsnummer in Ihrem Projekt verwenden. Wenn Sie beispielsweise AWS Solutions Constructs v.1.52.0 verwenden, müssen Sie auch AWS CDK v.1.52.0 verwenden.

Tipp

Notieren Sie sich die neueste Version von AWS Solutions Constructs, und wenden Sie diese Versionsnummer auf dieVERSION_NUMBERin den folgenden Schritten (sowohl für AWS Solutions Constructs als auch für AWS CDK-Pakete). Um alle öffentlichen Releases der Konstrukts-Bibliothek zu überprüfen,Click here.

TypeScript

Bearbeiten Sie diepackage.json-Dateienthält die folgenden Informationen:

"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

Bearbeiten Sie diesetup.py-Dateienthält die folgenden Informationen:

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

Installieren Sie die Projekt-Basisabhängigkeiten.

TypeScript
npm install
Python
source .venv/bin/activate pip install -r requirements.txt

Erstellen Sie die App und führen Sie sie aus und bestätigen Sie, dass sie einen leeren Stack erstellt.

TypeScript
npm run build cdk synth
Python
cdk synth

Sie sollten einen Stack-Code wie unten dargestellt, wobeiCDK-VERSIONist die Version des CDK. (Ihre Ausgabe kann geringfügig von der hier gezeigten Abbildung abweichen.)

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

Code für Lambda Handler

Wir beginnen mit dem AWS Lambda Handler-Code.

Erstellen eines -Verzeichnisseslambdaim Stammverzeichnis Ihres Projektbaums.

TypeScript

Fügen Sie eine Datei mit dem Namenlambda/hello.js-Inhalt mit folgendem Inhalt:

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

Fügen Sie eine Datei mit dem Namenlambda/hello.py-Inhalt mit folgendem Inhalt:

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

Dies ist eine einfache Lambda Funktion, die den Text „Hallo, Constructs! Sie haben [URL-Pfad]“ getroffen. Die Ausgabe der Funktion enthält auch den HTTP-Statuscode und HTTP-Header. Diese werden von API Gateway verwendet, um die HTTP-Antwort an den Benutzer zu formulieren.

Dieses Lambda ist in JavaScript zur Verfügung gestellt. Weitere Informationen zum Schreiben von Lambda Funktionen in Ihrer Sprache finden Sie imAWS Lambda Dokumentation.

Installieren der Abhängigkeiten von AWS CDK und AWS Solutions Constructs

Die AWS Solutions Constructs werden mit einer umfangreichen Bibliothek von Konstrukten ausgeliefert. Die Bibliothek ist in Module unterteilt, eines für jedes gut gestaltete Muster. Wenn Sie beispielsweise eine Amazon API Gateway Rest-API für eine AWS Lambda Funktion definieren möchten, müssen wir dieaws-apigateway-lambdaPattern-Bibliothek.

Außerdem müssen wir die Konstruktionsbibliothek AWS Lambda und Amazon API Gateway aus dem AWS CDK hinzufügen.

Installieren Sie das AWS Lambda Modul und alle seine Abhängigkeiten in unserem Projekt:

Anmerkung

Denken Sie daran, die richtige, übereinstimmende Version zu ersetzen, die sowohl für AWS Lösungskonstrukte als auch für das AWS-CDK verwendet werden soll, in dasVERSION_NUMBERPlatzhalterfelder für jeden Befehl. Fehlübereinstimmende Versionen zwischen Paketen können zu Fehlern führen.

TypeScript
npm install -s @aws-cdk/aws-lambda@VERSION_NUMBER
Python
pip install aws_cdk.aws_lambda==VERSION_NUMBER

Als nächstes installieren Sie das Amazon API Gateway Modul und alle seine Abhängigkeiten in unserem Projekt:

TypeScript
npm install -s @aws-cdk/aws-apigateway@VERSION_NUMBER
Python
pip install aws_cdk.aws_apigateway==VERSION_NUMBER

Installieren Sie schließlich die AWS Solutions Constructsaws-apigateway-lambdaModul und alle seine Abhängigkeiten in unser Projekt:

TypeScript
npm install -s @aws-solutions-constructs/aws-apigateway-lambda@VERSION_NUMBER
Python
pip install aws_solutions_constructs.aws_apigateway_lambda==VERSION_NUMBER

Hinzufügen eines Amazon API Gateway/AWS Lambda-Musters zu Ihrem Stack

Lassen Sie uns nun das AWS Solutions Constructs-Muster für die Implementierung eines Amazon API Gateway mit einem AWS Lambda Proxy definieren.

TypeScript

Bearbeiten Sie die Dateilib/hello-constructs.ts-Code mit folgendem Inhalt:

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

Bearbeiten Sie die Dateihello_constructs/hello_constructs_stack.py-Code mit folgendem Inhalt:

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

Das war's. Dies ist alles, was Sie tun müssen, um ein API Gateway zu definieren, das alle Anforderungen an eine AWS Lambda Funktion weiterleitet. Vergleichen wir unseren neuen Stack mit dem ursprünglichen:

TypeScript
npm run build cdk diff
Python
cdk diff

Die Ausgabe sollte in etwa wie folgt aussehen:

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

Das ist schön. In diesem einfachen Beispiel mit einem gut gestalteten Muster aus den AWS Solutions Constructs wurden Ihrem Stack 21 neue Ressourcen hinzugefügt.

cdk-Bereitstellen

Tipp

Bevor Sie Ihre erste AWS CDK-App mit einer Lambda Funktion bereitstellen können, müssen Sie Ihre AWS-Umgebung booten. Dadurch wird ein Staging-Bucket erstellt, den das AWS CDK zum Bereitstellen von Stacks mit Assets verwendet. Wenn Sie zum ersten Mal das AWS CDK für die Bereitstellung von Assets verwenden, müssen Sie diecdk bootstrap, um den CDK-Toolkit-Stack in Ihrer AWS Umgebung bereitzustellen.

Ok, bereit zur Bereitstellung?

cdk deploy

Stack-Ausgaben

Wenn die Bereitstellung abgeschlossen ist, werden Sie folgende Zeile bemerken:

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

Dies ist eine Stapelausgabe, die automatisch vom AWS Solutions Constructs-Muster hinzugefügt wird und die URL des API Gateway Endpunkts enthält.

Testen Ihrer Anwendung

Lassen Sie uns versuchen, diesen Endpunkt mitcurl. Kopieren Sie die URL und führen Sie sie aus (Ihr Präfix und Ihre Region werden wahrscheinlich anders sein).

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

Die Ausgabe sollte wie folgt aussehen:

Hello, AWS Solutions Constructs! You've hit /

Wenn dies die Ausgabe ist, die Sie erhalten haben, funktioniert Ihre App!