top of page

Śledź nasze wpisy w social media

  • Instagram
  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
  • Zdjęcie autoraPiotr Kośka

Infrastruktura jako kod (IaaC) - cześć 1

W swoich projektach czy to zawodowych czy hobbystycznych często wykorzystuję terraform. O tym czym jest możesz przeczytać w jednym z moich artykułów.


Pozwól że, pokarze Ci moc tego narzędzia na przykładzie mojej konfiguracji z wykorzystaniem OVH i Digital Ocean. Zatem usiąść wygodnie i zaczynamy:


Terraform i OVH



Na początku musimy na czymś bazować, a więc trochę materiałów źródłowych. Zaczniemy zatem od takiej terminologii jak provider - więcej o tym możesz przeczytać w dokumentacji terraforma.


  • providers - to nic innego jak deklaracja dostawcy zewnętrznego oraz jakich zasobów można używać u tego dostawcy (ang provider)

Weźmy sobie na początek naszego dostawcę OVH - jego provider terraform OVH. Kod źródłowy privider ovh możemy znaleźć na stronie github. Właścicielem tego kodu jest OVH czyli to on napisał tego providera a nie sam HashiCopr. W samym rejestrze providerów możemy przeczytać i zobaczyć, że ma status partnera, to dobrze - bo nie chciałbym powierzać moich danych api (kluczy API) komuś obcemu - o api jeszcze sobie porozmawiamy.


Rejestr Terraform dla provider ovh
Provider OVH w registry Terraform

Zatem jeżeli chcemy użyć tego providera wystarczy w naszym projekcie dodać taka linijkę:

provider.tf

terraform {
  required_providers {
    ovh = {
      source = "ovh/ovh"
    }
  }
}

provider "ovh" {
  endpoint           = "ovh-eu"
  application_key    = "xxxxxxxxx"
  application_secret = "yyyyyyyyy"
  consumer_key       = "zzzzzzzzzzzzzz"
}

Możemy zobaczyć że będziemy tutaj potrzebować naszych danych z OVH API w postaci klucza dostępowego. Są to dane dość wrażliwe, wiec spróbujmy je ukryć. Tak by przypadkiem nie trafiły do naszego projektu w którymś z commitów.


terraform {
  required_providers {
    ovh = {
      source  = "ovh/ovh"
    }
}

variable "ovh_endpoint" {
  description = "OVH endpoint"
  sensitive   = true
}
variable "ovh_application_key" {
  description = "OVH application key"
  sensitive   = true
}   
variable "ovh_application_secret" {
  description = "OVH application secret"
  sensitive   = true
}
variable "ovh_consumer_key" {
  description = "OVH consumer key"
  sensitive   = true
}

provider "ovh" {
  endpoint           = var.ovh_endpoint
  application_key    = var.ovh_application_key
  application_secret = var.ovh_application_secret
  consumer_key       = var.ovh_consumer_key
}

Teraz wygląda lepiej. Dzięki czemu nasze wartości będą bezpieczne w osobnym pliku - którego np możemy dodać w wykluczeniach .gitignore - lub podawać jako zmienne do naszej komendy lub ręcznie jako wartości odpytywane przez polecenia terraform wybór należy do Ciebie. Nasze zmienne używane w terraform też będą w stanie naszej konfiguracji przechowywane zahaszowane. O stanie sobie jeszcze porozmawiamy...


Rekordy w zonie


Dodawanie rekordu czy zarządzanie obecnym jest też proste - spójrzmy na nasz provider i jego zasoby (bo jak już wiemy provider to nic innego jak lista możliwych zasobów dostępnych u dostawcy, którymi możemy operować). Wybierzmy z rejestru ovh_domain_zone_record


Mamy tu informacje i przykład jak używać tego zasobu, jakie ma argumenty i atrybuty referencyjne oraz jak zaimportować obecne już istniejące DNS zone records (rekordy DNS). Tylko skąd wziąć te ID.


Api OVH


Wszystkie te informacje od ID i do ktrego wpisu w naszej konfiguracji jest przypisany znajdziemy w API OVH - z racji że moje zony są w strefie EU logujemy się do odpowiedniego API OVH - jest to odpowiednio https://eu.api.ovh.com/

Szukamy interesującą nas domain/zone i pobieramy wartości za pomocą get (na stronie mamy specjalna funkcje, która nam to pobierze i wyświetli oraz mamy przykłady w innych językach programowania):



Potem dla wybranej domeny pobieramy ID - szukamy teraz domain /zone/{zoneName}/record - i tu będziemy mieli nasze ID dla wszystkich rekordów (lub możemy ograniczyć dla konkretnego typu - ja zalecam zaimportować wszystkie, i też tak zrobię).



Oczywiście import możemy sobie zautomatyzować kodem z mojego repo na bitbucket.org - ovh-terreform-import (tak, tak wiem literówka w nazwie repo, ale to specjalnie :) ).


DigitalOcean i stan tf w bazie danych


Mówiłem że porozmawiamy o stanie w terreform, myślę że już nadszedł czas na tym etapie. My będziemy wykorzystywać stan naszej infrastruktury zapisane w bazie danych. Można jednak wykorzystywać plik znajdujący się lokalnie na naszym dysku. Na przykład jak dopiero zaczynasz zabawę z terraform lokalny stan jest trzymany w pliku - jest tym domyślnym stanem. Zalecanym kiedy korzystasz samodzielnie z projektu (będzie to bardzo rzadko). Co w takim pliku znajdziemy, pojawi on się po wydaniu komendy terraform apply (ale poczekaj jeszcze - nie wydawaj tej komendy) pojawił się plik terraform.tfstate (pod żadnym pozorem nie należy go edytować ręcznie). To w nim terraform przechowuje wszystkie informacje na temat stworzonych zasobów i dzięki niemu jeśli jeszcze raz wykonamy skrypt, to nie zostaną utworzone nowe zasoby (ponieważ już istnieją). W przypadku gdyby ktoś ręcznie dodał np. nowy tag do ec2 to terraform plan by to pokazał jako różnicę którą zamierza usunąć.


Przy naszej aktualnej konfiguracji taki plik stanu trzeba by wrzucić do repozytorium by inni widzieli nasze zmiany. Nie jest to zalecanym wyjściem, głównym problemem jest to, że dwie osoby modyfikujące ten sam plik stanu terraforma nie widzą swoich zmian, przez co pojawia się wyścig, który wygrywa osoba uruchamiająca terraforma jako ostatnia. W gorszym przypadku operacja może się zakończyć błędem, którego przyczynę będzie nam ciężko określić. Tutaj też powinniśmy się zatrzymać i pomyśleć gdzie chcemy przechowywać nasz stan konfiguracji naszej infrastruktury w terraform. Możemy (dla uproszenia) przechowywać go lokalnie (minusy już poznałeś) lub zdalnie. Ja wybiorę tą drugą opcję i skorzystam z bazy PostgreSQL w Digital Ocean.



Usera oraz bazę danych do przechowywania naszego stanu można utworzyć z pgadmin lub z samego panelu postgresql w digitalocean:



Konfiguracja skryptów z repo i import


Na początek będą potrzebne nam dwa pliki .auto.tfvars (jeżeli nie chcemy podawać wartości podczas wywołania skryptu) i ovh.api (to na potrzeby naszego kodu do pobierania wartości/ i importu w python).


plik .auto.tfvars

ovh_endpoint           = "ovh-eu"
ovh_application_key    = ""
ovh_application_secret = ""
ovh_consumer_key       = ""

plik ovh.api

export OVH_ZONE="example.com"
export OVH_CONSUMER_KEY=''
export OVH_APPLICATION_SECRET=''
export OVH_APPLICATION_KEY=''
export OVH_ENDPOINT='ovh-eu'



Uzupełnimy nasze klucze wygenerowane w panelu api ovh - pamiętajmy tylko o ich wykluczeniu w naszym repo git. Dodatkowo nasze API klucze możemy uwarunkować do działania tylko z konkretnego IP, lub ograniczyć czasowo. Zalecam mix tych opcji, bo zakres uprawnień choć zawężony tylko do opcji /domain to dający wszystkie uprawnienia GET, POST, PUT i DELETE


Zanim przejdziemy do uruchomienia naszego skryptu, który wygeneruje nasze pliki konfiguracyjne wydajmy polecenie


terraform init

Zainicjalizuje to nasze moduły - i jeżeli korzystamy z naszego stanu zapisywanego w bazie danych utworzy nam nasze połaczenie.


Plik 00_zones.txt uzupełniamy o nasze zony, wpisy per linia na każdą zone (Domenę z naszego panelu OVH) zakończony pustą linią (bez tej pustej lini pomija ostatni rekord - to nie bug to feature :P )


Po uruchomieniu importu (jednorazowo source ovh.api a potem nasz skrypt ./00_generate_tf.sh) będziemy mieli nasze poszczególne rekordy w naszej zonie DNS umieszczone w osobnym pliku tf, dla każdej domeny - tak by czytelność została zachowana. Jest to też odzwierciedlenie naszej infrastruktury w OVH tam też każdy rekord to osobna strona do konfiguracji.




Skrypt wykona też odrazu import naszej obecnej konfiguracji w OVH do naszego stanu. Bez tej operacji każdy wpis nawet gdyby odwoływał się już do istniejącego rekordu to byłby traktowany jako nowy wpis i mielibyśmy duplikaty.


Po imporcie wydajmy polecenie:

terraform plan 

Które zwróci nam informacje o tym że nasz import i nasze pliki konfiguracyjne odpowiadają stanowi w naszej konfiguracji w OVH



Czas na zmiany


Może nie dokońca zmian a nowe rekordy - dodane ich nie stanowi problemu. Poniższy przykład pokazuje jak to zrobić dla rekordu txt


resource "ovh_domain_zone_record" "terraform-in-txt-technicznie-nietechnicznie-cloud" {
    fieldtype = "TXT"
    ttl = "0"
    zone = "technicznie-nietechnicznie.cloud"
    subdomain = ""
    target = "terraform-in"
}

Po dodaniu takiego rekordu teraz gdy wydamy terraform plan zobaczymy taka informacje (Ja dodałem trzy rekordy):


Możemy zobaczyć że nasze rekordy teraz pokazują się na liście jako do dodania. Zatem jed oddajmy poleceniem terraform apply. Na koniec tylko bedziemy musieli zaakceptować zmianę słowem yes i nasz rekord bedzie dodany.




Podsumowanie.


Jak widać praca z terraform może być prosta i przyjemna oraz rodzi to dużo korzyści w postaci panowania nad naszą infrastrukturą.


Daj znać czy wpis i materiał się podobał oraz czy chcesz więcej takich wpisów.

514 wyświetleń0 komentarzy

Ostatnie posty

Zobacz wszystkie

Śledź nasze wpisy w social media

  • Instagram
  • Facebook
  • Twitter
  • LinkedIn
  • YouTube

Poznaj terraform jedno z najepszych narzedzi do zarządzania infrastrukturą w kodzie (IaC) - w kursie tym przeprowadzam Cię przez proces instalacji i konfiguracji tego narzędzia.

bottom of page