こんにちは出石です。
AWSアプリの開発で、ローカルでサクッと動作確認をとりたい時があります。またはコスト面などの理由で。
そんな時に使えそうかなとlocalstackを触ってみました。
localstackはコンテナでAWS各種サービスをエミュレートできる環境をローカルに用意できます。
先日localstack V1.0の一般提供が発表されました。
localstack.cloud
今回の目的
まずは以下を今回のゴールとして検証を進めたいと思います
ゴール:ローカル環境でS3のアクセス処理を行えるようにする
環境の構築
まずは、環境整備からです。今回はWindows環境で行います。
READMEを見る限りpython,dockerがあればよさそうです。今回は以下のバージョンを使いました。
$ python -V Python 3.9.13 $ docker -v Docker version 20.10.17, build 100c701
あと動作確認の為にaws cliも入れています。
$ aws --version aws-cli/2.7.18 Python/3.9.11 Windows/10 exe/AMD64 prompt/off
では、本題でlocalstackも環境構築していきます。
GitHubからcloneしてdockerを起動するだけです。
$ git clone https://github.com/localstack/localstack.git $ docker-compose -f ./localstack/docker-compose.yml up -d
イメージサイズはおおよそ1.4Gでした。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE localstack/localstack latest 62fb4c6db8c5 2 hours ago 1.39GB
コンテナが上がっていたらlocalstackの準備完了です。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8c0122aca215 localstack/localstack "docker-entrypoint.sh" About an hour ago Up About an hour (healthy) 127.0.0.1:53->53/tcp, 127.0.0.1:443->443/tcp, 127.0.0.1:4510-4559->4510-4559/tcp, 127.0.0.1:4566->4566/tcp, 127.0.0.1:53->53/udp, 5678/tcp localstack_main
動作の検証
では、実際にaws cliから確認してみます。
まずは、aws configを作成します。
$ cat >> ~/.aws/config << EOF [default] region = ap-northeast-1 output = json EOF
ついでクレデンシャルを設定
$ cat >> ~/.aws/credentials << EOF [default] aws_access_key_id = dummy aws_secret_access_key = dummy EOF
アクセスキー、シークレットキーはdummyでOKです。
では、S3バケットを作成します。普段と違うのはendpoint-urlがローカルで起動したコンテナを指定している亊です。
$ aws s3 mb s3://test-bucket --endpoint-url=http://localhost:4566
make_bucket: test-bucket
では、作成されたかを確認します。同じくendpoint-urlはローカルのコンテナを指定です。
$ aws s3 ls s3:// --endpoint-url=http://localhost:4566 2022-07-27 23:47:02 test-bucket
無事作成されている事を確認できました。
ここで毎回endpoint-urlの指定は煩わしいのでlocalstackで提供されているawscli-localを使ってみたいと思います。
docs.localstack.cloud
pipでインストールするだけです。
$ pip install awscli-local
同じくS3を確認してみます。コマンドはaws→awslocalとなり、endpoint-urlは指定しなくてもローカルコンテナに向きます。
$ awslocal s3 ls s3://
2022-07-27 23:47:02 test-bucket
では、最後にpythonプログラムでS3にアップロードしてみようと思います。
import boto3 def main() : client = boto3.client('s3', aws_access_key_id='dummy', aws_secret_access_key='dummy', region_name='ap-northeast-1', endpoint_url='http://localhost:4566') response = client.list_buckets() client.upload_file('./test.txt','test-bucket', 'test.txt') print('upload complate') if __name__ == "__main__": main()
test.pyでソースを保存し、同じ場所にtest.txt(中身は空でもOK)を配置後、実行します。
$ python test.py
upload complate
では、アップロードされているかを確認します。
$ awslocal s3 ls s3://test-bucket 2022-07-27 23:58:49 4 test.txt
無事test.txtがアップロードされました。
まとめと感想
今回のソースはローカルで動作確認をとる為にハードコーディングしていますが、aws_access_key_id、aws_secret_access_key、endpoint_urlを環境変数や設定ファイルに外だししておけば、ローカルとクラウド(AWS上)共にそのままのソースで動作することができます。
また、バケットもコマンドではなくcloudformationで作成できるので、クラウド環境構築時のcloudformationをローカルで再現・テストする事も容易にできそうです。
他サービスではkinesis、lambda、DynamoDBなども使えるようなのでAWSアプリのローカル開発も捗るかなと感じました。
$ awslocal cloudformation create-stack --stack-name test-stack --template-body file://cf_s3.yml { "StackId": "arn:aws:cloudformation:us-east-1:000000000000:stack/test-stack/779f6dc3" } $ awslocal s3 ls s3:// 2022-07-27 23:47:02 test-bucket 2022-07-28 00:10:38 test-stack-s3bucket-9d47f55f