Utilizando o AWS Cloudfront como CDN no Moodle
Tags: aws, cloudfront, moodle
Published: 2022-04-23 12:36:25

Olá!

Hoje vou explicar como implementar o [AWS Cloudfront](https://aws.amazon.com/cloudfront/), serviço de CDN da AWS, em instalações do [Moodle](https://moodle.org/)...mas antes

### O que é CDN e qual vantagem tenho em usar ele?

O _Content Delivery Networks_, ou CDN, é um mecanismo de distribuição de conteúdo que tem como objetivo fazer a entrega de arquivos de forma mais eficaz, usando pontos de distribuição próximos aos usuários

### ...OK, mas no Moodle, o que isso faz de diferença?

Como qualquer outra aplicação web, o Moodle possui alguns arquivos estáticos, que quem faz essa distribuição comumente são as instâncias de aplicação, onde está sendo executado o PHP, e por conta disso, todo o tráfego de saída é da EC2, onde só nisso já contamos com uma economia, pois o tráfego de saída do Cloudfront é mais barato comparado ao da EC2, e ainda conta com [Free Tier para o Data Transfer Out](https://aws.amazon.com/cloudfront/pricing/?loc=ft#AWS_Free_Usage_Tier)

E além disso, como expliquei mais acima, o CDN tem como um dos objetivos fazer a entrega mais eficaz do conteúdo, logo, se sua instância estiver localizada, por exemplo, em Virginia (us-east-1) e seus usuários localizados no Brasil, se tivermos o Cloudfront na frente da entrega de conteúdo da aplicação, ela será feita nos [pontos de acesso do Cloudfront](https://aws.amazon.com/cloudfront/features/?whats-new-cloudfront.sort-by=item.additionalFields.postDateTime&whats-new-cloudfront.sort-order=desc), aumentando o tempo de resposta dessa entrega do seu conteúdo

Só vantagem né? Então agora vamos colocar a mão na massa!

### Pré Requisitos

Antes de tudo, vamos partir do princípio que você já tenha sua aplicação Moodle configurada (na AWS) e sendo executada normalmente, entregando seu conteúdo por um Load Balancer e o DNS tudo bonitinho...certo?

Para essa configuração, vamos criar os seguinte componentes:

- Cloudfront
- Bucket S3 para hospedagem dos arquivos estáticos

### Criando o Cloudfront

No serviço "Cloudfront" no console da AWS, clique em "Create Distribution"

Nesse primeiro passo, vamos criar a nossa primeira origem de dados, que será o Load Balancer, então em "Origin domain" selecione o seu Load Balancer

Em "Protocol", selecione o que você já esteja usando (recomendo utilizar HTTPS e marcar "Match viewer" para ele responder tanto na 80 como na 443)

O restante pode deixar como está

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dojie353rms6pcwrtw9x.png)

Na sessão "Default cache behavior", o único ponto que vamos mudar é o "Allowed HTTP methods" para permitir todos os verbos, selecionando "GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE" e marcando o "OPTIONS"

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfo0434lyw9tdf0pvk3n.png)
 
Em "Settings", vamos adicionar o endereço da aplicação em "Alternate domain name (CNAME) - optional" e caso esteja usando SSL (espero que sim!), selecione o seu certificado em "Custom SSL certificate - optional"

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvrixub9luvvpegnnb26.png)
 
Pronto, pode clicar em "Create Distribution" e aguardar finalizar o deploy...mas ainda não acabou, temos ainda mais algumas coisinhas para configurar

### Adicionando o Behavior do S3

Após nosso Cloudfront ser "deployado", vamos criar a origem apontando para o S3, mas antes precisamos enviar nossos arquivos estáticos para o bucket que criamos na etapa de pré-requisitos

Como temos limites da quantidade de behaviors que podemos cadastrar, vamos enviar somente os arquivos que mais tem requisições dentro do moodle

No seu servidor, instale e configure o [AWS CLI](https://aws.amazon.com/cli/) caso ainda não tenha feito, e dentro do diretório onde está o source do seu moodle, execute o comando:

```
# Vamos criar um diretorio temporario
mkdir tmp_cloudfront

# Busca e copia somente os arquivos com as extensoes abaixo
find . -type f -iregex '.*\.\(css\|gif\|html\|htm\|jpg\|js\|scss\|png\|svg\|ttf\|woff2\)' -exec cp --parents {} tmp_cloudfront \;

# Envia os arquivos para o bucket S3
aws s3 sync tmp_cloudfront/ s3://CAMINHO DO SEU BUCKET/

# Remove o diretorio temporario
rm tmp_cloudfront
```

Pronto, agora precisamos criar nossa origem no Cloudfront, e para isso, no console da AWS dentro do serviço Cloudfront, clique na sua distribuição (que criamos na etapa anterior) e vá na aba "Origins" e clique em "Create origin"

Em "Origin domain", selecione o bucket S3 que você criou, em "S3 bucket access" selecione "Yes use OAI (bucket can restrict access to only CloudFront)" e clique em "Create new OAI" e em "Bucket policy" selecione "Yes, update the bucket policy". O restante pode manter do jeito que está

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14pop8f7sjoaw9q18u3x.png)

Uma vez com nossas origens cadastradas, vamos cadastrar os behaviors! Essa é a parte mais chatinha do processo...Vá na aba "Behaviors" e clique em "Create behavior"

Nesse processo, vamos cadastrar os behaviors referente a entrega de arquivos estáticos do Moodle que são feitas pelo PHP, então vamos cadastrar 8 behaviors:

- lib/*.php/*
- lib/editor/tinymce/plugins/loader.php/*
- theme/yui_combo.php
- theme/*.php/*
- /pluginfile.php*
- plugins/loader.php/*
- draftfile.php/*
- *.php

Todos eles apontando para seu Load Balancer em "Origin and origin groups" e em "Allowed HTTP methods" selecionado "GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE" com "OPTIONS" selecionado

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r42zxyvuf1iyg840qk14.png)

Alem disso, vamos modificar o "Cache key and origin requests", alterando para "Legacy cache settings", onde no "Headers" vamos deixar com "Include the following headers" e em "Add header" vamos adicionar "Host"; Em "Query strings" e "Cookies", selecione "All"

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zoa0jcil0hynbablw1jp.png) 

E agora, vamos criar todos os behaviors para todas as extensões dos arquivos estáticos que enviamos para o nosso S3, então a única parte que irá mudar em cada etapa é a "Path pattern", onde devemos colocar a extensão correspondente, por exemplo: _*.css_, _*.png_, etc...

Em "Origin and origin groups" vamos selecionar nosso bucket S3, o restante podemos manter do jeito que está

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qcuu9tq9n09yuta20qw1.png)

Muito importante seguir a ordem de cadastrar, deixando no topo os behaviors que vão ser entregues pelo PHP e depois os estáticos, senão podemos ter problema na ordem de entrega do conteúdo

Vai ficar mais ou menos assim quando você finalizar de cadastrar todos os behaviors

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pio2u0d049addoavzmjb.png)

E pronto! Seu Cloudfront está configurado! Agora basta modificar seu DNS para responder no "Distribution domain name"

### Uma última coisa bem importante...os Deploys!

Caso você instale um novo plugin ou faça alguma alteração no seu código fonte, é necessário atualizar esses arquivos também no seu bucket S3

Além disso, você vai precisar fazer uma invalidação do cache para refletir as novas alterações, e para isso basta entrar na sua distribuição, ir em "Invalidations" e "Create invalidation", e no "Add object paths" podemos colocar para invalidar todo o cache, colocando _/*_

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0q04nqrkls7ugcf3wl26.png)
 

_Até mais e muito obrigado pela Leitura! Ah, e se sentiu falta de alguma informação, algo que possa estar errado ou se quiser tirar dúvidas, fiquem a vontade de comentar!_ :smiley: