AWSをローカル環境にエミュレートしてみた

AWS CLIのコマンドを本番環境でのAWSアカウントでは試しにくかったり、お金がかかるため自分のAWSアカウント持っていなくて試せないことがあるのではないのでしょうか。

LocalStackというツールを利用すると、なんとローカル環境にAWSのコマンドを試せる環境が作れちゃいます。

ここまでで興味を持ってくれた方、以降で使い方を紹介するので、ぜひ自分のPC等で試してみてください。

※無償版(Community)と有償版(Pro)がありますが、今回は無償版(Community)の使い方になります。

LocalStackとは

ローカル環境のコンテナ上でAWSをエミュレートして、AWSの開発やテストができるツールです。

 

LocalStackを使ってみる

環境

OS:Ubuntu 24.04 LTS (自宅のPCのHyper-V上に仮想マシンを作成)

Docker:Docker version 26.1.3, build 26.1.3-0ubuntu1~24.04.1

AWS CLI:aws-cli/2.22.12 Python/3.12.6 Linux/6.8.0-49-generic exe/x86_64.ubuntu.24

→アクセスキーは適当な値でも問題ありません。

事前にインストールが必要なもの

  1. Docker
    Ubuntuの場合、Ubuntuのリポジトリからインストールできます。                                          

    sudo apt install docker.io

    参考:Docker

  2. AWS CLI
    Ubuntuの場合、初期セットアップの際、インストール可否を選択できるため、そこでインストールすると楽です。
    追加でインストールする際は公式サイトの手順に従ってインストールしてください。
    参考:AWS CLI

 

LocalStackをインストールする

参考:Installation

  1. LocalStack CLIをインストールする
    curl --output localstack-cli-4.0.0-linux-amd64-onefile.tar.gz \
    --location https://github.com/localstack/localstack-cli/releases/download/v4.0.0/localstack-cli-4.0.0-linux-amd64-onefile.tar.gz
    sudo tar xvzf localstack-cli-4.0.0-linux-*-onefile.tar.gz -C /usr/local/bin
  2. LocalStackのコンテナを起動する
    docker run \
    --rm -it \
    -p 127.0.0.1:4566:4566 \
    -p 127.0.0.1:4510-4559:4510-4559 \
    -v /var/run/docker.sock:/var/run/docker.sock \
    localstack/localstack

AWS CLIを実行してみる

AWS CLI実行時はエンドポイントを以下で指定する必要があります。

指定するエンドポイント:http://localhost:4566

■IAMユーザ作成
※UserIdはマスキングしています

user01@localstack:~$ aws iam --endpoint-url=http://localhost:4566 create-user --user-name testuser
{
    "User": {
        "Path": "/",
        "UserName": "testuser",
        "UserId": "**********************",
        "Arn": "arn:aws:iam::000000000000:user/testuser",
        "CreateDate": "2024-12-09T15:59:47.345000+00:00"
    }
}
user01@localstack:~$

■S3作成

user01@localstack:~$ aws s3api --endpoint-url=http://localhost:4566 create-bucket --bucket test-bucket001
{
"Location": "/test-bucket001"
}
user01@localstack:~$
user01@localstack:~$ aws s3api --endpoint-url=http://localhost:4566 put-bucket-tagging --bucket test-bucket001 --tagging 'TagSet=[{Key=Name,Value=test-bucket001},{Key=testTag,Value=abcd}]'
user01@localstack:~$ aws s3api --endpoint-url=http://localhost:4566 get-bucket-tagging --bucket test-bucket001
{
    "TagSet": [
        {
            "Key": "Name",
            "Value": "test-bucket001"
        },
        {
            "Key": "testTag",
            "Value": "abcd"
        }
    ]
}
user01@localstack:~$
user01@localstack:~$ aws s3 --endpoint-url=http://localhost:4566 cp /home/user01/test/testfile001 s3://test-bucket001
upload: test/testfile001 to s3://test-bucket001/testfile001
user01@localstack:~$
user01@localstack:~$ aws s3 --endpoint-url=http://localhost:4566 ls s3://test-bucket001
2025-01-03 06:42:16 0 testfile001
user01@localstack:~$

複数のS3を作成して特定のタグを変更するシェルスクリプトを実行してみる

実機での変更系のコマンドは試しにくいため、タグの変更を実行してみようと思います。

■タグが変更されるバケット

S3バケット:test-bucket001、test-bucket002
タグ:Name=バケット名
タグ:testTag=abcd(変更前)
タグ:testKey=XYZ(変更後)

■タグが変更されないバケット

S3バケット:test-bucket999
タグ:Name=バケット名
タグ:testTag =noChange

■シェルスクリプト

#!/bin/bash

ENDPOINT_URL="http://localhost:4566"

# S3バケットのリストを取得
BUCKET_NAMES=$(aws s3api list-buckets --query "Buckets[].Name" --output text --endpoint-url $ENDPOINT_URL)

for BUCKET_NAME in $BUCKET_NAMES
do
echo "Checking bucket: $BUCKET_NAME"

# 前後比較のファイル名を設定
OLD_TAG_FILE="${BUCKET_NAME}_old_tags.json"
NEW_TAG_FILE="${BUCKET_NAME}_new_tags.json"

# バケットのタグを取得
aws s3api get-bucket-tagging --bucket $BUCKET_NAME --endpoint-url $ENDPOINT_URL --query "TagSet" --output json 2>/dev/null > $OLD_TAG_FILE

# 対象のタグキーとバリューが存在するか確認
if jq -e '.[] | select(.Key == "testTag" and .Value == "abcd")' $OLD_TAG_FILE > /dev/null; then
echo "Updating tag for bucket: $BUCKET_NAME"

# 古いタグを読み込み、変更
TAGS=$(jq '.[] | if .Key == "testTag" and .Value == "abcd" then .Value = "XYZ" else . end' $OLD_TAG_FILE | jq -s .)
NEW_TAGS='{"TagSet":'"$TAGS"'}'

# タグを更新
aws s3api put-bucket-tagging --bucket $BUCKET_NAME --tagging "$NEW_TAGS" --endpoint-url $ENDPOINT_URL

# 新しいタグを取得
aws s3api get-bucket-tagging --bucket $BUCKET_NAME --endpoint-url $ENDPOINT_URL --query "TagSet" --output json > $NEW_TAG_FILE

# 変更前後のタグを比較
echo "=====$BUCKET_NAME====="
diff -y $OLD_TAG_FILE $NEW_TAG_FILE
echo "----------------------------------------"
else
echo "No matching tag 'testTag: abcd' for bucket: $BUCKET_NAME"
fi

done

■実行結果

test-bucket001、test-bucket002のタグが変更され、test-bucket999のみ変更されませんでした。
AWS CLIを使用したシェルスクリプトも試すことも可能です!

user01@localstack:~/test$ ./update-s3-tags.sh
Updating tag for bucket: test-bucket001
=====test-bucket001=====
[                                                               [
    {                                                               {
      "Key": "Name",                                              "Key": "Name",
      "Value": "test-bucket001"                               "Value": "test-bucket001"
      },                                                            },
    {                                                               {
      "Key": "testTag",                                            "Key": "testTag",
      "Value": "abcd"                                   |          "Value": "XYZ"
      },                                                            },
]                                                               ]
----------------------------------------
Updating tag for bucket: test-bucket002
=====test-bucket002=====
[                                                               [
    {                                                               {
      "Key": "Name",                                              "Key": "Name",
      "Value": "test-bucket002"                               "Value": "test-bucket002"
      },                                                            },
    {                                                               {
      "Key": "testTag",                                            "Key": "testTag",
      "Value": "abcd"                                   |          "Value": "XYZ"
      },                                                            },
]                                                               ]
----------------------------------------
No matching tag 'testTag: abcd' for bucket: test-bucket999
user01@localstack:~/test$

最後に

ネットサーフィンしているときに面白そうなツールだなと思い今回試してみました。
お試しというところで実際に開発に使えるかどうかまでは確認していないため、開発で使用できるかについてはご自身で試して判断してみてください。
また、今回は無償版を使っているため、コンテナが停止するとデータが残らない仕様になっています。
コンテナを再起動するたびに環境構築が必要となりますので、停止時にはご注意ください。

参考

LocalStack:https://www.localstack.cloud/

使用できるAWSサービス:AWS のサービス機能カバレッジ |ドキュメント

タイトルとURLをコピーしました