Hızlı Başlangıç: Terraform kullanarak özel uç nokta oluşturma

Bu hızlı başlangıçta terraform kullanarak özel uç nokta oluşturacaksınız. Özel uç nokta bir Azure SQL Veritabanı bağlanır. Özel uç nokta bir sanal ağ ve bir özel Etki Alanı Adı Sistemi (DNS) bölgesiyle ilişkilendirilir. Özel DNS bölgesi, özel uç nokta IP adresini çözümler. Sanal ağ, özel uç noktanın SQL Veritabanı örneğine bağlantısını test etmek için kullandığınız bir sanal makine içerir.

Betik, SQL sunucusu için rastgele bir parola ve sanal makine için rastgele bir SSH anahtarı oluşturur. Betik çalıştırıldığında, oluşturulan kaynakların adları çıkarılır.

Terraform , bulut altyapısının tanımlanmasını, önizlemesini ve dağıtımını sağlar. Terraform kullanarak HCL söz dizimlerini kullanarak yapılandırma dosyaları oluşturursunuz. HCL söz dizimi, Azure gibi bulut sağlayıcısını ve bulut altyapınızı oluşturan öğeleri belirtmenize olanak tanır. Yapılandırma dosyalarınızı oluşturduktan sonra, altyapı değişikliklerinizin dağıtılmadan önce önizlemesini görüntülemenizi sağlayan bir yürütme planı oluşturursunuz. Değişiklikleri doğruladıktan sonra, altyapıyı dağıtmak için yürütme planını uygularsınız.

Özel uç nokta hızlı başlangıcında oluşturulan kaynakların diyagramı.

Önkoşullar

Terraform kodunu uygulama

Not

Bu makalenin örnek kodu Azure Terraform GitHub deposunda bulunur.

Azure kaynaklarını yönetmek için Terraform'un nasıl kullanılacağını gösteren diğer makalelere ve örnek koda bakın

  1. Örnek Terraform kodunu test edip çalıştırmak ve geçerli dizin yapmak için bir dizin oluşturun.

  2. adlı main.tf bir dosya oluşturun ve aşağıdaki kodu ekleyin:

    resource "random_pet" "prefix" {
      prefix = var.resource_group_name_prefix
      length = 1
    }
    
    # Resource Group
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = "${random_pet.prefix.id}-rg"
    }
    
    # Virtual Network
    resource "azurerm_virtual_network" "my_terraform_network" {
      name                = "${random_pet.prefix.id}-vnet"
      address_space       = ["10.0.0.0/16"]
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    }
    
    # Subnet 1
    resource "azurerm_subnet" "my_terraform_subnet_1" {
      name                 = "subnet-1"
      resource_group_name  = azurerm_resource_group.rg.name
      virtual_network_name = azurerm_virtual_network.my_terraform_network.name
      address_prefixes     = ["10.0.0.0/24"]
    }
    
    # Public IP address for NAT gateway
    resource "azurerm_public_ip" "my_public_ip" {
      name                = "public-ip-nat"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      allocation_method   = "Static"
      sku                 = "Standard"
    }
    
    # NAT Gateway
    resource "azurerm_nat_gateway" "my_nat_gateway" {
      name                = "nat-gateway"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    }
    
    # Associate NAT Gateway with Public IP
    resource "azurerm_nat_gateway_public_ip_association" "example" {
      nat_gateway_id       = azurerm_nat_gateway.my_nat_gateway.id
      public_ip_address_id = azurerm_public_ip.my_public_ip.id
    }
    
    # Associate NAT Gateway with Subnet
    resource "azurerm_subnet_nat_gateway_association" "example" {
      subnet_id      = azurerm_subnet.my_terraform_subnet_1.id
      nat_gateway_id = azurerm_nat_gateway.my_nat_gateway.id
    }
    
    # Create public IP for virtual machine
    resource "azurerm_public_ip" "my_public_ip_vm" {
      name                = "public-ip-vm"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      allocation_method   = "Static"
      sku                 = "Standard"
    }
    
    # Create Network Security Group and rule
    resource "azurerm_network_security_group" "my_terraform_nsg" {
      name                = "nsg-1"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    
      security_rule {
        name                       = "SSH"
        priority                   = 1001
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "22"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
      }
    }
    
    # Create network interface
    resource "azurerm_network_interface" "my_terraform_nic" {
      name                = "nic-1"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    
      ip_configuration {
        name                          = "my_nic_configuration"
        subnet_id                     = azurerm_subnet.my_terraform_subnet_1.id
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = azurerm_public_ip.my_public_ip_vm.id
      }
    }
    
    # Connect the security group to the network interface
    resource "azurerm_network_interface_security_group_association" "example" {
      network_interface_id      = azurerm_network_interface.my_terraform_nic.id
      network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id
    }
    
    # Generate random text for a unique storage account name
    resource "random_id" "random_id" {
      keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = azurerm_resource_group.rg.name
      }
    
      byte_length = 8
    }
    
    # Create storage account for boot diagnostics
    resource "azurerm_storage_account" "my_storage_account" {
      name                     = "diag${random_id.random_id.hex}"
      location                 = azurerm_resource_group.rg.location
      resource_group_name      = azurerm_resource_group.rg.name
      account_tier             = "Standard"
      account_replication_type = "LRS"
    }
    
    # Create virtual machine
    resource "azurerm_linux_virtual_machine" "my_terraform_vm" {
      name                  = "vm-1"
      location              = azurerm_resource_group.rg.location
      resource_group_name   = azurerm_resource_group.rg.name
      network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
      size                  = "Standard_DS1_v2"
    
      os_disk {
        name                 = "myOsDisk"
        caching              = "ReadWrite"
        storage_account_type = "Premium_LRS"
      }
    
      source_image_reference {
        publisher = "Canonical"
        offer     = "0001-com-ubuntu-server-jammy"
        sku       = "22_04-lts-gen2"
        version   = "latest"
      }
    
      computer_name  = "hostname"
      admin_username = var.username
    
      admin_ssh_key {
        username   = var.username
        public_key = jsondecode(azapi_resource_action.ssh_public_key_gen.output).publicKey
      }
    
      boot_diagnostics {
        storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint
      }
    }
    
    # Create SQL server name
    resource "random_pet" "azurerm_mssql_server_name" {
      prefix = "sql"
    }
    
    # Random password for SQL server
    resource "random_password" "admin_password" {
      count       = var.admin_password == null ? 1 : 0
      length      = 20
      special     = true
      min_numeric = 1
      min_upper   = 1
      min_lower   = 1
      min_special = 1
    }
    
    locals {
      admin_password = try(random_password.admin_password[0].result, var.admin_password)
    }
    
    # Create SQL server
    resource "azurerm_mssql_server" "server" {
      name                         = random_pet.azurerm_mssql_server_name.id
      resource_group_name          = azurerm_resource_group.rg.name
      location                     = azurerm_resource_group.rg.location
      administrator_login          = var.admin_username
      administrator_login_password = local.admin_password
      version                      = "12.0"
    }
    
    # Create SQL database
    resource "azurerm_mssql_database" "db" {
      name      = var.sql_db_name
      server_id = azurerm_mssql_server.server.id
    }
    
    # Create private endpoint for SQL server
    resource "azurerm_private_endpoint" "my_terraform_endpoint" {
      name                = "private-endpoint-sql"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      subnet_id           = azurerm_subnet.my_terraform_subnet_1.id
    
      private_service_connection {
        name                           = "private-serviceconnection"
        private_connection_resource_id = azurerm_mssql_server.server.id
        subresource_names              = ["sqlServer"]
        is_manual_connection           = false
      }
    
      private_dns_zone_group {
        name                 = "dns-zone-group"
        private_dns_zone_ids = [azurerm_private_dns_zone.my_terraform_dns_zone.id]
      }
    }
    
    # Create private DNS zone
    resource "azurerm_private_dns_zone" "my_terraform_dns_zone" {
      name                = "privatelink.database.windows.net"
      resource_group_name = azurerm_resource_group.rg.name
    }
    
    # Create virtual network link
    resource "azurerm_private_dns_zone_virtual_network_link" "my_terraform_vnet_link" {
      name                  = "vnet-link"
      resource_group_name   = azurerm_resource_group.rg.name
      private_dns_zone_name = azurerm_private_dns_zone.my_terraform_dns_zone.name
      virtual_network_id    = azurerm_virtual_network.my_terraform_network.id
    }
    
  3. adlı outputs.tf bir dosya oluşturun ve aşağıdaki kodu ekleyin:

    output "resource_group_name" {
      description = "The name of the created resource group."
      value       = azurerm_resource_group.rg.name
    }
    
    output "virtual_network_name" {
      description = "The name of the created virtual network."
      value       = azurerm_virtual_network.my_terraform_network.name
    }
    
    output "subnet_name_1" {
      description = "The name of the created subnet 1."
      value       = azurerm_subnet.my_terraform_subnet_1.name
    }
    
    output "nat_gateway_name" {
      description = "The name of the created NAT gateway."
      value       = azurerm_nat_gateway.my_nat_gateway.name
    }
    
    output "sql_server_name" {
      value = azurerm_mssql_server.server.name
    }
    
    output "admin_password" {
      sensitive = true
      value     = local.admin_password
    }
    
  4. adlı provider.tf bir dosya oluşturun ve aşağıdaki kodu ekleyin:

    terraform {
      required_providers {
        azapi = {
          source  = "azure/azapi"
          version = "~>1.5"
        }
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    
    provider "azurerm" {
      features {
        resource_group {
          prevent_deletion_if_contains_resources = false
        }
      }
    }
    
  5. adlı ssh.tf bir dosya oluşturun ve aşağıdaki kodu ekleyin:

    resource "random_pet" "ssh_key_name" {
      prefix    = "ssh"
      separator = ""
    }
    
    resource "azapi_resource_action" "ssh_public_key_gen" {
      type        = "Microsoft.Compute/sshPublicKeys@2022-11-01"
      resource_id = azapi_resource.ssh_public_key.id
      action      = "generateKeyPair"
      method      = "POST"
    
      response_export_values = ["publicKey", "privateKey"]
    }
    
    resource "azapi_resource" "ssh_public_key" {
      type      = "Microsoft.Compute/sshPublicKeys@2022-11-01"
      name      = random_pet.ssh_key_name.id
      location  = azurerm_resource_group.rg.location
      parent_id = azurerm_resource_group.rg.id
    }
    
    output "key_data" {
      value = jsondecode(azapi_resource_action.ssh_public_key_gen.output).publicKey
    }
    
  6. adlı variables.tf bir dosya oluşturun ve aşağıdaki kodu ekleyin:

    variable "resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      default     = "rg"
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
    variable "username" {
      type        = string
      description = "The username for the local account that will be created on the new VM."
      default     = "azureuser"
    }
    
    variable "sql_db_name" {
      type        = string
      description = "The name of the SQL Database."
      default     = "SampleDB"
    }
    
    variable "admin_username" {
      type        = string
      description = "The administrator username of the SQL logical server."
      default     = "azureadmin"
    }
    
    variable "admin_password" {
      type        = string
      description = "The administrator password of the SQL logical server."
      sensitive   = true
      default     = null
    }
    

Terraform'u başlatma

Terraform dağıtımını başlatmak için terraform init komutunu çalıştırın. Bu komut, Azure kaynaklarınızı yönetmek için gereken Azure sağlayıcısını indirir.

terraform init -upgrade

Önemli noktalar:

  • -upgrade parametresi, gerekli sağlayıcı eklentilerini yapılandırmanın sürüm kısıtlamalarına uygun en yeni sürüme yükseltir.

Terraform yürütme planı oluşturma

Terraform planını çalıştırarak yürütme planı oluşturun.

terraform plan -out main.tfplan

Önemli noktalar:

  • komutu terraform plan bir yürütme planı oluşturur ancak yürütmez. Bunun yerine, yapılandırma dosyalarınızda belirtilen yapılandırmayı oluşturmak için hangi eylemlerin gerekli olduğunu belirler. Bu düzen, gerçek kaynaklarda değişiklik yapmadan önce yürütme planının beklentilerinizle eşleşip eşleşmediğini doğrulamanızı sağlar.
  • İsteğe bağlı -out parametresi, plan için bir çıkış dosyası belirtmenize olanak tanır. parametresinin -out kullanılması, gözden geçirdiğiniz planın tam olarak uygulanan plan olmasını sağlar.

Terraform yürütme planı uygulama

Yürütme planını bulut altyapınıza uygulamak için terraform apply komutunu çalıştırın.

terraform apply main.tfplan

Önemli noktalar:

  • Örnek terraform apply komut, daha önce komutunu çalıştırdığınızı terraform plan -out main.tfplanvarsayar.
  • parametresi için -out farklı bir dosya adı belirttiyseniz, çağrısında terraform applyaynı dosya adını kullanın.
  • parametresini -out kullanmadıysanız, parametresiz olarak çağırın terraform apply .

Sonuçları doğrulama

  1. Azure kaynak grubu adını alın.

    resource_group_name=$(terraform output -raw resource_group_name)
    
  2. SQL Server adını alın.

    sql_server=$(terraform output -raw sql_server)
    
  3. SQL Server özel uç noktasıyla ilgili ayrıntıları görüntülemek için az sql server show komutunu çalıştırın.

    az sql server show \
        --resource-group $resource_group_name \
        --name $sql_server --query privateEndpointConnections \
        --output tsv
    

Kaynakları temizleme

Terraform aracılığıyla oluşturulan kaynaklara artık ihtiyacınız kalmadığında aşağıdaki adımları uygulayın:

  1. terraform planını çalıştırın ve bayrağını destroy belirtin.

    terraform plan -destroy -out main.destroy.tfplan
    

    Önemli noktalar:

    • komutu terraform plan bir yürütme planı oluşturur ancak yürütmez. Bunun yerine, yapılandırma dosyalarınızda belirtilen yapılandırmayı oluşturmak için hangi eylemlerin gerekli olduğunu belirler. Bu düzen, gerçek kaynaklarda değişiklik yapmadan önce yürütme planının beklentilerinizle eşleşip eşleşmediğini doğrulamanızı sağlar.
    • İsteğe bağlı -out parametresi, plan için bir çıkış dosyası belirtmenize olanak tanır. parametresinin -out kullanılması, gözden geçirdiğiniz planın tam olarak uygulanan plan olmasını sağlar.
  2. Yürütme planını uygulamak için terraform apply komutunu çalıştırın.

    terraform apply main.destroy.tfplan
    

Azure'da Terraform sorunlarını giderme

Azure'da Terraform kullanırken karşılaşılan yaygın sorunları giderme.

Sonraki adımlar