Nesse desafio configuramos dois S3 buckets, um privado e um com acesso público de leitura. Utilizando uma função Lambda baixamos dados (temperatura 2m acima da superfície e precipitação total) de reanálise meteorológica de uma API pública para guardá-los temporariamente em um dos buckets criados. (Observa se, que nesse processo os credenciais para acessar a API são guardados de forma segura dentro do SecretsManager.) Em seguida, utilizamos um Glue Job para processar os dados e extrair as linhas de contorno das temperatura média e precipitação total de cada dia e as salvamos em formato GeoJSON dentro do segundo S3 bucket. Também mostramos como configurar um AWS Glue Crawler para catalogar arquivos nos formatos .csv, .json, etc...
Como o desafio deixou bastante liberdade a respeito dos dados utilizados, decidi usá-lo para mostrar que consigo implementar os pipelines de dados que constumo implementar em servidores dedicados de forma serverless também.
- Código da função Lambda:
download_ERA5.py
(Runtime: Python 3.11) - Código fonte adaptado da biblioteca
cdsapi
em formato.zip
para o layer adicional da função Lambda:cdsapi_layer.zip
(Para runtime Python 3.11) - Código do job AWS Glue:
extract_contours_from_netcdf3.py
(Runtime: Python 3.9) - Arquivo wheel para a instalação de bibliotecas adicionais:
geojsoncontour-0.1-py3-none-any.whl
O pipeline implementado consiste em dois buckets, um bucket para input picsel-demo-input
com acesso restrito e um bucket para output picsel-demo-output
com acesso público de leitura. A função Lambda download_ERA5.py
que faz o download dos dados meteorológicos históricos tem como argumentos year
, month
e day
. Uma vez invocada com argumentos válidos, a função baixa os dados meteorlógicos históricos para a data solicitada e salva o arquivo em formato netcdf3
no input bucket. Como a função dever ter um gatilho manual, executei a função três vezes de forma manual para baixar os dados meteorológicso históricos para três dias diferentes (2023-09-01, 2023-09-02 e 2023-09-03). Exemplo: O arquivo resultante era5land_2023-09-01.nc
para o dia 2023-09-01 tem um tamanho moderado de 2,8 MB.
Vale ressaltar que foi necessário adicionar um layer contendo a biblioteca cdsapi
que simplifica o processo de fazer a requisição à API da CDS. Para isso, montei o arquivo cdsapi_layer.zip
.
Uma vez que populamos o bucket picsel-demo-input
com os arquivos contendo os dados meteorólogicos históricos em formato netcdf3
, podemos processá-los. Escolhi utilizar um job escrito em Python 3.9 (a runtime mais recente disponível no AWS Glue) extract_contours_from_netcdf3.py
para calcular as linhas de contorno das temperatura média e precipitação total de cada dia, plotá-las com matplotlib.pyplot
e salvá-las em formato GeoJSON
no bucket picsel-demo-output
. A transformação das linhas de contorno em formato GeoJSON
nos permite visualizá-las com ferramentas web, como por exemplo Leaflet
ou OpenLayers
. Foi necessário disponibilizar ao job algumas bibliotecas como geopandas
, shapely
e geojson
de forma manual. O arquivo wheel pode ser encontrado aqui.
Confira os resultados abaixo.
A configuração da função Lambda foi bem direta. Escolhi como runtime a versão estável mais recente da Python, a Python 3.11, a qual também utilizo no meu computador pessoal. Pensei bastante em como demonstrar minha capacidade de escrever uma função Lambda e optei por implementar uma função que faz uma requisição a uma API e, em seguida, baixa os dados requeridos para o bucket a ser criado. Para isso, a função lambda precisa de permissões de escrever no bucket em questão.
Como parte deste desafio, criamos dois buckets. Parte 1 pede para criar um bucket com acesso público de leitura. Este é o nosso bucket piscel-demo-output
.
- Crie uma função no AWS Lambda:
download_ERA5.py
- Escolha uma runtime, como Python 3.x. Runtime escolhida: 3.11
- A função deve ter um gatilho de execução manual. Executamos a função de forma manual, com argumentos escolhidos por nós.
- Atribua a função a um papel com permissões adequadas para interagir com o Amazon S3 e o AWS Glue, se necessário. Papel criado: "downloadERA"
- Configure um bucket no Amazon S3: Bucket: "picsel-demo-output"
- Nome do bucket: "seu-nome-bucket". Para adequar o nome à função do projeto, mudei o nome do bucket para "picsel-demo-output"
- Configure permissões de acesso para que o bucket seja público (somente leitura). Bucket público: "picsel-demo-output". Confira o acesso público aqui: https://picsel-demo-output.s3.sa-east-1.amazonaws.com/plots/temperature_contours_2023-09-01.png
Como parte deste desafio, criamos dois buckets. Parte 1 pede para criar um bucket com acesso público de leitura. Este é o nosso bucket piscel-demo-output
.
Criamos um AWS Glue job extract_contours_from_netcdf3.py
para ler os arquivos em formato binário netcdf3
do bucket piscel-demo-input
, extrair a informação que nos interessa, transformá-la em formato .geojson
e escrever os dados no bucket picsel-demo-output
.
O nosso AWS Glue job extract_contours_from_netcdf3.py
criou arquivos em formato JSON
no bucket picsel-demo-output
.
Podemos utilizar um AWS Glue Crawler para inserir esses dados em um banco de dados SQL.
- Crie um bucket separado no Amazon S3 para armazenar dados processados. Bucket privado: "picsel-demo-input"
- Crie um job no AWS Glue para transformar dados: Job:
extract_contours_from_netcdf3.py
- Use um crawler para catalogar os dados do seu bucket no S3 criado anteriormente. Montamos um crawler que consegue catalogar os FeatureCollections dos arquivos
.geojson
que foram gerados. - Crie um job que transforme os dados de alguma forma (por exemplo, aplicando uma simples limpeza ou agregação) e armazene o resultado no segundo bucket. Job:
extract_contours_from_netcdf3.py
. Confira a seção Resultados para saber mais sobre a transformação dos dados.
Utilizei esse serviço para rastrear fontes de erros no momento da implementação do pipeline e depois para monitorar o funcionamento correto do pipeline. Por exemplo, em um primeiro momento não estava claro como incluir bibliotecas de terceiros na função Lambda e no job do Glue. Logar os erros foi essencial para rastrear o que deu errado. Dessa forma consegui resolver os problemas que surgiram de forma célere.
- Configure o Amazon CloudWatch para monitorar:
- Execuções e erros da sua função no AWS Lambda.
- Ocorrência de erros nos jobs do AWS Glue.
- Configure o Amazon CloudTrail:
- Ative o CloudTrail para monitorar eventos na sua conta AWS.