# Scripts de automação de start/stop em python para lambda
## Sumário
[TOC]
# Apresentação
<p style='text-align: justify;'> Esses scrips tem como objetivo a automação do start/stop de recursos AWS(EC2, Autoscalling e Instancia de RDS) fora de produção e/ou que não usados fora de horario comercial e finais de semana não incluso feriados </p>
# Configuração de permissões IAM
<p style='text-align: justify;'> Para executar corretamente os scripts é necessario configurar as permissões corretas IAM </p>
## Criar Politica
* Acesse o serviço IAM no console da AWS
* Clicar em Políticas e criar Política

* Clique em json e cole o conteudo do [json](https://bitbucket.org/fastchannel/aws-lambda-start-stop/src/master/iam-role-start-stop-instancias-ec2.json)

* Clicar em Próximo: Tags.
* Clicar em Próximo: Revisar.
* Faça a revisão da política e em seguida clique em Criar Política
## Criar a Função no AWS IAM
<p style='text-align: justify;'> Com esta função daremos permissão ao serviço AWS Lambda que definimos na política criada. </p>
* Clique em Funções escolher as opções conforme print abaixo e clicar em próximo.

* Adicionar a política criada e clicar em próximo.

* Nomeie, revise e clique em criar função.

# Lambda
<p style='text-align: justify;'> Esses scripts necessitam do Lambda ou outro gerenciador para serem executados, segue os passos para criação do lambda </p>
## Criar Função Lambda
* Acessar o serviço AWS LAMBDA
* Clique em fuções e depois em criar função
* Nomeie sua função
* Escolha a opção de Python que será utilizada para escrita do código
* Atribua permissão com base numa função existente ( aquela que criamos acima).
* Clique em criar função

* Limpe o conteúdo do Lambda function e cole o codigo de acordo com a função desejada do repositorio [aws-lambda-start-stop](https://bitbucket.org/fastchannel/aws-lambda-start-stop/src/master/) para desligar e repira o processo para criar a função para ligar.
* Clique em Deploy
* Teste o codigo após tagueamento correto dos recursos
Obs.: Teste o codigo apenas se tiver certeza dos recursos afetados.

# Amazon EventBridge
<p style='text-align: justify;'> Para execução pontual dos scripts é necessario a criação do cron no Amazon EventBrigde </p>
## Criando o evento no AWS EventBridge
* Acessar o serviço AWS EventBridge.
* Dentro da guia Scheduler, clique em Cronogramas.
* Criar Cronograma.
* Coloque o nome de acordo com a função de ligar/desligar do recurso e a descrição do cronograma Ex: startdbintancias, stopdbintancias, etc..

* Selecione em Cronograma recorrente e Cronograma baseado em cron.
* Digite nos valores o horario que o recurso irá desligar/ligar seguindo a logica do cron no caso do exemplo abaixo esta programado para desligar todo dia as 00:00 de segunda a sexta, caso tenha colocado os dados certos no cron logo abaixo ira mostrar a data da proxima ativação em seguinda os proximos dias que o cron será executado.
* Deixe desligado a opção de janela de tempo flexível
* Clique em Proximo

* Nessa parte selecionaremos o destino do cron no caso a função lambda correspondente para esse cron.
* Selecione APis usadas com frequência e Logo depois a API AWS Lambda Invoke

* Selecione a função do Lambda correspondente e clique em proximo

* Deixe o cronograma habilitado e na parte de permissões deixe selecionado para criar novo perfil e clique em proximo

* Revise as configurações e conclua.
* Refaça os passos para cada função lambda criada para sua correta execução nos horarios desejados
# Tagueamento dos Recursos
<p style='text-align: justify;'> Para segurança e especificação dos recursos a serem desligados/ligados o codigo filtra os recursos por Tags, aqui explicarei a parte de tagueamento no codigo e nos recursos e o caso especial da função lambda-start-autoscalling que precisa reconfigurar suas instancia de acordo que era antes de zera-la. </p>
## Explicando o tagueamento no codigo
### Instancias RDS e Instancias EC2
<p style='text-align: justify;'> Para Instancias RDS é necessario se atentar tag e valor abaixo, se tornando necessario acrecentar a tag: AgendamentoRDS com o valor: Sim na instancia RDS desejada. </p>
```
for tag in tags["TagList"]:
if tag['Key'] == 'AgendamentoRDS':
if tag['Value'] == 'Sim':
```
<p style='text-align: justify;'> Para Instancias EC2 é necessario se atentar a tag e valor abaixo, se tornando necessario acrecentar a tag: AgendamentoEC2 com o valor: Sim na instancia RDS desejada. </p>
```
def lambda_handler(event, context):
# Find all the instances that are tagged with Scheduled:True
filters = [{
'Name': 'tag:AgendamentoEC2',
'Values': ['Sim']
}
]
```
```
if tag['Key'] == 'AgendamentoEC2':
if tag['Value'] == 'Sim':
```
### Grupos de Autoscaling
<p style='text-align: justify;'> No caso de grupo de AutoScaling fazemos o codigo zerar as instancias em caso de desliamento e para religar reconfiguramos ela para seu estado original </p>
#### Stop
<p style='text-align: justify;'> No codigo de Stop é necessario se atentar a tag e valor abaixo, se tornando necessario acrescentar a tag: AgendamentoAutoscalling com o valor: Sim nos grupos desejados </p>
<p style='text-align: justify;'>Repare que estamos indicando no codigo que se sua capacitdade for maior q 0 ele ira zerar a DesiredCapacity=0, MinSize=0 e MaxSize=0, desligado assim as instancia envolvidas nesse grupo. </p>
```
for asg in auto_scaling_groups:
for t in asg['Tags']:
if t['Key'] == 'AgendamentoAutoscalling':
if t['Value'] == 'Sim':
if asg['DesiredCapacity'] > 0:
response = autoscaling.update_auto_scaling_group(AutoScalingGroupName=asg['AutoScalingGroupName'],DesiredCapacity=0,MinSize=0,MaxSize=0)
break
```
#### Start
<p style='text-align: justify;'> No codigo de Start é necessario se atentar a tag e valor abaixo, se tornando necessario acrecentar a tag: Agendamento"grupo" com o valor: Sim na instancia RDS </p>
<p style='text-align: justify;'> Repare no codigo que voltamos a ao estado original dos 3 grupos abaixo, como cada grupo tem suas particularidades é necessario criar um grupo de codigo para cada um indicando o DesiredCapacity, MinSize e MaxSize correto de cada grupo. </p>
```
for asg in auto_scaling_groups:
for t in asg['Tags']:
if t['Key'] == 'AgendamentoNode1':
if t['Value'] == 'Sim':
if asg['DesiredCapacity'] < 1:
response = autoscaling.update_auto_scaling_group(AutoScalingGroupName=asg['AutoScalingGroupName'],DesiredCapacity=1,MinSize=1,MaxSize=1)
break
for asg in auto_scaling_groups:
for t in asg['Tags']:
if t['Key'] == 'AgendamentoNode2':
if t['Value'] == 'Sim':
if asg['DesiredCapacity'] < 1:
response = autoscaling.update_auto_scaling_group(AutoScalingGroupName=asg['AutoScalingGroupName'],DesiredCapacity=4,MinSize=4,MaxSize=4)
break
for asg in auto_scaling_groups:
for t in asg['Tags']:
if t['Key'] == 'AgendamentoLupo':
if t['Value'] == 'Sim':
if asg['DesiredCapacity'] < 1:
response = autoscaling.update_auto_scaling_group(AutoScalingGroupName=asg['AutoScalingGroupName'],DesiredCapacity=1,MinSize=1,MaxSize=1)
break
```
## Tagueando recursos
<p style='text-align: justify;'> Por fim precisamos Taguear o recurso de acordo. </p>
* Acesse o rercuso desejado
* Localize a aba de Tags
* Clique em Gerenciar/editar Tags

* Clique Adicionar nova Tag
* Coloque o nome da chave de agendamendo e o valor
* Clique em salvar
