LocalStack と AWS CDK で AWS ローカル開発のすすめ

## はじめに

AWS クラウド開発では、コストやデプロイのタイムラインを短縮するために、ローカルでの開発とテストが重要な役割を果たします。
そのためには、AWS のサービスを模倣するローカル環境を構築することが有効です。
本記事では、**LocalStack** と **AWS CDK** を使用して、ローカル環境での AWS 開発を効率的に行う方法を紹介します🐱

## 対象読者

- AWS インフラの自動化に興味がある開発者やインフラエンジニア
- AWS CDK を利用したインフラ構成管理を行っているエンジニア
- ローカル環境での開発・テストを効率化したいエンジニア
- CI/CD のパイプラインにローカル開発を組み込みたい DevOps エンジニア

## 事前準備

AWS ローカル開発環境を構築するためには、以下のツールと環境が必要です。

- **Python 3.13 以上**（推奨）
- **pip**（Python パッケージ管理ツール）
- **Docker**（LocalStack を使用するため）
- **Docker Compose**（LocalStack を管理するため）
- **AWS CLI**（ローカル環境での AWS 操作）
- **AWS CDK**（インフラ構成管理ツール）

これらをインストールした後、AWS CDK のセットアップを行います。

```bash
npm install -g aws-cdk
```

## LocalStack と AWS CDK の概要

### LocalStack

LocalStack は、AWS の主要なサービスをローカルで模倣するためのツールです。
これを利用することで、AWS にリソースを作成することなく、ローカル環境でアプリケーションのテストや開発を行えます。
S3 や DynamoDB、Lambda、API Gateway などを含む多くの AWS サービスをサポートしています。

### AWS CDK

AWS CDK（Cloud Development Kit）は、プログラム的に AWS インフラを構成するためのフレームワークです。
インフラをコードとして定義し、再利用可能なリソース定義を作成できます。
AWS CDK は、TypeScript、Python、Java、C# など複数のプログラミング言語に対応しています。

## LocalStack と AWS CDK を用いたローカル開発環境の構築

### 1. LocalStack のインストールとセットアップ

まず、LocalStack を Docker コンテナで実行するために、`docker-compose` を使用します。以下の `docker-compose.yml` ファイルを作成します。

```yaml
version: '3.8'
services:
  localstack:
    image: localstack/localstack
    ports:
      - "4566:4566"
    environment:
      - SERVICES=s3,dynamodb,lambda,apigateway
      - DEFAULT_REGION=us-east-1
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
```

これで LocalStack が `4566` ポートで起動し、S3 や DynamoDB、Lambda、API Gateway などの AWS サービスをローカルで模倣します。以下のコマンドで LocalStack を起動します。

```bash
docker-compose up -d
```

### 2. AWS CDK を使ってインフラの定義

AWS CDK を使用して、S3 バケットや Lambda 関数、API Gateway を作成するインフラコードを定義します。

まず、AWS CDK プロジェクトを作成します。

```bash
cdk init app --language python
```

次に、必要な依存関係をインストールします。

```bash
pip install aws-cdk.aws-s3 aws-cdk.aws-lambda aws-cdk.aws-apigateway
```

インフラコードを以下のように作成します。

```python
from aws_cdk import core
from aws_cdk import aws_s3 as s3
from aws_cdk import aws_lambda as _lambda
from aws_cdk import aws_apigateway as apigateway

class LocalStackCdkApp(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # S3 バケットを作成
        bucket = s3.Bucket(self, "MyBucket")

        # Lambda 関数を作成
        lambda_function = _lambda.Function(
            self, "MyLambda",
            runtime=_lambda.Runtime.PYTHON_3_8,
            handler="lambda_function.lambda_handler",
            code=_lambda.Code.from_inline("""
def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': 'Hello from Lambda'
    }
            """)
        )

        # API Gateway を作成
        api = apigateway.LambdaRestApi(
            self, "MyApi",
            handler=lambda_function
        )

app = core.App()
LocalStackCdkApp(app, "LocalStackCdkApp")
app.synth()
```

このコードでは、以下を行っています。

- **S3 バケットの作成**
- **Lambda 関数の作成**（インラインコードを使用）
- **API Gateway** を作成し、Lambda 関数をトリガーするエンドポイントを作成

### 3. ローカル環境でのデプロイ

次に、CDK を使用してインフラをローカル環境にデプロイします。LocalStack をローカルの AWS 環境として設定するために、AWS CLI を LocalStack のエンドポイントに向けます。

```bash
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1
export AWS_ENDPOINT_URL=http://localhost:4566
```

その後、CDK を使ってローカル環境にデプロイします。

```bash
cdk deploy --no-verify-ssl
```

これで、ローカルの LocalStack 上に S3 バケット、Lambda 関数、API Gateway が作成されます。

### 4. ローカルでのテスト

ローカル環境で API Gateway を通じて Lambda 関数を呼び出すためには、以下のコマンドで API エンドポイントを呼び出します。

```bash
curl "http://localhost:4566/restapis/<api_id>/local/_user_request_/"
```

これにより、Lambda 関数が呼び出され、`"Hello from Lambda"` というレスポンスが返されます。

## LocalStack と AWS CDK を使うメリット

- **コスト削減**: ローカル環境でテストを行えるため、AWS の利用コストを削減できます。
- **迅速な開発**: クラウドにデプロイする前にローカルで機能確認でき、開発サイクルを短縮できます。
- **インフラのコード化**: AWS CDK によってインフラをコードで定義し、バージョン管理や再利用が可能です。
- **CI/CD 統合**: ローカル環境でのテストを CI/CD パイプラインに組み込むことで、自動化されたテストが可能になります。

:::message
LocalStack Community 版の Lambda Layers の注意事項
:::
LocalStack の Community 版 では、Lambda Layers の作成、更新、削除が可能です。
ただし、注意点として、Lambda 関数の実行時には Lambda Layers が適用されません。
このため、Lambda Layers を利用した機能をローカル環境でテストする場合には、あくまでコード内でインラインで追加された依存関係を使う形での実行が必要です。
実際の AWS 環境では問題なく動作するため、ローカル開発環境での制約として理解しておくことが重要です。

## まとめ

LocalStack と AWS CDK を組み合わせることで、ローカル環境での AWS 開発・テストが効率的に行えます。
LocalStack を使うことで実際の AWS 環境に近い形で動作確認を行い、AWS CDK でインフラをコードとして管理することで、再現性の高いインフラ環境を作成できます。
本記事で紹介した方法を参考に、ローカル環境での開発効率を向上させましょう。

良い、開発ライフを！！:smirk_cat: