6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LocalStack環境をネットワーク内で共有する

Posted at

業務上、開発用のAWS環境でも動作確認レベルの資材を気楽にデプロイできないことは多いですよね。
以前からLocalStackでS3やDynamoDBを立ち上げて動作確認をしていましたが、気付くと他のメンバーの成果物の動作確認を依頼されるようになっていました...
そこで、ネットワーク内の別マシンからも資材配置&アクセスできるLocalStack環境を構築してみました。

ちょうど2023/03/31にLocalStack v2.0.0がリリースされていたので、仕様が変わった点や環境構築中に詰まったポイントも含めて構築手順をまとめます。

環境構築(サーバ)

LocalStack公式のDockerコンテナ起動方法は以下の5通りあります。
今回はLocalStack CLIを使っていきます。

  • LocalStack CLI
  • LocalStack Cockpit
  • Docker
  • Docker-Compose
  • Helm

前提ソフトウェア

  • Python(3.7~3.10)
  • pip
  • Docker
$ python --version
Python 3.8.2
$ pip --version
pip 23.0.1 from /usr/local/var/pyenv/versions/3.8.2/lib/python3.8/site-packages/pip (python 3.8)
$ docker --version
Docker version 20.10.23, build 7155243

LocalStackインストール

$ pip install localstack
$ localstack --version
2.0.0.post1

# バージョンを指定してインストールする場合
# pip install localstack==<version>

LocalStack起動

$ GATEWAY_LISTEN=0.0.0.0:4566 localstack start

ネットワーク内の別マシンからアクセスできるように環境変数GATEWAY_LISTEN=0.0.0.0:4566を設定しています。

以前はIPとポート指定がそれぞれ別の環境変数でしたが、localstack v2.0.0から1つに統合されているので注意が必要です。
LocalStack v2.0.0リリースノートより

We are unifying the variables EDGE_BIND_HOST, EDGE_PORT and EDGE_PORT_HTTP into GATEWAY_LISTEN,

以前は環境変数DATA_DIRにファイルパスを指定することでデータの永続化ができましたが、LocalStack v1.0.0以降はPro版限定の機能となりました。
コンテナを止める度に構築した資材が消えてしまうので注意が必要です。
Pro版であればPERSISTENCE=1でデータ永続化できます。

LocalStack起動中にヘルスチェック用エンドポイントにHTTPアクセスすると、バージョン情報と利用可能なAWSサービスを一覧表示できます。

2023/04/05時点では以下の結果になりました。
今回はCommunity版を使用しているので、Pro版限定機能のAthenaやECSは表示されていません。

$ curl -s http://localhost:4566/_localstack/health | jq .
{
  "services": {
    "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"
  },
  "version": "2.0.1.dev"
}

環境構築(クライアント)

  • AWS CLI (awsコマンド)
  • [任意] awscli-local (awslocalコマンド)
    • AWS CLIのラッパーコマンド
    • 毎度--endpoint-url=http://{LocalStackホストのIP:Port}を指定する手間が省ける
    • 別ホストのLocalStackにアクセスする場合、環境変数LOCALSTACK_HOST={ホスト名orIP}を設定する
    $ pip install awscli-local
    

LocalStackサーバのIPをendpoint-urlに指定することで別マシンから資材作成できます。

> aws s3 mb s3://sample-bucket --endpoint-url=http://192.168.0.149:4566 --no-sign-request
make_bucket: sample-bucket

CloudFormationでの資材構築

コンテナを止める度に手動で資材を作成し直すのは手間なのでCloudFormationで資材を構築します。
今回作成する資材は以下の2つです。

  • API Gateway(v1)
    • v2はPro版限定
    • GETメソッドのみ実装
  • Lambda
    • API GatewayへのGETリクエストをトリガとして起動 & 固定レスポンスOK!を返却

localstack構成図.png

template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  FuncName:
    Type: String
    Default: TestFunction

Resources:
  lambda_function:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs18.x
      Role: arn:aws:iam::123456789012:role/lambda-role
      Handler: index.handler
      FunctionName: !Ref FuncName
      Code:
        ZipFile: |
          exports.handler = async function (event, context) {
            return {statusCode: 200, body: 'OK!'}
          }
      Description: test static function.

  gateway:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: TestApiGateway
      Description: test gateway.

  resource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref gateway
      ParentId: !GetAtt gateway.RootResourceId
      PathPart: !Ref FuncName

  method:
    Type: AWS::ApiGateway::Method
    Properties:
      RestApiId: !Ref gateway
      ResourceId: !Ref resource
      AuthorizationType: None
      HttpMethod: GET
      Integration:
        Type: AWS_PROXY
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${FuncName}/invocations

  deployment:
    Type: AWS::ApiGateway::Deployment
    Properties:
      RestApiId: !Ref gateway
      StageName: test
# デプロイ
$ awslocal cloudformation deploy --stack-name test-stack --template-file "./template.yaml"
!NOTE! awslocal does not currently work with the cloudformation package/deploy commands supplied bythe AWS CLI v2. Please run "pip install awscli" to install version 1 of the AWS CLI

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - test-stack

# 作成したAPI Gatewayのidを控えておく
$ awslocal apigateway get-rest-apis
{
    "items": [
        {
            "id": "sxixclx8jo",
            "name": "TestApiGateway",
            "description": "test gateway.",
            "createdDate": "2023-04-12T14:15:15+09:00",
            "apiKeySource": "HEADER",
            "endpointConfiguration": {
                "types": [
                    "EDGE"
                ]
            },
            "tags": {
                "aws:cloudformation:logical-id": "gateway",
                "aws:cloudformation:stack-name": "test-stack",
                "aws:cloudformation:stack-id": "arn:aws:cloudformation:us-east-1:000000000000:stack/test-stack/380cec49"
            },
            "disableExecuteApiEndpoint": false
        }
    ]
}

動作確認

以下の宛先にHTTPリクエストを送信します。
http://{LocalStackホストのIP:Port}/restapis/{APIGatewayのID}/{ステージ名}/_user_request_/{関数名}

$ curl -s http://localhost:4566/restapis/sxixclx8jo/test/_user_request_/TestFunction
OK!%

# これでもいける
$ curl http://wzwpeatdvb.execute-api.localhost.localstack.cloud:4566/test/TestFunction

# https://github.com/localstack/localstack/tree/master/doc/interaction#invoking-api-gateway より

マルチアカウントについて

LocalStackはアカウントIDとリージョンで資材のアクセス制限ができます。

環境変数AWS_ACCESS_KEY_IDでアカウントIDを指定できます。
指定がない or 有効でない値※を指定するとアカウントID000000000000が使用されます。
※12桁の数値以外

利用者ごとにIDを決めておけば他の人が作った資材に誤アクセスするトラブルを回避できそうです。

参考

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?