Construir uma contenção observável
O laboratório prepara dois diretórios de trabalho com um backend local que aponta ao mesmo caminho absoluto de state. Um recurso terraform_data é substituído apenas no ambiente temporário. Durante a criação, um helper Python local escreve um marcador e espera por uma libertação explícita, com prazo máximo. Esse marcador estabelece o momento em que a primeira execução está ativa. Só então o coordenador inicia os comandos concorrentes. Assim, a contenção não depende de acertar numa janela curta por acaso. O provisioner serve exclusivamente para controlar o ensaio; não representa uma recomendação de executar configuração de produção através de scripts.
Identificar o titular antes de intervir
Com o primeiro apply ativo, existe informação de lock com identificador, versão e tipo de operação. O segundo diretório tenta plan e recebe erro de aquisição; o identificador apresentado corresponde ao lock observado. O ficheiro de state mantém os mesmos bytes entre o início e o fim dessa tentativa rejeitada. Num incidente fictício, reúne esses dados com o executor e o responsável da mudança. Um terminal desligado ou uma pessoa indisponível não demonstram que o processo acabou. A existência do processo e do marcador é verificada diretamente no ensaio; em produção, a evidência tem de vir do executor real.
O prazo pertence a quem espera
Uma nova tentativa usa lock-timeout de um segundo e termina sem adquirir o lock. O guião verifica que o primeiro processo continua ativo e que ninguém pediu a sua libertação. O timeout limita a espera do segundo comando; não cancela o trabalho do titular nem converte automaticamente o lock em órfão. Ao gerir uma janela curta, distingue três decisões: aguardar dentro do limite permitido, adiar a operação ou investigar uma execução que parece parada. Escolher uma destas opções exige contexto sobre a mudança em curso. A duração observada neste computador não constitui um compromisso de latência de um backend remoto.
Esperar e voltar a observar o estado
O coordenador inicia outro plan com uma espera mais longa e confirma a mensagem de aquisição de lock, mantendo ambos os processos ativos. Depois cria o marcador de libertação. O primeiro apply termina e o plan que esperava consegue continuar. O plano resultante contém no-op porque lê a configuração já satisfeita pelo titular. Esta sequência não é uma fila operacional completa: não testa justiça entre múltiplos candidatos nem prioridades de mudança. Demonstra apenas que este comando esperou e planeou depois da libertação. A equipa deve interpretar o novo resultado, em vez de assumir que a intenção anterior continua a exigir uma alteração.
Ler um ficheiro não é obter uma visão final
Enquanto o apply está suspenso no helper, o coordenador consegue ler diretamente o ficheiro de state usando a mesma identidade do sistema operativo. Nesse ponto controlado da substituição, a lista gravada de recursos está vazia, embora o processo continue ativo. Este resultado não demonstra que a operação terminou ou que não existem efeitos em curso. Também mostra que o lock observado não bloqueia uma leitura arbitrária de bytes por um processo com acesso ao ficheiro. Permissões e confidencialidade precisam de controlos próprios. O ensaio não testa outro utilizador, ACLs, um serviço remoto ou uma garantia de snapshot durante uma escrita.
Fechar a investigação sem forçar a concorrência
Depois da libertação, os dois diretórios leem o mesmo identificador de recurso e o valor completed. A informação temporária de lock desaparece e os processos próprios terminam. Estes são critérios concretos de fecho do laboratório, não prova de saúde de um serviço cloud. Numa ocorrência real, acrescenta reconciliação funcional e registo de quem pode iniciar a operação seguinte. A documentação restringe force-unlock ao próprio lock quando a libertação automática falhou; não é a resposta normal a uma execução ativa. O exercício não usa force-unlock nem lock=false e não simula morte abrupta ou falha de energia.
# Run the isolated workshop with the exact supported CLI.
python3 content/labs/terraform-coordination/run.py /absolute/terraform /tmp/new-coordination-evidence.json
# The workshop coordinates its own processes; do not improvise on shared state.
# A competing plan uses a bounded acquisition wait:
terraform plan -input=false -lock-timeout=15s
# Inspect the holder and current target before choosing a retry.
Dois diretórios apontam ao mesmo state; o segundo plan é bloqueado enquanto o primeiro apply permanece ativo.
Armadilhas comuns
Tratar timeout como cancelamento do titular; confundir diretório com state separado; usar um lock como prova de confidencialidade.
Tópicos relacionados: Planos guardados e aprovação · Recuperação após execução parcial
Um lock coordena operações sobre um state. A decisão operacional exige conhecer o titular, o destino e o trabalho ainda em curso.
Referência: State locking and force-unlock boundaries · Terraform v1.16 concepts; official documentation consulted 2026-09-30; provider and backend capabilities must be confirmed