0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS】Gitマージ -> Alemicマイグレーション&ZIP化してS3にアップ&LambdaにそのZIPを適用するCI/CDの構築手順

Posted at

概要

AWS Lambdaで動かしているPythonアプリがあり、そのCI/CDについての記事になります。
本記事では、「Gitでマージしたら、自動でソースコードのZIPがS3にアップされ、また、そのZIPがLambdaにアップロードされる」という流れを実装しました。

また、S3アップ前にはAlembicでDBマイグレーションを行うようにしました。
(意外とこの部分の記事が少なかったので参考になればと思います)

CI/CDの流れ

  • Gitでマージ -> CodePipeline自動起動 -> Codebuild実行。buildspec.yamlにて以下を自動実行
    • AlembicでRDS DBへマイグレーション
    • ソースコードをzip化してS3にアップ
    • S3にアップしたzipをLambdaへアップロード

手順

①Codebuild作成

  • Codebuild用のセキュリティグループを作成
    • 作成後、RDS用のセキュリティグループのインバウンドルールに追加する
  • Codebuildプロジェクトを作成
    • RDSへアクセスするため、VPCに置く必要がある。RDSがあるVPCとサブネットを選択。セキュリティグループは上記で作成したものを選択する
    • IAMロールには、s3やcloudwatchlogsへの許可、また"lambda:UpdateFunctionCode" のアクセス許可を付与すること(参考までに私が使ったIAMロールは以下に後述)。
    • 環境変数には、DB情報や必要なENVパラメータを登録する。また、今回は後述のbuildspec.yamlで使うS3バケット名、ZIP名、Lambda関数名も登録しておくこと
    • 作成時、自動でVPCアクセスを許可するIAMポリシーが実行ロールに付与されます

※RDSへのアクセス許可が設定されていない場合、ビルド時に以下のタイムアウトエラーになる

lib/python3.12/socket.py", line 853, in create_connection
raise exceptions0
File "/***/.pyenv/versions/3.12.4/lib/python3.12/socket.py", line 838, in create_connection
sock.connect(sa)
TimeoutError: timed out

(参考)Codebuildの実行ロール


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation",
                "codebuild:CreateReportGroup",
                "codebuild:CreateReport",
                "codebuild:UpdateReport",
                "codebuild:BatchPutTestCases",
                "codebuild:BatchPutCodeCoverages",
                "codebuild:StartBuild",
                "codebuild:StopBuild",
                "codebuild:RetryBuild",
                "lambda:UpdateFunctionCode"  ## これ大事!
            ],
            "Resource": "*"
        }
    ]
}

②CodePipeline作成

  • CodePipelineを作成
    • SourceステージはGithub version2にして、該当リポジトリの指定ブランチを選択
    • Buildステージは上記のCodebuildプロジェクトを選択

image.png

image.png

image.png

buildspec.yaml作成

まず、ビルド時に必要なライブラリはrequirements_for_build.txtに記載し、ルートにおいておく。

requirements_for_build.txt
# 以下は必要に応じて変更してください
awscliv2==2.3.1
alembic==1.13.2
pymysql==1.1.1
SQLAlchemy==2.0.32

以下の内容でbuildspec.yamlを作成してこちらもルートに置く。
(環境変数用の.envもルートに)

version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.12
    commands:
      - yum update -y
      - pip install -r requirements_for_build.txt

  pre_build:
    commands:
      - echo Pre-build phase
      - echo DB_HOST=$DB_HOST >> .env
      - echo DB_PORT=3306 >> .env
      - echo DB_USER=$DB_USER >> .env
      - echo DB_PASSWORD=$DB_PASSWORD >> .env
      - echo DB_NAME=$DB_NAME >> .env
      - echo $S3_BUCKET_NAME
      - echo $ZIP_FILE_NAME
      - echo $LAMBDA_FUNCTION_NAME

  build:
    commands:
      - echo Build phase
      - cd app/database ## alembicディレクトリがapp/databaseにある場合
      - alembic upgrade head
      - cd ../../
      - export TIMESTAMP=$(date +%Y%m%d%H%M%S)
      - export UNIQUE_ZIP_FILE_NAME="${ZIP_FILE_NAME%.zip}_$TIMESTAMP.zip"
      - echo $UNIQUE_ZIP_FILE_NAME
      - zip -r $UNIQUE_ZIP_FILE_NAME .
      - aws s3 cp $UNIQUE_ZIP_FILE_NAME s3://$S3_BUCKET_NAME/

  post_build:
    commands:
      - echo Post-build phase
      - aws lambda update-function-code --function-name $LAMBDA_FUNCTION_NAME --s3-bucket $S3_BUCKET_NAME --s3-key $UNIQUE_ZIP_FILE_NAME

artifacts:
  files:
    - $UNIQUE_ZIP_FILE_NAME

pre_buildフェーズの環境変数は、Codebuildプロジェクトから取得しています。あらかじめ登録しておいてください。

zipコマンドでルート以下全てをZIP化し、
aws s3 cpでS3にアップ、
aws lambda update-function-codeでLambdaにアップロード、
という手順です。

また、上記でタイムスタンプを利用しているのは、S3に保存されるZIP名称を一意にして、どの時点のZIPかを明示的にわかりやすくするためです。こうすることで、以下のようにZIP名に日時が含まれるようになります。

image.png

以上で、正常にマイグレーションとLambda関数の更新ができたことを確認できました。
参考になれば幸いです。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?