Goalist Developers Blog

Serverless Framework,CircleCIでの更新の自動化

どうも,エンジニアのナカノです.

今回は,Serverless Framework,CircleCIでの更新の自動化の内容をご紹介致します.

このお話は,前回の以下の記事の続編となります.主に,CI/CDの話です.

developers.goalist.co.jp

目 次
  • 背景
  • 作り方
  • 所感



背景

テスト,ビルド,デプロイの手順は,EC2の自動管理の開発の際に作っていました.

ただ,手動実行するのが面倒なのと,更新履歴を管理したいというのがありました.

また,CI/CDを作ってしまえば,ローカルでの準備が最低限度の形で済みます.

以上より,インフラと関数パッケージの更新の自動化を行うことに決めました.



作り方

インフラの作成/更新はServerless Frameworkで行い,CI/CDツールはCircleCIにしました.

f:id:r-nakano:20200831193353j:plain


Gitプロジェクトの構成は次の通りです.CI/CDの処理はSHファイルにまとめる様にしています.

ec2-serverless-manager
├── .circleci
│   └── config.yml       # CircleCIの設定ファイル
├── .gitignore
├── README.md
├── ci-package
│   ├── Dockerfile       # ビルドしたイメージはECRで管理している
│   └── bin
│       ├── deploy.sh    # パッケージのビルド、インフラやパッケージのデプロイ
│       └── validate.sh  # モジュールのインストール、Goソースのエラーチェック
├── go.mod
├── main.go
├── pkg
│   ├── aws-ec2.go
│   ├── aws-ssm.go
│   └── chatwork.go
└── serverless.yml       # Serverless Frameworkの設定ファイル


Dockerfileは,golangのイメージをベースとして,以下の様に作成しました.

FROM golang:1.15.0

ENV NODE_VERSION=12 \
    SLS_VERSION=1.79.0

RUN apt-get -q -y update && \
    curl -SL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash && \
    apt-get -q -y install -y nodejs && \
    npm install -g serverless@${SLS_VERSION}


CircleCIで実行するシェルスクリプトは,それぞれ次の様に実装しました.

# ci-package/bin/validate.sh
#!/bin/bash


# Params
set -eux
script_dir=`(cd $(dirname $0); pwd)`


# Execution
cd ${script_dir}/../../
go install
go test -race -v ./...
# ci-package/bin/deploy.sh
#!/bin/bash


# Params
set -eux
script_dir=`(cd $(dirname $0); pwd)`


# Execution
cd ${script_dir}/../../
GOOS=linux go build main.go
sls deploy -v


また,Serverless Frameworkの設定ファイルserverless.ymlの中身は,次の様な感じです.

service: ec2-serverless-manager

frameworkVersion: '>=1.28.0 <2.0.0'

configValidationMode: warn

provider:
  name: aws
  runtime: go1.x
  stage: ${opt:stage, 'dev'}
  region: ${env:AWS_DEFAULT_REGION}
  stackName: ec2-serverless-manager-cf-stack
  apiName: ec2-serverless-manager-rest-api
  deploymentPrefix: artifacts
  deploymentBucket:
    name: xxxxxxxx.xxxxxxxx.xxxxxxxx
    maxPreviousDeploymentArtifacts: 3
  iamManagedPolicies:
    - 'arn:aws:iam::aws:policy/AmazonEC2FullAccess'
    - 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
    - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
  iamRoleStatements:
    - Effect: Allow
      Action:
        - 'ssm:Get*'
        - 'kms:Encrypt'
        - 'kms:Decrypt'
        - 'kms:ReEncrypt*'
        - 'kms:GenerateDataKey*'
        - 'kms:DescribeKey'
      Resource: '*'
  logs:
    restApi:
      accessLogging: true
      format: 'requestId: $context.requestId'
      executionLogging: true
      level: INFO
      fullExecutionData: true
      roleManagedExternally: true

functions:
  ec2Manager:
    handler: main
    name: ec2-serverless-manager-lambda-function
    description: Lambda function of EC2 serverless management system
    memorySize: 128
    runtime: go1.x
    timeout: 300
    environment:
      CW_ROOM_ID: xxxxxxxx
    tags:
      Name: ec2-serverless-manager-lambda-function
    events:
      - http:
          path: /
          method: POST


更に,**CircleCIの設定ファイル.circleci/config.ymlの作成は,次の記事を参考に作りました.

medium.com

GitHubとの連携は,次の様なブランチとタグの使い分けの方法で実施する様に対応しました.

  • masterブランチが更新された時は,Goソースのエラーチェックのみを実施する

  • タグが作成された時は,パッケージのビルド,インフラやパッケージのデプロイを行う



所感

Serverless Frameworkは初めて利用しました.やはり,サーバレスインフラの構築に合ってます.

インフラの規模としては,恐らく大きく無いものを作るのに適していそうな気がしますね.

小さく無いインフラを細かく設計して作る等だと,Terraformの方が使い勝手が良さそうです.

何はともあれ,以前から気になってたIaCツールを,今回の自動化の対応で試せて良かったです.