Ligando/Desligando um servidor na AWS usando o Home Assistant

Olá, segue um breve tutorial de como integrei o Home Assistant com AWS para ligar/desligar um servidor hospedado no AWS EC2 com o Home Assistant

1) Criar usuário e permissão para o Home Assistant

  • No AWS * IAM, criar um grupo “home-assistant” e um usuário “home-assistant”.

  • O usuário deve ter acesso programático, e o sistema deve te dar o arquivo csv com as credenciais dele (Access key ID,Secret access key)

  • Atribuir o grupo “home-assistant” ao usuario “home-assistant”

  • Ir na configuração do grupo e adicionar a permissão “AWSLambdaRole” e “IAMReadOnlyAccess” ao grupo.

2) Configurar permissões ligar/desligar servidores EC2

Ainda no IAM, vá em Políticas, Criar Políticas, JSON, e coloque o seguinte código

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:Start*",
                "ec2:Stop*",
                "ec2:ModifyInstanceAttribute"
            ],
            "Resource": "*"
        }
    ]
}

Continue até salvar. Dê o nome’“StartStopEC2Server” para esta política

3) Criar função para a função Lambda que vai ligar/desligar o servidor

Ainda em IAM, vá em Funções, Criar Função

Escolha Política de confiança personalizada e coloque:

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

Na tela seguinte, em Adicionar permissões, escolha apenas “StartStopEC2Server” que você criou na etapa anterior

No nome da função, pode usar algo como “LambdaStartStopEC2ServerRole”

4) Criar função Lambda para ligar/desligar o servidor

No AWS Lambda, você vai criar duas funções, uma para desligar e outra para ligar o servidor.

Inicie criando uma nova função lambda (ex: “StartServer”), escolha Node.js 12.x, na opção “Alterar a função de execução padrão” escolha “Usar uma função existente” e selecione a função que criou no passo anterior (“LambdaStartStopEC2ServerRole”)

Depois de criada, coloque o seguinte código no arquivo index.js que vai aparecer:

var AWS = require("aws-sdk");
exports.handler = (event, context, callback) => {
    var ec2 = new AWS.EC2();
    var describeParams = { Filters: [
        {
            Name:"tag:LambdaControlType",
            Values: [
                "serverAutoStartStop"
            ]
        },
    ]};
    var instances = [];
    ec2.describeInstances(describeParams, function(err, data) {
        if (err) {
            console.log(err, err.stack);
        } else {
            console.log(data);
            for (var i = 0; i < data.Reservations.length; i++) {
                for (var j = 0; j < data.Reservations[i].Instances.length; j++) {
                    var instanceId = data.Reservations[i].Instances[j].InstanceId;
                    if (instanceId != undefined && instanceId != null && instanceId != "") {
                        instances.push(instanceId); 
                    }
                }
            }
            if (instances.length > 0){
                var instanceParams = { InstanceIds: instances };
                
                    // Starting Instances
                    console.log('INICIANDO instancias:');                
                    console.log(instanceParams);                
                    ec2.startInstances(instanceParams, function(err,data) {
                        if (err) {
                          console.log(err, err.stack);
                        } else {
                          console.log(data);
                        }
                    }); 
                
            }
       }
    });
};

Em seguide, duplique a função, renomeia para outro nome como “StopServer”, e coloque o seguinte código:

var AWS = require("aws-sdk");
exports.handler = (event, context, callback) => {
    var ec2 = new AWS.EC2();
    var describeParams = { Filters: [
        {
            Name:"tag:LambdaControlType",
            Values: [
                "serverAutoStartStop"
            ]
        },
    ]};
    var instances = [];
    ec2.describeInstances(describeParams, function(err, data) {
        if (err) {
            console.log(err, err.stack);
        } else {
            console.log(data);
            for (var i = 0; i < data.Reservations.length; i++) {
                for (var j = 0; j < data.Reservations[i].Instances.length; j++) {
                    var instanceId = data.Reservations[i].Instances[j].InstanceId;
                    if (instanceId != undefined && instanceId != null && instanceId != "") {
                        instances.push(instanceId); 
                    }
                }
            }
            if (instances.length > 0){
                var instanceParams = { InstanceIds: instances };
                
                    // Stopping Instances
                    console.log('INTERROMPENDO instancias:');                
                    console.log(instanceParams);                
                    ec2.stopInstances(instanceParams, function(err,data) {
                        if (err) {
                          console.log(err, err.stack);
                        } else {
                          console.log(data);
                        }
                    }); 

            }
       }
    });
};

Note que a única diferença está na função chamada, seja stopInstances ou startInstances

Note também que a tag “LambdaControlType” de valor “serverAutoStartStop” no meu caso é usada para determinar quais servidores ligar no EC2. Você pode usar qual texto quiser aqui, só precisa alterar no servidor como estou fazendo no passo seguinte.

5) Adicionar tags nos servidores que quer ligar/desligar com a função Lambda

Indo no console do EC2, selecione os servidores que deseja controlar, vá na aba Tags, Gerenciar Tags, e adicione a tag com chave “LambdaControlType” e o valor “serverAutoStartStop”.

6) Configurar a integração AWS no Home Assistant

Para configurar a chamada da função Lambda no Home Assistant, adicione o seguinte no arquivo configuration.yaml:

# AWS
aws:
  credentials:
    - name: Minha conta pessoal
      aws_access_key_id: AWS_ID
      aws_secret_access_key: AWS_SECRET
  notify:
    # use the first credential defined in aws integration by default
    - service: lambda
      region_name: sa-east-1
      aws_access_key_id: AWS_ID
      aws_secret_access_key: AWS_SECRET

Lembrando de substituir AWS_ID e AWS_SECRET para os valores do usuário home-assistant que você criou antes.
Note também que caso seus servidores estejam em outra região que não seja São Paulo, você precisa trocar o sa-east-1 acima também.
Obs: Eu fui obrigado a colocar as credenciais duas vezes, exatamente como no exemplo, senão a integração não funcionava

7) Adicionar script para ligar ou desligar o servidor no Home Assistant

Na sua instância Home Assistant, crie scripts para ligar/desligar as suas instâncias. Crie os scripts “Server Turn On” e “Server Turn Off”, coloque como única ação o serviço seguinte:

service: notify.aws_lambda
data:
  title: Ligar Servidor
  message: Start Server
  target: StartServer

e no outro

service: notify.aws_lambda
data:
  title: Desligar Servidor
  message: Stop Server
  target: StopServer

Lembre-se de usar no target os mesmos nomes das funções Lambdas que criou.

8) Adicionar switch para ligar e desligar o servidor

Nos arquivos de configuração configuration.yaml, coloque:

switch:
  - platform: template
    switches:
      servers_aws:
        friendly_name: Servers AWS
        turn_on:
          service: script.server_turn_on
        turn_off:
          service: script.server_turn_off

9) Pronto, agora é só usar o switch como se fosse um botão em qualquer lugar!

4 curtidas

Você criou algum vídeo ensinando esse tutorial ?