0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Terraformでazure Database for Mysqlをフレキシブル サーバーでレプリケーションをしたい。

Posted at

AzureMysqlサーバのprimaryとreplicaを作ります。
また接続できる踏み台VMを一つ作ります。

main.tf
terraform {
  required_version = ">= 1.6.0"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=3.116.0"
    }
    random = {
      source  = "hashicorp/random"
      version = ">=3.5.0"
    }
  }
}

provider "azurerm" {
  features {
    resource_group {
      prevent_deletion_if_contains_resources = false
    }
  }
  subscription_id = ""
}

# ランダム文字列で名前の衝突を防止
resource "random_string" "unique" {
  length  = 6
  special = false
  upper   = false
}

#######################
# Resource Group
#######################
resource "azurerm_resource_group" "mysql_rg" {
  name     = "mysql-rg-${random_string.unique.result}"
  location = "westus2"
}

#######################
# Virtual Network & Subnets
#######################
resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-${random_string.unique.result}"
  resource_group_name = azurerm_resource_group.mysql_rg.name
  location            = azurerm_resource_group.mysql_rg.location
  address_space       = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "mysql_subnet" {
  name                 = "mysql-subnet-${random_string.unique.result}"
  resource_group_name  = azurerm_resource_group.mysql_rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.1.0/24"]

  delegation {
    name = "mysqlDelegation"
    service_delegation {
      name    = "Microsoft.DBforMySQL/flexibleServers"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"]
    }
  }
}

resource "azurerm_subnet" "vm_subnet" {
  name                 = "vm-subnet-${random_string.unique.result}"
  resource_group_name  = azurerm_resource_group.mysql_rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.2.0/24"]
}

resource "azurerm_subnet" "bastion_subnet" {
  name                 = "AzureBastionSubnet"
  resource_group_name  = azurerm_resource_group.mysql_rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.3.0/24"]
}

#######################
# NSG & Association
#######################
resource "azurerm_network_security_group" "mysql_nsg" {
  name                = "mysql-nsg-${random_string.unique.result}"
  location            = azurerm_resource_group.mysql_rg.location
  resource_group_name = azurerm_resource_group.mysql_rg.name

  security_rule {
    name                       = "AllowMySQL"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "3306"
    source_address_prefix      = "10.0.2.0/24"
    destination_address_prefix = "*"
  }
}

resource "azurerm_subnet_network_security_group_association" "mysql_nsg_assoc" {
  subnet_id                 = azurerm_subnet.mysql_subnet.id
  network_security_group_id = azurerm_network_security_group.mysql_nsg.id
}

resource "azurerm_network_security_group" "vm_nsg" {
  name                = "vm-nsg-${random_string.unique.result}"
  location            = azurerm_resource_group.mysql_rg.location
  resource_group_name = azurerm_resource_group.mysql_rg.name

  security_rule {
    name                       = "AllowSSH"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "22"
    source_address_prefix      = "10.0.3.0/24"
    destination_address_prefix = "*"
  }
}

resource "azurerm_subnet_network_security_group_association" "vm_nsg_assoc" {
  subnet_id                 = azurerm_subnet.vm_subnet.id
  network_security_group_id = azurerm_network_security_group.vm_nsg.id
}

#######################
# Private DNS
#######################
resource "azurerm_private_dns_zone" "mysql_dns" {
  name                = "privatelink.mysql.database.azure.com"
  resource_group_name = azurerm_resource_group.mysql_rg.name
}

resource "azurerm_private_dns_zone_virtual_network_link" "mysql_dns_link" {
  name                  = "mysql-link-${random_string.unique.result}"
  resource_group_name   = azurerm_resource_group.mysql_rg.name
  private_dns_zone_name = azurerm_private_dns_zone.mysql_dns.name
  virtual_network_id    = azurerm_virtual_network.vnet.id
}

#######################
# Bastion
#######################
resource "azurerm_public_ip" "bastion_ip" {
  name                = "bastion-ip-${random_string.unique.result}"
  location            = azurerm_resource_group.mysql_rg.location
  resource_group_name = azurerm_resource_group.mysql_rg.name
  allocation_method   = "Static"
  sku                 = "Standard"
}

resource "azurerm_bastion_host" "bastion" {
  name                = "bastion-${random_string.unique.result}"
  location            = azurerm_resource_group.mysql_rg.location
  resource_group_name = azurerm_resource_group.mysql_rg.name
  
  ip_configuration {
    name                 = "config"
    subnet_id            = azurerm_subnet.bastion_subnet.id
    public_ip_address_id = azurerm_public_ip.bastion_ip.id
  }
}

#######################
# VM
#######################
resource "azurerm_network_interface" "vm_nic" {
  name                = "vm-nic-${random_string.unique.result}"
  location            = azurerm_resource_group.mysql_rg.location
  resource_group_name = azurerm_resource_group.mysql_rg.name
  
  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.vm_subnet.id
    private_ip_address_allocation = "Dynamic"
  }
}

resource "azurerm_linux_virtual_machine" "vm" {
  name                  = "vm-${random_string.unique.result}"
  location              = azurerm_resource_group.mysql_rg.location
  resource_group_name   = azurerm_resource_group.mysql_rg.name
  size                  = "Standard_B1s"
  admin_username        = "azureuser"
  admin_password        = "AzureVMpass123!"
  disable_password_authentication = false
  network_interface_ids = [azurerm_network_interface.vm_nic.id]
  
  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }
  
  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-focal"
    sku       = "20_04-lts"
    version   = "latest"
  }
}

#######################
# MySQL - General Purpose SKUでレプリケーション対応
#######################
resource "azurerm_mysql_flexible_server" "primary" {
  name                   = "mysql-primary-${random_string.unique.result}"
  resource_group_name    = azurerm_resource_group.mysql_rg.name
  location               = azurerm_resource_group.mysql_rg.location
  
  # General Purpose SKU(レプリケーション対応)
  sku_name               = "GP_Standard_D2ds_v4"
  
  administrator_login    = "mysqladmin"
  administrator_password = "MySQLadmin123!"
  version                = "8.0.21"
  backup_retention_days  = 7
  
  # プライベートアクセスを有効化
  delegated_subnet_id    = azurerm_subnet.mysql_subnet.id
  private_dns_zone_id    = azurerm_private_dns_zone.mysql_dns.id
  
  storage {
    size_gb           = 20
    auto_grow_enabled = true
  }
  
  depends_on = [
    azurerm_private_dns_zone_virtual_network_link.mysql_dns_link,
    azurerm_subnet_network_security_group_association.mysql_nsg_assoc
  ]
}

# 読み取りレプリカ
resource "azurerm_mysql_flexible_server" "replica" {
  name                = "mysql-replica-${random_string.unique.result}"
  resource_group_name = azurerm_resource_group.mysql_rg.name
  location            = azurerm_resource_group.mysql_rg.location
  
  # レプリカモードを明示的に設定
  create_mode        = "Replica"
  source_server_id   = azurerm_mysql_flexible_server.primary.id
  
  # レプリカも同じGeneral Purpose SKUを使用
  sku_name = "GP_Standard_D2ds_v4"
  
  # レプリカも同じサブネットとDNSゾーンを使用
  delegated_subnet_id = azurerm_subnet.mysql_subnet.id
  private_dns_zone_id = azurerm_private_dns_zone.mysql_dns.id
  
  # ストレージ設定
  storage {
    auto_grow_enabled = true
  }
  
  depends_on = [
    azurerm_mysql_flexible_server.primary
  ]
}

#######################
# Outputs
#######################
output "resource_group_name" {
  value = azurerm_resource_group.mysql_rg.name
}

output "bastion_public_ip" {
  value = azurerm_public_ip.bastion_ip.ip_address
}

output "vm_private_ip" {
  value = azurerm_network_interface.vm_nic.private_ip_address
}

output "mysql_primary_fqdn" {
  value = azurerm_mysql_flexible_server.primary.fqdn
}

output "mysql_replica_fqdn" {
  value = azurerm_mysql_flexible_server.replica.fqdn
}

output "vm_ssh_command" {
  value = "az network bastion ssh --name ${azurerm_bastion_host.bastion.name} --resource-group ${azurerm_resource_group.mysql_rg.name} --target-resource-id ${azurerm_linux_virtual_machine.vm.id} --auth-type password --username azureuser"
}

output "unique_suffix" {
  value = random_string.unique.result
}

output "mysql_connection_commands" {
  value = <<EOT
プライマリ接続:
  mysql -h ${azurerm_mysql_flexible_server.primary.fqdn} -u mysqladmin -p

レプリカ接続:
  mysql -h ${azurerm_mysql_flexible_server.replica.fqdn} -u mysqladmin -p
EOT
}

順番

terraform apply -target=azurerm_resource_group.mysql_rg

terraform apply -target=azurerm_virtual_network.vnet
terraform apply -target=azurerm_subnet.mysql_subnet -target=azurerm_subnet.vm_subnet -target=azurerm_subnet.bastion_subnet

terraform apply -target=azurerm_network_security_group.mysql_nsg -target=azurerm_network_security_group.vm_nsg
terraform apply -target=azurerm_subnet_network_security_group_association.mysql_nsg_assoc -target=azurerm_subnet_network_security_group_association.vm_nsg_assoc

terraform apply -target=azurerm_private_dns_zone.mysql_dns -target=azurerm_private_dns_zone_virtual_network_link.mysql_dns_link

terraform apply -target=azurerm_public_ip.bastion_ip -target=azurerm_bastion_host.bastion

terraform apply -target=azurerm_network_interface.vm_nic -target=azurerm_linux_virtual_machine.vm

terraform apply -target=azurerm_mysql_flexible_server.primary

terraform apply -target=azurerm_mysql_flexible_server.replica

terraform apply

-auto-approveを付けてshファイルにして実行可能。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?