初めてAWSのLambdaを触ってみた
この記事は、最終目的に向けて複数回にわたってtryする話
最終目的
- AWSの利用料金を毎朝Slacknに通知して請求額が跳ね上がるのを防ぎたい
なぜそんなことするのか?
- Terraformの学習をしてた際に、applyした後にdestroyし忘れて個人としては痛い額の請求がきたからです。
- 個人的観測範囲だと個人でのプロダクト持ってない人では、上位に食い込んでいるのでは?
今回やること
- 今更だがLambdaに入門してSlackに通知を送ってみること
次回以降に行うこと
- その日までの利用料金を取得しSlackに通知する
- deploy方法
- GithubActions or serverless
- どちらかを使用して行えるといいなと思っています
参照
前提
- AWSのアカウントを作成している人
- Goが動く環境
実装
aws
- アカウント作成
IAMロールの作成
-
- IAMでユーザーを作成している前提で話を進めます。
コードを lambda-uploader でデプロイするためには、あらかじめ空の関数を用意する必要があります。
- と書いてあるので予めにlambdaにて空の関数を作成します
- 右上に存在している
関数の作成
を押下、「一から作成」を行います - 以下の画像のように入力し、
関数の作成
を押下します関数定義の際にポリシーテンプレートから自動作成された IAM ロールに CloudWatchReadOnlyAccess ポリシーをアタッチします。コスト情報を Lambda から読み込むのに必要です。 ロール ARN はあとで必要になるのでメモしておきます。
- 右上に存在している
- と記載があるのでこちらも対応しましょう
- IAM > ロールで先ほど作成したロールを選択します。
- 選択したら以下の画像のように表示されますので
ポリシーをアタッチします
ボタンを押下しましょう- 遷移後に検索窓に
CloudWatchReadOnlyAccess
と入れてチェックを入れてポリシーのアタッチ
を行ってください。アタッチが完了したら以下の画像のようになっているはずです。
- IAMでユーザーを作成している前提で話を進めます。
aws側の作業は一旦ここで終わりです。
Goで作る
package main import ( "encoding/json" "net/http" "net/url" "github.com/aws/aws-lambda-go/lambda" "github.com/pkg/errors" ) type Slack struct { Blocks []Block `json:"blocks"` } type Block struct { Type string `json:"type"` Text Text `json:"text"` } type Text struct { Type string `json:"type"` Text string `json:"text"` } func run() error { incomingUrl := "slackのincoming hook URL" // slackの指定するjson形式じゃないとエラーになる slackMap := Slack{ Blocks: []Block{ Block{ Type: "section", Text: Text{ Type: "mrkdwn", Text: "検証", }, }, }, } p, _ := json.Marshal(slackMap) resp, err := http.PostForm( incomingUrl, url.Values{"payload": {string(p)}}, ) if err != nil { return errors.WithStack(err) } defer resp.Body.Close() return nil } func main() { lambda.Start(run) }
- Goのfileをzipに固める
GOOS=linux GOARCH=amd64 go build -o main zip handler.zip ./main
Go error: \$ GOPATH / go.mod exists but should not
- このエラーが出たら自分は以下のコマンドで回避しました
export GOPATH=
作成したものをawsのlambdaにアップロードしテストを実行すればslackに通知がきているかと思います
今回は、ここまでとします。