ECS(Beanstalk Docker)の場合、docker内でcronを設定するのに悩むと思いますが、
lambdaを使ってお手軽cronを設定できたので簡単にメモ
SSMのインストール
ECSインスタンスに入ってdocker runを叩きたいのですが、
今回はSSMというものをインストールし、こいつをlambdaのpythonから呼び出す方針です。
http://dev.classmethod.jp/cloud/aws/introduce-to-run-a-command-button-for-linux/
ECSのsshでログインして、以下のコマンドでssm-agentをインストールして下さい。
amazon-ssm-ap-northeast-1のところが重要で、ここを間違えると動きません。
sudo yum -y update
curl https://amazon-ssm-ap-northeast-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm -o amazon-ssm-agent.rpm
sudo yum install -y amazon-ssm-agent.rpm
ECS(EC2)のロールにAmazonEC2RoleforSSMをアタッチ
ECS(EC2)に紐付いているロールにssm-agentへのアクセス権限を与えるために、
AmazonEC2RoleforSSMをアタッチして下さい。
自分の場合はロールはaws-elasticbeanstalk-ec2-roleだったので、
こいつにAmazonEC2RoleforSSMをアタッチします。
EC2のコマンド実行が出来るか確認
EC2のコンソール画面でコマンド履歴という項目があると思いますが、ここでコマンド実行をクリックし、
AWS-RunShellScriptを選択した時に上記で設定したインスタンスが表示されるか確認して下さい。
これが出てこないのであれば上の設定がミスってるので確認して下さい。
※ アタッチして即、出るわけではないみたいです。少し待ってみましょう
#lambdaの設定
こちらを参考にしました
http://dev.classmethod.jp/cloud/aws/lambda-ssm-pseudo-cron/
docker runを呼び出すことで、コンテナ内のコマンドを実行できます。
いつもは -it をつけていると思いますが、今回はttyに出力するわけでないのでtは不要です
ここでtをつけると動かないので注意
ssm-agentをインストールしたインスタンスから、一つを選んで実行する感じです。
ssm-agentのインストールを手動でやってますが、インスタンスが増えた時に
自動で行えたほうがいいのですが、スマートなやり方がわかりません。誰かいい方法知ってる人いたら教えてください。
import boto3
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
ec2 = boto3.client('ec2')
ssm = boto3.client('ssm')
def lambda_handler(event, context):
try:
ec2_resp = ec2.describe_instances(Filters=[{'Name':'tag:Name','Values':['hogehoge_production']}, {'Name':'tag:ssm-agent','Values':['installed']}] )
instances = [i["InstanceId"] for r in ec2_resp["Reservations"] for i in r["Instances"]]
instances = instances[0:1]
logger.info(instances)
ssm.send_command(
InstanceIds = instances,
DocumentName = "AWS-RunShellScript",
Parameters = {
"commands": [
"sudo docker run --rm -i $(sudo docker ps |grep hoge-production | head -n 1 | awk '{print $2}') rails r Hoge.hogehoge >> /tmp/lambda_cron"
],
"executionTimeout": ["3600"]
},
)
except Exception as e:
logger.error(e)
raise e
cronの設定
TriggerでCloudWatch Events - Scheduleを選択して、
Schedule expressionのところに cron(5 * * * ? *) など
任意のスケジュールを設定すれば完了です。
便利な機能ですが、Schedule expressionの説明が薄い上に、
selectになってるのに、文字列を貼り付けて
登録するUIってのはどうなんですか? Amazonさんw