Skip to main content

LocalStackとterraformでAWSのローカル環境を構築する

· 11 min read
Nico
Nico
Software Developer

AWSに関連する開発を行う時、どうしても「完全なローカル環境で開発や動作確認をしたい」と頭によぎってしまいませんか。無料利用枠があるとはいえ開発用にアカウントを作成するのは少し手間だし、なにより無料利用枠を思いがけず超過してしまう可能性もありますよね。

筆者は新米の頃(5~6年前)、勉強もかねてAWSのアカウントを構築して色々と試してみていたのですが、ある日、当時としてはとんでもない金額が請求されていることに気づきました。 勉強用に作って使用していたアカウントのクローズを忘れており、色々なサービスを稼働させ続けてしまい... 高い勉強代...

会社で共有の開発アカウントがあるとしても、自分の操作が他の人に影響を与えるかもしれないし、それこそ意図せぬ大きな課金を発生させてしまいまねませんよね。

本記事では、以下のツールを利用して、自分のローカル環境でAWSサービスの動作確認をできるようになる手順を紹介できたらと思います。

  1. Docker desktop
  2. LocalStack (AWSのモックを提供しているサービス)
  3. tarraform-local (Terraformをローカルで実行するのに便利なツール)

aws-cliを利用して構築することも可能ですが、本記事ではTerraformを利用してAWSのサービスを構築する手順を紹介しています。Terraformの学習用環境としても利用できるのではないでしょうか。

対象読者

本記事はMacユーザーの方へ向けた記事となります。

ツールのインストール

Docker Desktop

公式サイトからご自身のOSに合わせてインストールしましょう。

terraform-local

info

本記事の環境構築にはTerraformのインストールも必要となるので、まだインストールできていない方はこちらの記事を参照し、インストールしましょう。

こちらがterraform-localの公式リポジトリです。コマンドが動作しないなどがあればこちらを参照ください。

公式手順ではpipでパッケージをインストールしていますが、筆者はbrewでもインストールができたので、下記をお勧めします。

brew install terraform-local

terraform-localを使うことで、terraform実行時にAWSのCredentialのチェックをスキップすることができるようになります。

インストールが完了したら、tflocalをターミナルから実行できるので、下記コマンドで確認してみましょう。

tflocal -v

Terraform v1.9.5

現在インストールされているTerraformのバージョンが表示されます。

tflocalで利用するコマンドはTerraformで利用するコマンドと基本的に同じです。

Terraformterraform-local
terraform inittflocal init
terraform plantflocal plan
terraform applytflocal apply
terraform destroytflocal destroy

以上で必要なツールのインストールは完了です。

LocalStack環境の構築

LocalStackとは、前述のようにAWSのモック環境をローカルに構築できるツールです。ライセンスにより利用できるサービスの種類が異なります。 Proライセンスを購入するとほとんどのサービスが利用できるそうですが、筆者のモチベーションは「課金を避けたい」ためにこのようにローカル環境を構築しているので、購入はしておりません。

では、LocalStackを構築しましょう。おすすめはDocker環境下への作成です。不要になればすぐ削除できたり、簡単に環境を初期化できます。

本記事で取り扱うディレクトリ構造は下記の通りとし、API Lambdaの構築をサンプルケースに取り扱います。

application/
├── compose.yml ... LocalStackのContainer定義
├── docker/
│ └── localstack/
│ ├── terraform/ ... LocalStackに環境構築するためのterraform file
│ │ └── hello-world/ ... Lambda関数ごとにディレクトリを作成
│ │ ├── zip/ ... Lambdaのzipファイルを配置
│ │ └── main.tf
│ └── volume/ ... LocalStack Containerのマウント先
└── src/
└── lambda/
└── hello-world
└── index.js ... Lambdaにデプロイする関数

Docker Composeファイルを作成しましょう。公式からも実装例が提供されていますが、今回のディレクトリ構成に従うように少し修正しました。

info

Docker Composeファイルの命名について、公式からはcompose.yamlを使うようにと推奨されています。
https://docs.docker.com/compose/compose-application-model/

application/compose.yaml
version: "3.8"

services:
localstack:
container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
image: localstack/localstack
ports:
- "127.0.0.1:4566:4566" # LocalStack Gateway
- "127.0.0.1:4510-4559:4510-4559" # external services port range
environment:
# LocalStack configuration: https://docs.localstack.cloud/references/configuration/
- DEBUG=${DEBUG:-0}
volumes:
- "./docker/localstack/volume:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"

プロジェクトのルートディレクトリに移動し、下記のコマンドを実行しましょう。これでLocalStackのDocker Containerの作成完了です。

docker compose up -d

Lambda関数

サンプルケースとして実装するLambdaを準備します。 ここでは、LocalStackの公式が提供しているサンプルのLambda関数を参照し、「Hello World」の文字列を返却するとてもシンプルなLambdaを作成します。

application/src/lambda/hello-world/index.js
exports.handler = async (event) => {
return {
statusCode: 200,
body: "Hello World!",
};
};

Lambdaで実行するコードはZip形式でアップロードすることとします。下記コマンドでファイルをzip化し、docker/localstack/terraform/hello-world/zipに配置しましょう。 zipファイル名はfunction.zipです。

zip function.zip index.js
mv function.zip path/to/zip/folder

Terraform file

LocalStackの環境内にLambdaを作成しますが、このLambdaの作成にTerraformを活用しましょう。

application/docker/localstack/terraform/hello-world/main.tf
provider "aws" {
region = "us-east-1"
access_key = "local_access_key"
secret_key = "local_secret_key"

skip_credentials_validation = true
skip_region_validation = true
skip_requesting_account_id = true
skip_metadata_api_check = true

endpoints {
lambda = "http://localhost:4566"
}
}

resource "aws_lambda_function" "hello-world-lambda" {
function_name = "HelloWorldFunction"
filename = "./zip/function.zip"
role = "arn:aws:iam::000000000000:role/lambda-role"
runtime = "nodejs20.x"
handler = "index.handler"
timeout = 60
memory_size = 128
}

通常のterraformコマンドでこちらのファイルを実行すると、CredentialsやRegionの有効性検証が実行されますが、terraform-localを使うことでこれらの検証をSkipすることができます。

HelloWorldFunction Lambdaの構築

お疲れ様でした。ここまででLocalStackへのLambda作成準備は完了です。実際に環境を構築しましょう。 まずはterraformファイルが配置されているディレクトリへ移動します。

cd application/docker/localstack/terraform/hello-world

次にterraform-localコマンドを実行します。下記のコマンドを実行します。

tflocal init

tflocal apply

構築するLambdaの詳細がコンソールに出力されます。この出力情報はTerraformの内容と同じです。内容を確認し作成を実行しましょう。

HelloWorldFunction Lambdaの実行

では実際に構築したLambdaを実行してみましょう。そのためにはawscliのインストールが必要となります。まだインストールできていない方は公式の手順に従いインストールしましょう。

インストールが完了したら、awscliからLocalStackの環境へコマンドが実行できるようにCredentialsを作成しましょう。

vim ~/.aws/config
# プロファイルを追加しましょう
[profile localstack]
region=us-east-1
output=json
endpoint_url = http://localhost:4566

vim ~/.aws/credentials
# Credentialを追加しましょう
[localstack]
aws_access_key_id=local_access_key
aws_secret_access_key=local_secret_key

ここまで準備が完了したら、下記コマンドにてLambdaの情報を取得してみましょう。

aws lambda list-functions \
--endpoint http://localhost:4566 \
--profile localstack

# 出力結果
{
"Functions": [
{
"FunctionName": "HelloWorldFunction",
"FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:HelloWorldFunction",
"Runtime": "provided.al2",
"Role": "arn:aws:iam::000000000000:role/lambda-role",
"Handler": "handler",
"CodeSize": 262,
"Description": "",
"Timeout": 60,
"MemorySize": 128,
"LastModified": "2024-08-31T00:00:00.000000+0000",
"CodeSha256": "CLFtqm1Xy2/1tOH+gsEW2Ik4yerXxIMxUHt7Ct7qbP4=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "520868a9-7949-436f-a032-fc83bd6afe74",
"PackageType": "Zip"
}
]
}

  • --endpoint: コマンドの実行先を指定します
  • --profile: コマンドの実行に利用するプロファイルを指定します

このように作成したLambdaの情報が出力されていると成功です。ローカルにてLambdaの構築が完了です。

aws lambda invoke \
--function-name HelloWorldFunction \
--endpoint http://localhost:4566 \
--profile localstack \
output.txt

# 実行結果
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}

実行結果のファイルがoutput.txtに出力されています。

cat output.txt

{"statusCode":200,"body":"Hello World!"}

Lambdaで実装した内容がファイルに出力されれば成功です。

おわりに

いかがでしょうか。AWSのローカル環境をLocalStackを使い、Terraformで構築できました。 冒頭で述べたように開発の過程でちょっと確認したい時の検証環境や、Terraformやawscliの学習環境として活用できそうです。

本記事で利用したサンプルのソースコードはGitHubから参照してください。