search
LoginSignup
1
Help us understand the problem. What are the problem?

posted at

AWS Lambda(EC2のシェル)を毎月営業日◯日に実行したい

AWSのカレンダー機能を使って、毎月の営業日◯日目にEC2のシェルを実行する(Lambda関数を実行する)

AWS EC2上に構築したHulftの集信コマンド(utlrecv)を「月初〇〇営業日」に実行したい
…といった問題に当たりました。

以下の機能を使って実装しました。
・AWS Systems Manager(Change Calendar)機能
 → (シェル や Lambda)を実行した日時を管理
・Amazon EventBridge機能
 → Calenderの状態を確認し、条件を満たしたら、ssm経由でLambda関数を実行する
・AWS Systems Manager(ssm)機能
 → Lambdaから(EC2のシェル)をキックする

(※きれいに作る場合、Calenderに祝日や土日を設定して、その日が営業何日目かを判断したりする必要があると思いますが…今回は、実行する日時のみをCalenderに登録し、定期的にメンテナンスする前提で作成しました)

①カレンダーの作成

まずはカレンダーを作成します。
image.png

今回は、実行日が少ない(月2回の前提)ため、「デフォルトで閉じる」を選択しました。
(普段は実行せずに、「カレンダー登録日時」となったら、起動するイメージ)
image.png

カレンダーを作成したら、以下を行います。
・タイムゾーンの設定(Asia/Tokyo)
・イベントを作成
image.png

これで、カレンダーの作成は完了です。
設定したイベント時刻になると、AWSイベントが発生します。
これだけでは、AWSイベントを拾うことができないため、②Amazon EventBridgeの作成をします

②Amazon EventBridgeの作成

EventBridgeで、ルールを作成します。
image.png

「イベントパターンを持つルール」を選択します。
image.png

イベントソースは「AWSイベントまたは…」を選択します
image.png

サンプルイベントオプションは特に設定していないです。
image.png

イベントパターンは以下のように、①で作成したカレンダーの情報を入力していきます。
image.png

ターゲットでは、実行したいLambda関数を選択します。
(※事前にLambda関数を作成しておく必要があります)
(ここで、Lambda関数に対して、トリガー設定されるイメージです)
image.png

タグの設定は行いませんでした。(使い方がよくわからん…汗)
image.png

これでイベントブリッジの設定は完了です。
次に、Lambda関数の確認です。

③Lambda関数の確認

トリガーが設定されているのを確認できました。
image.png

Lambdaの中身は以下のようにしました。

import boto3
from string import Template
import logging

logger = logging.getLogger()

def lambda_handler(event, context):
        print("スケジュール(Change Calendar)に従って定期実行されました")
        # HULFT集信コマンド実行
        hulft_recv()
        print("HULFT集信コマンドを実行しました") 
    
def hulft_recv():
    
    ssm = boto3.client('ssm')
    instance = ["i-***************"] # EC2のインスタンスid
    
    # HULFT配信
    # コマンド原本(utlrecv -f 0000_TEST_FILE) # ファイルID(0000部分は変数化してます)
    org_cmd = Template('su - hulft -c \"utlrecv -f ${b_code}_TEST_FILE\"')
    # 変数(コード)を設定(変数を使う場合)
    sh_cmd = org_cmd.substitute(b_code=9999)
    
    try:
        # コマンドを実行
        res = ssm.send_command(
            InstanceIds = instance,
            DocumentName = "AWS-RunShellScript",
            Comment = 'b_code : ' + "9999", # ここは必要に応じて編集してください 
            TimeoutSeconds = 100, 
            Parameters = {
                "commands": [
                    sh_cmd
                ]
            }
        )
        command_id = res['Command']['CommandId'] # CommandIdを取得
        # 実行コマンドを出力
        print(res['Command']['Parameters'])
        
        # 処理完了まで5秒待つ
        time.sleep(5)

        # ステータスを取得し出力
        list_invocations = ssm.list_command_invocations(
            CommandId = command_id,
            Details = True
            )
        deploy_res = list_invocations['CommandInvocations'][0]['Status']
        print(deploy_res)
    
    except Exception as e:
        logger.error(e)
        raise e

④ロールの設定

Lambda関数内でシェル実行する場合は、
Lambda関数の実行ロールに以下の設定を行う必要があります。
・AmazonSSMFullAccess
image.png

⑤実行確認

カレンダーでは、2022年5月16日 14:00 にイベントを作成しました。
実行されたかを、CloudWatchで確認しました。
image.png

最後に

今回、EC2上のHulftコマンドを定期的に実行したい…という機能を作成しました。
「月初営業日○日と○日にHULFT集信したい」といった要望でした…
「日本の祝日カレンダーをGoogleカレンダーから取り込み…」という方法でも実装可能かとは思われますが…祝日がコロコロ変わる日本のカレンダーであれば、
「実行する日時だけをawsカレンダーで管理しよう」と思い、今回対応しました。
ただ、カレンダーの更新は定期的に必要です。(とりあえずは、3年分位をカレンダーに登録しようかな…と思ってます)

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
1
Help us understand the problem. What are the problem?