はじめに
本記事はLocalStackを使用してAWSサービスをローカル環境にエミュレートする方法について記載しています。
LocalStackは、AWSサービスをローカル環境にエミュレートすることができるサービスです。
Announcing LocalStack 2.0 General Availability!よりLocalStack 2.0がリリースされています。
AWSの主要なサービスとしてAWS Lambda、S3、Dynamodb、Kinesis、SQS、SNSなどのAPIを擬似的に利用することができます。
従ってクラウド環境を使用することなく、ローカル環境で開発及びテストなどを行うことができます。
LocalStackとは
ホームページのAbout Usを踏まえて、2016年にGitHubのオープンソースとして始まりました。その後、2021年に法人化されています。
LocalStackの特徴は、AWSクラウドのAPIをエミュレートすることで、AWS環境でデプロイするアプリケーションのローカル開発及びテストを可能とします。
無料で利用可能なオープンソース版と、サービスが拡充された有料のPro版があります。
それぞの違いはFeaturesから確認できます。
環境構築
LocalStackを使用するためには、公式ドキュメントInstallationのとおりにいくつかの手段が用意されています。
本記事ではLocalStack CLIを用いた環境構築の方法について記載しています。
前提条件は以下の通りです。
(本記事はPython 3.8.2を使用)
- python (Python 3.7 up to 3.11 supported)
- pip (Python package manager)
- Docker
デスクトップクライアントとして、Cockpitを利用したインスタンスの管理もできます。
localstack
pip
からlocalstackをインストールします。
$ pip3 install localstack
LocalStackの詳細は、GitHubのlocalstackリポジトリから確認できます。
awscli-local
localstackをインストールしただけでは、後述するawslocal
コマンドが使用できません。
awslocal
コマンドを使用するためには、awscli-localもインストールします。
$ pip3 install awscli-local
以下のコマンドを実行して、awslocal
コマンドがインストールされたことが確認できます。
$ which awslocal
/usr/local/bin/awslocal
awscli-localの詳細は、GitHubのawscli-localリポジトリから確認できます。
動作確認
LocalStackを起動するためには、以下のコマンドを実行します。
$ localstack start -d
__ _______ __ __
/ / ____ _________ _/ / ___// /_____ ______/ /__
/ / / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
/ /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
/_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|
💻 LocalStack CLI 2.0.2
[17:00:38] starting LocalStack in Docker mode 🐳 localstack.py:142
preparing environment bootstrap.py:615
[17:00:39] configuring container bootstrap.py:623
starting container bootstrap.py:630
[17:00:41] detaching
以下のコマンドを実行して、サービスの状態を確認します。
$ localstack status services
┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ 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 │
│ secretsmanager │ ✔ available │
│ ses │ ✔ available │
│ sns │ ✔ available │
│ sqs │ ✔ available │
│ ssm │ ✔ available │
│ stepfunctions │ ✔ available │
│ sts │ ✔ available │
│ support │ ✔ available │
│ swf │ ✔ available │
│ transcribe │ ✔ available │
└──────────────────────────┴─────────────┘
LocalStackはDockerで動いているため、LocalStack起動後コンテナの起動が確認できます。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ee9cee6a3b8 localstack/localstack "docker-entrypoint.sh" About a minute ago Up About a minute (healthy) 127.0.0.1:4510-4559->4510-4559/tcp, 127.0.0.1:4566->4566/tcp, 5678/tcp localstack_main
awslocal
コマンドが使用可能な場合、READMEにサンプルとして記載があるSQSも確認できます。
$ awslocal sqs create-queue --queue-name sample-queue
{
"QueueUrl": "http://localhost:4566/000000000000/sample-queue"
}
LocalStackのログは、以下のコマンドを実行することで確認できます。
$ localstack logs
LocalStack version: 2.0.3.dev
LocalStack Docker container id: 3ee9cee6a3b8
LocalStack build date: 2023-04-19
LocalStack build git hash: 11c094bd
2023-04-20T08:00:42.810 INFO --- [-functhread3] hypercorn.error : Running on https://0.0.0.0:4566 (CTRL + C to quit)
2023-04-20T08:00:42.810 INFO --- [-functhread3] hypercorn.error : Running on https://0.0.0.0:4566 (CTRL + C to quit)
Ready.
2023-04-20T08:03:20.596 WARN --- [ asgi_gw_0] localstack.deprecations : /health is deprecated (since 1.3.0) and will be removed in upcoming releases of LocalStack! Use /_localstack/health instead.
2023-04-20T08:07:19.917 INFO --- [ asgi_gw_0] localstack.request.aws : AWS sqs.CreateQueue => 200
Local AWS Services
ローカル環境でAWS Servicesを構築します。
本記事では例として、S3とEC2を記載しています。
Amazon S3
S3のバケットを作成するためには、以下のコマンドを実行します。
local-test
はバケット名になるため、任意の名前を指定します。
$ awslocal s3 mb s3://local-test
make_bucket: local-test
以下のコマンドを実行すると、バケットが作成されたことが確認できます。
$ awslocal s3 ls
2023-04-20 17:08:54 local-test
テストファイルを作成して、LocalStackのS3にアップロードを行います。
$ touch test.txt && echo test > test.txt
$ awslocal s3 cp ./test.txt s3://local-test
upload: ./test.txt to s3://local-test/test.txt
ダウンロードして確認します。
$ awslocal s3 cp s3://local-test/test.txt ./
download: s3://local-test/test.txt to ./test.txt
ブラウザからも確認できます。
http://localhost:4566/local-test/
にアクセスすると、バケットが参照できます。
http://localhost:4566/local-test/test.txt
にアクセスすると、オブジェクトの中身が確認できます。
localstack logs
コマンドを実行して、APIに関するログが確認できます。
2023-04-20T08:08:54.210 INFO --- [ asgi_gw_0] localstack.request.aws : AWS s3.CreateBucket => 200
2023-04-20T08:09:02.611 INFO --- [ asgi_gw_0] localstack.request.aws : AWS s3.ListBuckets => 200
2023-04-20T08:09:43.375 INFO --- [ asgi_gw_0] localstack.request.aws : AWS s3.PutObject => 200
2023-04-20T08:12:36.670 INFO --- [ asgi_gw_0] localstack.request.aws : AWS s3.HeadObject => 200
2023-04-20T08:12:36.682 INFO --- [ asgi_gw_0] localstack.request.aws : AWS s3.GetObject => 200
Amazon EC2
EC2インスタンスを起動します。
イメージはDocker HubのamazonlinuxからAmazon Linux 2023を使用します。
以下のコマンドを実行して、イメージを取得します。
$ docker pull public.ecr.aws/amazonlinux/amazonlinux:2023
2023: Pulling from amazonlinux/amazonlinux
48dcbee877aa: Pull complete
Digest: sha256:1241d87a424c299c6cccc4528504c80bf02923529628edd94ea6fb0ab01030e1
Status: Downloaded newer image for public.ecr.aws/amazonlinux/amazonlinux:2023
public.ecr.aws/amazonlinux/amazonlinux:2023
以下のコマンドを実行して、イメージにタグを付けます。
$ docker tag public.ecr.aws/amazonlinux/amazonlinux:2023 localstack-ec2:ami-local
以下のコマンドを実行して、EC2を起動します。
$ awslocal ec2 run-instances --image-id ami-local
{
"Groups": [
{
"GroupName": "default",
"GroupId": "sg-245f6a01"
}
],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-local",
"InstanceId": "i-875f2ea3652a2ec66",
"InstanceType": "m1.small",
"KernelId": "None",
"LaunchTime": "2023-04-20T08:46:38+00:00",
"Monitoring": {
"State": "enabled"
},
"Placement": {
"AvailabilityZone": "ap-northeast-1a",
"GroupName": "",
"Tenancy": "default"
},
"PrivateDnsName": "ip-10-97-137-152.ap-northeast-1.compute.internal",
"PrivateIpAddress": "10.97.137.152",
"PublicDnsName": "ec2-54-214-47-151.ap-northeast-1.compute.amazonaws.com",
"PublicIpAddress": "54.214.47.151",
"State": {
"Code": 0,
"Name": "pending"
},
"StateTransitionReason": "",
"SubnetId": "subnet-0eb4ceca",
"VpcId": "vpc-c78226a1",
"Architecture": "x86_64",
"ClientToken": "",
"EbsOptimized": false,
"Hypervisor": "xen",
"NetworkInterfaces": [
{
"Association": {
"IpOwnerId": "000000000000",
"PublicIp": "54.214.47.151"
},
"Attachment": {
"AttachTime": "2015-01-01T00:00:00+00:00",
"AttachmentId": "eni-attach-b317e893",
"DeleteOnTermination": true,
"DeviceIndex": 0,
"Status": "attached"
},
"Description": "Primary network interface",
"Groups": [
{
"GroupName": "default",
"GroupId": "sg-c7923fb1a5174e467"
}
],
"MacAddress": "1b:2b:3c:4d:5e:6f",
"NetworkInterfaceId": "eni-75b3367f",
"OwnerId": "000000000000",
"PrivateIpAddress": "10.97.137.152",
"PrivateIpAddresses": [
{
"Association": {
"IpOwnerId": "000000000000",
"PublicIp": "54.214.47.151"
},
"Primary": true,
"PrivateIpAddress": "10.97.137.152"
}
],
"SourceDestCheck": true,
"Status": "in-use",
"SubnetId": "subnet-0eb4ceca",
"VpcId": "vpc-c78226a1"
}
],
"SecurityGroups": [],
"SourceDestCheck": true,
"Tags": [],
"VirtualizationType": "paravirtual"
}
],
"OwnerId": "000000000000",
"ReservationId": "r-04a780bc"
}
同じようにEC2のログも確認できます。
2023-04-20T08:46:38.115 INFO --- [ asgi_gw_0] localstack.request.aws : AWS ec2.RunInstances => 200
2023-04-20T08:52:21.052 INFO --- [ asgi_gw_0] localstack.request.aws : AWS ec2.DescribeInstances => 200
Amazon Linux 2023については、5分で理解するAmazon Linux 2023をご参照ください。
おわりに
本記事では紹介しきれませんが、公式ドキュメントTerraformのとおりにIac構成のテストなどにも利用することもできます。
新年度が始まりこれからクラウドを初めて触る人も出てくると思うので、リスク管理としての利用や、コスト削減にも活用できるので、お勧めなツールです。