【CI/CD】AWS LambdaのZIP生成はGitLab Runnerにお任せ!

はじめに

こんにちは、AI・IoTサービス開発部のがんがんこと岩丸です。
最近在宅ワークのメリハリ向上を目指してお香を購入しました。リラックス効果が高く、当初想定していたよりも購入してよかったです。


前回の記事では AWS CLIのQueryオプションを使用してリリース対象のECRイメージ一覧取得を行いました。もしお時間ある方は合わせてご覧ください。

tech-blog.optim.co.jp

タイトルでお察しかと思いますが今回はGitLab Runnerに関する記事です。

AWS Lambda用のZIP生成を楽に出来ないかと色々調べていた時、ふと「GitLab RunnerのArtifacts機能を用いてZIPの生成出来ないか?」と思ったのがきっかけです。 そこで今回はGitLab RunnerのArtifacts機能を用いてAWS LambdaのZIP生成を行いました。

目次

やりたいこと

AWS Lambdaを普段からお使いの皆様、Lambdaの管理・デプロイはどのように行なっていますか。

公式のLambda デプロイパッケージを読むとコンテナイメージ.zipファイルアーカイブの2種類の方法がサポートされています。
.zipファイルアーカイブを選択した場合、デプロイの方法として「AWS CLI、Lambrollはどちらを用いるべきか?」、「TerraformやAWS SAMは必要か?」など、AWS Lambdaの管理・デプロイの選定はチームによって千差万別だと思います。


本記事では.zipファイルアーカイブ + AWS CLIを用いたLambdaのデプロイを前提にしています。以下のような既存運用を行っています。

zip XXXXコマンドでZIP化 -> aws lambda update-function-code XXXコマンドでLambdaデプロイ

Lambdaが1つ、2つの時は既存運用で問題ありませんでしたが、数が増えてくるとCI/CD パイプラインでなんとか楽したいなと思いました。 2STEPある既存運用のうち今回は「ZIP生成」に焦点を当てて改善活動を行います。

本記事で扱わないこと

既存運用と異なるため以下について本記事では触れておりません。また、デプロイについても本記事では取り上げておりません。

  1. コンテナイメージによるLambdaの利用
  2. TerrafromやAWS SAMの利用

成果物

ディレクトリ構成

.
├── .gitlab-ci.yml
├── lambdaA
│   ├── src
│   └── test
├── lambdaB
│   ├── src
│   └── test
├── lambdaC
...
└── lambdaN

.gitlab-ci.yml

stages:
  - test
  - build

# Test Job
test:
  stage: test
  image: node:14-buster-slim
  script:
    - |
      for file in `find . -type d -maxdepth 1 | grep lambda`; do
        cd $file
        npm install
        npm test -- --coverage
        cd ../
      done

# Create-Zip Extends Template
.create_zip_template:
  stage: build
  image: node:14-buster-slim
  variables:
    # NOTE: デフォルト値を仮設定
    TARGET_LAMBDA: target-lambda
  script:
    - cd $TARGET_LAMBDA
    - mv ./src/*.js .
    - npm i --production
  artifacts:
    name: $TARGET_LAMBDA
    paths:
      - $TARGET_LAMBDA/*
    exclude:
      - $TARGET_LAMBDA/src*
      - $TARGET_LAMBDA/src/**/*
      - $TARGET_LAMBDA/test*
      - $TARGET_LAMBDA/test/**/*
      - $TARGET_LAMBDA/README.md
    expire_in: 1 days

# Create Zip Job for LambdaA
create-zip:lambdaA:
  variables:
    TARGET_LAMBDA: "lambdaA"
  extends:
    - .create_zip_template

# Create Zip Job for LambdaB
create-zip:lambdaB:
  variables:
    TARGET_LAMBDA: "lambdaB"
  extends:
    - .create_zip_template

create-zip:lambdaC:
...

CIファイルの工夫

extends機能の利用

以下の記事を執筆した時はYAMLアンカー機能を利用しました。ただGitLabの公式ドキュメントを見てみるとアンカー機能よりextends機能の利用を推奨していました。そのため今回はextends機能を採用しました。

tech-blog.optim.co.jp

Artifacts用テンプレート作成

Artifacts機能Extends機能を用いてArtifacts用のテンプレートを作成しました。

GitLab公式ドキュメントのextends > マージの詳細の項を読むと継承したテンプレートのvariablesを上書きしていることが分かります。こちらを利用することでcreate-zip:lambdaAのジョブは以下のようになります。

create-zip:lambdaA:
  stage: build
  image: node:14-buster-slim
  variables:
    TARGET_LAMBDA: lambdaA
  script:
    - cd $TARGET_LAMBDA
    - mv ./src/*.js .
    - npm i --production
  artifacts:
    name: $TARGET_LAMBDA
    paths:
      - $TARGET_LAMBDA/*
    exclude:
      - $TARGET_LAMBDA/src*
      - $TARGET_LAMBDA/src/**/*
      - $TARGET_LAMBDA/test*
      - $TARGET_LAMBDA/test/**/*
      - $TARGET_LAMBDA/README.md
    expire_in: 1 days

不要ディレクトリもexcludeで排除できる

当初の実装は以下のようになってました。

  artifacts:
    name: $TARGET_LAMBDA
    paths:
      - $TARGET_LAMBDA/*
    exclude:
      - $TARGET_LAMBDA/src/**/*
      - $TARGET_LAMBDA/test/**/*
      - $TARGET_LAMBDA/README.md
    expire_in: 1 days

このArtifacts設定で生成されたZIPファイルの中身は以下の様になります。不要なsrctestディレクトリが空の状態で残ってしまいました。

.
├── xxx.js
├── yyy.js
├── zzz.js
├── src
│   └── {empty}
└── test
    └── {empty}


GitLab公式のイシューによると、排除したいディレクトリを対象ディレクトリ*の形で別途指定してあげる必要があるみたいです。

gitlab.com

おわりに

今回はGitLab RunnerのArtifacts機能を用いてAWS LambdaのZIP生成を行いました。チームが楽になるようなCI/CD改善を今後も積極的に行っていきたいですね。


そんなOPTiMでは運用改善やDevOpsに興味があるエンジニア、新卒からどんどんチャレンジしていきたいエンジニア学生を随時募集しております。少しでもご興味のある方はこちらも合わせてご覧ください。

www.optim.co.jp