みなさんこんにちは、システム部のエーデルワイスです。
フィリピンから日本に来て、GMOリサーチに入社し半年以上が経ちました。この半年間はとても充実していて、技術的なスキルはもちろんのこと、日本語スキルも少しだけですが向上させることができました。
私はこれまで、インフラの整備や保守に携わっており、インフラのデプロイとメンテナンスをできるだけ簡単にすることを常に最優先事項としていました。なので、みなさんにもプロジェクトのインフラを理解することの重要性を知ってもらいたいと思っています。
また、その中で私はAWS Cloud Development Kit(CDK)とLocalstackに出会いました。
AWS CDKはAWS CloudFormationテンプレートのように機能しますが、ユーザーは複雑なCloudFormationの関数やテンプレートを覚える必要はないので、管理がより簡単になります。さらに、ユーザーが特定のプログラミング言語をきちんと理解していれば、リソースのデプロイも簡単に行うことができます。
これらのツールの詳細については、AWS CDKとLocalstackの公式ページを見てみてください。
この記事では、そのツールのインストール方法と使用方法を紹介していきたいと思います。
具体的には、私はLocalstackとAWS CDKを使用して、学習や調査に使用できるAPIをデプロイすることに成功しました。ここから、私がこの目的を達成するために実行した手順を紹介していきたいと思います。
基本設計・アーキテクチャ
この記事における基本設計は、とてもシンプルで分かりやすいものです。API Gateway と Lambda のみを使用して、サンプルの REST API を作成します。
環境構築 (Windows)
Localstack
1.pythonを使用してlocalstackをインストールする
1 |
python -m pip install localstack |
2. localstackを開始
1 |
localstack start |
3. localstackの状況を確認
1 2 |
localstack status services |
localstackのインストールと起動が成功すると、次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓ ┃ Service ┃ Status ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩ │ acm │ ✔ available │ │ apigateway │ ✔ available │ │ cloudformation │ ✔ available │ │ cloudwatch │ ✔ available │ │ config │ ✔ available │ │ dynamodb │ ✔ available │ │ dynamodbstreams │ ✔ available │ │ ec2 │ ✔ available │ │ es │ ✔ available │ │ events │ ✔ available │ │ firehose │ ✔ available │ │ iam │ ✔ available │ │ kinesis │ ✔ available │ │ kms │ ✔ available │ │ lambda │ ✔ available │ │ logs │ ✔ available │ │ opensearch │ ✔ available │ │ redshift │ ✔ available │ │ resource-groups │ ✔ available │ │ resourcegroupstaggingapi │ ✔ available │ │ route53 │ ✔ available │ │ route53resolver │ ✔ available │ │ s3 │ ✔ available │ │ s3control │ ✔ available │ │ scheduler │ ✔ available │ │ secretsmanager │ ✔ available │ │ ses │ ✔ available │ │ sns │ ✔ available │ │ sqs │ ✔ available │ │ sqs-query │ ✔ available │ │ ssm │ ✔ available │ │ stepfunctions │ ✔ available │ │ sts │ ✔ available │ │ support │ ✔ available │ │ swf │ ✔ available │ │ transcribe │ ✔ available │ └──────────────────────────┴─────────────┘ |
AWS CDK
AWS CDKをインストールして使用するために必要となるのは、新しい空のディレクトリを作成し、cdkコマンドを実行するだけです。
1.空のディレクトリを作成
1 2 3 |
mkdir cdk-techblog cd cdk-techblog |
2.cdkをインストール
1 |
npm install -g aws-cdk-local aws-cdk |
3.cdklocalを初期化する
1 |
cdklocal init --language python |
この記事では、私はプログラミング言語としてPythonを使用しました。また、AWS CDKではTypeScript、JavaScript、Java、C#、Goなどのプログラミング言語もサポートされているため、このツールは誰にとっても非常に使いやすいものになります。
cdklocal initというコマンドを使用した場合、リソースの作成を開始するためのディレクトリが初期化されます。
リソースを作成するために、1つのファイルを編集し、新しいファイルを作成します。
AWSリソースの作成(LambdaとAPI Gateway)
Lambdaコードの作成
新しいディレクトリとLambdaハンドラー込*1用の新しいファイルを作成します。
このプロジェクトでは、実行されるたびに「Hello World!」を返す非常にシンプルなLambdaをデプロイします。
※*1:イベントを処理する関数コード内のメソッドのこと
参照:Python の Lambda 関数ハンドラー
File: src/lamba_handler.py
1 2 3 4 5 6 7 8 9 10 |
def handler(event, context): response = { 'statusCode': 200, 'body': "Hello World!", 'headers': { 'Content-Type': 'application/json' } } return response |
スタックを更新して、Lambda関数を作成し、Lambda関数をAPI Gatewayと統合します。
File: cdk_techblog/cdk_techblog_stack.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from aws_cdk import ( aws_lambda as _lambda, aws_apigateway as apigw, Stack, ) from constructs import Construct class CdkTechblogStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) lambda_func = _lambda.Function( self, 'HelloWorldLambda', handler='lambda_handler.handler', runtime=_lambda.Runtime.PYTHON_3_7, code=_lambda.Code.from_asset('src') ) api = apigw.RestApi(self, "HelloWorldApi") api_gw_resource = api.root.add_resource("test") api_gw_integration = apigw.LambdaIntegration(lambda_func) api_gw_resource.add_method("GET", api_gw_integration) |
上記のコードでは、Pythonで’HelloWorldLambda’という名前のLambda関数と、HelloWorldApiという名前のAPI Gateway RestAPIを作成します。また、API Gatewayにはtestという名前のリソースも含まれています。
リソースのコードが完成したら、デプロイする準備が整います。
LocalStackへのリソースのデプロイ
1.Run cdk bootstrap
1 |
cdklocal bootstrap |
このコマンドは、AWS CDKがスタックをデプロイするために使用するAWS S3 Bucketを作成します。このコマンドは、最初のデプロイ時または一度だけ実行されます。
バケットが正常に作成されたことを確認するには、次の localstack を実行して確認します。
1 |
aws s3 ls --endpoint-url=http://localhost:4566 |
これにより、次のように作成されたS3バケットが出力されます。
1 2 |
2023-11-13 20:40:12 cdk-hnb659fds-assets-000000000000-ap-northeast-1 |
2.Deploy Command
1 2 |
cdklocal deploy |
デプロイが成功した場合、作成されたスタックが表示され、デプロイが成功したことが確認されます。
1 2 3 4 5 6 |
✅ CdkTechblogStack ✨ Deployment time: 10.39s Outputs: CdkTechblogStack.HelloWorldApiEndpointAD496187 = https://7u9zuost7i.execute-api.localhost.localstack.cloud:4566/prod/ Stack ARN: arn:aws:cloudformation:ap-northeast-1:000000000000:stack/CdkTechblogStack/9e5b2cf2 |
これで以上です。ほんのわずかなコマンドを利用するだけで、AWSリソースをLocalstackにデプロイすることができました。ただし、リソースが希望どおりに機能するかどうかを確認する必要があります。それでは、テストしてみましょう。
デプロイされたリソースのテスト
リソースがデプロイされたかどうかを確認するために、curlコマンドを使用します。
1 |
curl http://localhost:4566/restapis/<rest_api_id>/<stage_name>/_user_request_/<resource_name> |
AWS CLIを使用して、URLを完成させるための値を取得します。
1. <rest_api_id>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
aws apigateway get-rest-apis --endpoint-url=http://localhost:4566 $ aws apigateway get-rest-apis --endpoint-url=http://localhost:4566 { "items": [ { "id": "7u9zuost7i", "name": "HelloWorldApi", "createdDate": "2023-11-13T20:45:01+09:00", "apiKeySource": "HEADER", "endpointConfiguration": { "types": [ "EDGE" ] }, "tags": { "aws:cloudformation:logical-id": "HelloWorldApi9E278160", "aws:cloudformation:stack-name": "CdkTechblogStack", "aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:000000000000:stack/CdkTechblogStack/9e5b2cf2" }, "disableExecuteApiEndpoint": false } ] } |
上記の出力から、次の情報が取得できます。
1 |
"id": "7u9zuost7i", |
この値は、後に続くコマンドで使用されます。
2.<stage_name>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
aws apigateway get-stages --rest-api-id 7u9zuost7i --endpoint-url=http://localhost:4566 { "item": [ { "deploymentId": "snr2rt92wl", "stageName": "prod", "cacheClusterEnabled": false, "cacheClusterStatus": "NOT_AVAILABLE", "methodSettings": {}, "tracingEnabled": false } ] } |
上記の出力から、以下の値を使用することができます。
1 |
"stageName": "prod", |
3.<resource_name>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
aws apigateway get-resources --rest-api-id 7u9zuost7i --endpoint-url=http://localhost:4566 { "items": [ { "id": "3fihy4az23", "path": "/" }, { "id": "thhe71dqtz", "parentId": "3fihy4az23", "pathPart": "test", "path": "/test", "resourceMethods": { "GET": { "httpMethod": "GET", "authorizationType": "NONE", "apiKeyRequired": false, "requestParameters": {}, "requestModels": {}, "methodResponses": {}, "methodIntegration": { "type": "AWS_PROXY", "httpMethod": "POST", "uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:000000000000:function:CdkTechblogStack-HelloWorldLambda5A02458E-770e5667/invocations", "requestParameters": {}, "requestTemplates": {}, "passthroughBehavior": "WHEN_NO_MATCH", "timeoutInMillis": 29000, "cacheNamespace": "thhe71dqtz", "cacheKeyParameters": [] } } } } ] } |
上記の出力から、以下を利用することができます。
1 2 |
"pathPart": "test", |
URLを完成させるために必要なすべての値を取得したので、curlコマンドを実行します。
1 2 |
curl http://localhost:4566/restapis/7u9zuost7i/prod/_user_request_/test |
リクエストが成功すると、画面に「Hello World」と表示されます。
1 2 3 4 5 6 |
curl http://localhost:4566/restapis/7u9zuost7i/prod/_user_request_/test % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 12 100 12 0 0 139 0 --:--:-- --:--:-- --:--:-- 139 Hello World! |
まとめ
昨今のクラウド技術に対する需要の高まりから、私たち開発者はインフラストラクチャの使い方や、展開方法、保守の方法を理解することが重要です。
この記事ではAWS CDKとLocalstackという2つの最も簡単且つよく知られているデプロイツールの使用方法を紹介しました。これによって、今後登場してくるより高度な新しいツールをさらに探索することができるかと思います。これらの簡易的なツールの助けを借りながら、みなさんがプロジェクトにおけるインフラストラクチャの知識の重要性を、より深く理解していけることを願っています。
以上、ありがとうございました! 😀
【参考文献】