0
0

LocalStackにAWS SAMでデプロイしたLambdaにAndroidからアクセスしてみた

Last updated at Posted at 2024-08-29

はじめに

  • AWS SAM CLI for LocalStack を使ってアプリをLocalStackにデプロイできる
  • Dockerでhttpdを起動した端末とスマホが同じネットワークにいれば、スマホのブラウザからWebページを閲覧できる

…ということから、「Dockerで動いているLocalStackにデプロイしたLambda関数へ、同じネットワークのAndroidアプリからアクセスできるのでは?」などと思いつきました。試してみたところ、一応できたのでここに残しておきます
AWSとスマホアプリを連携させるケースを、不具合の混入や費用などの心配なくローカルで好き勝手に試したい、という方の参考になれば幸いです

ちなみに当方はAndroid専門なので、iOSについては言及しておりません。申し訳ありませんが、ご了承ください

追記

私のGitHubに以下の3点を含むレポジトリを共有しております。よければご参考ください

  • LocalStackコンテナを起動するための docker-compose.yaml
  • 簡単なSAMプロジェクト
  • Lambda関数を呼び出せす簡単なAndroidアプリ

実行環境について

このエントリを書くにあたり、以下の環境で作業を行いました

  • MacとAndroid端末を用意し、両者を同じネットワークに接続
  • MacにDockerをインストールし、コンテナでLocalStackを起動
    • AWS SAM CLI for LocalStackを使ってアプリをビルド、デプロイ
    • アプリに含まれるLambda関数は、REST APIとして呼び出せるよう設定
  • APIにリクエストをかけるAndroidアプリを用意して、Lambdaからのレスポンスが得られるかを確認

ソフトウェアのバージョン

AWS関連

% aws --version
aws-cli/2.17.13 Python/3.11.9 Darwin/23.6.0 exe/x86_64

% sam --version
SAM CLI, version 1.121.0

LocalStack関連

% docker compose up
[+] Running 1/0
 ✔ Container localstack-main   Created   0.0s 
Attaching to localstack-main
localstack-main  | LocalStack version: 3.5.1.dev
localstack-main  | LocalStack build date: 2024-07-19
localstack-main  | LocalStack build git hash: 9d37d8285
localstack-main  | Ready.

Android関連

  • Android Studio Koala | 2024.1.1
  • Pixel5 (Android 14)

その他

  • macOS sonoma
  • Docker Desktop 27.1.1, build 6312585
  • Python 3.12.5

SAMを使ったアプリのビルドとデプロイ

前提条件

PythonやDocker Desktop以外に、AWS CLIとSAM CLIがインストール済みとします

手順

基本的には下記を実施すれば、アプリをLocalStackにデプロイできます(場合によっては不要な作業もあります)

  1. LocalStack AWS CLI のセットアップ
  2. AWS SAM CLI for LocalStack のセットアップ
  3. docker-compose.yaml で SERVICES 環境変数をセット
  4. AWS_ENDPOINT_URL 環境変数をセット(必要に応じて)
  5. samlocal コマンドを使って、アプリをビルド・デプロイ

LocalStack AWS CLI のセットアップ

% pip install awscli-local

% awslocal --version
aws-cli/2.17.13 Python/3.11.9 Darwin/23.6.0 exe/x86_64

AWS SAM CLI for LocalStack のセットアップ

% pip install aws-sam-cli-local

% samlocal --version
SAM CLI, version 1.122.0

docker-compose.yaml で SERVICES 環境変数をセット

  • LocalStackでエミュレーションするAWSサービスの一覧を SERVICES という環境変数に列挙します
  • SAMでのデプロイにCloudFormationが必要だったり、ロール付与のためにIAMが必要なので、以下を指定しておくのが無難だと思います
    • logs
    • cloudformation
    • iam 
  • テンプレートに定義されているサービスが SERVICES に無いと samlocal deploy でエラーになります
    • 例えばREST APIとしてLambdaを起動する場合は apigateway が必要です
  • 私が実際に使用した docker-compose.yaml は こちら でご確認ください
(例) 必要な SERVICES を指定しないとどうなるか

cloudformationSERVICES に指定しないで samlocal deploy を実行した場合です。下記のエラーが発生してデプロイに失敗します

% samlocal deploy --config-env local        
	Creating the required resources...
Error: Failed to create managed resources: An error occurred (InternalFailure) when calling the CreateChangeSet operation: Service 'cloudformation' is not enabled. Please check your 'SERVICES' configuration variable.

AWS_ENDPOINT_URL 環境変数をセット(必要に応じて)

  • こちらは docker-compose.yaml でなく、 awslocal コマンドや samlocal コマンドを発行する側にセットします。このエントリの場合、Macのターミナルで export することになります
  • AWS_ENDPOINT_URL 環境変数によって、DockerコンテナにセットアップしたLocalStackが samlocal コマンドの相手として設定されます
    • aws コマンド発行時に endpoint-url を指定するのと同様の効果があります
    • AWS_ENDPOINT_URL のデフォルトは http://localhost.localstack.cloud:4566 です。そのためコンテナの設定でポート番号などを変更していなければ、 AWS_ENDPOINT_URL を設定しなくても samlocal は期待通りに機能します。状況に応じて設定して下さい

アプリのビルド・デプロイ

  • 実環境に対して sam コマンドを発行するのと同様、 samlocal コマンドを使ってLocalStackにアプリをビルド・デプロイします
    • 下記の例では何もオプションを指定していませんが、必要に応じて --guided などを指定してください
  • ビルドには samlocal でなく sam コマンドでも構いませんが、 deploy には必ず samlocal を使うようにしてください
samlocal build
samlocal deploy

Lambda関数をAPIとして起動

同じネットワークに繋がっており、エンドポイントが分かれば、基本的にはcURLでもAndroidアプリでも、同じようにLambda関数に対するリクエストをかけることができます

Lambdaの設定

AWS::Serverless::FunctionEvents は以下のように設定されているとします
(必要な箇所だけ抜粋)

Type: AWS::Serverless::Function
Properties:
  Events:
    SimpleResponseApiEvent:
      Type: Api
      Properties:
        Method: get
        Path: /sample

エンドポイントの確認

  1. awslocal apigateway get-rest-apis コマンドでREST API IDを取得
    • 実行結果の “items” > “id” から取得できます(実行例を後掲してあります)
  2. LocalStack のリファレンスを参考に、Lambda関数を起動するためのURLを割り出します

REST API IDからエンドポイントを割り出す

エンドポイントのルールは以下の通りです
ここではホスト名が localhost になっていますが、他の端末からアクセスする場合は、LocalStackの稼働している端末のIPアドレスに置き換えてください

http://localhost:4566/restapis/[REST API ID]/[パス]/_user_request_/[パス]?[クエリ]

apigateway get-rest-apis で確認したREST API IDが “abcde12345” だった場合、Lambda関数にアクセスするためのエンドポイントは以下のようになります

# クエリを必要としない場合
http://localhost:4566/restapis/abcde12345/sample/_user_request_/sample

# param というキーでクエリを利用する場合
http://localhost:4566/restapis/abcde12345/sample/_user_request_/sample?param=XXXXXX

ここまでで、cURLなりAndroid端末なりで目的の関数にリクエストをかけることができます

curl http://localhost:4566/restapis/abcde12345/sample/_user_request_/sample

(参考) awslocal apigateway get-rest-apis の実行結果

% awslocal apigateway get-rest-apis
{
    "items": [
        {
            "id": "8g99upccg5",
            "name": "sample-sam-app-local-ServerlessRestApi-9a7a3dda",
            "createdDate": "2024-08-28T13:57:18+09:00",
            "version": "1.0",
            "apiKeySource": "HEADER",
            "endpointConfiguration": { "types": [ "EDGE" ] },
            "tags": {
                "aws:cloudformation:logical-id": "ServerlessRestApi",
                "aws:cloudformation:stack-name": "sample-sam-app-local",
                "aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-3:000000000000:stack/sample-sam-app-local/ac48696f"
            },
            "disableExecuteApiEndpoint": false,
            "rootResourceId": "8pv2rh0na7"
        }
    ]
}
0
0
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
0
0