この記事では、AWS のサービスを利用したサーバーレス API の開発を示し、AWS 環境内で継続的インテグレーション/継続的デプロイメント (CICD) パイプラインを確立します。
パート 1: API ゲートウェイからのリクエストを処理し、サーバーレス アプリケーション モデルを使用してデータを DynamoDB に保存する Lambda 関数の作成について説明します。
パート 2: AWS で CodeCommit リポジトリを設定し、リポジトリへの新しい変更の送信時にビルド プロセスを自動的に開始する CICD パイプラインを設定するために必要な手順を詳しく説明します。
このプロジェクトには、AWS アカウントが必要です (無料利用枠で十分です)。次の AWS コンポーネントが使用されます。
ローカル開発環境が次のように設定されていることを確認してください。
AWS CLI をインストールする:ここのガイドに従って、AWS コマンドライン インターフェイスをインストールします。
AWS SAM (サーバーレス アプリケーション モデル) のインストール: ここの手順に従って SAM CLI をインストールします。
IDE を選択する: 開発には IntelliJ または同様の IDE を使用します。私はIntelliJの方が好きです
パッケージ化用の Maven : アプリケーションをパッケージ化するために Maven がインストールされていることを確認してください。
オプション: Docker (Lambda 関数をローカルでテストする必要がある場合): Lambda 関数をローカルでテストする予定がある場合は、Docker をインストールします。
これらのツールとコンポーネントがプロジェクトの基礎を形成します。
このセクションでは、ハンドラー クラスの完成、構築、AWS へのデプロイ、Postman を使用したテストの実施など、AWS SAM を使用してスターター プロジェクトを作成するプロセスについて説明します。
環境設定
AWS のセットアップ:
https://aws.amazon.com/console/の AWS コンソールに移動し、管理者ユーザーの認証情報を使用してログインします。
ローカルマシンで AWS CLI を設定します。
$ aws configure
を実行しますAWS サーバーレス アプリケーション モデル (SAM) を使用してプロジェクトを初期化します。
$ sam init
を実行しますプロジェクトの名前を変更する: プロジェクトの名前を好みの名前に変更します。
IntelliJ でプロジェクトを開く: IntelliJ を起動し、プロジェクトを開きます。
依存関係を pom.xml に追加します。
必要な依存関係をpom.xml
ファイルに追加します。他の依存関係は SAM によって自動的に組み込まれるため、DynamoDB を追加するだけで済みます。
<dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.11.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-dynamodb</artifactId> <version>1.12.573</version> </dependency> </dependencies>
ハンドラークラスを書く
lambda 関数の場合、sam によって自動的に生成されたハンドラー クラスを編集し、次のコードを追加します。これは単純なコードですが、実際のプロジェクトでは、よりモジュール化されたコードを使用することもできます。
public class UserRequestHandler implements RequestHandler<Map<String,String>, Map<String,String>> { private AmazonDynamoDB amazonDynamoDB; private String DYNAMODB_TABLE_NAME = "users"; private Regions REGION = Regions.US_EAST_1; @Override public Map<String,String> handleRequest(Map<String,String> input, Context context) { this.initDynamoDbClient(); LambdaLogger logger = context.getLogger(); logger.log("Input payload:" + input.toString()); String userId = UUID.randomUUID().toString(); String firstName= input.get("firstName"); String lastName= input.get("lastName"); Map<String, AttributeValue> attributesMap = new HashMap<>(); attributesMap.put("id", new AttributeValue(userId)); attributesMap.put("firstName", new AttributeValue(firstName)); attributesMap.put("lastName", new AttributeValue(lastName)); logger.log(attributesMap.toString()); amazonDynamoDB.putItem(DYNAMODB_TABLE_NAME, attributesMap); Map<String, String> response = new HashMap<>(); response.put("id", userId); response.put("firstName", firstName); response.put("lastName", lastName); return response; } private void initDynamoDbClient() { this.amazonDynamoDB = AmazonDynamoDBClientBuilder.standard() .withRegion(REGION) .build(); } }
SAM テンプレート ファイルを更新する
SAM テンプレート ファイルは、AWS への変更を構築してデプロイする際に重要な役割を果たします。プロジェクトのファイルを更新します。このファイル内で注目すべき重要な要素は、Lambda 関数名と API Gateway エンドポイントです。これらはサーバーレス アプリケーションの機能の中心となります。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > pc-aws-user-api Sample SAM Template for pc-aws-user-api # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 20 MemorySize: 128 Tracing: Active Api: TracingEnabled: true Resources: UserRequestHandlerLambdaFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: PcAwsUsersApi Handler: com.pc.aws.users.UserRequestHandler::handleRequest Runtime: java11 Architectures: - x86_64 MemorySize: 512 Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: PARAM1: VALUE JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1 # More info about tiered compilation https://aws.amazon.com/blogs/compute/optimizing-aws-lambda-function-performance-for-java/ Events: PcUsers: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /users Method: post ApplicationResourceGroup: Type: AWS::ResourceGroups::Group Properties: Name: Fn::Sub: ApplicationInsights-SAM-${AWS::StackName} ResourceQuery: Type: CLOUDFORMATION_STACK_1_0 ApplicationInsightsMonitoring: Type: AWS::ApplicationInsights::Application Properties: ResourceGroupName: Ref: ApplicationResourceGroup AutoConfigurationEnabled: 'true' Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api PcAwsUsersApi: Description: API Gateway endpoint URL for Prod stage Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/users/" UserRequestHandlerLambdaFunction: Description: Lambda Function ARN Value: !GetAtt UserRequestHandlerLambdaFunction.Arn UserRequestHandlerLambdaFunctionIamRole: Description: Implicit IAM Role created Value: !GetAtt UserRequestHandlerLambdaFunctionRole.Arn
SAM を使用したコードのビルドとデプロイ
IntelliJ でターミナルを開き、次のコマンドを実行します。
$ sam build
$ sam deploy –guided
プロンプトが表示されたら、スタック名として「PcAwsUsersApi」を入力し、デフォルトのオプションを選択します。
出力には、作成された CloudFormation スタックが表示され、API ゲートウェイ エンドポイントも提供されます。
APIをテストする
API をテストする前に、SAM によって作成された Lambda ロールへの DynamoDB アクセスを許可します。
このステップにより、Lambda 関数が DynamoDB と対話するために必要な権限を持っていることが保証されます。
API Gateway に移動し、次の手順に従ってサービスの URL を取得します。
AWS コンソールで API ゲートウェイに移動します。
API を選択します。
左側のサイドバーで「ステージ」をクリックします。
「ステージ」で「本番」ステージを選択します。
Stage Editor セクションに「Invoke URL」があります。この URL をコピーします。
Content-Type: application/json
)。
このセクションでは、AWS CodeCommit、CodeBuild、CodePipeline を使用して CICD パイプラインを構築する方法を説明します。パイプラインは、リポジトリからコードを取得し、ビルド ファイルを使用してコードをビルドし、CloudFormation をトリガーしてスタックを作成するビルド プロセスを開始します。
CodeCommit リポジトリの作成
AWS にログインし、CodeCommit サービスを検索します。
AWS CodeCommit で新しいリポジトリを作成し、プロジェクトのソースコードを保存します。
コードをリポジトリにコミット
IntelliJ でターミナルを開き、次のコマンドを入力して、手順 I で作成したコードをコミットします。
$ git init → This initialize local git $ git add . → This will stage files $ git commit -m "commit to CodeCommit"
変更をリモート リポジトリにプッシュする
aws コンソールから CodeCommit リポジトリ URL をコピーします。
$ git remote add origin <repo URL> $ git push --set-upstream origin master --> This will prompt for user/password
AWS CodeBuild プロジェクトを作成する
アプリケーションの構築方法を指定する CodeBuild プロジェクトを設定します。これには、ビルド環境、ビルド コマンド、依存関係の定義が含まれます。
CodeBuild を設定するには、プロジェクト ディレクトリにbuildspec.yml
という名前のビルド仕様ファイルを作成する必要があります。このファイルには、CodeBuild のビルド コマンドと手順が含まれます。
buildspec.yml
ファイルの作成に関する詳細な手順については、こちらの公式ドキュメントを参照してください。
version: 0.2 phases: install: runtime-versions: java: corretto11 pre_build: commands: - echo Nothing to do in the pre_build phase... build: commands: - echo Build started on `date` - sam build - sam package --output-template-file pcoutputtemplate.yaml --s3-bucket com-appsdev-pc-001 post_build: commands: - echo Build completed on `date` artifacts: files: - pcoutputtemplate.yaml
新しいファイルをローカルからリポジトリにプッシュします。
この後、プロジェクトをビルドして、コードがリポジトリからプルされ、アーティファクトがビルドされるかどうかを確認できます。
コードパイプラインを作成する
パイプラインは、git コミットに基づいてコードを自動的に構築し、デプロイします。
パイプラインをテストする
$ git branch CR01 $ git checkout CR01 $ git add . $ git commit -m “CR01” $ git push --set-upstream origin CR01 You cand also create a pull request in aws code commit, just for simplicity I am merging from local $ git checkout master $ git merge --ff-only CR01 $ git push
これにより、コードに変更を加えてリポジトリにプッシュし、CICD パイプラインが自動的にトリガーして更新されたコードをデプロイするプロセスがシミュレートされます。
この記事では、AWS API Gateway、Lambda、DynamoDB、CodeCommit、CodeBuild、および CodePipeline を利用して、復元力のある自動化されたデプロイメント プロセスを構築する方法を示します。
読んでくれてありがとう。あなたのサーバーレスへの取り組みが成功と革新をもたらしますように!