# Como Agendar um START/STOP Automático no EC2

## Introdução

Você pode ter vários motivos e razões diferentes para querer agendar um `start` e `stop` automático para suas instâncias EC2. No meu caso eu estava criando um ambiente de QA onde não precisava que o EC2 ficasse ligado o tempo todo para manter os custos reduzidos, então compartilho como consegui atingir esse objetivo.

---

## Tutorial

1- Acesse o console **AWS → IAM → Policies → crie uma política** conforme abaixo:

`Name:`

* Defina um nome de sua preferência
    
* Por exemplo:
    
    * `ec2-scheduler-qa-policy`
        

`Description:`

* Defina uma descrição de sua preferência
    
* Por exemplo:
    
    * `Policy that grants EventBridge permission to automatically start and stop EC2 in the QA environment`
        

```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": [
				"ec2:DescribeInstances",
				"ec2:StartInstances",
				"ec2:StopInstances"
			],
			"Resource": "*"
		}
	]
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712780321010/9197cfcb-b068-4262-ab0b-a6b69717f842.png align="center")

2- Agora vá para **IAM → Role → crie uma role** conforme abaixo:

* `Name:`
    
    * Defina um nome de sua preferência
        
    * Por exemplo:
        
        * `ec2-scheduler-qa-role`
            
* `Description:`
    
    * Defina uma descrição de sua preferência
        
    * Por exemplo:
        
        * `Role with necessary EventBridge permissions to automatically start and stop EC2 in the QA environment`
            

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712780420064/dbe1b9d5-8e6e-4b11-a250-42900aa54b8c.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Filtre por <code>Customer managed</code> e <code>ec2</code> → selecione a política que criamos anteriormente</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712780536319/b68e53f6-be84-497e-b5ff-e39a4834cf62.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Edite a aba <code>Trust Relashionship</code> para conceder permissão ao <code>EventBridge</code>, conforme abaixo</div>
</div>

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "scheduler.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712780705038/092d0503-9ddd-4e11-b44e-0ff4bd54e8be.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712780766831/b163ffa5-6990-45c6-b82a-607bb6e85050.png align="center")

---

3- Agora vá para o console **AWS → EventBridge → Rules → Create rule**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712780811044/912c7811-b258-4bc7-8cbc-979633f2e038.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712780826296/6607b4d5-6846-4766-9c4e-87d0d51e9e55.png align="center")

4- Defina um nome e descrição de sua preferência, por exemplo:

* **Name:**`ec2-start-qa-monday-to-friday-morning`
    
* **Description:**`Rule that automatically starts QA environment EC2`
    
* Altere para a opção `Schedule`
    
* Clique em `Continue in EventBridge Scheduler`
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712780960766/acaaceb7-d7a1-4b2c-be99-f95548307bf4.png align="center")

5- Altere para `Recurring schedule` → defina uma expressão `cron` de sua preferência

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Por exemplo, eu gostaria de iniciar o EC2 de segunda a sexta as 9 horas (horário de Brasília)</div>
</div>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781018160/d0fa3900-c350-43f5-b95b-5cfbaf1ef098.png align="center")

Por exemplo, para executar de segunda a sexta às `09 horas` (UTC -3), isso seria:

```plaintext
00 9 ? * MON-FRI *
```

* **00**: é o minuto em que o cron será executado. Neste caso, o que significa que a tarefa será executada quando o relógio marcar exatamente 0 minutos.
    
* **9**: é a hora em que o cron será executado. Neste caso, o que significa que a tarefa será executada às 9 horas. (UTC -3)
    
* **?:** isso indica que não estamos definindo um dia específico do mês. A tarefa será executada independentemente do dia do mês.
    
* **\***: isso indica que a tarefa será executada em todos os meses. Não estamos definindo um mês específico.
    
* **MON-FRI**: especifica os dias da semana em que a tarefa será executada. Neste caso, a tarefa será executada de segunda a sexta-feira.
    
* **\***: indica que a tarefa será executada em todos os anos. Não estamos definindo um ano específico.
    

Uma vez compreendido o formato do `cron`, lembre-se de ajustar seu `Time Zone` e preencher de acordo com suas necessidades.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781079986/e1b648eb-9566-498e-a53b-3916f28d65e5.png align="center")

6- Defina a opção `Flexible Time Window`, essa opção é útil quando você quiser que o `EventBridge` funcione dentro do tempo dessa janela que você definiu, pense nisso em casos que as tasks ou targets ainda não estão prontos, desta forma você define um intervalo de tempo para que isso seja feito.

Por exemplo, se eu definisse o `cron as 9 horas` e um `Flexible Time Window de 15 minutos`, na prática significa que o `EventBridge Scheduler` garantirá que ele seja executado dentro deste período, ou seja entre `9:00 às 9:15`, mas isso não significa que ele será executado as `9:15`, mas sim que será acionado dentro deste intervalo a qualquer momento a partir do horário agendado (no exemplo as `9:00 + flexible time window`).

Isso é muito bom para distribuir as execuções nesta janela de tempo, reduzindo os impactos de várias solicitações ao mesmo tempo em um ambiente grande.

Como neste meu caso isso não é um requisito necessário, defino como `Off`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781101869/6155ee45-950f-4195-a364-09489da1ca26.png align="center")

7- Você também pode definir uma data de início e término, como eu espero que a expressão `cron` funcione e não planejo inserir uma data para que esse `cron` comece a funcionar ou terminar, **não preencho** e clico em `Next`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781121334/a4a68195-2075-4a71-8f9b-48534d0876c0.png align="center")

8- Agora altere para `All APIs` → pesquise por `ec2` → selecione a opção `EC2`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781264431/44505bcb-1829-4685-93f1-7de7d368ba44.png align="center")

9- Agora pesquise por `start` → selecione a opção `StarInstances`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781386527/448f572c-aac3-46b0-9880-237489df208b.png align="center")

10- Como nessa regra estamos querendo iniciar as instâncias EC2, defino o campo `InstancesIds` com o `ID` das minhas instâncias EC2

```json
{
  "InstanceIds": [
    "<Instance-ID-1>",
    "<Instance-ID-2>"
  ]
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781529405/debfa587-c840-4d19-89bd-79e6354d96f3.png align="center")

11- Deixo a opção `Schedule`**habilitada**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781578486/3ec8102f-c5a6-4902-ae79-0d83c801c440.png align="center")

12- Não defino nenhuma ação após o agendamento ser executado, pois neste caso de uso não planejo excluir o agendamento

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781599379/627bcd55-bddd-4f78-ac8b-2e31b36eb7a7.png align="center")

13- Agora você pode definir uma `DLQ (Dead Letter Queue)`, isso seria uma fila `SQS` para armazenar os eventos que falharam, aqui ainda existem dois tipos:

* **Recuperáveis**
    
    * Se houver uma falha ou uma entrega mal sucedida no `target (que no nosso caso é a API StartInstances do EC2)`, por padrão o EventBridge tentará fazer ela novamente por 24 horas e até 185 vezes.
        
* **Não recuperáveis**
    
    * Se houver um erro não recuperável, como `AccessDenied` por exemplo, isso não será repetido pelo EventBridge, mas ele poderá adicionar se você quiser isso em uma fila DLQ para ser tratado ou processado posteriormente
        

Mesmo desabilitando a opção `Retry Policy`, ainda sim o EventBridge tentará repetir para eventos recuperáveis por 24 horas e até 185 vezes. Isso é um comportamento padrão, você configurando ou não.

Para este tutorial, defino isso como `Disable`, mas se isso for importante para você, este é o momento de configurar de acordo com suas preferências:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781637666/5dafc768-a0df-4ee9-a385-284fe4300fc5.png align="center")

14- Não defino nenhuma criptografia

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781656721/22e7e3da-5420-4a39-84a9-534e9c3be763.png align="center")

15- Seleciono a `Role` que criamos no início do tutorial

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781763472/7cea3e8a-836b-4c55-976d-24859a7b1fcd.png align="center")

16- Clico em **Create**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781809501/6e1acd5a-a3c9-4a2c-864b-56a379cef912.png align="center")

---

Pronto! 😄

Porém criamos até agora apenas para iniciar as instâncias EC2, ainda falta uma parte importante que seria parar as instâncias EC2, para isso basta repetir os mesmos passos, porém mudando o request da API para `StopInstances`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712781975601/8291a8a8-d983-4585-99d5-1a6a2312de92.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712782030509/7eb3f789-fde1-424b-b80f-4cf9e75c2b4c.png align="center")

E novamente passar os `IDs` corretos das instâncias EC2 substituindo `<Instance-ID>`

```json
{
  "InstanceIds": [
    "<Instance-ID-1>",
    "<Instance-ID-2>"
  ]
}
```

---

## Limitações

* As instâncias EC2 e o Event Bridge precisam estar na mesma região.
    

---

## Conclusão

Pronto! 😄

Agora sim temos todo o nosso objetivo completo.

Vimos neste artigo um tutorial passo a passo para iniciar e parar as instâncias EC2 que faz:

1. O `EventBridge Scheduler` configurado com uma expressão `cron` que **inicia** as instâncias EC2 enviando uma chamada `API` para o `StartInstances` do `EC2`
    
2. O `EventBridge Scheduler` configurado com uma expressão `cron` que **para** as instâncias EC2 enviando uma chamada `API` para o `StopInstances` do `EC2`
    

---

Por fim, depois que o `cron` for executado em seu horário definido, poderemos ver no EC2 a instância pausada ou iniciada:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712782864743/d51b2edc-c8b8-45b9-ac7d-a540f15d49d2.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712782284284/f69933fc-d2a1-462a-ba4e-49b0df1f6421.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Lembre-se de excluir todos os recursos ao final para não obter cobranças indesejadas e manter sua conta AWS limpa e organizada.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">✅</div>
<div data-node-type="callout-text">Espero que essas informações tenham sido úteis para você!</div>
</div>
