AWS CDKとLocalStackによるローカルデプロイの一例紹介

AWS CDKとLocalStackによるローカルデプロイの一例紹介

みなさんこんにちは、システム部のエーデルワイスです。
フィリピンから日本に来て、GMOリサーチに入社し半年以上が経ちました。この半年間はとても充実していて、技術的なスキルはもちろんのこと、日本語スキルも少しだけですが向上させることができました。

私はこれまで、インフラの整備や保守に携わっており、インフラのデプロイとメンテナンスをできるだけ簡単にすることを常に最優先事項としていました。なので、みなさんにもプロジェクトのインフラを理解することの重要性を知ってもらいたいと思っています。
また、その中で私はAWS Cloud Development Kit(CDK)とLocalstackに出会いました。

AWS CDKはAWS CloudFormationテンプレートのように機能しますが、ユーザーは複雑なCloudFormationの関数やテンプレートを覚える必要はないので、管理がより簡単になります。さらに、ユーザーが特定のプログラミング言語をきちんと理解していれば、リソースのデプロイも簡単に行うことができます。

これらのツールの詳細については、AWS CDKLocalstackの公式ページを見てみてください。
この記事では、そのツールのインストール方法と使用方法を紹介していきたいと思います。
具体的には、私はLocalstackとAWS CDKを使用して、学習や調査に使用できるAPIをデプロイすることに成功しました。ここから、私がこの目的を達成するために実行した手順を紹介していきたいと思います。

基本設計・アーキテクチャ

この記事における基本設計は、とてもシンプルで分かりやすいものです。API Gateway と Lambda のみを使用して、サンプルの REST API を作成します。

環境構築 (Windows)

Localstack

1.pythonを使用してlocalstackをインストールする

python -m pip install localstack

2.   localstackを開始

localstack start

3.     localstackの状況を確認

localstack status services

localstackのインストールと起動が成功すると、次のようになります。

┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ 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.空のディレクトリを作成

mkdir cdk-techblog
cd cdk-techblog

2.cdkをインストール

npm install -g aws-cdk-local aws-cdk

3.cdklocalを初期化する

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

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

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

cdklocal bootstrap

このコマンドは、AWS CDKがスタックをデプロイするために使用するAWS S3 Bucketを作成します。このコマンドは、最初のデプロイ時または一度だけ実行されます。
バケットが正常に作成されたことを確認するには、次の localstack を実行して確認します。

aws s3 ls --endpoint-url=http://localhost:4566

これにより、次のように作成されたS3バケットが出力されます。

2023-11-13 20:40:12 cdk-hnb659fds-assets-000000000000-ap-northeast-1

2.Deploy Command

cdklocal deploy

デプロイが成功した場合、作成されたスタックが表示され、デプロイが成功したことが確認されます。

✅  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コマンドを使用します。

curl http://localhost:4566/restapis/<rest_api_id>/<stage_name>/_user_request_/<resource_name>

AWS CLIを使用して、URLを完成させるための値を取得します。

1.     <rest_api_id>

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

上記の出力から、次の情報が取得できます。

 "id": "7u9zuost7i",

この値は、後に続くコマンドで使用されます。

2.<stage_name>

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

上記の出力から、以下の値を使用することができます。

"stageName": "prod",

3.<resource_name>

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": []
                    }
                }
            }
        }
    ]
}

上記の出力から、以下を利用することができます。

  "pathPart": "test",

URLを完成させるために必要なすべての値を取得したので、curlコマンドを実行します。

curl http://localhost:4566/restapis/7u9zuost7i/prod/_user_request_/test

リクエストが成功すると、画面に「Hello World」と表示されます。

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つの最も簡単且つよく知られているデプロイツールの使用方法を紹介しました。これによって、今後登場してくるより高度な新しいツールをさらに探索することができるかと思います。これらの簡易的なツールの助けを借りながら、みなさんがプロジェクトにおけるインフラストラクチャの知識の重要性を、より深く理解していけることを願っています。

以上、ありがとうございました! 😀

【参考文献】

  1. What is the AWS CDK?
  2. localstack.cloud
  3. apigatewayーAWS CLI Command Reference
前の記事
«
次の記事
»

技術カテゴリの最新記事