LoginSignup
0
0

More than 1 year has passed since last update.

CodeシリーズとLambdaを利用したデータファイルの自動登録

Last updated at Posted at 2021-08-30

背景

サービスを提供している場合、マスタデータの登録ってついてまわりますよね
この作業ってトイルに分類されるものだと思っています
自動化できる部分は自動化したいものです

幸いなことに、AWS環境には、CodePipelineやLambdaと自動化への環境は整えられています
細かい作り込みは必要となりましたが、自動化そのものは実現できましたので、ご参考になりましたら

実装関係

使ったサービスやコマンド

  • CodePipeline
  • CodeCommit
  • CodeBuild
  • git
  • SSM(ParameterStore)
  • S3
  • Lambda

CodeCommit

ポイントは1つだけです
出力アーティファクト形式に「完全クローン」を選択してください
image.png

CodeBuild

細かい技術の組み合わせとなっています
ポイントとそれに関する説明をしていきます

登録用データファイルの作成

git archiveコマンドでgitで管理しているファイルをzip形式で出力できます
git diffコマンドで特定のCommit間のファイルを特定できます
この2つのコマンドで、前回CommitとHEADの間のファイルをzipファイルに出力できます

buildspec.yml.sh
git archive [ブランチ] `git diff --name-only ${PRE_COMMIT} HEAD --diff-filter=AM` -o ${FILENAME} --worktree-attributes

PRE_COMMITはSSMのパラメータストアに保持するようにしました
下のコマンドで取得しています

buildspec.yml.sh
PRE_COMMIT=$(aws ssm get-parameter --name [パラメータストア名] | jq ".Parameter.Value" | sed -e "s/\"//g")

apiの戻り値のJSONからjqでパラメータストアの値を取得し、sedコマンドでダブルコーテーションを除去しています

--worktree-attributes は、.gitattributesに記載したgit archiveに含めたくないファイルを反映してくれるオプションです

dot.gitattributes
buildspec.yml export-ignore
script/ export-ignore

後は、ファイルをS3に上げて

buildspec.yml.sh
aws s3 cp ${FILENAME} s3://${S3_BUCKET}/${S3_KEY}

最新のcommit番号をパラメータストアに更新し直して、Codeシリーズのタスクは完了です
なお、--overwriteオプションがないとエラーになります

buildspec.yml.sh
- NOW_COMMIT=$(git rev-parse HEAD)
- aws ssm put-parameter --name [パラメータストア名] --value ${NOW_COMMIT} --overwrite

対象のファイルがなかったら

commitするのはデータファイルばかりではないので、登録対象のファイルがない場合もあります
マスタデータの登録を行うLambdaでの対応も出来ますが、無駄にS3にファイルを上げたりLambdaを実行したりするのは嫌だったので、
CodeBuildのbuildspec.ymlにまつわるexitいろいろ を参考に下のshellファイルで処理を止めるようにしました
Dai@FastLabel さん、ありがとうございます

count_target_file.sh
#!/bin/sh
CNT=$(git diff --name-only ${PRE_COMMIT} HEAD --diff-filter=AM -- data | wc -l)
echo $CNT
if [ $CNT -eq 0 ]; then
  exit 1
fi

対象となるマスターファイルはdataディレクトリに置く運用になっています
commitされたファイルをdataディレクトリのものに絞って、その件数が0かどうかで判定するようにしました

Lambdaの起動

後は、S3のPUTイベントで、Lambdaを起動して、LambdaでDynamoDBに登録すれば完了です
Lambdaの処理内容は、Qiitaを読むレベルの方には蛇足になりますので、2点だけ述べておきます

エイリアスを付与したLambdaを実行

開発、ステージング、本番と環境を別に設けているケースがほとんどだと思います
環境ごとに同じLambdaを用意するのは無駄なコストになりますので、devやstg、prdといったエイリアスをつけて
環境を識別するようにしました

lambda.py
Stage = context.invoked_function_arn.split(":")[-1]

unzip先はディレクトリ

S3にアップロードしたファイルはzipファイルなので当然解凍しますが、解凍先のパラメータをファイルと思い込んでいまして、無駄に時間を費やしました
下のpythonコードの最後の行のunzip_dirのところですね
同じ轍を踏みませんように

lambda.py
   with zipfile.ZipFile(zip_file, "r") as z:
        for f_name in z.namelist():
            if f_name.endswith(".csv") or f_name.endswith(".json"):
                z.extract(f_name, unzip_dir)

終わりに

まだ本格的な運用が始まっていないこと、私がshellをあまり書いたことがないことから、不具合やもっと効率の良い書き方もあると思います
ですが、現時点ではやりたかったことを実現できましたので、Qiitaでシェアすることにしました

皆様のトイル撲滅の一助になりましたら

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0