【やってみた】goで動くlambdaをgithubからデプロイできる環境を作ってみる! その2

どーも!

たかぽんです!

引き続き、lambdaをgithubからデプロイできるように環境作成をやっていきます!

本記事でできること

本記事では以下の内容を行なっていきます。

  • main.goをlambdaで動かしやすいように修正
  • github Actionsの設定
  • lambdaの作成
  • 適当に編集してpushして動作確認...!

ボリューミーな内容ですが、本記事の内容まで終えれば、いったんはlambdaへのデプロイが完成する形になります...!

デプロイだけで十分な方は本記事までで十分かと思います。

その後の記事ではslackへの通知を追加したり、lambdaのログを出して確認をする方法を解説しようと思います。

そこまでしたい方は合わせてご確認ください。

では、やっていきましょう!

main.goをlambdaで動かしやすいように修正する

では、やっていきます!

まず、main.goをlambdaで動かしやすいように修正します。

以下がコードになります。

package main

import (
	"context"
	"fmt"
	"log"
	"github.com/aws/aws-lambda-go/lambda"
)

type MyEvent struct {
    Name string `json:"Name"`
}

func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
  log.Printf("lambda finished! response will be returned!")
  return fmt.Sprintf("Hello %s!", name.Name), nil
}

func main() {
	log.Printf("lambda started!")
    lambda.Start(HandleRequest)
}

行なっていることとしては、json形式で渡される名前の値を取得し、その値をそのまま返す...という内容になっています。

こうしておくことで、lambdaのテストでの動作確認が簡単に行えます。

書き換えたらgitへpushしておきましょう。

コードを保存したら、エディタでpushするか、あるいは以下コマンドにてpushします。

今回はmainに直接pushしていきます。

コメントは適当に。

git add main.go
git commit -m "edit main.go for lambda"
git push

main.goの改修は上記でOKです。

次にそのために必要なモジュールを修正します。

以下のコマンドで準備が可能です。

go get github.com/aws/aws-lambda-go/lambda

うまくいくと以下のような感じになります。

(base) taka@Taka goTest % go get github.com/aws/aws-lambda-go/lambda
go get: added github.com/aws/aws-lambda-go v1.24.0

すると、"go.mod"に対して行が追加され...(indirectが追加されているはず)

module github.com/Takapon0407/go-lambda

go 1.16

require github.com/aws/aws-lambda-go v1.24.0 // indirect

さらに、"go.sum"というファイルも新しくできているはずです。

github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/aws/aws-lambda-go v1.24.0 h1:bOMerM175hLqHLdF1Nonfv1NA20nTIatuC0HK8eMoYg=
github.com/aws/aws-lambda-go v1.24.0/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
...

こちらはチェックサムを確認するためのファイルになっています。

これらも合わせてpushしておきましょう。

git add go.mod go.sum
git commit -m "add lambda module"
git push

これで、コードの準備はOKです!

次にgithub actionsを作っていきましょう...!

Github Actionsの設定を行う

さて、それではGithub Actionsの設定を行なっていきます。

Github Actionsとは、例えばpushされたタイミングなどに、決まった作業を行なってくれるプログラム...と思ってくれればいいかなと思います。

具体的には、pushしたタイミングで、用意されているテストの実行を行ったり、今回のようにlambdaへのデプロイを行ったり...といったことができます。

今回はgithubのリポジトリ上で追加後、pullして持ってきてから編集してみます。

まずはリポジトリ画面から"Actions"タブを選択します。

すると、テンプレートの選択画面が出てきます。

今回はテンプレートは使用しないので、以下の"set up a work flow yourself"リンクを選択します。

すると、以下のように初期のファイルを編集することができるので、ファイル名だけ"deploy.yml"に編集して右側の"Start commit"ボタンを押します。

すると、以下のようにコミットメッセージを指定できるので、おすすめの通り、create deploy.ymlとしておきます。

descriptionは不要かなと思います。

ここまでできたら、今度はターミナルにもどってpullしましょう。

git pull

mainブランチにてpullをして先程追加された"deploy.yml"ファイル分の差分がちゃんと追加されていればOKです。

(base) taka@Taka goTest % git branch
* main
(base) taka@Taka goTest % git pull
Updating 72fdf1a..4e3c379
Fast-forward
 .github/workflows/deploy.yml | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 .github/workflows/deploy.yml

これで、手元で編集できるようになりました!

では、"deploy.yml"の内容を以下のように修正します。

name: deploy to lambda

on:
  push:
    branches: [main]

jobs:
  build:
    name: Build Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Setup Go
        uses: actions/setup-go@v2

      - name: Checkout Code
        uses: actions/checkout@v2

      - name: Get Dependencies
        run: go get -v

      - name: Build
        run: go build -v main.go

      - name: Zip
        run: zip function.zip main

      - name: Deploy
        uses: appleboy/lambda-action@master
        with:
          aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY }}
          aws_secret_access_key: ${{ secrets.AWS_SECRET_KEY }}
          aws_region: ${{ secrets.AWS_REGION }}
          function_name: goLambdaDeploy
          zip_file: function.zip

細かい説明は割愛させていただきますが...

やっていることとしては、mainブランチへpushされた場合にビルドを行うようになっています。

ビルドの中身を簡単にご説明すると...

      - name: Setup Go
        uses: actions/setup-go@v2

      - name: Checkout Code
        uses: actions/checkout@v2

上記でgoのコマンドをワークフローで使えるようにセットアップし、リポジトリをworkflowが扱えるようにしています。

setup-goについては以下をご参考ください。

checkoutについては以下を...

そして、以下の内容にて...デプロイの準備を行なっていきます。

      - name: Get Dependencies
        run: go get -v

      - name: Build
        run: go build -v main.go

      - name: Zip
        run: zip function.zip main

まずはbuildする前にコードで使われている依存関係のあるモジュールを取得、そして、そのモジュールを含めてbuildします。

(モジュールがないのに実行ファイルを作ってもうまく動かないだろうことはわかりますね...!)

そして、実行ファイルができたら、その実行ファイルをzip化します。

これは、lambdaでのデプロイ時にzipファイルとして実行ファイルをアップロードしてあげる必要があるためです。

その下準備ですね。

そして、最後にlambdaへのデプロイを行います。

      - name: Deploy
        uses: appleboy/lambda-action@master
        with:
          aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY }}
          aws_secret_access_key: ${{ secrets.AWS_SECRET_KEY }}
          aws_region: ${{ secrets.AWS_REGION }}
          function_name: goLambdaDeploy
          zip_file: function.zip

同じく、lambdaをデプロイするためのactionがあるため、そちらを使っています。

そして、withにて、追加対象のAWSアカウントのアクセスキー、シークレットキー、リージョン情報、関数名と、zipファイルの名称を渡しています。

これらの設定をしておくことで、自動で特定のAWSアカウントへデプロイすることができるんですね。

ただし...!

以下三点に関してはgithubの"secrets"機能を利用しています。

          aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY }}
          aws_secret_access_key: ${{ secrets.AWS_SECRET_KEY }}
          aws_region: ${{ secrets.AWS_REGION }}

ここの"${{ secrets.AWS_ACCESS_KEY }}"といった値は、githubのsecretsから、"AWS_ACCESS_KEY"という値を使いますよ〜という意味になります。

ここで使う情報は、秘匿情報になります。

そのため、直接git管理せず、secretsで管理するんですね。(秘匿情報が他の人に見られると困る)

今回、筆者は自分のアカウントで作成したAWSの認証情報を使おうと思います。

(ただし、本格的に使用するなら、このlambda専用のロールにて最低限の権限のキーを別途作成すべきです)

ロールでの作成は割愛しますが、アカウントでの作り方に関しては以下AWSコンソール上にて、マイセキュリティ資格情報を開いた画面で設定が可能です。

筆者は二つ作っているため、もう作れないですが(今のプランだと2件が限度なのかな?)、アクセスキーの作成を押せば、アクセスキーとシークレットが表示されるはずです。

すでに作っている場合、この画面から確認することはできません。

代わりに、txtファイルとしてダウンロードしている可能性があるので、探してみると良いかもしれないです。

(最悪、見つからない場合、削除すれば再発行が可能です。そのキーを使っている他のサービス等がなければ削除して再発行しても大丈夫です。)

この内容は外部に漏らしてはいけない秘匿情報なので、共有はしないように気をつけてください。

再度お伝えしますが、今回githubのsecretsを利用するのもその秘匿性があるためです。

通常、actionsにそのまま指定しても動きはするのですが、前述の通り、そのまま書くと、publicであれば全世界の人が、privateでも同じ組織の人が閲覧できてしまいます。

そのため、秘匿情報をgithubのworkflowで扱う場合はsecretsで行うのが大前提になっています。

リージョンに関しては必ずしもsecretsで扱う必要はありません(秘匿ではないので....)が、今後何かの機会でその情報を使う場所も多くなりそうなので、変数として一箇所で管理できるように追加しています。

こうしておけば、今後このworkflowの10箇所で使用した場合にリージョンの変更があっても、secretsを変更すばそれで済みますね。

さて、それでは値を取得できたら、Githubのリポジトリのページから、settingを開きます。

Settingsを開き、画面左側にてSecretsという項目があるので、そこからSecretsで扱う値を追加していきます。

何もない状態の画面は以下のようになっています。

画面右上の"New repository secret"から追加が可能です。

Nameには先程workflowで指定した値(AWS_ACCESS_KEYやAWS_SECRET_KEYなど...)をいれ、Valueにコピーしたキーの情報等を入れます。

regionは"ap-northeast-1"にしておきます。

このregionにてこの後lambdaを作成します。

細かい値の正誤は確認できませんが、こんな感じになるかと思います。

さて、ここまでできればworkflowの準備はバッチリです...!

次に、deploy先となるlambdaを用意します...!

lambdaを用意する

ここでは、デプロイ先になるlambdaを作成していきます!

コンソールでぽちぽちしておけばできるので、そんなに難しくはないはず...です!

まずはリージョンを東京にしておきます。

画面右上からリージョンの選択ができるので、以下の項目に修正します。

作ったlambdaがない!とか、うまくいかない!の原因になりがちなので、リージョンに関しては都度確認しておくといいかもしれないです。(違うリージョンで作られたリソースは表示されなかったりします...)

次に、AWSのコンソール上でlambdaを検索します。

すると、lambdaがでてくるので、クリックします。

開くと、上記のような画面がでてくるので、"関数の作成”を行います。

一から作成, 関数名は先程のworkflowのfunction_nameに合わせて"goLambdaDeploy"、そしてランタイムはGoを選択します。

他にも設定項目がありますが、今回はこれだけでOKです。

したの方にある"関数の作成”を選択します。

そして、完成したlambdaにて、ハンドラを修正してあげる必要があります。

以下の"ランタイムの設定"の"編集"をクリック

そして、ハンドラとあるところに"hello"が入っていると思うので、"main"に書き換えます。

これで保存をクリック。

以上でlambdaの準備もOKです...!

最後に適当なものをpush後、動作を確認してみましょう...!

適当に編集してpushして動作確認...!

では、ターミナルに戻り、READMEを以下のように修正し、Pushします。

# go-lambda

# デプロイよ動け!

デプロイよ動け...!という念じをかけました。これできっと動きます。

git add READ.me
git commit -m "edit readme"
git push

さて、先程ワークフローにて"main"へのpush時に実行されるように設定していました。

そのため、githubの画面からActionsを開くと...

このように、edit readmeのコミット時に実行されていることがわかります。(筆者はその前に検証のために回したため、2 workflow runsになっていますが...)

edit readmeをクリックすると詳細が見れます。

さらにBuild Deployをクリックすると詳細が見れます。

エラーが出ていると、ここで赤いばつ印が出ています。

その場合、何かしら問題があるためdeploy.ymlを見直してみてください。

問題なければ上記のような感じになっているはずです。

では、先程作ったlambdaの画面へ戻ります。

lambdaではテストすることができるようになっています。

テストのタブを開くと、以下のような画面が出てきます。

テストの値を以下に、名前を"NameReturnTest"に修正してテストを実行します。

{
  "Name": "Takapon"
}

すると...

うまくいきました...!

コードをコンソールから追加していませんが、ちゃんと"Hello Takapon!"と表示されました...!

以上あとはコードを書き換えて、mainへpushをすれば都度workflowが走り、lambdaも更新されます。

本記事では一旦ここまでになります。

次の記事で行うこと

最後に、先程作成したデプロイフローの中で、デプロイ時にsalckへの通知を行うことと、細かいログの確認方法を見ておこうと思います。

実際、プログラムではlambdaの処理の開始と終わりでログを出していますが、先程のテストではそのログが確認できませんでした。

そういったログを確認する方法ですね。

また、デプロイが完了したらslackで通知してくれると嬉しいですよね..!

現状の形だとほぼ即時で終わるので必要性は薄いですが、エラー等が起きた場合にわざわざgithubの画面で確認せずともエラーチェックができると嬉しいです。

そういったところをやっていこうと思います...!

おすすめの記事