Gerenciar o upload de arquivos estáticos, como ativos de sites, configurações ou documentos, para o Azure Blob Storage é uma tarefa comum em projetos de infraestrutura como código (IaC). Este guia demonstra como usar o Terraform para automatizar o envio de arquivos e diretórios inteiros para um contêiner de Blob do Azure, utilizando a função fileset, que simplifica a gestão de conteúdo dinâmico.
Utilizando a Função fileset no Terraform
A função fileset do Terraform é essencial para enumerar arquivos em um determinado caminho que correspondem a um ou mais padrões. Ela retorna um conjunto de nomes de arquivo regulares, permitindo que o Terraform itere sobre eles. Isso é particularmente útil para carregar múltiplos arquivos sem preicsar listá-los individualmente.
Para ilustrar, vamos considerar uma estrutura de projeto onde nossos arquivos Terraform estão em um diretório e o conteúdo a ser carregado está em outro:
.
├── main.tf
└── files_to_upload/
├── index.html
└── css/
└── style.css
Primeiramente, assumimos que um Grupo de Recursos, uma Conta de Armazenamento e um Contêiner de Blobs já foram provisionados ou são definidos em outras partes da sua configuração Terraform. O foco aqui é o recurso azurerm_storage_blob que será usado para o upload.
O bloco de código a seguir utiliza for_each em conjunto com fileset para percorrer todos os arquivos dentro do diretório files_to_upload e subdiretórios, carregando-os para o contêiner de armazenamento:
resource "azurerm_storage_blob" "conteudo_web_estatico" {
for_each = fileset(path.module, "files_to_upload/**/*") # Padrão para incluir subdiretórios
name = trimprefix(each.key, "files_to_upload/")
storage_account_name = local.nome_conta_armazenamento # Variável local ou referência
storage_container_name = local.nome_container_blob # Variável local ou referência
type = "Block"
source = each.key
}
Neste exemplo:
for_each = fileset(path.module, "files_to_upload/**/*"): Itera sobre todos os arquivos dentro defiles_to_uploade seus subdiretórios (**/*). Opath.modulegarante que o caminho seja relativo ao módulo atual.name = trimprefix(each.key, "files_to_upload/"): Define o nome do blob no Azure. A funçãotrimprefixremove a parte do diretório local do caminho do arquivo (files_to_upload/), garantindo que o nome do blob seja apenas o caminho relativo dentro do diretório de origem (ex:index.htmloucss/style.css).storage_account_nameestorage_container_name: Referenciam nomes de recursos ou variáveis locais que devem ser previamente definidos.source = each.key: Aponta para o caminho do arquivo local que será carregado.
Detecção de Alterações no Conteúdo do Arquivo
Por padrão, o Terraform pode não detectar alterações no conteúdo de um arquivo se seu nome e caminho permanecerem os mesmos. Para garantir que o Terraform atualize um blob quando o conteúdo do arquivo local correspondente mudar, podemos usar o argumento content_md5 em conjunto com a função filemd5.
A função filemd5(path) calcula o hash MD5 de um arquivo local. Ao atribuir este valor ao content_md5 do blob, o Terraform compara o hash atual do arquivo local com o hash armazenado para o blob no estado. Se houver uma diferença, o Terraform detectará uma alteração e recarregará o arquivo.
resource "azurerm_storage_blob" "conteudo_web_estatico" {
for_each = fileset(path.module, "files_to_upload/**/*")
name = trimprefix(each.key, "files_to_upload/")
storage_account_name = local.nome_conta_armazenamento
storage_container_name = local.nome_container_blob
type = "Block"
<strong>content_md5 = filemd5(each.key)</strong> # Garante a detecção de alterações no conteúdo
source = each.key
}
Com essa adição, qualquer modificação no conteúdo de index.html ou style.css será detectada, e o Terraform aplicará a atualização ao blob correspondente no Azure na próxima execução de terraform apply.
Práticas Recomendadas
Após concluir seus experimentos ou quando os recursos não forem mais necessários, é uma boa prática destruir os recursos provisionados para evitar custos desnecessários. Execute terraform destroy para remover o grupo de recursos, a conta de armazenamento e os blobs criados.