はじめに
AWSをローカルで動かすためのツールLocalstack
を使ってみる。
https://github.com/localstack/localstack
環境
1
2
3
| Windows 11 Pro
Docker Desktop 4.33.1 (161083)
WSL2 Ubuntu 24.04 LTS
|
構築
ローカル環境は、Dockerを使って構築する。
イメージは、localstack/localstack
を使う。
https://hub.docker.com/r/localstack/localstack
aws-cliを使って、localstackにアクセスするので、下記も参照する。
https://hub.docker.com/r/amazon/aws-cli
環境変数は下記を参照する。
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
compose.yml
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
| services:
localstack:
container_name: localstack
image: localstack/localstack:3.6.0
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:
- "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
aws-cli:
container_name: aws-cli
image: amazon/aws-cli:2.17.37
environment:
- AWS_ACCESS_KEY_ID=dummy
- AWS_SECRET_ACCESS_KEY=dummy
- AWS_DEFAULT_REGION=us-east-1
- AWS_DEFAULT_OUTPUT=json
- AWS_ENDPOINT_URL=http://localstack:4566
tty: true
stdin_open: true
entrypoint: ["sh"]
depends_on:
- localstack
|
上記を適当なディレクトリに保存する。
コンテナの起動
S3
S3バケットを作成する
aws-cli
コンテナに入る。
1
| docker compose exec aws-cli bash
|
S3バケットを作成する。
1
| aws s3api create-bucket --bucket test
|
結果↓
1
2
3
| {
"Location": "/test"
}
|
下記のように出力される。
1
2
3
| bash-4.2# aws s3 ls
2024-08-25 02:56:27 test
bash-4.2#
|
S3バケットにファイルをアップロード
1
| aws s3 cp /etc/hosts s3://test/hosts
|
結果↓
1
2
| bash-4.2# aws s3 cp /etc/hosts s3://test/hosts
upload: ../etc/hosts to s3://test/hosts
|
S3バケットの中身を確認する
1
2
| bash-4.2# aws s3 ls s3://test
2024-08-25 04:49:31 174 hosts
|
アップロードした hosts
ファイルをダウンロードする
1
| aws s3 cp s3://test/hosts /tmp/hosts
|
1
2
| bash-4.2# aws s3 cp s3://test/hosts /tmp/hosts
download: s3://test/hosts to ../tmp/hosts
|
ダウンロードしたファイルの中身を確認する
結果↓
1
2
3
4
5
6
7
8
| bash-4.2# cat /tmp/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.23.0.3 ef72d46edfec
|
↑お~できていますね。
S3api コマンドで確認する
1
| aws s3api list-objects --bucket test
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| {
"Contents": [
{
"Key": "hosts",
"LastModified": "2024-08-25T04:49:31+00:00",
"ETag": "\"7248e9dd3e36e61a22956ba1306f2cf2\"",
"Size": 174,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "webfile",
"ID": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"
}
}
],
"RequestCharged": null
}
|
hosts
ファイルが表示されていますね。
S3バケットを削除する
1
| aws s3 rb s3://test --force
|
1
2
3
| bash-4.2# aws s3 rb s3://test --force
delete: s3://test/hosts
remove_bucket: test
|
確認
※何も返ってこなければ削除されている。
Lambda
pythonコードの作成
lambda_function.py
を作成する。
1
2
3
4
5
| def lambda_handler(event, context):
return {
'statusCode': 200,
'body': 'Hello, World!'
}
|
シンプルなHello WorldのLambda関数を作成する。
zipファイルの作成
1
| zip lambda_function.zip lambda_function.py
|
zipファイルをaws-cliコンテナにアップロード
1
| docker cp lambda_function.zip aws-cli:/tmp/lambda_function.zip
|
localstackにLambda関数をデプロイ
1
| docker compose exec aws-cli bash
|
1
2
| cd /tmp
aws lambda create-function --function-name hello-world --role arn:aws:iam::000000000000:role/role1 --runtime python3.12 --handler lambda_function.lambda_handler --zip-file fileb://lambda_function.zip
|
ランタイム
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-runtimes.html
結果↓
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
| {
"FunctionName": "hello-world",
"FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:hello-world",
"Runtime": "python3.12",
"Role": "arn:aws:iam::000000000000:role/role1",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 281,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2024-08-25T05:24:39.443750+0000",
"CodeSha256": "OjFvsqOXa1Du2sy+rSm4APYN9x6YsnuvDhiM1aYsIaQ=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "14a1140b-754d-48e2-833e-c0685b5b0903",
"State": "Pending",
"StateReason": "The function is being created.",
"StateReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:us-east-1::runtime:8eeff65f6809a3ce81507fe733fe09b835899b99481ba22fd75b5a7338290ec1"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/hello-world"
}
}
|
Lambda関数の実行
1
| aws lambda invoke --function-name hello-world /tmp/output.json
|
1
2
3
4
| {
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
|
output.json
に結果が出力される。
1
| {"statusCode": 200, "body": "Hello, World!"}
|
OK!
DynamoDB
テーブルを作る
1
2
3
4
5
6
| aws dynamodb create-table \
--table-name test \
--key-schema AttributeName=id,KeyType=HASH \
--attribute-definitions AttributeName=id,AttributeType=S \
--billing-mode PAY_PER_REQUEST \
--region ap-south-1
|
結果↓
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
| {
"TableDescription": {
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "S"
}
],
"TableName": "test",
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2024-08-25T06:07:20.435000+00:00",
"ProvisionedThroughput": {
"LastIncreaseDateTime": "1970-01-01T00:00:00+00:00",
"LastDecreaseDateTime": "1970-01-01T00:00:00+00:00",
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 0,
"WriteCapacityUnits": 0
},
"TableSizeBytes": 0,
"ItemCount": 0,
"TableArn": "arn:aws:dynamodb:ap-south-1:000000000000:table/test",
"TableId": "200004d2-5a7c-4bd7-a4ab-a5f7340baf4f",
"BillingModeSummary": {
"BillingMode": "PAY_PER_REQUEST",
"LastUpdateToPayPerRequestDateTime": "2024-08-25T06:07:20.435000+00:00"
},
"DeletionProtectionEnabled": false
}
}
|
テーブルの確認
1
2
| aws dynamodb list-tables \
--region ap-south-1
|
結果↓
1
2
3
4
5
| {
"TableNames": [
"test"
]
}
|
データを入れる
1
2
3
4
| aws dynamodb put-item \
--table-name test \
--item '{"id":{"S":"foo"}}' \
--region ap-south-1
|
データの数を確認する
1
2
3
4
| aws dynamodb describe-table \
--table-name test \
--query 'Table.ItemCount' \
--region ap-south-1
|
データを確認する
1
2
3
4
| aws dynamodb get-item \
--key '{"id": {"S": "foo"}}' \
--table-name test \
--region ap-south-1
|
結果↓
1
2
3
4
5
6
7
| {
"Item": {
"id": {
"S": "foo"
}
}
}
|
おぉ!できてる。
参考
おわりに
この記事書いた後に知ったのだが、aws-cli-localというものがあるらしい。
aws-cli
より、aws-cli-local
の方が使いやすいかもしれない。
https://github.com/localstack/awscli-local
本番ではS3を使えるけど、ローカルの場合はどうするべきかと悩んでいたのでLocalstack
という選択肢を知れてよかった。