Overview
In the following article, I described how to perform health checks.
I also described the command for restarting Virtuoso when it stops in the following article.
This time, I will try restarting Virtuoso in conjunction with Amazon SNS notifications.
Method
To send a command like sudo rm -rf /usr/local/var/lib/virtuoso/db/virtuoso.lck && ... to an EC2 instance, SSM (AWS Systems Manager) configuration was required.
IAM Roles and Policies
I created a new IAM role and granted the AmazonSSMFullAccess policy. Initially, I had granted the AmazonSSMManagedInstanceCore policy, but the following error occurred when executing the Lambda function described later, and it did not work properly.
An error occurred (InvalidInstanceId) when calling the SendCommand operation: Instances [[i-xxxxxx]] not in a valid state for account xxxxxx
I selected and updated the created IAM role from “Modify IAM role” on the EC2 instance.
AWS SAM: Creating the Lambda Function
I used AWS SAM. Create a project with the following:
sam init
I created hello_world/app.py as follows. The instance_id part needs to be modified.
import boto3
import time
def lambda_handler(event, context):
# Initialize EC2 client
ec2 = boto3.client('ec2')
# Specify a specific EC2 instance ID
instance_id = 'i-xxxxxxxx'
# Check EC2 instance status
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'
# Send command to EC2 instance via SSM
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
I also added boto3 to hello_world/requirements.txt.
boto3
Local testing can be done with the following. If using a profile other than the default, provide the appropriate profile name for xxxx.
sam build && sam local invoke --profile xxxx
AWS SAM: Updating template.yaml
Modify template.yaml so that the Lambda function is executed in response to SNS notifications.
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 # ARN of the existing SNS topic
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
Please modify the “ARN of the existing SNS topic” to the appropriate value. Also, the folder name storing the Lambda function shown earlier has been changed from hello_world to virtuoso_restart.
AWS SAM: Deployment
Deployment is done with the following:
sam build && sam deploy --profile xxxx
Summary
Since this was my first time using SSM (AWS Systems Manager), it took some time to resolve the errors, but I found it to be a convenient feature.
I hope this serves as a useful reference for others.