Amazon SNSを用いたEC2上のVirtuosoの再起動
概要
以下の記事で、ヘルスチェックを行う方法について記述しました。
また、Virtuosoが停止した際の再起動のためのコマンドを以下に記述しました。
今回は、Amazon SNSを用いた通知に合わせて、Virtuosoを再起動してみます。
方法
EC2インスタンスにsudo rm -rf /usr/local/var/lib/virtuoso/db/virtuoso.lck && ...
のようなコマンドを送信するには、SSM(AWS Systems Manager)に関する設定が必要でした。
IAMロールとポリシー
IAMロールを新規に作成して、AmazonSSMFullAccess
というポリシーを許可しました。はじめ、AmazonSSMManagedInstanceCore
というポリシーを許可していましたが、後述するlambda実行時に以下のようなエラーが発生して、うまく動作させることができませんでした。
An error occurred (InvalidInstanceId) when calling the SendCommand operation: Instances [[i-xxxxxx]] not in a valid state for account xxxxxx
EC2インスタンスの「IAMロールを変更」から、作成したIAMロールを選択して更新しました。
AWS SAM: lamda関数の作成
AWS SAMを用いました。以下でのプロジェクトを作成します。
sam init
hello_world/app.py
を以下のように作成しました。instance_id
の部分には、要修正です。
import boto3
import time
def lambda_handler(event, context):
# EC2クライアントの初期化
ec2 = boto3.client('ec2')
# 特定のEC2インスタンスIDを指定
instance_id = 'i-xxxxxxxx'
# EC2インスタンスのステータスチェック
response = ec2.describe_instance_status(InstanceIds=[instance_id])
if len(response['InstanceStatuses']) == 0:
print(f"インスタンス {instance_id} は停止中です。")
return
# Define the command to be executed on the instance (e.g., restart software)
command = 'sudo rm -rf /usr/local/var/lib/virtuoso/db/virtuoso.lck && sudo /usr/local/bin/virtuoso-t +configfile /usr/local/var/lib/virtuoso/db/virtuoso.ini'
# SSMを通じてEC2インスタンスにコマンドを送信
ssm_client = boto3.client('ssm')
response = ssm_client.send_command(
InstanceIds=[instance_id],
DocumentName='AWS-RunShellScript',
Parameters={'commands': [command]}
)
time.sleep(1.0)
command_id = response['Command']['CommandId']
output = ssm_client.get_command_invocation(
CommandId=command_id,
InstanceId=instance_id,
)
print("コマンドを実行しました。")
# Extract only the necessary information from the output
simplified_response = {
"Output": output['StandardOutputContent'],
"Error": output['StandardErrorContent'],
}
return simplified_response
また、hello_word/requirements.txt
にboto3を追記しました。
boto3
ローカルでのテストは以下で行います。デフォルト以外のprofileを使用する場合には、xxxxに適切なプロファイル名を与えます。
sam build && sam local invoke --profile xxxx
AWS SAM: template.yamlの更新
SNSの通知に合わせて、lambda関数が実行されるように、template.yaml
を修正します。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
cj-virtuoso-restart
Sample SAM Template for restarting Virtuoso instances
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 15
MemorySize: 128
Resources:
VirtuosoRestarter:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: virtuoso_restart/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
# This property associates this Lambda function with the SNS topic defined above, so that whenever the topic
# receives a message, the Lambda function is invoked
Events:
MySNSTrigger:
Type: SNS
Properties:
Topic: arn:aws:sns:us-east-1:xxxxx:xxxxx # 既存のSNSトピックのARN
Outputs:
VirtuosoRestarter:
Description: "Virtuoso Restarter Lambda Function ARN"
Value: !GetAtt VirtuosoRestarter.Arn
VirtuosoRestarterIamRole:
Description: "Implicit IAM Role created for Virtuoso Restarter function"
Value: !GetAtt VirtuosoRestarterRole.Arn
「既存のSNSトピックのARN」は適切なものに修正してください。また、先に示したlambda関数を格納するフォルダ名をhello_word
からvirtuoso_restart
に変更しています。
AWS SAM: デプロイ
デプロイは以下で行います。
sam build && sam deploy --profile xxxx
まとめ
SSM(AWS Systems Manager)の利用が初めてだったので、エラーを解消させるまで時間がかかりましたが、便利な機能だと思いました。
他の方の参考になりましたら幸いです。
Discussion