はじめに
AWS Lambdaの管理ツールであるApexを使ってgoを実行する
LambdaFunctionの作り方と使い方のメモ。
割とapex.run に載ってる内容ではありますがが。
AWS Lambdaとは
いわゆるサーバーレスアーキテクチャの一種でFaas(Function as a Service)
公式
-
コードをアップするとAWSInfra上でサーバー用意したり、プロビジョニングしなくても実行する事ができるコンピューティングサービス。
- 現状はjs,java,c#,pythonなどをサポートしてる(近々goもやるらしい)
- apexだとNodeでgoを実行してくれるのでgoもいける
-
AWS内の他サービスで定義されたトリガーに紐付けてpubsubみたいな事もできる
-
s3,dynamoの変更通知を受け取ってゴニョゴニョしてあげたり、code deployのデプロイ完了のトリガーを使ってなにがし、みたいに。
簡単に言うとLambdaでサポートしてる言語なら、デプロイとか実行環境整備したりとか不要でEC2インスタンスわざわざ立てなくても
実行できるし、他のAWSサービスと連携しやすいよって感じ。
ウェブサーバーやバッチサーバーみたいなIaasを必要とするようなものではなく、イベントに引っ掛けて
ちょっとした処理をするくらいのものに使うのがいい感じ
インストール
apexのインストール
curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh
awscliのインストール
aws使うなら入れてる人が大半だと思いますが
apexの動作にaws credentialが必要なので...
公式の引用
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py
sudo pip install awscli
sixの依存関係errorが出る場合は
sudo pip install --ignore-installed awscli
あたりで無視しちゃうと早いです。
credentialの設定
公式の引用。
regionは自分の使ってるもので。
$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE #
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json
プロジェクト作成
apex cliで雛形作成ができるのでサクッと作ってしまいましょう。
$ mkdir your_lambda_function_dir
$ cd your_lambda_function_dir
$ apex init
_ ____ _______ __
/ \ | _ \| ____\ \/ /
/ _ \ | |_) | _| \ /
/ ___ \| __/| |___ / \
/_/ \_\_| |_____/_/\_\
Enter the name of your project. It should be machine-friendly, as this
is used to prefix your functions in Lambda.
Project name: xxx_notify
Enter an optional description of your project.
Project description: notification for xxx
[+] creating IAM xxxx_function role
[+] creating IAM xxxxx policy
[+] attaching policy to lambda_function role.
[+] creating ./project.json
[+] creating ./functions
Setup complete, deploy those functions!
$ apex deploy
テンプレートな構成を作ってくれます。
terraform使ってない場合はIAMを求められるので、作るor指定が必要。
tree
.
├── functions
│ └── hello
│ └── index.js
└── project.json
goでコードを書く
特にgoを使うための細かな設定などは不要です。apexできる子。
今回は受け取ったsnsのbodyをsqsに投稿するサンプルを。
- .apexignoreでdeployしないファイルを指定する(バイナリをあげれば良いので*.goは無視)
cat .apexignore
*.go
- snsで受け取ったbodyをsqsに送るコードを書く
import (
"bytes"
"encoding/json"
"strings"
apex "github.com/apex/go-apex"
apexSns "github.com/apex/go-apex/sns"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/sqs"
)
func main() {
apexSns.HandleFunc(func(event *apexSns.Event, ctx *apex.Context) error {
body := event.Records[0].SNS.Message
//bodyをsqsに送るよ
awscli := sqs.New(sess, &aws.Config{Region: aws.String("ap-northeast-1")})
queueUrl := "your_sqs_queue_url"
params := &sqs.SendMessageInput{
QueueUrl: &queueUrl,
MessageBody: &body,
}
_, err = awscli.SendMessage(params)
return err
})
}
こんな感じ。
apexでのgo実行は、プロセス立ち上げてnodeでgoのバイナリを実行してるだけなので
importとかはローカルで解決してれば大丈夫です。
aws-sdk-goがいい感じにIAMの権限を使ってくれるので
403とか出る場合はlambdaを実行するIAMのロールにsqsのアクセス権を与えてあげてください。
イメージ湧きづらい場合は
公式をみると良いです。
deployと実行
- deploy
apex deploy function_name
- 実行
apex invoke function_name
- logを見る
apex logs function_name -f
/aws/lambda/*** 2017-11-15T06:05:30.238Z fb0b2dbb-c9ca-11e7-afc4-6762e3c5815e {"errorMessage":"hoge"} // handlerFuncで返したerrがprintされる
/aws/lambda/*** END RequestId: fb0b2dbb-c9ca-11e7-afc4-6762e3c5815e
/aws/lambda/*** REPORT RequestId: fb0b2dbb-c9ca-11e7-afc4-6762e3c5815e Duration: 936.31 ms Billed Duration: 1000 ms Memory Size: 128 MB M
[応用] vpc内のリソースにアクセスする
公式のやり方でもいいし、
package json
に以下を追加する感じでもおkです
{
"vpc": {
"securityGroups": ["xxx"],
"subnets": ["aaaa", "bbbb"]
}
}