Tworząc manifest terraforma, korzystasz z jakiś nazw dla zasobów. Nie tych, które zostaną użyte gdzieś tam w chmurze, tylko tych, które używamy wewnętrzenie w kodzie. Lubię myśleć o tych programistycznych nazwach zasobów, jak o zmiennych w języku programowania. Nie są to w pełni zmienne, bo zmienne definiujemy w bloku variable {}, a ja tu odnoszę się do nazw z bloku resource „” „NAME” {}
W każdym razie, wymyślając nazwy tych zmiennych pracujemy, jak programista i staramy się wymyślić coś sensownego. Po pewnym czasie może się jednak okazać, że ta nazwa zmiennej nie pasuje i trzeba by ją zmienić.
Problem w tym, że jeśli nasz manifest już był uruchomiony, to w chmurze istnieją zasoby. Uruchomienie terraform apply spowodowałoby, że rzeczywiste zasoby z chmury zostaną usunięte i utworzone na nowo, tylko dlatego, że zmieniliśmy nazwę resource w kodzie terraform.
Obejściem jest wykorzystanie polecenia terraform state mv. Może ono zmienić nazwę zasobu w state file. Dzięki temu uzyskamy zgodność między:
- kodem manifestu terraform, który korzysta z nowej nazwy
- stanem, który skojarzy rzeczywiste zasoby chmury z nowymi nazwami zasobów
- samą chmurą, gdzie zasoby już są utworzone i nie trzeba ich usuwać i tworzyć na nowo
Ogólnie rzecz biorąc przed modyfikacją state należy sporządzić kopię state file. Można to zrobić dowolną metodą, ale da się też tak:
terraform state pull > my_copy.state.file
Potem uruchamiamy
terraform state list | grep '^OLD_NAME'
To pozwoli nam zrozumieć ile zasobów musi mieć dokonane zmiany. Może to być więcej niż jeden, zwłaszcza jeśli dany zasób składa się z innych zasobów, jak np. moduł
Potem można już uruchamiać polecenie
terraform state mv 'OLD_RESOURCE_NAME' 'NEW_RESOURCE_NAME'
State mv to sprytna komenda, która na czas modyfikacji pliku state blokuje go, uniemożliwiając jednoczesna edycję przez wiele procesów, jest to więc komenda bezpieczna.
Gdyby takich zasobów do zmiany było więcej to można użyć skryptu:
for addr in $(terraform state list | grep '^OLD_NAME'); do
new=$(echo "$addr" | sed 's/^OLD_NAME/NEW_NAME/')
echo "Moving: $addr -> $new"
terraform state mv "$addr" "$new"
done
Po wszystkim warto oczywiście uruchomić terraform plan. Dzięki temu przekonamy się, czy coś jeszcze zostało do zmiany





























