Aprenda a Reiniciar sua Instância Lightsail com Agendamento Automático

INTRODUÇÃO
Recentemente recebi um projeto para reiniciar uma instância Lightsail todos os dias em um horário específico automaticamente. Essa instância Lightsail era uma pilha otimizada de WordPress de um site que recebia um alto tráfego de visitas, e por um motivo não relevante para este artigo, quando essa instância ficava muito tempo ligada, alguns problemas e lentidões aconteciam, porém um simples clique no botão reboot resolvia todos os problemas.
Embora haja outras abordagens que poderiam resolver esse problema, esse cliente em específico gostaria de manter as coisas simples, tão simples como apenas reiniciar essa instância Lightsail, nada além disso, isso era o suficiente, porém deveria ser de forma automática. Ainda esse projeto exigia como premissa não termos que acessar a instância através de ssh e realizar configurações como scripts ou crontab, preferencialmente deveríamos criar uma solução fora da caixa para que isso fosse feito sem qualquer acesso na instância.
Então aqui está o passo a passo que fiz para atingir esse objetivo, note que citei esse caso de uso real do site WordPress, mas isso pode ser aplicado para toda e qualquer instância Lightsail que você deseja reiniciar automaticamente, independentemente dos seus motivos.
Então vamos lá!
ETAPA 1 - Permissões
1- Acesse o IAM → Policy → alterne para a aba JSON

Defina o nome como “lightsail_reboot_policy”
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "lightsail:RebootInstance",
"Resource": "*"
}
]
}
2- Acesse o IAM → Role → selecione AWS Service e Lambda

Defina o nome como “lightsail_reboot_role” → adicione a política criada no passo anterior → clique na aba Trust Relationships

Verifique se está igual o código abaixo:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
ETAPA 2 - Função Lambda
1- Acesse o Lambda (author from scratch) → crie uma função com:
Function Name:
lightsail_rebootRuntime:
Pyhton 3.9Architecture:
x86_64Expanda a opção “Change default execution role” → Use existing role → selecione a role criada no passo anterior

instanceName e region_name pelos valores reais do seu cenárioimport json
import boto3
def lambda_handler(event, context):
client = boto3.client("lightsail", region_name="us-east-1")
response = client.reboot_instance(instanceName="EXAMPLE")
return {
"statusCode": 200,
"body": json.dumps({
"message": "Lightsail instance restarted successfully!"
})
}

ETAPA 3 - CloudWatch Events Rules
1- Acesse o Cloudwatch → Events → Rules → Create Rule → defina o nome “Site_Reboot” por exemplo ou qualquer outro nome que faça sentido para você
Defina sua expressão cron, por exemplo:
Cron express:0 7 * * ? * → expressão cron diária as 7 horas UTC e 4 horas no horário de Brasília.
50 16 ? MON-FRI * funcionaria de segunda a sexta as 16 horas e 50 minutos UTC (ou 13 horas e 50 minutos no horário de Brasília)Ou qualquer horário de sua preferência e que faça sentido para seu cenário

2- Em Target → selecione a função Lambda criada anteriormente

Bônus
As vezes em seu cenário pode ser que as instâncias Lightsail possuem um prefixo no nome, ou seja você em algum momento adotou um padrão de nomenclatura e suas instâncias começam sempre com um prefixo, por exemplo por SC-instance1, SC-instance2, etc.
Se esse for o caso, tudo que vimos acima ainda funcionará para você, mas se você está se perguntando se terá que criar uma função e uma regra para cada uma então a resposta curta é não.
Opção 1 - Use prefixos e reinicie várias instâncias ao mesmo tempo
Para esse cenário, mude o código da sua função Lambda para:
region_name e o prefix para os valores reais que você está usando.import json
import boto3
def lambda_handler(event, context):
# Lightsail Configuration
lightsail_client = boto3.client("lightsail", region_name="us-west-2")
# Prefix to search for instances
prefix = 'your-prefix'
# List all instances
response = lightsail_client.get_instances()
# List of instance names to be restarted
instance_names = []
# Filter and add instances that begin with the prefix to the list
for instance in response["instances"]:
if instance["name"].startswith(prefix):
instance_names.append(instance["name"])
responses = {} # Dictionary to store restart responses
# Loop through the list of names and restart each instance
for instance_name in instance_names:
response = lightsail_client.reboot_instance(
instanceName=instance_name
)
responses[instance_name] = response
return {
"statusCode": 200,
"body": json.dumps({
"message": "Successfully restarted instances"
})
}
Opção 2 - Envie um email também com AWS SES
Para esse cenário, mude o código da sua função Lambda para:
region_name, o email do remetente e destinatário, além do prefix que você utiliza. Também seu AWS SES precisa estar devidamente configurado e verificado com o domínio ou email que você utilizará aqui.import json
import boto3
def send_email(subject, body, recipient):
ses = boto3.client('ses', region_name='us-west-2')
response = ses.send_email(
Source='your-email@example.com ',
Destination={
'ToAddresses': [recipient]
},
Message={
'Subject': {
'Data': subject
},
'Body': {
'Text': {
'Data': body
}
}
}
)
def lambda_handler(event, context):
# Lightsail Configuration
lightsail_client = boto3.client("lightsail", region_name="us-west-2")
# Prefix to search for instances
prefix = 'your-prefix'
# List all instances
response = lightsail_client.get_instances()
# List of instance names to be restarted
instance_names = []
# Filter and add instances that begin with the prefix to the list
for instance in response["instances"]:
if instance["name"].startswith(prefix):
instance_names.append(instance["name"])
responses = {} # Dictionary to store restart responses
# Loop through the list of names and restart each instance
for instance_name in instance_names:
response = lightsail_client.reboot_instance(
instanceName=instance_name
)
responses[instance_name] = response
# Send notification email
subject = 'Lightsail - Restarted Instances'
body = 'Lightsail instances were successfully restarted by lambda.'
recipient = 'other-email@example.com'
send_email(subject, body, recipient)
return {
"statusCode": 200,
"body": json.dumps({
"message": "Instances restarted and email sent successfully"
})
}
CONCLUSÃO
Criamos uma solução para reiniciar automaticamente instâncias Lightsail sem a necessidade de acessar ssh ou fazer qualquer configuração dentro da instância, minimizando qualquer problema, desta forma nosso Cloudwatch Event Rules possui um agendamento, e então no momento definido invocará nossa função lambda que possui permissões necessárias para reiniciar a instância Lightsail.
Além disso essa é uma solução barata, pois Cloudwatch Event Rules e Lambda possuem bons níveis gratuitos, por exemplo o Lambda possui até um milhão de requisições gratuitas por mês.






