これは、なにをしたくて書いたもの?
Javaのアプリケーションフレームワークを使って、LocalStackにAmazon API Gateway+AWS Lambdaな環境を作って
みようとしていたのですが、ちょっとハマったのでひとつずつ順番に見ていこうかなと。
今回は、LocalStack上にAWSのツールを使って作成したAWS Lambda関数をデプロイしてみたいと思います。
まあ、Mavenアーキタイプを使っても、デプロイにはSAMを求められるようですが。
AWS Lambda用のMavenアーキタイプ
AWS Lambda関数については、最初はシンプルにこちらのドキュメントを見て作ろうかと思っていたのですが。
Java の AWS Lambda 関数ハンドラー - AWS Lambda
少し調べてみると、AWS Lambda用のMavenアーキタイプが出ていることがわかったので、こちらを使ってみることに
しました。
READMEは、GitHub上のものを読んだ方がよさそうですね。
https://github.com/aws/aws-sdk-java-v2/blob/2.17.46/archetypes/archetype-lambda/README.md
環境
今回の環境は、こちらです。
LocalStack。
$ localstack --version 0.12.18
こちらのコマンドで起動しておきます。
$ LAMBDA_EXECUTOR=docker-reuse localstack start
AWS CLIやSAMは、LocalStackが提供しているローカル用のものを使います。
$ awslocal --version aws-cli/2.2.41 Python/3.8.8 Linux/5.4.0-86-generic exe/x86_64.ubuntu.20 prompt/off $ samlocal --version SAM CLI, version 1.31.0
Javaに関するもの。
$ java --version openjdk 11.0.11 2021-04-20 OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04) OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing) $ mvn --version Apache Maven 3.8.2 (ea98e05a04480131370aa0c110b8c54cf726c06f) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 11.0.11, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "5.4.0-86-generic", arch: "amd64", family: "unix"
AWS Lambda関数用のMavenアーキタイプを使って、プロジェクトを作成する
では、最初にMavenアーキタイプを使ってAWS Lambda用のプロジェクトを作成してみます。
こちらのブログを見ながら
コマンド実行。
$ mvn archetype:generate \ -DarchetypeGroupId=software.amazon.awssdk \ -DarchetypeArtifactId=archetype-lambda \ -DarchetypeVersion=2.17.46 \ -DgroupId=org.littlewings \ -DartifactId=hello-java-lambda \ -Dversion=0.0.1-SNAPSHOT \ -Dservice=s3 \ -DinteractiveMode=false
指定するパラメーターは、こちらを参照。
Maven Archetype for lambda function using AWS SDK for Java 2.x / Parameters
service
というパラメーターに使いたいAWSサービス名を指定することで、依存関係にそのサービスを使うための
ライブラリと、クライアントコードを生成してくれるようなのですが。
これ、必須になっています。今回はとりあえず動かしてみたいだけなので要らないのですが…。仕方ないので、今回は
s3
を指定して後で削除することにしました。
指定できるサービス名は、ここから選びます。
https://github.com/aws/aws-sdk-java-v2/tree/2.17.46/services
存在しないものを指定しても、怒られたりはしないみたいです(変なpom.xml
ができあがる)。
作成されたプロジェクト内に移動して
$ cd hello-java-lambda
どのようなものができあがったか、見てみましょう。
$ tree . ├── README.md ├── pom.xml ├── src │ ├── main │ │ └── java │ │ └── org │ │ └── littlewings │ │ ├── App.java │ │ └── DependencyFactory.java │ └── test │ └── java │ └── org │ └── littlewings │ └── AppTest.java └── template.yaml 9 directories, 6 files
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.littlewings</groupId> <artifactId>hello-java-lambda</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version> <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version> <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version> <aws.java.sdk.version>2.17.46</aws.java.sdk.version> <aws.lambda.java.version>1.2.0</aws.lambda.java.version> <junit5.version>5.4.2</junit5.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>${aws.java.sdk.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <exclusions> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </exclusion> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>url-connection-client</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>${aws.lambda.java.version}</version> </dependency> <!-- Test Dependencies --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit5.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>${maven.shade.plugin.version}</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <finalName>hello-java-lambda</finalName> <filters> <filter> <artifact>*:*</artifact> <excludes> <!-- Suppress module-info.class warning--> <exclude>module-info.class</exclude> </excludes> </filter> </filters> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
依存関係は、こちら。最初に定義されているのが、service
に指定したものですね。
<dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <exclusions> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </exclusion> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>url-connection-client</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>${aws.lambda.java.version}</version> </dependency> <!-- Test Dependencies --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit5.version}</version> <scope>test</scope> </dependency> </dependencies>
Maven Shade Pluginの設定も入っています。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>${maven.shade.plugin.version}</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <finalName>hello-java-lambda</finalName> <filters> <filter> <artifact>*:*</artifact> <excludes> <!-- Suppress module-info.class warning--> <exclude>module-info.class</exclude> </excludes> </filter> </filters> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin>
スケルトンのコード。
src/main/java/org/littlewings/App.java
package org.littlewings; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import software.amazon.awssdk.services.s3.S3Client; /** * Lambda function entry point. You can change to use other pojo type or implement * a different RequestHandler. * * @see <a href=https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html>Lambda Java Handler</a> for more information */ public class App implements RequestHandler<Object, Object> { private final S3Client s3Client; public App() { // Initialize the SDK client outside of the handler method so that it can be reused for subsequent invocations. // It is initialized when the class is loaded. s3Client = DependencyFactory.s3Client(); // Consider invoking a simple api here to pre-warm up the application, eg: dynamodb#listTables } @Override public Object handleRequest(final Object input, final Context context) { // TODO: invoking the api call using s3Client. return input; } }
service
で指定したサービスに対する、クライアントを作成するコードもついてくるようです。
src/main/java/org/littlewings/DependencyFactory.java
package org.littlewings; import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.core.SdkSystemSetting; import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3Client; /** * The module containing all dependencies required by the {@link App}. */ public class DependencyFactory { private DependencyFactory() {} /** * @return an instance of S3Client */ public static S3Client s3Client() { return S3Client.builder() .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))) .httpClientBuilder(UrlConnectionHttpClient.builder()) .build(); } }
テストコード。
src/test/java/org/littlewings/AppTest.java
package org.littlewings; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class AppTest { @Test public void handleRequest_shouldReturnConstantValue() { App function = new App(); Object result = function.handleRequest("echo", null); assertEquals("echo", result); } }
AWS SAMでデプロイするためのYAMLテンプレートもついてきます。
template.yaml
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: # See https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html # for more info to see how to tune the lambda function configs based on your use case. AppFunction: Type: AWS::Serverless::Function Properties: Runtime: java8 Handler: org.littlewings.App::handleRequest Timeout: 60 MemorySize: 512 CodeUri: ./target/hello-java-lambda.jar # Attach policies here to give the function permission to access other AWS resources if needed # See: https://github.com/awslabs/serverless-application-model/blob/master/docs/policy_templates.rst # eg: #Policies: # - S3ReadPolicy: # BucketName: test-bucket
README.md
も作成され、こちらには事前にインストールしておくものが書かれていたり(AWS SAM CLIが入って
いますね)
## Prerequisites - Java 1.8+ - Apache Maven - [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) - Docker
ビルド方法やローカルでの動かし方
#### Building the project mvn clean install #### Testing it locally sam local invoke
デプロイ方法が書かれています。完全にAWS SAMを使う形です。
## Deployment The generated project contains a default [SAM template](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) file `template.yaml` where you can configure different properties of your lambda function such as memory size and timeout. You might also need to add specific policies to the lambda function so that it can access other AWS resources. To deploy the application, you can run the following command: sam deploy --guided
AWS Lambda関数を作成してLocalStackにデプロイする
では、生成されたプロジェクトを変更してみましょう。今回は、あくまでデプロイと動作確認が目的なので、
リクエストで受け取ったパラメーターを使った簡単な処理を書くことにします。
まずは、プロジェクトで使用するJavaのバージョンを11にしておきます。
<maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target>
Amazon S3へのアクセスは行わないので、依存関係から削除。
<!-- <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <exclusions> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </exclusion> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> </exclusion> </exclusions> </dependency> -->
既存のソースコードも要らないので、削除。
$ rm src/main/java/org/littlewings/* src/test/java/org/littlewings/AppTest.java
作成したコードは、こちら。
src/main/java/org/littlewings/lambda/App.java
package org.littlewings.lambda; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; import com.amazonaws.services.lambda.runtime.RequestHandler; public class App implements RequestHandler<Map<String, Object>, Map<String, Object>> { @Override public Map<String, Object> handleRequest(Map<String, Object> input, Context context) { LambdaLogger logger = context.getLogger(); logger.log(String.format("Request: %s", input)); String message = (String) input.get("message"); int repeat = (Integer) input.get("repeat"); return Map.of( "result", IntStream.rangeClosed(1, repeat).mapToObj(i -> message).collect(Collectors.toList()) ); } }
リクエストにはメッセージと回数を受け取るものとし、指定された回数だけメッセージを返す関数にしています。
こちらをパッケージングして
$ mvn package
LocalStackにデプロイ。
$ awslocal lambda create-function \ --function-name hello_java_lambda \ --zip-file fileb://target/hello-java-lambda.jar \ --handler org.littlewings.lambda.App::handleRequest \ --runtime java11 \ --role test-role
関数を更新する場合は、こちらになります。
$ awslocal lambda update-function-code \ --function-name hello_java_lambda \ --zip-file fileb://target/hello-java-lambda.jar
動作確認。
$ awslocal lambda invoke --function-name hello_java_lambda --payload '{"message": "Hello World", "repeat": 3 }' --cli-binary-format raw-in-base64-out result.json { "StatusCode": 200, "LogResult": "", "ExecutedVersion": "$LATEST" }
OKです。
$ cat result.json {"result":["Hello World","Hello World","Hello World"]}
では、いったん削除。
$ awslocal lambda delete-function --function-name hello_java_lambda
AWS SAMでデプロイする
せっかくテンプレートファイルが生成されているので、AWS SAMでもデプロイしてみましょう。
テンプレートファイルのRuntime
をjava11
に変更し、Handler
も作成したクラスおよびメソッドに変更します。
Properties: Runtime: java11 Handler: org.littlewings.lambda.App::handleRequest
LocalStackの場合は先にAmazon S3バケットを作成して
$ awslocal s3 mb s3://my-bucket
デプロイ。
$ samlocal deploy --stack-name my-stack --template-file template.yaml --region us-east-1 --s3-bucket my-bucket
作成されたAWS Lambda関数のFunctionName
を確認して
$ awslocal lambda list-functions { "Functions": [ { "FunctionName": "my-stack-AppFunction-e4577968", "FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:my-stack-AppFunction-e4577968", "Runtime": "java11", "Role": "arn:aws:iam::000000000000:role/cf-my-stack-AppFunctionRole", "Handler": "org.littlewings.lambda.App::handleRequest", "CodeSize": 290766, "Description": "", "Timeout": 60, "MemorySize": 512, "LastModified": "2021-09-26T07:20:51.368+0000", "CodeSha256": "qY08o6ZnzAkdcl03jNcWNhgkZvY8e+UnziUnuN4ObP0=", "Version": "$LATEST", "VpcConfig": {}, "TracingConfig": { "Mode": "PassThrough" }, "RevisionId": "467b7b1a-85ce-45c3-949b-d729fd100669", "State": "Active", "LastUpdateStatus": "Successful", "PackageType": "Zip" } ] }
確認。
$ awslocal lambda invoke --function-name my-stack-AppFunction-e4577968 --payload '{"message": "Hello World", "repeat": 3 }' --cli-binary-format raw-in-base64-out result.json
こちらもOKですね。
$ cat result.json {"result":["Hello World","Hello World","Hello World"]}
オマケ: AWS SAMでAWS Lambda関数を作成して、LocalStackにデプロイしてみる
なんとなく、AWS SAMでAWS Lambda関数を作成して、LocakStackにデプロイするところもやってみましょう。
こちらは、Amazon API Gateway経由で動かすことにします。
プロジェクトの作成。
$ samlocal init
Java 11で、プロジェクト名はhello-java-lambda-sam
で作成。
Template selection: 1 ----------------------- Generating application: ----------------------- Name: hello-java-lambda-sam Runtime: java11 Dependency Manager: maven Application Template: hello-world Output Directory: . Next steps can be found in the README file at ./hello-java-lambda-sam/README.md
プロジェクト内に移動。
$ cd hello-java-lambda-sam
生成されたファイルは、こんな感じです。
$ tree . ├── HelloWorldFunction │ ├── pom.xml │ └── src │ ├── main │ │ └── java │ │ └── helloworld │ │ └── App.java │ └── test │ └── java │ └── helloworld │ └── AppTest.java ├── README.md ├── events │ └── event.json └── template.yaml 9 directories, 6 files
テンプレートファイル。
template.yaml
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > hello-java-lambda-sam Sample SAM Template for hello-java-lambda-sam # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 20 Resources: HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: HelloWorldFunction Handler: helloworld.App::handleRequest Runtime: java11 MemorySize: 512 Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: PARAM1: VALUE Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn
生成されたAWS Lambda関数本体。
HelloWorldFunction/src/main/java/helloworld/App.java
package helloworld; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; /** * Handler for requests to Lambda function. */ public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> { public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() .withHeaders(headers); try { final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); return response .withStatusCode(200) .withBody(output); } catch (IOException e) { return response .withBody("{}") .withStatusCode(500); } } private String getPageContents(String address) throws IOException{ URL url = new URL(address); try(BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { return br.lines().collect(Collectors.joining(System.lineSeparator())); } } }
https://checkip.amazonaws.com を使って、自端末のグローバルIPを返すAWS Lambda関数のようです。
テストコード。
HelloWorldFunction/src/test/java/helloworld/AppTest.java
package helloworld; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.junit.Test; public class AppTest { @Test public void successfulResponse() { App app = new App(); APIGatewayProxyResponseEvent result = app.handleRequest(null, null); assertEquals(result.getStatusCode().intValue(), 200); assertEquals(result.getHeaders().get("Content-Type"), "application/json"); String content = result.getBody(); assertNotNull(content); assertTrue(content.contains("\"message\"")); assertTrue(content.contains("\"hello world\"")); assertTrue(content.contains("\"location\"")); } }
HelloWorldFunction/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>helloworld</groupId> <artifactId>HelloWorld</artifactId> <version>1.0</version> <packaging>jar</packaging> <name>A sample Hello World created for SAM CLI.</name> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.6.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <configuration> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
今回は、生成されたコードをそのまま使うことにします。pom.xml
の定義は、Java 8向けですが、とりあえず
気にしないことにします。
ビルドして
$ samlocal build Building codeuri: /path/to/hello-java-lambda-sam/HelloWorldFunction runtime: java11 metadata: {} functions: ['HelloWorldFunction'] Running JavaMavenWorkflow:CopySource Running JavaMavenWorkflow:MavenBuild Running JavaMavenWorkflow:MavenCopyDependency Running JavaMavenWorkflow:MavenCopyArtifacts Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided
$ awslocal s3 mb s3://my-bucket
デプロイ。
$ samlocal deploy --stack-name my-stack --region us-east-1 --s3-bucket my-bucket
Amazon API GatewayのREST APIのIDを確認して
$ awslocal apigateway get-rest-apis
変数に設定。
$ REST_API_ID=...
動作確認。
$ curl http://localhost:4566/restapis/$REST_API_ID/Prod/_user_request_/hello { "message": "hello world", "location": "[自端末のグローバルIP]" }
OKですね。
これで、確認したいところはひととおり見れた感じです。