AWS

O que é AWS S3?

O AWS S3 (Simple Storage Service) é um serviço de armazenamento de arquivos, também chamados de objetos ou blobs, com foco em escalabilidade, disponibilidade, segurança e performance, tudo isso com um custo extremamente acessível.

O AWS S3 é um serviço distribuído globalmente dentro da sua conta da AWS, com uma organização em buckets regionais. Isso quer dizer que, diferente das EC2, VPC, e RDS, ao acessar o S3 pelo console da AWS, teremos uma visão global do nosso ambiente, ao invés de uma visão de uma única região.

Como comentado anteriormente, o AWS S3 se destaca pelo seu custo extremamente acessível. Você só paga pelo armazenamento e transferência de saída dos seus arquivos, com um custo aproximado de cinco centavos para cada gigabyte armazenado, o que é muito mais barato se comparado com o custo de disco EBS de uma EC2 tradicional.

Amazon Web Services (AWS) - Fundamentos
Curso de Amazon Web Services (AWS) - Fundamentos
CONHEÇA O CURSO

Quando usar o S3?

O S3 é um serviço de armazenamento bastante flexível, que suporta diversos casos de uso, como por exemplo:

  • Armazenamento de arquivos para aplicações web: como arquivos CSS e JavaScript do frontend da sua aplicação, e imagens enviadas pelos seus usuários via upload.

  • Arquivos de backups e logs: você pode armazenar arquivos privados, como logs de alguma aplicação, ou até mesmo backups de longo prazo do seu banco de dados, usados para fins legais.

  • Archive para um grande volume de dados: é possível armazenar muita coisa no S3. É possível armazenar objetos com até 5 terabytes e um bucket suporta um número ilimitado de objetos. Para grandes volumes de dados você pode utilizar o S3 Glacier e economizar ainda mais o custo de armazenamento.

  • Replicação de dados entre diferentes regiões: para aplicações distribuídas globalmente, você pode replicar buckets inteiros em diferentes regiões da AWS com um Batch Operation.

  • Hospedagem de sites estáticos: se você tem uma aplicação web que consiste só em arquivos estáticos, ou uma Single Page Applications (SPA), você pode utilizar somente o S3 para hospedar essa aplicação em completo.

Amazon Web Services (AWS) - RDS - Fundamentos
Curso de Amazon Web Services (AWS) - RDS - Fundamentos
CONHEÇA O CURSO

O que o S3 não faz

Embora seja um serviço flexível, o S3 não é indicado para todos os casos de uso. Existem serviços mais apropriados dentro da própria AWS para alguns cenários.

Com o S3 não temos uma hierarquia de arquivos. Isso é a principal diferença ao comparar o S3 com nosso disco local. Imagine que no S3 todos os arquivos são salvos em um único diretório. Não é possível distinguir se os seus arquivos estavam armazenados numa determinada pasta ou não.

Visualmente você até acha que existe uma organização por pastas, mas na verdade o que você está vendo é um separador lógico no nome do seu arquivo. Se a sua aplicação depende de operações em diretórios, como listar ou mover diretórios inteiros, o S3 pode não ser a melhor alternativa.

Você também não tem suporte direto ao Hadoop ou HDFS. Essas são soluções muito utilizadas em Big Data e você não consegue fazer a ingestão de dados do S3 para um cluster Hadoop com HDFS. Para isso você pode utilizar o Amazon EMR, um serviço especializado para data lakes com suporte a HDFS e hierarquia de diretórios. Uma curiosidade, o EMR utiliza o S3 por debaixo dos panos, entregando uma camada de compatibilidade com HDFS, mantendo um preço bem acessível.

Com o S3 você também não pode montar um bucket como um disco numa EC2 ou utilizá-lo como um compartilhamento de arquivos de rede. Para usar o S3 você pode utilizar APIs REST, o AWS CLI, ou até mesmo as SDKs disponíveis para diversas linguagens. Para esses casos de uso, prefira outros serviços, como o EBS para montagem de discos, ou o EFS para o compartilhamento de arquivos em rede.

Amazon Web Services (AWS) - EC2 - Fundamentos
Curso de Amazon Web Services (AWS) - EC2 - Fundamentos
CONHEÇA O CURSO

Conclusão

Essa foi uma breve introdução sobre o AWS S3. Vimos aqui algumas vantagens e quando utilizar esse serviço que é um dos principais da AWS. Nas próximas semanas será lançado o curso AWS S3 Fundamentos que irá abordar com muito mais detalhes esse serviço. Fiquem ligados e nos sigam nas nossas redes sociais, como Twitter, Instagram, Facebook e LinkedIn, para saber quando esse curso for lançado em primeira mão!

Primeiros passos com o Amazon Aurora

O Amazon Aurora é um banco de dados relacional da AWS compatível com MySQL e PostgreSQL. Esse banco de dados foi construído pensando em alta disponibilidade e escalabilidade. Nesse artigo vamos entender os benefícios do Amazon Aurora e como podemos criar nosso primeiro cluster.

Benefícios do Amazon Aurora

Anunciado em 2014, o Amazon Aurora é um banco de dados relacional oferecido como um serviço na AWS. O Amazon Aurora busca entregar um banco de dados com features e performance de soluções comerciais mas com um custo de uso de um banco de dados open source, não requerendo o uso de licenças para seu uso. Você só paga pela infraestrutura ao provisionar o Amazon Aurora.

Apesar de ser oferecido juntamente com o Relational Database Service (RDS), o Aurora tem um funcionamento diferente das outras engines disponíveis no serviço. Além das funcionalidades já oferecidas com as outras engines, como suporte a múltiplas availability zones, réplicas de leitura e backup automático, o Aurora estende esses recursos e adiciona suporte a bancos de dados globais replicados em diferentes regiões da AWS, réplicas que permitem escrita de dados e até mesmo instâncias serveless, o que economiza bastante a conta com bancos de dados que tem grande tempo de ociosidade ou pouco uso.

Amazon Web Services (AWS) - Elastic Beanstalk - Fundamentos
Curso de Amazon Web Services (AWS) - Elastic Beanstalk - Fundamentos
CONHEÇA O CURSO

Isso é possível graças ao funcionamento da camada de storage do Amazon Aurora. Todas as réplicas e a instância principal compartilham de um mesmo storage replicado, reduzindo drasticamente a latência necessária para atividades de replicação entre as instâncias, se comparado com os mecanismos de replicação nativa dos bancos de dados:

Arquitetura de storage do Aurora

Isso permite ao Amazon Aurora alcançar números impressionantes de escalabilidade e performance. Segundo a Amazon, o Aurora chega a ser cinco vezes mais rápido que um banco de dados rodando MySQL tradicional e até três vezes mais rápido que o PostgreSQL. Além disso, o Amazon Aurora suporta de até 15 replicas de leitura, tem um RTO (Recovery time objective) de um minuto e o tempo replicação global entre as regiões da AWS é de aproximadamente um segundo.

Tendo em vista todos esses benefícios, podemos pelo menos cogitar seu uso com aplicações que já usam MySQL ou PostgreSQL, não é mesmo? Para ajudar nesse processo vamos aprender como criar nosso primeiro cluster com Amazon Aurora.

Criando um cluster do Amazon Aurora

Para criar nosso cluster de Amazon Aurora vamos utilizar o AWS CLI. É preciso que você instale essa ferramenta na sua máquina e configure junto a sua conta da AWS. Confira como instalar e configurar o AWS CLI aqui no nosso blog.

Amazon Web Services (AWS) - Fundamentos
Curso de Amazon Web Services (AWS) - Fundamentos
CONHEÇA O CURSO

A primeira coisa que precisamos fazer é criar o security group que será associado ao nosso cluster:

aws ec2 create-security-group --group-name sg_aurora --description "Allow MySQL Aurora access from internet"
aws ec2 authorize-security-group-ingress --group-name sg_aurora --protocol tcp --port 3306 --cidr 0.0.0.0/0
aws ec2 describe-security-groups --group-names sg_aurora

# salva o id do security group para ser usado a seguir
sg_id=$(aws ec2 describe-security-groups --group-names "sg_aurora" --query "SecurityGroups[0].GroupId" --output text)

O security group vai funcionar como uma camada de segurança extra no nível da rede. Configure a porta de configuração apropriada (3306 para MySQL e 5432 para o PostgreSQL) e o mais importante, o CIDR permitido. Para fins didáticos, esse security group vai aceitar conexões de qualquer lugar da internet, porém é altamente recomendado que você limite para o endereçamento da sua rede, por exemplo.

O próximo passo é criar o cluster do Amazon Aurora. No cluster será possível obter as informações para fazer a conexão com o Amazon Aurora, bem como suas credenciais de acesso e versão do banco de dados compatível:

aws rds create-db-cluster \
--db-cluster-identifier sample-cluster-mysql-aurora \
--engine aurora \
--engine-version 5.6.mysql_aurora.1.22.2 \
--master-username username \
--master-user-password password \
--vpc-security-group-ids $sg_id

Por fim, enquanto nosso cluster é criado, podemos adicionar nossa primeira instância de banco de dados. Utilize o comando abaixo, observando o tamanho de instância desejado:

aws rds create-db-instance \
--db-instance-identifier sample-instance \
--db-cluster-identifier sample-cluster-mysql-aurora \
--engine aurora \
--db-instance-class db.t3.small

Com isso, após aguardar alguns minutos, nosso cluster estará criado e pronto para ser utilizado:

Cluster RDS sendo criado no console

Referências e mais informações

Vimos aqui como podemos criar nosso primeiro cluster com Amazon Aurora, mas existem muitas outras configurações que você pode explorar para criar o seu banco de dados. Abaixo você pode conferir a documentação da AWS que te mostra algumas variações de como você pode criar seu cluster, bem como as referências dos comandos utilizados:

Como instalar e configurar o AWS CLI

O AWS CLI é uma ferramenta em linha de comando capaz de gerenciar recursos na AWS. Com ela é possível listar todas as EC2 no seu ambiente, ou até mesmo criar um novo banco de dados com RDS com poucos comandos, tudo isso sem precisar acessar o console da AWS. Nesse artigo vamos acompanhar como é o processo de instalação e configuração do AWS CLI.

Instalação

Por ser uma ferramenta desenvolvida em Python e recentemente ter seu código fonte aberto, o AWS CLI pode rodar em qualquer sistema, seja uma distribuição Linux, macOS ou Windows. Para sua instalação no Linux ou no macOS podemos utilizar o pip, gerenciador de dependência do Python para instalar o AWS CLI com alguns poucos comandos.

Para sistemas Windows, você pode utilizar um instalador que, além de instalar o AWS CLI, inclui uma versão do Python compatível com o AWS CLI e também adiciona o caminho do executável na variável de ambiente de PATH do seu sistema, deixando tudo pronto para usar.

Amazon Web Services (AWS) - Fundamentos
Curso de Amazon Web Services (AWS) - Fundamentos
CONHEÇA O CURSO

Para instalar o AWS CLI nos sistemas macOS e Linux, você precisa atender alguns requisitos mínimos. O AWS CLI requer pelo menos o Pyhton nas versões 2.7 ou 3.4 e versões superiores, e também que o pip esteja instalado. Você pode verificar a versão do Pyhton e do pip instalados no seu sistema utilizando os comandos:

$ python --version
Python 3.6.9

$ pip --version
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)

Podemos ver aqui que os requisitos foram atendidos. Em alguns sistemas, o Python e o pip podem estar disponíveis com os binários python3 e pip3. Caso esse seja seu caso, lembre-se de executar os comandos a seguir substituindo pelo comando disponível no seu sistema.

Para instalar o AWS CLI, vamos rodar então o comando do pip abaixo:

pip install awscli --user

Depois de instalado, é preciso adicionar o caminho onde o pip salva os binários no PATH do sistema. Isso vai variar dependendo do shell que você estiver utilizando. No meu caso, estudo usando o Bash com o Ubuntu 18.04, então vou adicionar a seguinte linha no final do meu arquivo ~/.bashrc:

export PATH=~/.local/bin:$PATH

Depois de recarregar o .bashrc (isso pode ser feito com source ~/.bashrc) ou abrir novamente o terminal, o AWS CLI já estará disponível para ser executado:

$ aws --version
aws-cli/1.17.4 Python/3.7.4 Linux/4.14.133-113.105.amzn2.x86_64 botocore/1.13

Para sistemas Windows, basta baixar e utilizar o instalador disponível nesse link e após executar o instalador, o AWS CLI estará disponível tanto no cmd como no PowerShell:

C:\> aws --version
aws-cli/1.17.4 Python/3.7.4 Windows/10 botocore/1.13

Configuração

Agora que temos o AWS CLI instalado, vamos configurar a linha de comando junto com a nossa conta da AWS. Vamos precisar de um access key e uma secret key que pode ser obtido a partir do console da AWS.

Para isso, faça o login com seu usuário no console da AWS e no canto superior direito, procure seu nome de usuário e selecione a opção My Security Credentials:

Menu para acessar My Security Credentials

Em seguida, procure a opção Access keys e gere uma nova access key para utilizar com o AWS CLI:

Opção para gerar uma nova access e secret key

É muito importante que você não compartilhe com ninguém esse access e secret key, pois com essas informações, qualquer um terá os mesmos privilégios que o seu usuário possui para executar ações dentro da AWS, incluindo criar recursos ou até mesmo excluir tudo que tem no seu ambiente, o que não é uma boa idéia.

Depois de gerar o access e secret key, você pode configurá-lo com o comando abaixo:

$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json

Esse comando vai criar um diretório no home do seu sistema chamado .aws com dois arquivos: config e credentials. Esse último arquivo terá as informações que você acabou de utilizar com o comando aws configure:

# ls ~/.aws
config  credentials

# cat ~/.aws/credentials
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Ressaltando, é importante você também proteger esses arquivos que estão salvos no seu usuário, pois a partir deles também é possível ter ao access e secret key da sua conta.

Passo a passo

Veja no vídeo abaixo o passo a passo sobre como instalar e configurar o AWS CLI. Esse vídeo mostra na pratíca todos os passos descritos aqui nesse artigo:

Publicando uma aplicação .NET Core 3.0 no AWS Elastic Beanstalk

Hoje em dia uma realidade muito comum é utilizar soluções em nuvem para hospedar nossas aplicações. Provedores como a AWS facilitam esse processo oferecendo serviços especializadas para hospedar nossas soluções que se encaixam do modelo de Plataforma como um Serviço (PaaS).

Um desses serviços é o Elastic Beanstalk, que tem suporte nativo a várias linguagens de programação, como Java, Python, NodeJS, PHP, e inclusive .NET Core. Nesse artigo vamos aprender como publicar e configurar um projeto desenvolvido em ASP.NET Core 3.0 no Elastic Beanstalk.

Elastic Beanstalk

O Elastic Beanstalk é um serviço do tipo Plataforma como um Serviço da AWS. Através dele é possível criar ambientes escaláveis e com alta disponibilidade para aplicações web de forma simples e sem muitos conhecimentos aprofundados sobre infraestrutura. Isso o faz uma ótima solução para times pequenos que não tem especialistas em infraestrutura para gerenciar um ambiente na nuvem.

O Elastic Beanstalk suporta inúmeras linguagens, desde Java, NodeJS, PHP, Pyhton, até aplicações desenvolvidas com .NET Core. Recentemente foi adicionado suporte a versão 3.0 do .NET Core e em breve teremos suporte também ao .NET Core 3.1.

Requisitos para criar um projeto .NET Core 3.0

Vamos criar nesse artigo uma nova aplicação .NET Core 3.0 utilizando o Ubuntu 18.04. É preciso que você tenha o .NET Core SDK instalado na sua máquina.

Para instalar o .NET Core SDK, execute os comandos abaixo:

wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb

sudo add-apt-repository universe
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.0

Mais detalhes estão disponíveis na documentação oficial da Microsoft.

Criar uma aplicação ASP.NET Core MVC

Para acompanhar a publicação de uma aplicação no Elastic Beanstalk, vamos criar uma nova aplicação em ASP.NET Core MVC simples com o comando abaixo:

dotnet new mvc -o AspNetMvc

Isso irá criar um projeto na pasta AspNetMvc. Por enquanto não vamos alterar nada no projeto criado, em seguida veremos o que precisa ser configurado no seu projeto para publicá-lo no Elastic Beanstalk.

Publicando para o Elastic Beanstalk

O processo de publicação para o Elastic Beanstalk consiste em criar um build do nosso projeto e empacotá-lo num arquivo zip contendo algumas informações adicionais. Felizmente esse processo pode ser automatizado utilizando o AWS Extensions for .NET CLI. Sua instalação é feita como um utilitário global na sua máquina, assim você precisa instalá-lo só na primeira vez.

Para instalar o AWS Extensions for .NET CLI, execute o comando abaixo.

dotnet tool install -g Amazon.ElasticBeanstalk.Tools

Isso permitirá que você utilize o comando dotnet eb para trabalhar com o Elastic Beanstalk diretamente da linha de comando. Caso esse comando não funcione, verifique se o diretório do .NET CLI Tools está adicionado na variável de PATH da sua máquina.

export PATH="$PATH:~/.dotnet/tools"

Antes de efetuar a publicação da sua aplicação, você precisa configurar as credenciais da sua conta da AWS. Caso você tenha o AWS CLI instalado, execute o comando aws configure e preencha com as informações solicitadas:

~/
> aws configure
AWS Access Key ID [None]: ********************
AWS Secret Access Key [None]: ****************************************
Default region name [None]: us-east-1
Default output format [None]: json

Você também pode gerar um arquivo em $HOME/.aws/credentials com os seguintes conteúdo:

[default]
aws_access_key_id = ********************
aws_secret_access_key = ****************************************
Amazon Web Services (AWS) - Fundamentos
Curso de Amazon Web Services (AWS) - Fundamentos
CONHEÇA O CURSO

Por fim, você pode publicar sua aplicação usando o comando dotnet eb deploy-environment. Preencha as perguntas seguintes com o nome da application e environment desejados e, casos eles ainda não existam no Elastic Beanstalk, eles serão criados para você:

~/Code/AspNetMvc (master) ✔
> dotnet eb deploy-environment
Amazon Elastic Beanstalk Tools for .NET Core applications (3.2.0)
Project Home: https://github.com/aws/aws-extensions-for-dotnet-cli

Enter Elastic Beanstalk Application: (The name of the Elastic Beanstalk application.)
aspnetcore-app
Enter Elastic Beanstalk Environment: (The name of the Elastic Beanstalk environment.)
aspnetcore-dev
Enter AWS Region: (The region to connect to AWS services, if not set region will be detected from the environment.)
us-east-1

Para facilitar, você pode criar um arquivo chamado aws-beanstalk-tools-defaults.json com as configurações padrão utilizadas pelo dotnet eb

{
    "region": "us-east-1",
    "application": "aspnetcore-app",
    "environment": "aspnetcore-dev",
    "configuration": "Release"
}

Ao final desse processo, será exibido uma url para acessar o ambiente recém criado. Mas ainda não terminamos, agora vamos aprender como utilizar as configurações de ambiente presentes no Elastic Beanstalk.

Configurações de ambiente

Em uma aplicação .NET Core podemos definir valores dentro de appsettings.json e utilizá-los dentro do nosso código. Como exemplo, podemos adicionar uma configuração chamada Environment que irá conter o nome do nosso ambiente na home page do projeto. Para isso, vamos alterar alguns arquivos do nosso projeto.

No appsettings.json, adicionei a seguinte configuração:

"Environment": "Local"

Na minha view principal exibo essa mensagem:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<p>@Configuration["Environment"]</p>

Com isso, ao rodar dotnet run essa mensagem será exibida:

Por padrão, o .NET Core também vai carregar as variáveis de ambiente do sistema e seus valores podem sobrescrever o que está definido no appsettings.json. Ao rodar novamente nossa aplicação, mas alterando a variável de ambiente na sua execução, a mensagem será alterada:

~/Code/AspNetMvc
> Environment=Dev dotnet run

Configurações de ambiente no Elastic Beanstalk

Infelizmente o Elastic Beanstalk não faz isso por padrão com o .NET Core, o que pode frustrar alguns desenvolvedores (passei por isso na pele, nesse caso…), pois esse comportamento funciona em outras linguagens e plataformas do Elastic Beanstalk e só no .NET Core isso é diferente. Por ser um problema de longa data, presente desde a primeira versão do .NET Core disponível no Elastic Beanstalk, de acordo com essa pergunta no Stack Overflow, não acredito que esse problema será resolvido em breve.

Para contornar esse problema, podemos customizar o carregamento de configurações da nossa aplicação para ele poder consumir as configurações de ambiente do Elastic Beanstalk.

Instale a dependência TTRider.Aws.Beanstalk.Configuration no seu projeto executando o comando abaixo:

dotnet add package TTRider.Aws.Beanstalk.Configuration

Altere o Program.cs na definição do host builder, adicionando o seguinte método:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddBeanstalkParameters();
})

No meu caso, o arquivo Program.cs ficou assim:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using TTRider.Aws.Beanstalk.Configuration;

namespace AspNetMvc
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddBeanstalkParameters();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Após feita essas alterações, vamos realizar um novo deploy para o Elastic Beanstalk e alterar as configurações desse ambiente no portal da AWS.

Execute então dotnet eb deploy-environment e adicione uma configuração de ambiente para alterar o valor da mensagem.

Podemos ver abaixo como era o retorno da nossa home no Elastic Beanstalk antes e depois dessa alteração:

Finalizando

Com isso aprendemos como publicar nossa aplicação e como configurar nossa aplicação para utilizar as configurações de ambiente do Elastic Beanstalk. O código completo desse exemplo se encontra disponível no GitHub da TreinaWeb: https://github.com/treinaweb/treinaweb-dot-net-core-aws-beanstalk

Função para converter HTML para PDF usando PHP e wkhtmltopdf no AWS Lambda

Aqui na TreinaWeb sempre usamos o wkhtmltopdf para a conversão de HTML para PDF. É a base da geração dos nossos certificados, ementas, relatórios administrativos etc.

Um problema que sempre tivemos foi com o manejo do binário do wkhtmltopdf. Tínhamos que tê-lo disponível em qualquer instância EC2 que fôssemos utilizar. Quando uma nova versão era lançada, tínhamos que compilá-lo do zero novamente em todas as instâncias que o utilizassem, até mesmo localmente no ambiente de desenvolvimento. Para além disso, tínhamos com frequência alguns erros na geração do PDF por causa de algum pico de uso da CPU por conta dele.

PHP Básico
Curso de PHP Básico
CONHEÇA O CURSO

Resolvemos os nossos problemas de uma forma bem tranquila e altamente escalável usando Serverless. Fizemos o deploy de uma função no AWS Lambda especializada na conversão de HTML para PDF. E, para o nosso caso de uso, tudo o que precisávamos era receber o HTML e então retornar um Base64 do PDF. Notamos, também, uma melhor performance na geração dos PDFs.

Se você não conhece o que é Serverless, sugiro a leitura do artigo: Serverless: uma introdução.

E, para que você consiga acompanhar como o deploy da função que converte o HTML para PDF foi feito, é necessário que você tenha lido o artigo: Aplicação Serverless desenvolvida em PHP usando AWS Lambda.

O que utilizaremos daqui pra frente:

  • PHP: essa maravilhosa linguagem de programação.
  • Bref: ferramenta que faz com que seja simples o deploy de aplicações PHP Serverless.
  • Serverless Framework: framework completo para teste e deploy de aplicações nas principais plataformas Serverless do mercado.
  • AWS Lambda: onde faremos o deploy da função.

Como funciona a conversão do HTML para PDF?

O sistema de layers para o Lambda lançado pela AWS no ano passado mudou o jogo completamente. Com ele é possível que uma função use qualquer binário. É possível rodar até Cobol no AWS Lambda. E foi ele que permitiu que agora pudéssemos criar uma função que use o binário do wkhtmltopdf para a conversão de HTML para PDF. Não obstante, ele também é o responsável por podermos usar o PHP no AWS Lambda.

O que inicialmente tivemos que fazer foi compilar o wkhtmltopdf manualmente na nossa máquina para que pudéssemos criar um Layer dele no AWS Lambda pra ser linkado com a função. E, para isso, o artigo Compiling wkhtmltopdf for use inside an AWS Lambda function with Bref is easier than you’d think deixou tudo bem detalhado sobre como isso pode ser feito.

O código completo da função você encontra nesse repositório: KennedyTedesco/wkhtmltopdf-lambda-php. Mas eu vou passar pelos principais pontos aqui nesse artigo.

Primeiro de tudo, vamos avaliar o arquivo serverless.yml:

service: wkhtmltopdf

provider:
    name: aws
    region: sa-east-1
    runtime: provided
    stage: prod
    memorySize: 1024
    timeout: 60

plugins:
    - ./vendor/bref/bref

functions:
    html-to-base64-pdf:
        handler: index.php
        description: 'HTML to Base64 PDF'
        layers:
            - ${bref:layer.php-73}
            - 'arn:aws:lambda:sa-east-1:391960246434:layer:wkhtmltopdf-bin:1'

Veja em layers que temos declarado arn:aws:lambda:sa-east-1:391960246434:layer:wkhtmltopdf-bin:1, esse é o layer que compilamos manualmente e subimos para a AWS. É o layer do binário do wkhtmltopdf. É o que faz ele ficar disponível no diretório /opt/wkhtmltopdf.

PHP Intermediário
Curso de PHP Intermediário
CONHEÇA O CURSO

E a função propriamente dita é pura e simplesmente isso:

<?php

declare(strict_types=1);

require __DIR__.'/vendor/autoload.php';

use Knp\Snappy\Pdf;

lambda(static function (array $event) {
    $pdf = new Pdf('/opt/wkhtmltopdf');

    $options = [
        'encoding' => 'utf-8',
        'page-size' => 'A4',
        'margin-bottom' => 0,
        'margin-left' => 0,
        'margin-top' => 0,
        'margin-right' => 0,
        'disable-smart-shrinking' => true,
        'disable-javascript' => true,
    ];

    if (isset($event['options'])) {
        $options = \array_merge(
            $options,
            \json_decode($event['options'], true)
        );
    }

    $output = $pdf->getOutputFromHtml($event['html'], $options);

    if (empty($output)) {
        throw new \RuntimeException('Unable to generate the html');
    }

    return \base64_encode($output);
});

Usamos a library snappy que abstrai o uso do wkhtmltopdf. No mais, apenas recebemos o HTML e algumas opções para a geração do PDF, executamos o binário e retornamos um base64 do PDF gerado.

Se você tiver seguido o artigo Aplicação Serverless desenvolvida em PHP usando AWS Lambda, para fazer o deploy dessa função na sua infra da AWS, tudo o que você precisará é clonar esse projeto que disponibilizei no Github e então executar:

$ composer install --optimize-autoloader --no-dev

Vai baixar as dependências do projeto. Por fim:

$ serverless deploy

Fará o deploy da função no AWS Lambda.

E como a função é usada nas aplicações?

Não tivemos a necessidade de expor um endpoint do API Gateway para intermediar a execução da função (isso seria perfeitamente possível, principalmente se o serviço fosse uma API de acesso público). Fazemos a invocação direta dela pela SDK da AWS. E a SDK tem implementação para as principais linguagens. No caso do PHP seria algo como:

$lambda = new AwsLambdaClient([
  'version' => 'latest',
  'region' => 'sa-east-1',
  'credentials' => [
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
  ],
]);

$result = $lambda->invoke([
  'FunctionName' => 'wkhtmltopdf-prod-html-to-base64-pdf',
  'InvocationType' => 'RequestResponse',
  'LogType' => 'None',
  'Payload' => \json_encode([
    'html' => '<html>...',
  ]),
]);

$result = \json_decode($result->get('Payload')->getContents(), true); // base64 pdf

E se eu precisar gerar grandes arquivos PDF?

Se o seu caso de uso envolve gerar arquivos PDF de mais de 6MB, esse método da invocação direta não vai ser a melhor opção por causa do limite do tamanho do payload de retorno do AWS Lambda. Nesse caso, a melhor opção é você mudar a estratégia e, ao invés de retornar um base64 do PDF, você passar a salvá-lo em um bucket no S3. E a sua função retornaria um body com o link para acesso ao arquivo, por exemplo:

{
    "url": "https://seu-bucket.s3-sa-east-1.amazonaws.com/pdf/nome-do-arquivo.pdf"  
}

Inclusive, se for necessário, é possível até mesmo ter um bucket para receber os arquivos HTML que precisam ser convertidos e então a função seria invocada para convertê-los e então salvá-los em outro bucket de destino. Algo como:

  • O arquivo HTML é salvo no bucket arquivos-html, esse bucket está configurado para disparar um evento sempre que um novo arquivo é upado, evento esse que vai executar a função que criamos;
  • A função é executada, o PDF é salvo no bucket arquivos-pdf e a função retorna um body com o link para acesso ao arquivo PDF.
PHP Avançado
Curso de PHP Avançado
CONHEÇA O CURSO

As possibilidades são muitas, ademais, na AWS tudo se integra por eventos.

Até a próxima!

Introdução à Amazon Web Services (AWS)

A Amazon Web Services ou simplesmente AWS é um dos serviços de nuvem mais antigos e usados do mercado. A plataforma possui uma infinidade de serviços com soluções para várias áreas. Veja abaixo as principais categorias de serviços:

  • Computação
  • Armazenamento e Banco de dados
  • Análise de dados
  • Inteligência artificial
  • Internet das coisas
  • Serviços auxiliares da plataforma

Existem ainda outras categorias de produtos não descritas acima e provavelmente quando acessar a página da AWS vão existir mais algumas. A AWS trabalha continuamente na criação de novos produtos, isso permite ao cliente concentrar todos os serviços de nuvem em uma única plataforma, gerando uma série de facilidades de administração.

Amazon Web Services (AWS) - Primeiros Passos
Curso de Amazon Web Services (AWS) - Primeiros Passos
CONHEÇA O CURSO

Regiões e Zonas

A AWS possui datacenters em diversos locais do mundo. Esses datacenters nos permitem alocar recursos o mais próximos possível dos clientes das nossas aplicações. Eles também podem ser usados como backup, hospedando nossos recursos em um local e criando uma estrutura de alta disponibilidade em outro.

Uma região possui várias zonas que estão localizadas fisicamente próximas e possuem conectividade com baixa latência entre elas.

Regiões e zonas da AWS

Cadastro na plataforma

O cadastro na plataforma não requer nenhum configuração especifica. Basicamente se resume em preenchimento de dados e confirmação. Ele pode ser feito clicando aqui e possui os seguintes passos:

  • Preenchimento dos dados pessoais
  • Informação sobre meio de pagamento
  • Confirmação por telefone
  • Seleção do plano de suporte (com opção do plano gratuito)

Ao final do processo é possível começar usar os serviços imediatamente. A AWS possui cotas gratuitas em muitos serviços e em outros uma capacidade limitada por 12 meses depois da criação da conta para testes. Sempre fique atento aos recursos que criar dentro da sua conta, pois dependendo do serviço o valor pode chegar a milhares de dólares por mês, o que não vai ser uma surpresa muito agradável quando chegar a fatura do cartão.

Meios de acesso a plataforma

Toda plataforma de nuvem deve ter amplo acesso para consumo e administração dos serviços. No caso da AWS temos 3 meios principais de acesso:

  • Console – É a plataforma de gerenciamento web onde podemos gerenciar serviços, usuários e pagamentos.
  • AWS-CLI – É um utilitário de linha de comandos instalado no sistema operacional que podemos usar para gerenciar os serviços.
  • API HTTP – Uma interface apropriada para integração de sistemas com a plataforma. A AWS também possui uma série de SDKs que facilitam a integração com as principais linguagens de programação do mercado.

Escolhendo a região

A AWS separa os recursos criados dentro da plataforma por região. Se criar um recurso dentro da região us-east (São Paulo) só poderá visualizar aquele recurso novamente se estiver com essa região selecionada.

Selecionando a região no console da AWS

A imagem acima mostra a região selecionada dentro do console web. Sempre que estiver gerenciando recursos na AWS verifique se está com a região correta selecionada, um problema comum é procurar um recurso e não encontrar, pois ele está em outra região.

Serviços

Depois de logar no console web e selecionar a região que deseja trabalhar, provavelmente vai querer testar algum dos muitos serviços que a plataforma possui. O acesso aos serviços é feito através do item services da barra de navegação, eles ficam separados por categorias:

serviços na aws

As paginas especificas de servicós costumam mudar de serviço para serviço. Um padrão comum para é exibir primeiro a página de status do serviço (dashboard) e um menu lateral com a navegação entre as paginas:

dashboard AWS EC2

Continuação

A página acima é a primeira do serviço Elastic Compute Cloud conhecido como EC2. No próximo post vamos aprender o que é o EC2 e como utilizá-lo na prática.

Como se preparar para falhas em alguma região da AWS

Na terça-feira de carnaval, vários sites e aplicativos móveis que utilizam a AWS (Amazon Web Services) enfrentaram uma brusca interrupção na disponibilidade do serviço. A Web ficou, por algumas horas, “quebrada”. Para você ter ideia da dimensão do problema, foram afetados, de alguma forma, Trello, Quora, Wix, Giphy, Slack, Dropbox, Instagram, Vine e até mesmo o Github. Rumores eram de que toda a AWS estava offline mas, na verdade, os problemas afetaram apenas os servidores da região us-east-1 (N. Virginia), que é apenas uma das 14 regiões que a AWS possui.

PHP Avançado
Curso de PHP Avançado
CONHEÇA O CURSO

Segundo a própria Amazon a raiz do problema aconteceu no S3, o serviço de storage da empresa, um dos mais antigos e que serve como base para uma série de outros serviços da AWS, como o Elastic Block Store de volumes do EC2 que utiliza persistentemente os servidores do S3.

Por não afetar a zona sa-east-1 (localizada em São Paulo), a mais utilizada por serviços do Brasil e também devido a maioria dos desenvolvedores estarem pulando carnaval (ou não) o problema acabou não sendo tão divulgado.

Aqui no TreinaWeb, a nossa arquitetura está toda na AWS, especificamente na região de São Paulo (sa-east-1), a ideia é ter o mínimo de latência (apesar dessa ser uma das regiões mais caras de toda a AWS, você sabe, impostos praticados no Brasil e tudo mais). Da nossa parte, não tivemos nenhum problema. No entanto, o nosso gateway de pagamento usava alguns serviços daquela região americana e tivemos alguns contra-tempos limitados ao checkout. Mas, os alunos não deixaram de acessar os cursos e usufruir dos serviços do site.

O histórico, da identificação até a resolução do problema:

1) 11:49 AM PST We can confirm increased query failure rates when running queries and executing DDL statements in the in US-EAST-1 Region.

2) 1:59 PM PST We are starting to see recovery when running SQL queries in the US-EAST-1 region. We continue to see elevated error rates when executing DDL statements in the US-EAST-1 region.

3) 2:12 PM PST We continue to see recovery when running SQL queries in the US-EAST-1 region. We are also starting to see recovery when executing DDL statements in the US-EAST-1 region.

4) 3:25 PM PST We are able to execute SQL queries normally in the US-EAST-1 region. We continue to see increasing recovery when executing DDL statements in the US-EAST-1 Region.

5) 3:44 PM PST Between 9:37 AM and 3:23 PM PST we experienced increased error rates when running SQL queries and executing DDL statements in the US-EAST-1 Region. The issue has been resolved and the service is operating normally.

Por fim:

“The issue has been resolved and the service is operating normally.”

alt

Por mais que tudo tenha sido restabelecido, a Amazon apenas mitigou o problema. E isso não é nenhum demérito. Ela focou os esforços em fazer as coisas voltarem a funcionar. O que não falta é expertise para que, nos próximos dias, eles resolvam, de fato, os verdadeiros problemas estruturais/lógicos que lhes acometeram.

Esse tipo problema, especialmente na AWS, não é regra, é exceção. Mas, como nada está imune, o que podemos fazer para evitar que nossos aplicativos fiquem fora do ar em casos como esse? Abaixo duas válidas opções.

Active-Active ou Active-Passive usando Route53

O termo Active-Active não é especifico da AWS, na verdade ele está relacionado a alta disponibilidade. Basicamente, significa que o trafego é direcionado para um nó que está online ou balanceado entre outros que permanecem ativos, quando uma falha é identificada. Para usar essa solução é necessário uma cópia ativa da sua infraestrutura em outra região. O problema é que para a maioria das aplicações de pequeno porte isso é inviável, devido ao alto preço de ter a aplicação “espelhada” em mais de uma região.

A solução Active-Passive é parecida, porém um pouco mais em conta. Nela as instâncias redundantes só são colocadas completamente online caso o nó primário falhe. A desvantagem está no tempo extra após a queda do nó primário até as instâncias redundantes estarem prontas.

A AWS possui uma ferramenta chamada Route53 que ajuda a direcionar o tráfego automaticamente em caso de falha. Ela possui duas funções adicionais, uma chamada Health Check e outra chamada Traffic Polices. A primeira verifica se está tudo funcionando e a segunda permite definir o que fazer caso encontre algum problema. Essas duas configurações permitem implementar as estratégias acima descritas.

Replicação entre regiões

Caso você não queira usar as opções Active-Active ou Active-Passive, pode-se utilizar apenas a opção replicação entre regiões, nela todos os objetos e metadados como ACLs e tags são armazenados automaticamente em uma outra região escolhida na hora da ativação da opção. Isso pode ser suficiente caso aconteça algum problema no armazenamento da região principal.

Java - Arquivos e I/O API
Curso de Java - Arquivos e I/O API
CONHEÇA O CURSO

Concluindo

Apesar da AWS ser um dos serviços mais confiáveis do mercado, sempre que tratamos de softwares que precisam da alta disponibilidade é necessário pensar em alternativas que mitiguem bruscas interrupções, para evitar a perda de dinheiro, sem contar a credibilidade da sua empresa.

Caso queira saber como implementar os recursos acima citados, veja nesse excelente artigo So AWS Went Down. Here’s How You Can be Prepared If It Happens Again

Fontes complementares: theverge e datacenterdynamics

TypeScript - Primeiros Passos
Curso de TypeScript - Primeiros Passos
CONHEÇA O CURSO