Posso iniciar e encerrar automaticamente minha instância da Amazon usando a API da Amazon? Você pode descrever como isso pode ser feito? Idealmente, preciso iniciar a instância e interrompê-la em intervalos de tempo especificados todos os dias.
Posso iniciar e encerrar automaticamente minha instância da Amazon usando a API da Amazon? Você pode descrever como isso pode ser feito? Idealmente, preciso iniciar a instância e interrompê-la em intervalos de tempo especificados todos os dias.
Respostas:
Caso alguém tropece nessa velha questão, hoje em dia você pode conseguir a mesma coisa adicionando uma programação a um grupo de auto scaling: aumente a quantidade de instâncias em um grupo de auto scaling para 1 em certos momentos e diminua de volta para 0 depois .
E como essa resposta está recebendo muitas visualizações, pensei em criar um link para um guia muito útil sobre isso: Como executar instâncias EC2 em uma programação recorrente com escalonamento automático
Você pode tentar usar as ferramentas de API do Amazon EC2 diretamente. Na verdade, você precisa de apenas dois comandos: ec2-start-instances e ec2-stop-instances. Certifique-se de que as variáveis de ambiente, como EC2_HOME, AWS_CREDENTIAL_FILE, EC2_CERT, EC2_PRIVATE_KEY, etc., estejam configuradas corretamente e todas as credenciais AWS, certificados e arquivos de chave privada estejam no local adequado - você pode encontrar mais informações na documentação das ferramentas de API do AWS EC2.
Você pode testar o comando manualmente primeiro e depois, quando tudo funcionar bem, configurar o crontab Unix ou Tarefas agendadas no Windows. Você pode encontrar o exemplo abaixo para o arquivo Linux / etc / crontab (não se esqueça que todas as variáveis de ambiente mencionadas acima precisam estar presentes para o usuário 'sua-conta'.
/etc/crontab
0 8 * * * your-account ec2-start-instances <your_instance_id>
0 16 * * * your-account ec2-stop-instances <your_instance_id>
# Your instance will be started at 8am and shutdown at 4pm.
Sou um desenvolvedor do projeto BitNami Cloud, onde empacotamos as ferramentas AWS (incluindo as que mencionei) em um instalador fácil de usar que você pode querer experimentar: BitNami CloudTools pack stack
Eu recomendo que você dê uma olhada no Guia de introdução do EC2 , que mostra como fazer o que você precisa usando as ferramentas de linha de comando do EC2. Você pode facilmente criar um script para um cron job (no Linux / UNIX) ou um trabalho agendado no Windows para chamar os comandos start e stop em um determinado momento.
Se quiser fazer isso a partir de seu próprio código, você pode usar as APIs SOAP ou REST; consulte o Guia do desenvolvedor para obter detalhes.
Eu escrevi código em Python, usando a biblioteca Boto, para fazer isso. Você pode ajustar isso para seu próprio uso. Certifique-se de executá-lo como parte de um cron job, e então você será capaz de iniciar ou desligar quantas instâncias forem necessárias durante a execução dos cron jobs.
#!/usr/bin/python
#
# Auto-start and stop EC2 instances
#
import boto, datetime, sys
from time import gmtime, strftime, sleep
# AWS credentials
aws_key = "AKIAxxx"
aws_secret = "abcd"
# The instances that we want to auto-start/stop
instances = [
# You can have tuples in this format:
# [instance-id, name/description, startHour, stopHour, ipAddress]
["i-12345678", "Description", "00", "12", "1.2.3.4"]
]
# --------------------------------------------
# If its the weekend, then quit
# If you don't care about the weekend, remove these three
# lines of code below.
weekday = datetime.datetime.today().weekday()
if (weekday == 5) or (weekday == 6):
sys.exit()
# Connect to EC2
conn = boto.connect_ec2(aws_key, aws_secret)
# Get current hour
hh = strftime("%H", gmtime())
# For each instance
for (instance, description, start, stop, ip) in instances:
# If this is the hour of starting it...
if (hh == start):
# Start the instance
conn.start_instances(instance_ids=[instance])
# Sleep for a few seconds to ensure starting
sleep(10)
# Associate the Elastic IP with instance
if ip:
conn.associate_address(instance, ip)
# If this is the hour of stopping it...
if (hh == stop):
# Stop the instance
conn.stop_instances(instance_ids=[instance])
Se não for de missão crítica - Uma coisa simplista a fazer é agendar o arquivo em lote para executar 'SHUTDOWN' (Windows) às 3 da manhã todos os dias. Assim, pelo menos, você não corre o risco de deixar acidentalmente uma instância indesejada em execução indefinidamente.
Obviamente, essa é apenas metade da história!
A empresa para a qual trabalho tinha clientes perguntando regularmente sobre isso, então escrevemos um aplicativo de agendamento EC2 freeware disponível aqui:
http://blog.simple-help.com/2012/03/free-ec2-scheduler/
Ele funciona no Windows e no Mac, permite que você crie várias programações diárias / semanais / mensais e permite que você use filtros correspondentes para incluir facilmente um grande número de instâncias ou incluir aquelas que você adicionar no futuro.
O AWS Data Pipeline está funcionando bem. https://aws.amazon.com/premiumsupport/knowledge-center/stop-start-ec2-instances/
Se desejar excluir dias do início (por exemplo, fim de semana), adicione um objeto ShellCommandPrecondition.
No AWS Console / Data Pipeline, crie um novo pipeline. É mais fácil editar / importar uma definição (JSON)
{
"objects": [
{
"failureAndRerunMode": "CASCADE",
"schedule": {
"ref": "DefaultSchedule"
},
"resourceRole": "DataPipelineDefaultResourceRole",
"role": "DataPipelineDefaultRole",
"pipelineLogUri": "s3://MY_BUCKET/log/",
"scheduleType": "cron",
"name": "Default",
"id": "Default"
},
{
"name": "CliActivity",
"id": "CliActivity",
"runsOn": {
"ref": "Ec2Instance"
},
"precondition": {
"ref": "PreconditionDow"
},
"type": "ShellCommandActivity",
"command": "(sudo yum -y update aws-cli) && (#{myAWSCLICmd})"
},
{
"period": "1 days",
"startDateTime": "2015-10-27T13:00:00",
"name": "Every 1 day",
"id": "DefaultSchedule",
"type": "Schedule"
},
{
"scriptUri": "s3://MY_BUCKET/script/dow.sh",
"name": "DayOfWeekPrecondition",
"id": "PreconditionDow",
"type": "ShellCommandPrecondition"
},
{
"instanceType": "t1.micro",
"name": "Ec2Instance",
"id": "Ec2Instance",
"type": "Ec2Resource",
"terminateAfter": "50 Minutes"
}
],
"parameters": [
{
"watermark": "aws [options] <command> <subcommand> [parameters]",
"description": "AWS CLI command",
"id": "myAWSCLICmd",
"type": "String"
}
],
"values": {
"myAWSCLICmd": "aws ec2 start-instances --instance-ids i-12345678 --region eu-west-1"
}
}
Coloque o script Bash a ser baixado e executado como pré-condição em seu balde S3
#!/bin/sh
if [ "$(date +%u)" -lt 6 ]
then exit 0
else exit 1
fi
Ao ativar e executar o pipeline nos dias de fim de semana, o status de integridade do pipeline do console da AWS mostra um erro "ERROR". O script bash retorna um erro (saída 1) e o EC2 não é iniciado. Nos dias 1 a 5, o status é "SAUDÁVEL".
Para interromper o EC2 automaticamente no horário de fechamento do escritório, use o comando AWS CLI diariamente sem a condição prévia.
Você poderia olhar para Ylastic para fazer isso. A alternativa parece ser ter uma máquina em execução que encerra / inicia outras instâncias usando um cron job ou tarefa agendada.
Obviamente, se você quiser apenas uma instância, esta é uma solução cara, pois uma máquina deve estar sempre em execução e pagar ~ $ 80 por mês para que uma máquina execute tarefas cron não é rentável.
O escalonamento automático é limitado a instâncias de encerramento. Se você deseja interromper uma instância e manter o estado do servidor, um script externo é a melhor abordagem.
Você pode fazer isso executando um trabalho em outra instância que esteja funcionando 24 horas por dia, 7 dias por semana, ou pode usar um serviço de terceiros, como Ylastic (mencionado acima) ou Rocket Peak .
Por exemplo, em C #, o código para parar um servidor é bastante simples:
public void stopInstance(string instance_id, string AWSRegion)
{
RegionEndpoint myAWSRegion = RegionEndpoint.GetBySystemName(AWSRegion);
AmazonEC2 ec2 = AWSClientFactory.CreateAmazonEC2Client(AWSAccessKey, AWSSecretKey, myAWSRegion);
ec2.StopInstances(new StopInstancesRequest().WithInstanceId(instance_id));
}
IMHO adicionando uma programação a um grupo de escalonamento automático é a melhor abordagem "semelhante à nuvem", conforme mencionado antes.
Mas caso você não possa encerrar suas instâncias e usar novas, por exemplo, se você tiver Elastic IPs associados a etc.
Você pode criar um script Ruby para iniciar e parar suas instâncias com base em um intervalo de data e hora.
#!/usr/bin/env ruby
# based on https://github.com/phstc/amazon_start_stop
require 'fog'
require 'tzinfo'
START_HOUR = 6 # Start 6AM
STOP_HOUR = 0 # Stop 0AM (midnight)
conn = Fog::Compute::AWS.new(aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'])
server = conn.servers.get('instance-id')
tz = TZInfo::Timezone.get('America/Sao_Paulo')
now = tz.now
stopped_range = (now.hour >= STOP_HOUR && now.hour < START_HOUR)
running_range = !stopped_range
if stopped_range && server.state != 'stopped'
server.stop
end
if running_range && server.state != 'running'
server.start
# if you need an Elastic IP
# (everytime you stop an instance Amazon dissociates Elastic IPs)
#
# server.wait_for { state == 'running' }
# conn.associate_address server.id, 127.0.0.0
end
Dê uma olhada em amazon_start_stop para criar um agendador gratuitamente usando o Heroku Scheduler .
Embora existam maneiras de fazer isso usando o escalonamento automático, ele pode não ser adequado para todas as ocasiões, pois encerra as instâncias. Os cron jobs nunca funcionarão para uma única instância (embora possam ser perfeitamente usados para situações como interromper uma única instância e agendar outras instâncias ao executar muitas instâncias). Você pode usar chamadas de API como StartInstancesRequest e StopInstancesRequest para conseguir o mesmo, mas novamente você precisa contar com um terceiro recurso. Existem muitos aplicativos para agendar instâncias da AWS com muitos recursos, mas para uma solução simples, eu recomendaria um aplicativo gratuito como o snapleaf.io
Sim, você pode fazer isso usando o AWS Lambda. Você pode selecionar o gatilho no Cloudwatch que é executado em expressões Cron no UTC.
Aqui está um link relacionado https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
Outra alternativa é usar awscli
o que está disponível a partir pip
, apt-get
, yum
ou brew
, e em seguida, executando aws configure
com suas credenciais exportados do IAM e executar o seguinte script bash, para parar um EC2 que foi marcado com Name: Appname
e Value: Appname Prod
. Você pode usar awscli
para marcar suas instâncias ou marcá-las manualmente no console da AWS. aws ec2 stop-instances
interromperá a instância e jq
é usado para filtrar a consulta json e buscar o ID correto da instância usando as tags deaws ec2 describe-instances
.
Para verificar se aws configure
foi bem-sucedido e retorna a saída json, execute aws ec2 describe-instances
e o ID da instância em execução deve estar lá na saída. Aqui está um exemplo de saída
{
"Reservations": [
{
"Instances": [
{
"Monitoring": {
"State": "disabled"
},
"PublicDnsName": "ec2-xxx.ap-south-1.compute.amazonaws.com",
"State": {
"Code": xx,
"Name": "running"
},
"EbsOptimized": false,
"LaunchTime": "20xx-xx-xxTxx:16:xx.000Z",
"PublicIpAddress": "xx.127.24.xxx",
"PrivateIpAddress": "xxx.31.3.xxx",
"ProductCodes": [],
"VpcId": "vpc-aaxxxxx",
"StateTransitionReason": "",
"InstanceId": "i-xxxxxxxx",
"ImageId": "ami-xxxxxxx",
"PrivateDnsName": "ip-xxxx.ap-south-1.compute.internal",
"KeyName": "node",
"SecurityGroups": [
{
"GroupName": "xxxxxx",
"GroupId": "sg-xxxx"
}
],
"ClientToken": "",
"SubnetId": "subnet-xxxx",
"InstanceType": "t2.xxxxx",
"NetworkInterfaces": [
{
"Status": "in-use",
"MacAddress": "0x:xx:xx:xx:xx:xx",
"SourceDestCheck": true,
"VpcId": "vpc-xxxxxx",
"Description": "",
"NetworkInterfaceId": "eni-xxxx",
"PrivateIpAddresses": [
{
"PrivateDnsName": "ip-xx.ap-south-1.compute.internal",
"PrivateIpAddress": "xx.31.3.xxx",
"Primary": true,
"Association": {
"PublicIp": "xx.127.24.xxx",
"PublicDnsName": "ec2-xx.ap-south-1.compute.amazonaws.com",
"IpOwnerId": "xxxxx"
}
}
],
"PrivateDnsName": "ip-xxx-31-3-xxx.ap-south-1.compute.internal",
"Attachment": {
"Status": "attached",
"DeviceIndex": 0,
"DeleteOnTermination": true,
"AttachmentId": "xxx",
"AttachTime": "20xx-xx-30Txx:16:xx.000Z"
},
"Groups": [
{
"GroupName": "xxxx",
"GroupId": "sg-xxxxx"
}
],
"Ipv6Addresses": [],
"OwnerId": "xxxx",
"PrivateIpAddress": "xx.xx.xx.xxx",
"SubnetId": "subnet-xx",
"Association": {
"PublicIp": "xx.xx.xx.xxx",
"PublicDnsName": "ec2-xx.ap-south-1.compute.amazonaws.com",
"IpOwnerId": "xxxx"
}
}
],
"SourceDestCheck": true,
"Placement": {
"Tenancy": "default",
"GroupName": "",
"AvailabilityZone": "xx"
},
"Hypervisor": "xxx",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xxx",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": true,
"VolumeId": "vol-xxx",
"AttachTime": "20xxx-xx-xxTxx:16:xx.000Z"
}
}
],
"Architecture": "x86_64",
"RootDeviceType": "ebs",
"RootDeviceName": "/dev/xxx",
"VirtualizationType": "xxx",
"Tags": [
{
"Value": "xxxx centxx",
"Key": "Name"
}
],
"AmiLaunchIndex": 0
}
],
"ReservationId": "r-xxxx",
"Groups": [],
"OwnerId": "xxxxx"
}
]
}
O script bash seguinte é stop-ec2.sh
em /home/centos/cron-scripts/
que é inspirado a partir deste post SO
(instance=$(aws ec2 describe-instances | jq '.Reservations[].Instances | select(.[].Tags[].Value | startswith("Appname Prod") ) | select(.[].Tags[].Key == "Appname") | {InstanceId: .[].InstanceId, PublicDnsName: .[].PublicDnsName, State: .[].State, LaunchTime: .[].LaunchTime, Tags: .[].Tags} | [.]' | jq -r .[].InstanceId) && aws ec2 stop-instances --instance-ids ${instance} )
Execute o arquivo usando sh /home/centos/cron-scripts/stop-ec2.sh
e verifique se a instância EC2 foi interrompida. Para depurar executeaws ec2 describe-instances | jq '.Reservations[].Instances | select(.[].Tags[].Value | startswith("Appname Prod") ) | select(.[].Tags[].Key == "Appname") | {InstanceId: .[].InstanceId, PublicDnsName: .[].PublicDnsName, State: .[].State, LaunchTime: .[].LaunchTime, Tags: .[].Tags} | [.]' | jq -r .[].InstanceId
e veja se ele retorna o ID de instância correto que foi marcado.
Então, na crontab -e
seguinte linha pode ser adicionado
30 14 * * * sh /home/centos/cron-scripts/stop-ec2.sh >> /tmp/stop
que registrará a saída /tmp/stop
. A 30 14 * * *
é a expressão cron UTC que você pode verificar https://crontab.guru/
. Da mesma forma, substituir por aws ec2 start-instances
pode iniciar uma instância.
Acho que a pergunta inicial foi um pouco confusa. Depende do que o Pasta precisa: 1. iniciar / encerrar (armazenamento de instância) - Auto Scaling é a solução certa (resposta da Nakedible) 2. iniciar / parar a instância de inicialização do EBS - Auto Scaling não vai ajudar, eu uso scripts remotos agendados (ex. , ec2 CLI).
Você não pode fazer isso automaticamente, ou pelo menos não sem alguma programação e manipulação de API nos arquivos de script. Se você deseja uma solução confiável para parar, reiniciar e gerenciar suas imagens (presumivelmente para controlar os custos em seu ambiente), você pode querer dar uma olhada no LabSlice . Aviso Legal: Eu trabalho para esta empresa.