1
resposta

[Sugestão] Atributo user_data (Terraform)

Comecei recentemente o modulo de Fundamentos de IAC no curso de DevOPS e notei algo interessante na aula "Criando arquivos com Terraform". O professor inicialmente ensina a como executar comandos bash de forma mais automatizada usando código dentro do terraform, então ele diz que para criarmos o mesmo cenário que criamos manualmente de forma mais automática teríamos que usar um atributo chamado user_data dentro do bloco resource{}.

Veja bem, a minha EC2 (Instancia) já estava criada, visto que estava realizando ela para estudos e testes nas aulas anteriores, então comecei a praticar o que havia sido ensinado na aula, criei o user_data de forma idêntica a como o professor havia feito e pra minha surpresa ao usar o terraform apply o retorno me deu 0 add, 1 modify and 0 destroyed.

Isso me fez pensar o porque não realizou alterações na minha instancia e porque a do professor teve um resultado totalmente diferente do meu, no qual retornou 1 add, 0 modify and 1 destroyed. Após um tempo de pesquisa vi que o user_data só faz alterações em novas instancias, obrigatoriamente no 1 boot dela, creio que muitos alunos na grande maioria do caso está tentando realizar um processo de update com o user_data, o que não irá acontecer nunca, porque o atributo não foi feito pra isso.

Para você esfriar a cabeça, tente destruir a sua instancia, ir em resource{}, usar o user_data e criar novamente a instancia usando o terraform apply, dessa forma você vai ver que, como é o 1 boot dela vai executar normalmente os comandos designados e inserir o titulo na pagina.

Espero que tenha ajudado a quem está nesse modulo, pois ficou bem superficial a forma como o atributo foi apresentado.

1 resposta

Olá amigo.
Obrigado por compartilhar seu aprendizado.
Sua análise está absolutamente correta e toca em um dos pontos que mais gera confusão para quem está começando com Terraform e AWS.
Você teve uma excelente percepção de "depuração" ao notar a diferença entre o comportamento do seu console (1 modify) e o do professor (1 destroyed, 1 add).
Aqui está um detalhamento técnico sobre por que isso acontece e como você pode melhorar essa abordagem:
Por que sua instância não foi recriada? (O "Pulo do Gato")
No Terraform, o comportamento de um atributo depende do que a API da AWS permite.
User Data nativo: Por padrão, o campo user_data na AWS pode ser editado sem interromper a instância.
Por isso o Terraform marcou como "1 modified".
Ele simplesmente atualizou o texto que está lá nas configurações da máquina, mas a AWS não executa esse script novamente em máquinas que já estão ligadas.
A diferença do Professor: Provavelmente, o código do professor ou a versão do provider da AWS que ele utilizou tinha um comportamento onde alterações no user_data forçavam a substituição do recurso.
Como melhorar a sua solução no Terraform
Embora "destruir manualmente" funcione, o objetivo do Terraform é que o código controle o estado.
Existem formas de forçar o Terraform a destruir e recriar a máquina automaticamente sempre que você mudar o script de inicialização.

  1. Use o atributo user_data_replace_on_change
    Nas versões mais recentes do provider da AWS no Terraform, você pode adicionar uma linha que resolve exatamente o seu problema.
    Isso força o ciclo "Destroy/Create" que você mencionou:
hcl
resource "aws_instance" "app_server" {
  ami                         = "ami-0c55b159cbfafe1f0"
  instance_type               = "t2.micro"
  user_data                   = <<-EOF
                                #!/bin/bash
                                echo "Página Atualizada" > index.html
                                EOF

  # ESTA LINHA É A CHAVE:
  user_data_replace_on_change = true 
}

Com user_data_replace_on_change = true, sempre que você alterar uma letra no seu script, o Terraform entenderá que a modificação não é suficiente e fará o taint (destruição e recriação) da instância automaticamente.
2. Entenda a diferença entre Provisionamento e Gerenciamento de Configuração
Sua conclusão está correta: User Data é para o "Primeiro Boot" (Provisionamento).
Se o seu objetivo no dia a dia for atualizar o conteúdo de um site sem derrubar o servidor, o Terraform/User Data não é a ferramenta ideal para essa tarefa específica. Para isso, usamos:
Ansible: Para entrar na máquina ligada e alterar arquivos.
CI/CD: Para fazer o deploy do novo código.
Você acabou de aprender na prática um dos conceitos mais importantes de IaC: Infraestrutura Imutável.
Em vez de consertar uma máquina velha, nós a destruímos e criamos uma nova, exatamente como o código manda.
Quer que eu te mostre como usar o comando terraform taint para forçar essa recriação sem precisar mudar o código?
Comente ai!
Bons estudos.