背景
- 私たちが提供しているAnyMotionを試せる環境がなかったため、デモアプリケーションを作成しました(こちら)。
- デモアプリケーションを作成するにあたり、LocalStackを活用しながら開発を進めたので、LocalStackについて簡単に紹介したいと思います
LocalStackとは
LocalStackは、シングルコンテナで動作するクラウドサービスエミュレータです。AWSの各種サービスをサポートしており、AWSサービスをローカル環境で動かすことができます。一部のAWSサービスは有償ですが、基本的には無償で使えるサービスが非常に多いです。無償版や有償版で利用できるAWSサービスに関しては、こちらをご参照ください。
今回やること
- Terraformを用いて、S3バケットの作成を行う
- Pythonスクリプトから、S3バケットにファイルをアップロードする
実装
構成
.
├── compose.yml
├── infra
│ ├── provider.tf
│ ├── s3.tf
│ └── version.tf
└── src
├── __init__.py
├── main.py
└── my_file.txt
前準備
compose.yml
を以下のように定義します。環境変数として設定するAWS_ACCESS_KEY_ID
とAWS_SECRET_ACCESS_KEY
は適当な値で問題ないです。LocalStackは4566
ポートを使用するので開けておきます。
services:
app:
image: python:3.9.9
tty: true
environment:
AWS_ACCESS_KEY_ID: dummy
AWS_SECRET_ACCESS_KEY: dummy
volumes:
- ./src:/workspace
working_dir: /workspace
localstack:
image: localstack/localstack:0.14.2
ports:
- "4566:4566"
S3の作成
Terraformを用いて、S3バケットを作成します。TerraformのバージョンとAWSのバージョンは以下の通りです。
terraform {
required_version = "1.1.7"
required_providers {
aws = {
version = "4.6.0"
source = "hashicorp/aws"
}
}
}
Terraformの適応先をLocalStackにするために以下のようにproviderを定義します。ここで使用するaccess_key
とsecret_key
も適応な値で問題ありません。
provider "aws" {
access_key = "dummy"
secret_key = "dummy"
region = "ap-northeast-1"
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
endpoints {
s3 = "http://s3.localhost.localstack.cloud:4566"
}
}
S3を以下のように作成します。
resource "aws_s3_bucket" "default" {
bucket = "my-bucket"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "default" {
bucket = aws_s3_bucket.default.bucket
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_public_access_block" "default" {
bucket = aws_s3_bucket.default.bucket
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_acl" "default" {
bucket = aws_s3_bucket.default.id
acl = "private"
}
terraform init
とterraform apply
を実行して、S3バケットが作成されて確認してみましょう。LocalStackのコンテナに入り、S3バケットの一覧を確認します。LocalStackではawsコマンドをラップしたawslocal
コマンドが利用できるため、awslocal
コマンドを利用して確認を行います。 my-bucketが作成されていることが確認できると思います。
docker compose up -d
docker compose exec localstack bash
awslocal s3 ls
Pythonコード
AWS SDKをインストールします。
docker compose exec app bash
pip install boto3
ファイルをS3バケットにアップロードします。S3のendpointはLocalStackになるので、endpointを修正します。
from pathlib import Path
import boto3
BASE_DIR = Path(__file__).parent
BUCKET = "my-bucket"
S3_ENDPOINT = "http://localstack:4566"
def upload(filename: Path) -> None:
client = boto3.client("s3", endpoint_url=S3_ENDPOINT)
client.upload_file(str(filename), BUCKET, filename.name)
if __name__ == "__main__":
filename = BASE_DIR / "my_file.txt"
upload(filename)
ファイルがアップロードされているか確認してみましょう。awslocal s3 cp s3://my-bucket/my_file.txt .
でローカルに持ってきて、ファイルの中身を確認することもできます。
docker compose exec localstack bash
awslocal s3 ls s3://my-bucket
awslocal s3 cp s3://my-bucket/my_file.txt .
話はそれますが(デモアプリケーション)
今回、LocalStackを用いてデモアプリケーションの開発を進めました。デモアプリケーションはこちらで公開しております。これまで、AnyMotionを手軽に使える環境のありませんでしたので、試しに一度使ってみてください。いくつか制約はありますが、無償でご利用できます。
まとめ
- LocalStackについて簡単に紹介しました
- LocalStackを用いることにより、ローカル環境での開発を効率よく進めることができます