LoginSignup
0

More than 1 year has passed since last update.

AWS Elastic BeanstalkでDjangoカスタムコマンドを定期実行する

Last updated at Posted at 2022-12-12

この記事はエヌ次元株式会社 Advent Calendar 2022の13日目の記事です。

Django × AWS Elastic Beanstalkを使って個人的にWeb アプリケーションを構築した際に、
Djangoカスタムコマンドの定期実行を実装しようとして、躓いた部分があったので備忘録もかねて投稿させて頂きます。

Djangoカスタムコマンド定期実行の実装

必要なこと

  1. 定期実行したいDjangoカスタムコマンドの作成
  2. cron.configの作成

Djangoカスタムコマンドの作成

定期実行したいDjangoカスタムコマンドを作成します。
WebAPIから情報を取ってきて、データベースのデータを更新するという処理を実装しました。(実際のコードからは簡略化してます)

management/commands/update_data.py
import os
import requests

from django.core.management.base import BaseCommand
from django.utils import timezone

from main.models import Team,Match

from django import setup
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Sampleproject.settings')
setup()


class Command(BaseCommand):
    help = 'Update data from webapi'

    def handle(self, *args, **options):
        leagues = League.objects.all()
        league_codes = [league.code for league in leagues]

        for league_code in league_codes:
            self.update_standing(league_code)
            self.update_match(league_code)

    def get_dict_from_api(self, url):
        # webapiへリクエスト、レスポンスデータの加工など
        return data

    def update_match(self, league_code):
        target_url = 'webapi_url'
        input_dict = self.get_dict_from_api(target_url)
        for match_info in input_dict['matches']:
            # updateしたいオブジェクトをDBからselect
            match = Match.objects.get(match_day=match_info['matchday'], 
            # ...
            # 中略(データの更新処理など)
            # ...
            match.save()

configファイルの設定

.ebextensionsディレクトリ内にconfigファイルを作成します。
ここでは

  • 環境変数の設定、Djangoカスタムコマンドを実行するシェルスクリプトの作成
  • Cronの設定ファイルの作成
  • クリーンアップ
    を行っています。
.ebextensions/update_data_cron.config

files:
    # シェルスクリプトの作成
    /usr/local/bin/update_data_script.sh:
        mode: "000755"
        owner: root
        group: root
        content: |
            #!/bin/bash
            source /var/app/venv/staging-LQM1lest/bin/activate
            cd /var/app/current
            # DB接続情報を環境変数へセッティング
            RDS_USERNAME=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_USERNAME`
            export RDS_USERNAME
            RDS_PASSWORD=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_PASSWORD`
            export RDS_PASSWORD
            RDS_HOSTNAME=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_HOSTNAME`
            export RDS_HOSTNAME
            RDS_PORT=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_PORT`
            export RDS_PORT
            RDS_DB_NAME=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_DB_NAME`
            export RDS_DB_NAME
            # Djangoコマンドの実行
            python manage.py update_data

    # cronの設定
    /etc/cron.d/update_data_cron:
        mode: "000644"
        owner: root
        group: root
        # UTC22:30に定時実行(日本時間7:30)
        content: |
            30 22 * * * root /usr/local/bin/update_data_script.sh

# クリーンアップ
commands:
  rm_old_cron:
    command: "rm -fr /etc/cron.d/*.bak"
    ignoreErrors: true

注意点(躓いたポイント)

RDSへのアクセスが発生するカスタムコマンドを実行する場合、コマンド実行環境の環境変数にRDSへの接続情報を入れておく必要があります。
ElasticBeanstalkではget-configコマンドを使ってRDSの接続情報を取得できるので、それを利用して環境変数に接続情報をsetしています。
自動的に設定してくれるものと勘違いして詰まりました、、、

所感

AWS Elastic BeanstalkはEC2、VPC、RDSなどを自動でセッティングしてくれる便利なサービスですが、拡張的な機能を設定するには、各種configファイルを設定する必要があります。
まだまだ勉強中ですが、公式のドキュメントは充実しているので、うまく活用していければと思います。

参考資料

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