<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <docs>https://blogs.law.harvard.edu/tech/rss</docs>
    <title>Data-Factory on FXShell - DevOps &amp; Sec</title>
    <link>https://fxshelll.github.io/tags/data-factory/</link>
    <description>Recent content in Data-Factory on FXShell - DevOps &amp; Sec</description>
    <image>
      <title>Data-Factory on FXShell - DevOps &amp; Sec</title>
      <link>https://fxshelll.github.io/tags/data-factory/</link>
      <url>fxshell.png</url>
    </image>
    <ttl>1440</ttl>
    <generator>Hugo 0.152.2</generator>
    <language>pt-br</language>
    <lastBuildDate>Sun, 10 May 2026 05:14:34 UT</lastBuildDate>
    <atom:link href="https://fxshelll.github.io/tags/data-factory/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Migração S3 - Azure Blob Storage com Ansible e Azure Data Factory</title>
      <link>https://fxshelll.github.io/posts/ansible-adf-migrate-s3-azure/</link>
      <pubDate>Fri, 08 May 2026 00:00:00 UT</pubDate>
      <dc:creator>Felipe da Matta</dc:creator>
      <guid>https://fxshelll.github.io/posts/ansible-adf-migrate-s3-azure/</guid>
      <description>Em um projeto de migração real, precisamos mover os dados de dezenas de buckets S3 de clientes para o Azure Blob Storage. O processo manual - criar o ADF no portal, configurar cada linked service, montar a pipeline, disparar e monitorar - era repetitivo e propenso a erro. A solução foi um único playbook Ansible que provisiona toda a infraestrutura e executa a cópia de ponta a ponta.
Objetivo do Lab Construir um playbook Ansible que automatiza completamente a migração de dados de um bucket AWS S3 para um container no Azure Blob Storage, usando o Azure Data Factory como motor de cópia. O playbook cria todos os recursos necessários, dispara a pipeline e faz polling do status até confirmar o sucesso (ou falha explícita).
</description>
      <content:encoded><![CDATA[Em um projeto de migração real, precisamos mover os dados de dezenas de buckets S3 de clientes para o Azure Blob Storage. O processo manual - criar o ADF no portal, configurar cada linked service, montar a pipeline, disparar e monitorar - era repetitivo e propenso a erro. A solução foi um único playbook Ansible que provisiona toda a infraestrutura e executa a cópia de ponta a ponta.
Objetivo do Lab Construir um playbook Ansible que automatiza completamente a migração de dados de um bucket AWS S3 para um container no Azure Blob Storage, usando o Azure Data Factory como motor de cópia. O playbook cria todos os recursos necessários, dispara a pipeline e faz polling do status até confirmar o sucesso (ou falha explícita).
Tecnologias Utilizadas Ansible é uma ferramenta de automação de infraestrutura sem agente. Ela executa tarefas em sequência, em formato YAML, sem precisar instalar nada nos servidores de destino. É amplamente usada para provisionar recursos em nuvem via CLI, configurar servidores e orquestrar fluxos de deploy.
Azure Data Factory (ADF) é o serviço de integração de dados da Microsoft. Ele permite criar pipelines visuais (ou via API/CLI) que copiam, transformam e movem dados entre fontes heterogêneas - como AWS S3 e Azure Blob Storage. O ADF escala automaticamente, tem retry nativo e gera logs detalhados para cada execução.
AWS S3 (Simple Storage Service) é o serviço de armazenamento de objetos da Amazon. Os dados ficam organizados em buckets, e o acesso externo é controlado por IAM com AccessKey e SecretKey.
Azure Blob Storage é o equivalente ao S3 na Azure. Dados são armazenados em containers dentro de uma Storage Account. Suporta acesso via connection string, Managed Identity ou SAS token.
az CLI é a interface de linha de comando da Azure. Permite criar e gerenciar recursos diretamente do terminal, sem usar o portal. O Ansible chama o az CLI via módulo command, que é a forma mais direta e sem dependências extras.
Arquitetura ┌─────────────────────────────────────────────────────────────────┐ │ AWS Account │ │ ┌─────────────┐ │ │ │ S3 Bucket │ ← s3:GetObject + s3:GetObjectVersion │ │ └──────┬──────┘ │ └─────────┼───────────────────────────────────────────────────────┘ │ │ HTTPS (LinkedService_S3 - AccessKey) ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Azure (Resource Group) │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Azure Data Factory (ADF) │ │ │ │ │ │ │ │ Dataset_S3 ──[CopyActivity]──► Dataset_Blob │ │ │ │ (BinarySource) (BinarySink) │ │ │ │ parallelCopies=4 / DIU=4 │ │ │ └──────────────────────────┬──────────────────────────────┘ │ │ │ │ │ │ LinkedService_BlobStorage │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ Storage Account: stdadosmigrados │ │ │ │ └── Container: dados-migrados │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ▲ │ ansible-playbook playbook.yml -e @vars.yml │ ┌─────────┴──────────┐ │ Control Node │ │ Ansible + az CLI │ └────────────────────┘ Componente Função S3 Bucket Origem dos dados. IAM com s3:GetObject e s3:GetObjectVersion Azure Data Factory Orquestra a cópia. Gerencia linked services, datasets e pipeline LinkedService_S3 Credencial do ADF para autenticar no S3 (AccessKey) LinkedService_Blob Credencial do ADF para gravar no Blob (connection string) Dataset_S3 Define o caminho de origem: bucket + prefixo Dataset_Blob Define o destino: storage account + container Pipeline CopyActivity Executa a cópia com parallelCopies=4 e DIU=4 Storage Account Conta de armazenamento Azure que recebe os dados Container Namespace dentro da Storage Account (equivale a um bucket) Como as Partes se Conectam O ADF age como intermediário inteligente: ele autentica no S3 usando as credenciais do IAM, lê os objetos (recursivamente, se configurado), e grava em paralelo no Blob Storage usando a connection string da Storage Account. A pipeline usa formato Binary em ambos os lados - isso preserva os arquivos como estão, sem transformação, o que é exatamente o que queremos em uma migração de dados brutos.
O Ansible não move nenhum dado diretamente. Ele é responsável por orquestrar o provisionamento de todos os recursos no az CLI e, ao final, fazer polling do runId da pipeline até receber Succeeded ou Failed.
Estrutura do Projeto ansible-adf-migrate-s3-azure/ ├── playbook.yml # playbook principal - tudo em um só arquivo ├── vars.yml # variáveis não-sensíveis (pode commitar) ├── vars_vault.yml # credenciais AWS - criptografar com ansible-vault └── diagrama/ ├── gerar_gif.py ├── ansible-adf-migrate-s3-azure.gif └── ansible-adf-migrate-s3-azure.html Pré-requisitos Antes de executar, você precisa:
az CLI instalado e autenticado (az login) Ansible instalado (pip install ansible) IAM user na AWS com permissões: s3:GetObject s3:GetObjectVersion ansible-vault para criptografar as credenciais AWS Preparando as Variáveis vars.yml - configure com os valores do seu ambiente:
resource_group: &#34;rg-migrate-s3-azure&#34; location: &#34;eastus&#34; storage_account_name: &#34;stdadosmigrados&#34; container_name: &#34;dados-migrados&#34; adf_name: &#34;adf-migrate-s3&#34; adf_pipeline_name: &#34;pipeline-s3-to-blob&#34; s3_bucket_name: &#34;meu-bucket-s3&#34; s3_region: &#34;us-east-1&#34; s3_prefix: &#34;&#34; # vazio = copia tudo; ou &#34;pasta/&#34; para subdiretório log_level: verbose vars_vault.yml - nunca commitar sem criptografia:
aws_access_key_id: &#34;AKIAIOSFODNN7EXAMPLE&#34; aws_secret_access_key: &#34;wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY&#34; Criptografar antes de qualquer commit:
ansible-vault encrypt vars_vault.yml Playbook - Explicação por Bloco O playbook está dividido em 9 tasks principais mais pre_tasks e post_tasks.
pre_tasks - Verificação de Ambiente pre_tasks: - name: Verificar az CLI instalado command: az --version changed_when: false failed_when: az_check.rc != 0 - name: Verificar login na Azure command: az account show changed_when: false failed_when: az_account.rc != 0 Falha imediatamente se o az CLI não estiver instalado ou se não houver sessão ativa. Economiza tempo debugando tasks que viriam depois.
Tasks 1-2 - Resource Group e Storage Account - name: &#34;[ 1/9 ] Criar Resource Group&#34; command: &gt; az group create --name {{ resource_group }} --location {{ location }} --output none - name: &#34;[ 2/9 ] Criar Storage Account&#34; command: &gt; az storage account create --name {{ storage_account_name }} --resource-group {{ resource_group }} --sku Standard_LRS --kind StorageV2 --access-tier Hot --output none - name: &#34;[ 2/9 ] Criar container com acesso privado&#34; command: &gt; az storage container create --name {{ container_name }} --account-name {{ storage_account_name }} --public-access off --auth-mode login --output none O container é criado com public-access off - o acesso é controlado pelo ADF via connection string, não por URL pública. Isso é diferente de quando você quer servir arquivos via CDN (nesse caso, --public-access blob).
Tasks 3-5 - ADF e Linked Services - name: &#34;[ 3/9 ] Criar Azure Data Factory&#34; command: &gt; az datafactory factory create --factory-name {{ adf_name }} --resource-group {{ resource_group }} --location {{ location }} - name: &#34;[ 4/9 ] Criar Linked Service - AWS S3&#34; command: &gt; az datafactory linked-service create --factory-name {{ adf_name }} --linked-service-name {{ adf_linked_s3_name }} --properties &#39;{ &#34;type&#34;: &#34;AmazonS3&#34;, &#34;typeProperties&#34;: { &#34;accessKeyId&#34;: &#34;{{ aws_access_key_id }}&#34;, &#34;secretAccessKey&#34;: { &#34;type&#34;: &#34;SecureString&#34;, &#34;value&#34;: &#34;{{ aws_secret_access_key }}&#34; }, &#34;authenticationType&#34;: &#34;AccessKey&#34; } }&#39; no_log: true # nunca logar credenciais O no_log: true garante que a task não apareça em logs de auditoria com as credenciais expostas. Sempre usar em tasks que passam segredos como argumento de CLI.
Tasks 6-7 - Datasets e Pipeline Os datasets definem o &ldquo;onde&rdquo; da cópia: o S3 como AmazonS3Location com bucketName e folderPath, e o Blob como AzureBlobStorageLocation com container. Ambos usam tipo Binary - sem transformação de dados.
A pipeline usa parallelCopies: 4 e dataIntegrationUnits: 4, que é o mínimo para extrair performance razoável em objetos médios. Para migrações de terabytes, aumentar para 32 DIUs.
Tasks 8-9 - Execução e Polling - name: &#34;[ 8/9 ] Executar pipeline&#34; command: &gt; az datafactory pipeline create-run --factory-name {{ adf_name }} --name {{ adf_pipeline_name }} register: pipeline_run - name: &#34;[ 9/9 ] Aguardar conclusão (polling 30s)&#34; command: &gt; az datafactory pipeline-run show --run-id {{ run_id }} --query status --output tsv until: pipeline_status.stdout.strip() in [&#39;Succeeded&#39;, &#39;Failed&#39;, &#39;Cancelled&#39;] retries: 120 delay: 30 O until com retries: 120 e delay: 30 cobre até 1 hora de execução. Para buckets muito grandes, aumentar retries.
Executando # 1. criptografar credenciais AWS ansible-vault encrypt vars_vault.yml # 2. executar o playbook ansible-playbook playbook.yml -e @vars.yml --ask-vault-pass # 3. verificar o resultado no portal # https://adf.azure.com Para testar sem criar recursos (dry-run não funciona com az CLI, mas você pode checar a sintaxe YAML):
ansible-playbook playbook.yml --syntax-check Após a migração, verificar os blobs via CLI:
az storage blob list \ --container-name dados-migrados \ --account-name stdadosmigrados \ --auth-mode login \ --query &#34;[].name&#34; \ --output table Monitoramento e Troubleshooting Sintoma Causa provável Solução AuthorizationFailure no linked service S3 IAM sem s3:GetObject Adicionar a policy no IAM user da AWS StorageErrorCode: AuthorizationFailure no Blob az CLI sem role no storage Atribuir Storage Blob Data Contributor ao usuário Pipeline travada em InProgress DIU insuficiente para o volume Aumentar dataIntegrationUnits na pipeline Pipeline terminated with status: Failed Erro na cópia de objeto específico Verificar logs no ADF Monitor: https://adf.azure.com az: command not found az CLI não instalado curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash retries exceeded no polling Pipeline demorou mais de 1h Aumentar retries no playbook Para Que Serve no Mercado Migrações de cloud são comuns em contextos de aquisição de empresa, mudança de provedor, ou consolidação de infraestrutura. Ter um playbook parametrizado para esse fluxo permite que o time de DevOps ou SRE replique a operação para N buckets com mínima intervenção - só ajusta s3_bucket_name, container_name e roda.
O ADF também é usado para sincronização contínua com triggers agendados, não só migração one-shot. O mesmo playbook pode ser adaptado para provisionar um trigger no ADF que executa a pipeline periodicamente.
Conclusão A combinação Ansible + ADF é mais robusta do que scripts de shell com aws s3 sync + azcopy porque o ADF gerencia o estado da cópia, faz retry automático em falhas transitórias e dá visibilidade detalhada no portal. O Ansible garante que toda a infraestrutura é declarativa, versionada e reproduzível - rodar duas vezes não cria recursos duplicados.
A migração real que deu origem a este lab copiou 10GB em aproximadamente 9 minutos com configuração padrão de 4 DIUs.
Referências Azure Data Factory - documentação oficial Copiar dados do Amazon S3 para o Azure Blob Storage az datafactory - referência CLI Ansible command module Azure Blob Storage - documentação Playbook Completo --- # ============================================================================= # Migração S3 → Azure Blob Storage via Azure Data Factory # Playbook: playbook.yml # Autor: fxshell # Uso: ansible-playbook playbook.yml -e @vars.yml --ask-vault-pass # ============================================================================= - name: Migração S3 → Azure Blob Storage via ADF hosts: localhost connection: local gather_facts: false vars_files: - vars_vault.yml # arquivo criptografado com ansible-vault vars: resource_group: &#34;rg-migrate-s3-azure&#34; location: &#34;eastus&#34; storage_account_name: &#34;stdadosmigrados&#34; container_name: &#34;dados-migrados&#34; adf_name: &#34;adf-migrate-s3&#34; adf_pipeline_name: &#34;pipeline-s3-to-blob&#34; adf_linked_s3_name: &#34;LinkedService_S3&#34; adf_linked_blob_name: &#34;LinkedService_BlobStorage&#34; adf_dataset_s3_name: &#34;Dataset_S3&#34; adf_dataset_blob_name: &#34;Dataset_Blob&#34; s3_bucket_name: &#34;meu-bucket-s3&#34; s3_region: &#34;us-east-1&#34; # Prefixo de objetos a migrar (vazio = tudo) s3_prefix: &#34;&#34; # Nível de log: verbose | normal log_level: normal # --------------------------------------------------------------------------- # PRÉ-REQUISITOS: verificar dependências antes de qualquer task # --------------------------------------------------------------------------- pre_tasks: - name: Verificar az CLI instalado command: az --version register: az_check changed_when: false failed_when: az_check.rc != 0 - name: Verificar login na Azure (az account show) command: az account show register: az_account changed_when: false failed_when: az_account.rc != 0 - name: Exibir subscription ativa debug: msg: &#34;Subscription ativa: {{ (az_account.stdout | from_json).name }}&#34; when: log_level == &#34;verbose&#34; # --------------------------------------------------------------------------- # BLOCO 1 - Resource Group # --------------------------------------------------------------------------- tasks: - name: &#34;[ 1/9 ] Criar Resource Group {{ resource_group }}&#34; command: &gt; az group create --name {{ resource_group }} --location {{ location }} --output none register: rg_result changed_when: &#39;&#34;Succeeded&#34; in rg_result.stdout or rg_result.rc == 0&#39; # --------------------------------------------------------------------------- # BLOCO 2 - Storage Account + Container # --------------------------------------------------------------------------- - name: &#34;[ 2/9 ] Criar Storage Account {{ storage_account_name }}&#34; command: &gt; az storage account create --name {{ storage_account_name }} --resource-group {{ resource_group }} --location {{ location }} --sku Standard_LRS --kind StorageV2 --access-tier Hot --output none register: sa_result changed_when: sa_result.rc == 0 - name: &#34;[ 2/9 ] Obter connection string do Storage Account&#34; command: &gt; az storage account show-connection-string --name {{ storage_account_name }} --resource-group {{ resource_group }} --query connectionString --output tsv register: sa_conn_string changed_when: false no_log: true - name: &#34;[ 2/9 ] Criar container &#39;{{ container_name }}&#39; com acesso privado&#34; command: &gt; az storage container create --name {{ container_name }} --account-name {{ storage_account_name }} --public-access off --auth-mode login --output none register: container_result changed_when: container_result.rc == 0 # --------------------------------------------------------------------------- # BLOCO 3 - Azure Data Factory # --------------------------------------------------------------------------- - name: &#34;[ 3/9 ] Criar Azure Data Factory {{ adf_name }}&#34; command: &gt; az datafactory factory create --factory-name {{ adf_name }} --resource-group {{ resource_group }} --location {{ location }} --output none register: adf_result changed_when: adf_result.rc == 0 - name: &#34;[ 3/9 ] Obter ID do Storage Account para ADF&#34; command: &gt; az storage account show --name {{ storage_account_name }} --resource-group {{ resource_group }} --query id --output tsv register: sa_id changed_when: false # --------------------------------------------------------------------------- # BLOCO 4 - Linked Service: AWS S3 # ADF precisa de access key + secret key com permissões s3:GetObject # e s3:GetObjectVersion no bucket de origem # --------------------------------------------------------------------------- - name: &#34;[ 4/9 ] Criar Linked Service - AWS S3&#34; command: &gt; az datafactory linked-service create --factory-name {{ adf_name }} --resource-group {{ resource_group }} --linked-service-name {{ adf_linked_s3_name }} --properties &#39;{ &#34;type&#34;: &#34;AmazonS3&#34;, &#34;typeProperties&#34;: { &#34;serviceUrl&#34;: &#34;https://s3.amazonaws.com&#34;, &#34;accessKeyId&#34;: &#34;{{ aws_access_key_id }}&#34;, &#34;secretAccessKey&#34;: { &#34;type&#34;: &#34;SecureString&#34;, &#34;value&#34;: &#34;{{ aws_secret_access_key }}&#34; }, &#34;authenticationType&#34;: &#34;AccessKey&#34; } }&#39; register: ls_s3_result changed_when: ls_s3_result.rc == 0 no_log: true # --------------------------------------------------------------------------- # BLOCO 5 - Linked Service: Azure Blob Storage # --------------------------------------------------------------------------- - name: &#34;[ 5/9 ] Criar Linked Service - Azure Blob Storage&#34; command: &gt; az datafactory linked-service create --factory-name {{ adf_name }} --resource-group {{ resource_group }} --linked-service-name {{ adf_linked_blob_name }} --properties &#39;{ &#34;type&#34;: &#34;AzureBlobStorage&#34;, &#34;typeProperties&#34;: { &#34;connectionString&#34;: &#34;{{ sa_conn_string.stdout | trim }}&#34; } }&#39; register: ls_blob_result changed_when: ls_blob_result.rc == 0 no_log: true # --------------------------------------------------------------------------- # BLOCO 6 - Datasets (origem S3 + destino Blob) # --------------------------------------------------------------------------- - name: &#34;[ 6/9 ] Criar Dataset origem - S3 Binary&#34; command: &gt; az datafactory dataset create --factory-name {{ adf_name }} --resource-group {{ resource_group }} --dataset-name {{ adf_dataset_s3_name }} --properties &#39;{ &#34;type&#34;: &#34;Binary&#34;, &#34;linkedServiceName&#34;: { &#34;referenceName&#34;: &#34;{{ adf_linked_s3_name }}&#34;, &#34;type&#34;: &#34;LinkedServiceReference&#34; }, &#34;typeProperties&#34;: { &#34;location&#34;: { &#34;type&#34;: &#34;AmazonS3Location&#34;, &#34;bucketName&#34;: &#34;{{ s3_bucket_name }}&#34;, &#34;folderPath&#34;: &#34;{{ s3_prefix }}&#34; } } }&#39; register: ds_s3_result changed_when: ds_s3_result.rc == 0 - name: &#34;[ 6/9 ] Criar Dataset destino - Blob Binary&#34; command: &gt; az datafactory dataset create --factory-name {{ adf_name }} --resource-group {{ resource_group }} --dataset-name {{ adf_dataset_blob_name }} --properties &#39;{ &#34;type&#34;: &#34;Binary&#34;, &#34;linkedServiceName&#34;: { &#34;referenceName&#34;: &#34;{{ adf_linked_blob_name }}&#34;, &#34;type&#34;: &#34;LinkedServiceReference&#34; }, &#34;typeProperties&#34;: { &#34;location&#34;: { &#34;type&#34;: &#34;AzureBlobStorageLocation&#34;, &#34;container&#34;: &#34;{{ container_name }}&#34; } } }&#39; register: ds_blob_result changed_when: ds_blob_result.rc == 0 # --------------------------------------------------------------------------- # BLOCO 7 - Pipeline de cópia S3 → Blob # --------------------------------------------------------------------------- - name: &#34;[ 7/9 ] Criar Pipeline de migração {{ adf_pipeline_name }}&#34; command: &gt; az datafactory pipeline create --factory-name {{ adf_name }} --resource-group {{ resource_group }} --name {{ adf_pipeline_name }} --pipeline &#39;{ &#34;activities&#34;: [ { &#34;name&#34;: &#34;CopyS3ToBlob&#34;, &#34;type&#34;: &#34;Copy&#34;, &#34;inputs&#34;: [ { &#34;referenceName&#34;: &#34;{{ adf_dataset_s3_name }}&#34;, &#34;type&#34;: &#34;DatasetReference&#34; } ], &#34;outputs&#34;: [ { &#34;referenceName&#34;: &#34;{{ adf_dataset_blob_name }}&#34;, &#34;type&#34;: &#34;DatasetReference&#34; } ], &#34;typeProperties&#34;: { &#34;source&#34;: { &#34;type&#34;: &#34;BinarySource&#34;, &#34;storeSettings&#34;: { &#34;type&#34;: &#34;AmazonS3ReadSettings&#34;, &#34;recursive&#34;: true } }, &#34;sink&#34;: { &#34;type&#34;: &#34;BinarySink&#34;, &#34;storeSettings&#34;: { &#34;type&#34;: &#34;AzureBlobStorageWriteSettings&#34; } }, &#34;parallelCopies&#34;: 4, &#34;dataIntegrationUnits&#34;: 4, &#34;enableStaging&#34;: false } } ] }&#39; register: pipeline_result changed_when: pipeline_result.rc == 0 # --------------------------------------------------------------------------- # BLOCO 8 - Disparar execução da pipeline # --------------------------------------------------------------------------- - name: &#34;[ 8/9 ] Executar pipeline de migração&#34; command: &gt; az datafactory pipeline create-run --factory-name {{ adf_name }} --resource-group {{ resource_group }} --name {{ adf_pipeline_name }} register: pipeline_run changed_when: pipeline_run.rc == 0 - name: &#34;[ 8/9 ] Capturar Run ID&#34; set_fact: run_id: &#34;{{ (pipeline_run.stdout | from_json).runId }}&#34; - name: &#34;[ 8/9 ] Exibir Run ID&#34; debug: msg: &#34;Pipeline iniciada - Run ID: {{ run_id }}&#34; # --------------------------------------------------------------------------- # BLOCO 9 - Aguardar conclusão e verificar status # Polling a cada 30s, timeout de 120 tentativas (≈ 1h) # --------------------------------------------------------------------------- - name: &#34;[ 9/9 ] Aguardar conclusão da pipeline (polling 30s)&#34; command: &gt; az datafactory pipeline-run show --factory-name {{ adf_name }} --resource-group {{ resource_group }} --run-id {{ run_id }} --query status --output tsv register: pipeline_status until: pipeline_status.stdout.strip() in [&#39;Succeeded&#39;, &#39;Failed&#39;, &#39;Cancelled&#39;] retries: 120 delay: 30 changed_when: false - name: &#34;[ 9/9 ] Falhar se a pipeline não completou com sucesso&#34; fail: msg: &gt; Pipeline terminou com status: {{ pipeline_status.stdout.strip() }}. Acesse https://adf.azure.com para detalhes do erro. when: pipeline_status.stdout.strip() != &#39;Succeeded&#39; - name: &#34;[ 9/9 ] Exibir resultado final&#34; debug: msg: | ============================================================ Migração concluída com sucesso! Origem : s3://{{ s3_bucket_name }}/{{ s3_prefix }} Destino : {{ storage_account_name }}/{{ container_name }} Run ID : {{ run_id }} ADF URL : https://adf.azure.com/en-us/home?factory=%2FresourceGroups%2F{{ resource_group }}%2Fproviders%2FMicrosoft.DataFactory%2Ffactories%2F{{ adf_name }} ============================================================ # --------------------------------------------------------------------------- # PÓS-TASKS: limpeza opcional de recursos temporários # --------------------------------------------------------------------------- post_tasks: - name: &#34;[ CLEANUP ] Listar blobs migrados para validação&#34; command: &gt; az storage blob list --container-name {{ container_name }} --account-name {{ storage_account_name }} --auth-mode login --query &#34;[].name&#34; --output table register: blob_list changed_when: false when: log_level == &#34;verbose&#34; - name: &#34;[ CLEANUP ] Exibir blobs migrados&#34; debug: msg: &#34;{{ blob_list.stdout }}&#34; when: log_level == &#34;verbose&#34; and blob_list is defined ]]></content:encoded>
    </item>
  </channel>
</rss>
