Travis CIによるLambdaの自動デプロイ with AWS SAM in Go

Summary

  • AWS SAMで管理しているLambda Functionのデプロイ自動化を、AWS CodePipelineやAWS CodeBuildを使うことなく Travis CIを活用して行う
    • 今回利用したLambda FunctionはGo製
    • Pull Requestのmasterブランチへのmerge時に、samコマンドで自動デプロイ

前提条件

  • Lambdaのリポジトリはgithub
  • 各種バージョン情報は下記の通り
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ python --version
Python 2.7.12

$ pip --version
pip 19.0.3 from /usr/local/lib/python2.7/dist-packages/pip (python 2.7)

$ aws --version
aws-cli/1.16.175 Python/2.7.12 Linux/4.15.0-1028-gcp botocore/1.12.165

$ sam --version
SAM CLI, version 0.17.0

SAMで管理しているLambdaのデプロイをTravis CIで自動化したい

SAMで管理しているLambdaのデプロイ自動化をTravis CIで行います。SAMで管理しているからにはSAMのテンプレートとaws-sam-cliを使ってデプロイを行いたいです。なのでTravis公式のLambdaデプロイサポートは使用しません。

  • branch != master の場合のCI
    1. Lambdaコードのテスト
    2. Lambdaコードのlint(golintやgo vetなど)
    3. sam validate
  • branch == master の場合のCI, デプロイ
    1. CI時に実施した事全て
    2. sam package
    3. sam deploy

これらを.travis.ymlで定義してデプロイを自動化します。

セキュアな環境変数の設定

Travis CIでsamコマンドを実行したい場合に必要な環境変数は下記の3つです。

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_DEFAULT_REGION

セキュアな変数は travis encrypt コマンドで暗号化して.travis.yml に設定します

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ travis encrypt AWS_ACCESS_KEY_ID=YOUR_KEY_ID

Please add the following to your .travis.yml file:

  secure: "XXX"  # この内容を.travis.ymlに設定する

$ travis encrypt AWS_SECRET_ACCESS_KEY=YOUR_KEY

Please add the following to your .travis.yml file:

  secure: "XXX"  # この内容を.travis.ymlに設定する

.travis.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
dist: xenial

go:
  - 1.12.x

sudo: false

env:
  matrix:
    - GO111MODULE=on
  global:
    - AWS_DEFAULT_REGION=ap-northeast-1
    - secure: ENCRYPTED_ACCESS_KEY_ID
    - secure: ENCRYPTED_SECRET_ACCESS_KEY

install:
  - go mod download
  - python --version
  - pip --version
  - pip install --user awscli
  - pip install --user aws-sam-cli

script:
  - go test ./...
  - sam validate

deploy:
  provider: script
  script: "./deploy.sh"
  skip_cleanup: true
  on:
    branch: master

notifications:
  email:
    on_success: never

pythonのバージョンが古いとsamコマンドがコケるのでdist: xenialでXenialベースのイメージを指定し、極力新しいバージョンのpythonを利用できるようにします。

language: goなビルドイメージにインストールされているpythonのバージョンは、dist: xenialを指定しない=dist: trustyが選択されれば(この記事の執筆時点では)2.7.6になります。例えばsam validateをver 2.7.6なpython環境で実行すると、SNIMissingWarningが発生してしまいます。

1
2
3
4
/home/travis/.local/lib/python2.7/site-packages/urllib3/util/ssl_.py:365: SNIMissingWarning: An HTTPS request has been made, but the SNI (Server Name Indication) extension to TLS is not available on this platform.
This may cause the server to present an incorrect TLS certificate, which can cause validation failures.
You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  SNIMissingWarning

deployセクションのscriptでgo build => sam package => sam deployを実行するスクリプトを用意・指定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash

# ./deploy.sh

set -eu

# template.yamlのResourcesの関数定義の内容と合わせる
# 例えば
#   CodeUri: hoge/
#   Handler: huga
# であれば、
#   CODE_URI=hoge/
#   HANDLER=huga
# とする

CODE_URI=hoge/
HANDLER=huga
GOOS=linux GOARCH=amd64 go build -o ${CODE_URI}${HANDLER} ${CODE_URI}main.go

TEMPLATE=./template.yaml
OUTPUT_TEMPLATE=./serverless-output.yaml  # デプロイ用の中間生成物なのでgitignoreしておくのが良いです
S3_BUCKET=YOUR_BUCKET
S3_PREFIX=YOUR_PREFIX
STACK=YOUR_STACK

sam package --template-file ${TEMPLATE} \
  --output-template-file ${OUTPUT_TEMPLATE} \
  --s3-bucket ${S3_BUCKET} \
  --s3-prefix ${S3_PREFIX}

sam deploy --template-file ${OUTPUT_TEMPLATE} \
  --stack-name ${STACK} \
  --capabilities CAPABILITY_IAM

これで、今後masterブランチへのpushをトリガーにgo build => sam package => sam deploy によるデプロイが自動で行われるようになります。

今回の例のようにsam package => sam deploy をシンプルに実行するだけのフローであれば(且つCodePipeline導入によるメリットを享受したい強い理由が無ければ)、Travis CIでも十分でした、という所感です。

ブックマーク