Concrete | (2+2) Como e quanto custa colocar seu site no AWS S3
Nós utilizamos diversos serviços da AWS (Amazon Web Services), e não é apenas para nossos clientes, pelo contrário. Começamos usando dentro da Concrete para acelerar a disponibilidade dos ambientes de desenvolvimento e QA, e depois disso, começamos a utilizar para nossa própria infraestrutura.
Nossa parceria e prestação de serviços e revenda dos serviços da Amazon são consequências.
Dentre os serviços que usamos estão o próprio domínio da Concrete Solutions e este blog. Ambos rodando em cima de máquinas no EC2.
Tínhamos também, na mesma estrutura EC2 em Apache, a Landing Page sobre nossos serviços AWS (https://aws.concretesolutions.com.br). Mesmo sendo um gasto pequeno, nossas conversas internas sempre trazem oportunidade para evoluir, e nos pareceu desperdício ter um servidor para páginas que são essencialmente estáticas.
O site da Concrete Solutions foi parar no GitHub. O hosting do GitHub para projetos públicos é gratuito, e nem precisa ser totalmente estático uma vez que você pode usar Jekyll nas suas páginas.
Agora vamos deixar o GitHub para outro dia. O assunto é o hosting do S3.
Achamos que seria muito apropriado colocar nossa landing page sobre AWS na própria Amazon e, sendo possível, foi isso mesmo que fizemos. Movemos a página para o S3. Veja como fizemos abaixo.
O primeiro passo é criar um Bucket no S3.
Acesse o console do S3 e clique em Create a Bucket.
Crie o Bucket com o nome do domínio que você vai usar. No nosso caso, colocamos aws.concretesolutions.com.br.
Há um motivo duplo para colocar o nome do bucket igual ao do seu site. O primeiro tem relação com o suporte a CNAME do S3, e o segundo com a utilização do CloudFront para a entrega do site.
Em ambos os casos, as regras de nome são mais restritivas que as regras para nomear Buckets. Então, fique atento a isso.
É interessante deixar o log habilitado. As informações de acesso, por exemplo, somente ficarão acessíveis dessa forma.
Tendo criado o Bucket, precisamos habilitar o hosting. De dentro do console do S3, selecione as propriedades do seu novo Bucket criado e habilite o Website Hosting.
Nós marcamos o arquivo da home do site para ser o index.html, e no nosso caso, não há arquivo para erros customizado.
Então, se você acessar um arquivo que não existe no nosso site, verá a tela de erro 403 (forbidden) padrão do S3. Por exemplo, acessando: https://aws.concretesolutions.com.br/essearquivonaoexiste.html.
O próximo passo é fazer o upload dos seus arquivos estáticos para o site.
Com o site habilitado, e antes de fazer a mudança do nosso domínio nos servidores de DNS, já podemos testar.
Nas propriedades do Bucket existe um endpoint que deixa o seu site acessível sem um domínio customizado.
Agora só falta uma coisinha para subir: o site tem um formulário em PHP que envia um email para nós. Ou seja, não é estático! E agora ?
SDK Javascript e SNS
Felizmente, para nós há uma grande variedade de serviços, e há como contornar muitas das necessidades de páginas dinâmicas no nosso site. Mandar um e-mail de contato em um formulário não deveria ser complicado.
Uma forma de resolver a questão é utilizar o SNS para nos mandar um email e o SDK Javascript para fazer a comunicação entre o browser do cliente e o SNS.
Configurando o SNS
Acessando o console do SNS, o primeiro passo é criar um novo Tópico.
O site vai enviar mensagens para este tópico, então precisamos subscrever a este tópico de alguma forma.
O jeito mais simples é subscrever com uma conta de e-mail.
Não se esqueça de confirmar a subscrição na caixa de entrada do seu e-mail.
Depois disso, faça um teste publicando uma mensagem para esse tópico.
Uma vez configurado o tópico, podemos colocar no site nosso javascript para enviar mensagens. O javascript vai fazer com que o browser do cliente envie mensagens para o tópico que criamos. Assim conseguimos mandar um e-mail de contato usando um site totalmente estático.
O uso do javascript é bem fácil.
Comece por incluir na página em que você quer usar o SDK o seguinte script.
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.0.9.min.js"></script>
O passo seguinte é colocar suas credenciais de acesso.
É claro que você não quer que todo mundo possa usar a sua conta, então, o jeito mais fácil é criar um usuário para isso, com credenciais de segurança apenas com direito para publicar no tópico específico já criado.
Crie no console do IAM um usuário, gerando credenciais de acesso no processo de criação.
No item de segurança, escolha apenas o acesso ao SNS com a função Publish, e no ARN coloque os dados do tópico que você criou anteriormente.
Ou seja, a única funcionalidade que estas credenciais dão acesso é a de envio de mensagem para o tópico que você criou. Assim, ficamos tranquilos de incluir estas credenciais nos arquivos estáticos do site. Afinal, eles não têm grande utilidade além de mandar uma mensagem de e-mail.
A seguir, disponibilizamos estas credenciais para o javascript.
AWS.config.update({accessKeyId: 'IDdoAccessKeyDoUsuarioCriado'
, secretAccessKey: 'AccessKeyDoUsuarioCriado'});
Agora ficou fácil, é só pegar os valores desejados e montar a mensagem!
var sns = new AWS.SNS({params: {TopicArn: 'ARN_DO_TOPICO_SNS'}});
sns.publish({Message: str_var_da_mensagem}, function (err, data) {
console.log('Message published');
alert('Biutiful');
Veja aqui outros exemplos de como usar o SDK no Browser.
Agora que resolvemos a parte "dinâmica" do site e atualizamos os arquivos no S3, estamos prontos para apontar o domínio para nosso resultado final.
Route 53, why not ?
Agora só falta configurar nosso domínio no Route 53 para apontar para o novo site.
Para garantir uma latência ainda menor, nada melhor que habilitar o Cloudfront para o site.
Acesse o console do Cloudfront e crie uma nova distribuição.
No nosso caso, vamos fazer uma distribuição Web. A outra opção RTMP vai te ajudar em casos de streaming para Adobe Flash, utilizando este protocolo.
A próxima parece complicada, mas não é.
Fique atento para não criar uma distribuição do seu bucket, e sim do seu site. O autocomplete vai te apresentar o endereço do Bucket, cuidado. Para isso, coloque no Domain Name o Endpoint que vimos acima, o endpoint da opção de Static Website Hosting. E é só.
A sua preocupação maior ao usar o Cloudfront vai ser na verdade a invalidação de cache quando você mudar o seu site. Dúvidas sobre o Cloundfront ? Se houver alguma insegurança no uso, você pode deixar sem no início e ligar o serviço depois.
Isso é caro ?
É na verdade uma das soluções mais baratas que você pode ter para um site estático.
Ainda mais considerando a escalabilidade, latência e durabilidade disponível.
A qualidade final é muito grande pelo preço pago. Não precisa acreditar em mim. Vamos olhar para cada serviço:
A precificação do S3 leva em conta a região. Regiões diferentes tem preços diferentes. No caso deste site, pagamos $0,03/Gb. Há ainda um valor gratuito para os primeiros 5Gb. Ou seja, para este site o storage é gratuito.
Pagamos também pelos requests. Para os requests de administração (PUT, COPY, POST, or LIST Requests) a cobrança é de $0,005/1000 pedidos. Também nos encaixamos no free tier de 2.000 requests/mês.
Para os requests de GET os preços são de $0,004/10.000 pedidos, e a faixa gratuita de 20.000 requests. Duvido que nos custe mais que alguns centavos/mês para esta landing page.
O terceiro critério de cobrança para o S3 é a tranferência de dados.
Como o Cloudfront vai se encarregar da maior parte da transferência, nosso eventual custo deve ficar lá, e não aqui no S3. De qualquer forma, o custo de tranferência para o Cloudfront é de $0,02/GB. E para a Internet, o custo de tranferência fica em $0,12/GB (o 1o Gb é gratuito).
Na prática, com o Cloudfront configurado, nosso custo em S3 deve ficar menor que $0,10/mês.
A precificação do SNS vai depender muito de quais são as subscrições do seu canal.
O custo do 1o milhão de publicações é 0. A partir daí o custo é de $0.50/milhão de publicações. No nosso caso, as publicações vão custar pelo menos $0.50 centavos #soquenao, e também fica gratuito.
Para a entrega o custo será de $0.50/milhão para Push Mobile.
Para SMS o custo é de $0.75/centena.
No caso de email/email-JSON são $2,00/100.000 envios. A faixa gratuita é de 1.000 emails.
Ainda há envios via http ou para o serviço SQS.
Talvez seja o mais caro do nosso novo site, mas $2.00/mês ainda estão valendo.
Há também o custo de transferência de dados da mensagem, e que no nosso caso, certamente fica na quota gratuita de 1Gb/mês.
O serviço do Route 53
vai nos cobrar $0.50/mês por cada hosted zone. As queries ALIAS para o Cloudfront e para buckets são gratuitas. As outras queries, dependendo do tipo, custam $0.50/milhão ou $0.75/milhão. Não vou entrar em detalhes sobre o funcionamento do DNS em si, mas na prática não vamos ter tantos request para o DNS do site.
Agora sim, o cara que vai nos dar o prejuízo. O Cloudfront é que vai fazer a maior parte do trabalho e efetivamente servir o site estático para os clientes.
Lembrando que, tipicamente na AWS, pagamos pelos dados que saem da infra Amazon, e não pelos que entram.
No caso do Cloudfront, pagamos pelos dados que saem do S3 para cada CDN, e dos dados que saem dos CDN para os browsers dos clientes. De qualquer forma, com CDNs no Rio de Janeiro e em São Paulo, a latência do nosso site certamente será baixa para clientes aqui no Brasil.
A taxa de transferência do Brasil é a mais cara, mas mesmo assim, estamos falando de $0,25 para 10TB de transferência. Ok, é mais que o dobro dos $0,12 nos EUA, mas mesmo assim, acho que com uma moeda/mês pagamos essa.
Vamos também pagar pelos requests http e https, são $0,016 e $0,022 por 10.000 pedidos respectivamente.
Também nada que chame muito a atenção.
Temos uns centavos aqui, outros ali, mas quanto vai custar tudo ?
Para isso, podemos usar a calculadora AWS e somar todos os valores com o uso que vamos ter.
Veja a calculadora que fizemos para a nossa landing page https://aws.concretesolutions.com.br.
Com a estimativa de gastar no total $1,77/mês seguimos em frente. E agora nossa landing page é servida pela infraestrutura AWS.