Terraform i Azure – przykład

Wprowadzenie

Podstawy Terraforma i konfiguracji środowiska mamy już za sobą, więc możemy przejść do bardziej rozbudowanego przykładu. W tym wpisie zobaczysz, w jaki sposób przygotować infrastrukturę pod prostą aplikację webową działającą w Azure. Z wykorzystaniem Terraforma utworzymy takie zasoby jak App Service Plan, czy bazę danych.

Zmienne Terraform

W poprzednim wpisie pokazałem, w jaki sposób zacząć przygodę z Terraform i Azure. Jeśli nie czytałeś/czytałaś to zachęcam do nadrobienia zaległości – Terraform i Azure. Przykład w tamtym wpisie był bardzo prosty i sprowadzał się do utworzenie grupy zasobów (Resource Group) w Azure.

Zanim przejdziemy do tworzenia bardziej rozbudowanego przykładu, chciałbym najpierw wprowadzić nowe pojęcie z Terraforma, które ułatwi nam późniejszą pracę. Zmienne, o których mowa, pozwolą nam tworzyć parametryzowane szablony infrastruktury. Przydaje się to szczególnie wtedy, gdy będziemy mieli kilka różnych środowisk tworzonych z tego samego kodu infrastruktury; na przykład środowisko testowe, UAT, czy produkcyjne.

Aby skorzystać ze zmiennych, musimy w pierwszej kolejności utworzyć definicje zmiennej. W przykładzie utworzę plik variables.tf, w którym będą znajdowały się definicje zmiennych. Zaczniemy od utworzenia pierwszej prostej zmiennej, w której określimy nazwę środowiska (dev, test, prod i tym podobne). Plik variables.tf będzie wyglądał tak:

variable "env" {
type = string
default = "__env__"
}
view raw variables.tf hosted with ❤ by GitHub

Za pomocą bloku variable określamy nową zmienną, gdzie „env” to nazwa zmiennej, której później będziemy używać. W bloku określamy dwie wartości: typ zmiennej (type) oraz domyślną wartość (default). Jest to odpowiednio string oraz __env__. Domyślna wartość może wydawać się trochę dziwna, ale jest ona już przygotowana do automatycznego stawiania infrastruktury z wykorzystaniem Azure DevOps. Omówię to w kolejnym wpisie.

Darmowy kurs Visual Studio

Pracując z setkami programistów, zauważyłem, że większość osób nie pracuje efektywnie w Visual Studio. W skrajnych przypadkach korzystali z kopiowania z wykorzystaniem menu Edit. Wiem, że to dziwne, ale naprawdę niektórzy tak pracują. Dlatego postanowiłem stworzyć kurs Visual Studio – aby pomóc koleżankom i kolegom w efektywniejszej pracy.

Przygotowałem 30 lekcji e-mail, w których pokażę Ci, w jaki sposób pracować efektywniej i szybciej w Visual Studio. Poznasz dodatki, bez których nie wyobrażam sobie pracy w tym IDE.

Po więcej informacji zapraszam na dedykowaną stronę kursu: Darmowy Kurs Visual Studio.

Quiz C#

Ostatnio przygotowałem również quiz C#, w którym możesz sprawdzić swoją wiedzę. Podejmiesz wyzwanie?

Użycie zmiennych

Mając już przygotowaną zmienną, możemy ją już użyć. Dostęp do zmiennych mamy za pomocą słowa kluczowego var, gdzie po kropce podajemy nazwę zmiennej. Na przykład „var.env”.

Poniżej znajduje się fragment kodu, który utworzy nam grupę zasobów, gdzie w nazwie właśnie użyłem zmienną określającą środowisko:

resource "azurerm_resource_group" "resource_group" {
name = "onlin-rg-${var.env}"
location = "westeurope"
}
view raw rg.tf hosted with ❤ by GitHub

Zmienna została użyta do zbudowania nazwy grupy zasobów. Wartość „onlin” w nazwie określa nazwę wymyślonej aplikacji, „rg” to skrót od resource grup i ostatni człon to właśnie nazwa środowiska, która pochodzi ze zmiennej env. W przypadku środowisk test grupa zasobów będzie nazywać się onlin-rg-test, a środowiska produkcyjnego onlin-rg-prod.

Terraform umożliwia nam jeszcze utworzenie plików tfvars, w których będą znajdować się już konkretne wartości zmiennych. Plik ten możemy wykorzystać podczas wykonywania komend Terraforma i wartości zmiennych z niego nadpiszą wartości domyślne, które podaliśmy podczas definicji zmiennej.

Na przykład dla środowiska developerskiego moglibyśmy mieć plik dev.tfvars, w którym będą używane wartości zmiennych dla tego środowiska. Na przykład:

env = "dev"
view raw dev.tfvars hosted with ❤ by GitHub

W pliku tfvars podajemy tylko wartości zmiennych w formie „nazwa = wartość”.

Aby wykorzystać tak utworzony plik musimy skorzystać z przełącznika -var-file podczas wykonywania komend Terraform. Na przykład:

terraform apply -var-file="dev.tfvars"

Powyżej omówione zmienne to tak zwane Input variables, które służą właśnie do parametryzowania szablonu infrastruktury. Terraform udostępnia jeszcze dwa dodatkowe rodzaje zmiennych: Output oraz Local. Ale to już temat na inny wpis.

Web Aplikacja w Azure

Po poznaniu zmiennych możemy przejść do utworzenia bardziej rozbudowanej infrastruktury w Azure. Jako przykład wykorzystamy prostą aplikację webową, którą będę chciał hostować w Azure. W ramach aplikacji utworzę takie elementy infrastruktury:

  • App Service Plan
  • App Service
  • Application Insight – podpięty zostanie pod utworzony App Service
  • Sql Server
  • Sql Database
  • Konfiguracja firewall dla Sql Servera

Do utworzenia powyższych zasobów wykorzystam kilka zmiennych, które umożliwią mi ich sparametryzowanie w taki sposób, by można było mieć trochę inną konfigurację poszczególnych środowisk. Plik ze zmiennymi wygląda tak:

variable "env" {
type = string
default = "__env__"
}
variable "resource_location" {
type = string
default = "__resource_location__"
}
variable "app_service_plan_size" {
type = string
default = "__app_service_plan_size__"
}
variable "app_service_plan_tier" {
type = string
default = "__app_service_plan_tier__"
}
variable "database_sku" {
type = string
default = "__database_sku__"
}
variable "sql_server_login" {
type = string
default = "__sql_server_login__"
}
variable "sql_server_password" {
type = string
default = "__sql_server_password__"
}
view raw variables2.tf hosted with ❤ by GitHub

Wykorzystane zmienne to:

  • env – nazwa środowiska np. dev, test, prod
  • resource_location – region w Azure np. westeurope
  • app_service_plan_size – rozmiar App Service Plan – np. B1
  • app_service_plan_tier – poziom cenowy App Service Plan – np. Basic
  • database_sku – rozmiar bazy np. Basic
  • sql_server_login – login administratora w SQL Server
  • sql_server_password – hasło administratora w SQL Server

Dodatkowo przygotowałem jeszcze plik dev.tfvars z wartościami zmiennych dla środowiska developerskiego. Na ogół ten plik wykorzystuję lokalnie podczas testów skryptów Terraforma. W przykładzie wygląda on tak:

env = "dev"
resource_location = "westeurope"
app_service_plan_size = "B1"
app_service_plan_tier = "Basic"
database_sku = "Basic"
sql_server_login = "sql-admin"
sql_server_password = "KrLFJ3n7SLXQrmPApQLzcuohyUv5Nex5KHyt"
view raw dev2.tfvars hosted with ❤ by GitHub

Zasoby w Azure

Po przygotowaniu zmiennych możemy przejść teraz do tworzenia zasobów. Dla przypomnienia opis poszczególnych typów zasobów znajdziesz w dokumentacji azurerm – https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs. Zaczniemy od tego, co pokazałem w poprzednim wpisie Terraform i Azure, czyli konfiguracji samego Terraform i utworzenia grupy zasobów:

terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=2.46.0"
}
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "resource_group" {
name = "onlin-rg-${var.env}"
location = var.resource_location
}

Różnica głównie polega na sparametrowaniu nazwy grupy zasobów i wykorzystaniu zmiennej env jako ostatni człon nazwy (linijka 15) oraz użyciu zmiennej określającej region, w którym ma zostać utworzona grupa zasobów (linijka 16).

Kolejny zasób, jaki utworzymy to Application Insight:

resource "azurerm_application_insights" "app_insight" {
name = "onlin-ai-${var.env}"
location = azurerm_resource_group.resource_group.location
resource_group_name = azurerm_resource_group.resource_group.name
application_type = "web"
}

Konfiguracja jest tutaj dość standardowa, czyli określamy nazwę, grupę zasobów oraz lokalizację. Będzie to się przewijało przez większość tworzonych zasobów w Azure. Tutaj korzystam z kolejnej fajnej funkcjonalności Terraforma, którą jest możliwość odnoszenia się do wcześniej utworzonych zasobów. W tym przypadku używamy wcześniej utworzoną grupę zasobów. Odnosimy się poprzez podanie [typu zasobu].[jego nazwy].[właściwości zasobu]. Zobacz linijkę 3 oraz 4.

Możemy teraz przejść do utworzenia App Service Plan oraz App Service:

resource "azurerm_app_service_plan" "app_service_plan" {
name = "onlin-sp-${var.env}"
location = azurerm_resource_group.resource_group.location
resource_group_name = azurerm_resource_group.resource_group.name
kind = "app"
sku {
tier = var.app_service_plan_tier
size = var.app_service_plan_size
}
}
resource "azurerm_app_service" "app" {
name = "onlin-app-${var.env}"
location = azurerm_resource_group.resource_group.location
resource_group_name = azurerm_resource_group.resource_group.name
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
https_only = true
client_affinity_enabled = true
identity {
type = "SystemAssigned"
}
site_config {
dotnet_framework_version = "v5.0"
always_on = true
use_32_bit_worker_process = false
default_documents = [
"index.html"
]
}
app_settings = {
WEBSITE_RUN_FROM_PACKAGE = "1"
APPINSIGHTS_INSTRUMENTATIONKEY = azurerm_application_insights.app_insight.instrumentation_key
APPLICATIONINSIGHTS_CONNECTION_STRING = azurerm_application_insights.app_insight.connection_string
}
}
view raw appservice.tf hosted with ❤ by GitHub

Myślę, że większość właściwości jest dość jasna. Chciałbym tylko zaznaczyć tutaj sposób podpięcia Application Insight do App Service. Robimy to przez ustawienie app settings, gdzie odwołujemy się do właściwości wcześniej utworzonego Application Insight – linijki 36 oraz 37.

Ostatnią częścią jest utworzenie SQL Servera oraz bazy danych:

sql.tf

Podobnie jak wcześniej, większość właściwości jest moim zdaniem dość jasna. W tym przypadku chciałbym tylko zaznaczyć utworzenie ostatniego zasobu, czyli reguły firewall w SQL Service. Ustawiamy w niej dość specyficzne wartości adresów IP, którymi są same zera. W tym przypadku oznaczają one utworzenie reguły, która umożliwia korzystanie z SQL Servera przez zasoby znajdujące się w Azure. Jest to więc odpowiednik ustawienia „Allow Azure services and resources to access this server” z konfiguracji SQL Servera w Azure.

Cały plik z przykładu znajdziesz w repozytorium przygotowanym do tego wpisu – main.tf.

Utworzenie infrastruktury

Możemy w tym momencie przejść do utworzenia infrastruktury dla środowiska dev. W tym celu wystarczy wykonać komendę (oczywiście po wcześniejszej konfiguracji lokalnego środowiska opisanego w wpisie Terraform i Azure):

terraform apply -var-file="dev.tfvars"

Po dłuższej chwili zasoby zostaną utworzone:

Utworzone zasoby w Azure

Dla przypomnienia, usunięcie wszystkich utworzonych zasobów możemy wykonać z wykorzystaniem komendy:

terraform destroy -var-file="dev.tfvars"

Przykład

Tradycyjnie na githubie znajdziesz przykład do tego wpisu, w którym znajdują się wszystkie wspomniane powyżej pliki Terraforma – https://github.com/danielplawgo/TerraformAzure

Podsumowanie

W kolejnym wpisie dotyczącym Terraform i Azure pokazałem Ci przede wszystkim, w jaki sposób parametryzować szablony infrastruktury z wykorzystaniem zmiennych (typu Input). Następnie utworzyłem większą ilość zasobów w Azure. Jako przykład posłużyła mi prosta aplikacja webowa.

W kolejnym wpisie pokażę Ci, w jaki sposób wykonywać skrypty Terraform w Azure DevOps.

1 thought on “Terraform i Azure – przykład

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *